The attached patch adds the beginnings of Currah µSpeech emulation. The SP0256 speech systhesis chip is not yet emulated -- the names of the allophones are written to standard output instead of being 'played'.
Unfortunately, as memory mapped I/O is used, this patch slows Fuse down slightly even when the interface is not enabled.
'uspeech.rom' is 'currah.rom' in Phil's ROM collection.
The SP0256 was also used in several other speech synthesis peripherals for the Spectrum:
* Cheetah Sweet Talker
* dk'tronics Speech Synthesizer (probably a rebranded * µSpeech)
* Fuller Orator (and Fuller Master Unit)
The Sweet Talker's demo tape (ftp://ftp.worldofspectrum.org/pub/sinclair/games/c/Chatbox.tzx.zip) contains a program written in BASIC which serves as limited documentation for that interface.
Patches: #142
Wiki: Fuse 1.2 Release Plan
Wiki: Fuse 1.2.2 Release Plan
Wiki: Fuse 1.3.0 Release Plan
Wiki: Fuse 1.3.1 Release Plan
Wiki: Fuse 1.3.2 Release Plan
Wiki: Fuse 1.3.3 Plan
Wiki: Fuse 1.3.4 Release Plan
Wiki: Fuse 1.3.5 Release Plan
Wiki: Fuse 1.3.6 Release Plan
Wiki: Fuse 1.3.7 Release Plan
Wiki: Fuse 1.3.8 Release Plan
Wiki: Fuse 1.4.0 Release Plan
Wiki: Fuse 1.4.1 Release Plan
Wiki: Fuse 1.5.0 Release Plan
Wiki: Fuse 1.5.1 Release Plan
Wiki: Fuse 1.5.2 Release Plan
Wiki: Fuse 1.5.3 Release Plan
Wiki: Fuse 1.5.4 Release Plan
Wiki: Fuse 1.5.5 Release Plan
Wiki: Fuse 1.5.6 Release Plan
Wiki: Fuse 1.5.7 Release Plan
Wiki: Fuse 1.6.0 Release Plan
Wiki: Fuse Next Release Plan
Preliminary µSpeech emulation
Logged In: YES
user_id=207506
Originator: YES
The second program on the Fuller & Orator demo tape (ftp://ftp.worldofspectrum.org/pub/sinclair/utils/FullerBoxOratorDemonstration.tzx.zip) also serves as documentation for the Orator. It seems it uses port 0x9f, and I think bit 6 might be used to specify intonation.
Logged In: YES
user_id=29214
Originator: NO
Looks good to me once we get it outputting something useful. One very tiny point: any calls to abort() should use fuse_abort() which makes an attempt to restore the video mode; without this, the SVGAlib version leaves you without a working screen.
Timing emulation
Logged In: YES
user_id=207506
Originator: YES
I've attached a new version which uses events. There's still no actual audio, but there are pauses between allophones. BTW, the abort() calls are in coretest.
File Added: uspeech-2.diff
Update for changes in SVN head
I've attached an updated version, which applies to the head of the trunk. There are no changes in functionality.
I’ve attached a new version which actually works! It still needs some Fusification in places. As I intend to make Fuse more C99/POSIXy anyway, I’ve decided not to go too far down that path. The main thing left to do is to avoid the use of 64-bit integers and add as many of the other SP0256-based interfaces as is practical. Those that deliver an interrupt upon depletion of the FIFO will not fit brilliantly well into the model used in this patch. For these, it may be necessary to generate audio in small batches using an event.
Note: the sp0256_1.bin is a doubling of the sp0256-al2.bin file used in MAME with:
CRC32 = b504ac15
SHA1 = e60fcb5fa16ff3f3b69d36c7a6e955744d3feafc
MD5 = c6fe422a12d834b34c54956782ec5f81
The file expected by MAME is 2K long, whereas the code here expects a 4K file.
Thanks Stuart, that sounds very interesting.
There seems to be an official home of the so0256 al2 ROM here: http://www.spatula-city.org/~im14u2c/sp0256-al2/
Can we use this ROM for this emulation? I don't have access to MAME ROMs so can't try out the code.
Thanks, Fred. The ROM on Joe Zbiciak’s web site that you have linked to is exactly the same, except that the ordering of data bits is reversed, i.e. d7↔d0, d6↔d1, d5↔d2 and d4↔d3. There’s code in jzIntv’s ivoice.c, where I got this from, for reversing the order of the data bits when loading the ROM, but this is effectively unused, given that jzIntv emulates an SP0256-012 with its own Mattel-specific ROM. The MAME version of this code, devices/sound/sp0256.c (now that MESS is part of MAME; formerly emu/sound/sp0256.c) lacks this reversal of the data bits. Given that MAME does emulate the SP0256-AL2 and even includes µSpeech emulation I think it’s best to avoid this reversal of bit order. There’s a posting by Joe which explains some of this which may be worth reading.
I’m not sure whether the doubling up of the ROM’s content is accurate. The SP0256-AL2 datasheet refers to an 2K × 8-bit internal serial ROM (which it also calls a 16K[bit] ROM). The SP0256 can also use an external SPR016 2K × 8-bit serial ROM, and that datasheet for that makes mention of the “least significant 11 bits of the PC” and that “it is not necessary to load all 16 bits of address sequentially in one ASR load”, so perhaps we can safely make the same assumption about mirroring of the address space as we might make for a parallel ROM. I haven’t actually checked MAME’s behaviour, yet. If the file is only 2K long, the code in my patch will ignore the short item count returned by read() and the second half of the 4K ROM image buffer will be left as zeroes. This is one part of the code that we will want to Fusify, although we should avoid the usual ROM handling routines as these are geared towards images that map into the Z80’s address space.
The version of jzIntv that I based this on is jzIntv 1.0 beta 4. This seems to be newer than the code that is currently in MAME. Note that the code in jzIntv is licensed under the GPLed (version 2 or later), but that the code in MAME is not. However, the code in MAME seems pretty much the same as an earlier version of that of jzIntv.
Right now I’m only after feedback, but when I commit this, I intend to first commit a version of Joe’s original source with only simple modifications (reindenting / respacing, adopting POSIX types, replacing LOCAL with static, adding const, replacing iv/ivoice with sp0256), before committing the Fuse version of this code and adding it to Makefile.am along with µSpeech emulation, just as I would quite like to be able to see which parts we have modified ourselves.
What is important though is that we remove the mask[] array from any version of Joe’s ivoice.c that we commit: it is large and specific to the SP0256-12, and it is not GPLed AFAIK.
Thanks Stuart. I'm having problems using that approach - the page you link seems to say the expected ROM starts with 0x17 while the unswapped ROM starts with 0x38 but the one at Joe Zbiciak’s site starts with 0x07?:
Any ideas what I am missing?
As I understand, the expected ROM starts with 0xE8:
But Joe Zbiciak is talking about the sp0256-012 model...
The sp0256-al2 in MAME starts with 0xE0...
And the one at Joe Zbiciak’s site starts with 0x07...
Thanks Sergio - I think that in summary it would be good for the documentation for the interface give some guidance on what is required to get the emulation up and running.
Another thing we could possibly do is remove the SPB-640 emulation from this code. It seems to have been sufficiently entangled with the SP0256 emulation that I thought better of removing it just yet. The SP0256 does have a single-decle FIFO but the 64-decle FIFO of the SPB-640 should have been factored out. It’s not clear to me how to emulate an SP0256 without the SPB-640 attached, though. I can well imagine that there’s logic within the SP0256 for communication with an SPB-640 and emulation of that logic may well be correct, even without an SPB-640 present in a device.
HI Stuart,
I think your proposed minimal plan to get the code ready to commit looks good (naturally we also need to get snapshot support in etc.)
I don't think it is necessary to extract the SPB-640 code at this point - the peripheral is a bit obscure and unless some obvious harm can come of having it left in there I'd suggest leaving it in place.
I've been playing with this patch and looks brilliant. I think most other emulators use a set of dumped allophones rather than dealing with the SP0256 emulation.
I've noticed lots of clicks and pops in the speaker and I wonder if you are having the same audio experience. I've recorded two samples:
https://www.dropbox.com/s/8qdeqatipcousys/uspeech_capture.tar.bz2?dl=0
That seems to happen at the end of allophones. CPCWIKI states:
But I see a level 0 with some glitches. I've made another record from SpecEmu where there are some low sound, not sure if this is a repetition or a random noise, though.
Last edit: Sergio Baldoví 2015-12-06
Just out of interest, has this iconic Spectrum feature been forgotten about, it's been nearly two years ?
Just a crude update for the uspeech-4.diff to make it compatible with the 1.6.0 release. No functional changes whatsoever. It seems to work rather well though, considering its prototype nature. Unfortunately, I do not have enough knowledge of FUSE internals (yet) to turn it into release-ready code.
In case if someone is able to pick it up, the way I understand the following enhancements will help:
1. The sp0256_rdrom(...) routine needs to be updated to load sp0256_1.bin from a proper location (roms?). Perhaps, no need to double it in size, loading 2048 bytes and memcpy'ing it should work, right?
2. The game Booty does not seem to detect uSpeech presence, so something is missing in ports(?) emulation.
3. As I have no experience with the real hardware, Sergio's comments may need to be addressed, too.
Last edit: Vic Chwe 2023-06-05
Thank you Vic. I've fixed a few bits to make it working with current git version. Booty seems to work now.
Currently you need a uspeech.rom file (2 Kb) in roms folder:
and a sp0256_1.bin (2 Kb) file in the working directory:
The sp0256_1.bin rom file can be downloaded from spatula-city.org, but you need to reverse the bits:
Thanks a lot for reviewing it! Attached is an additional patch to be applied on top of your 0001-Initial-support-for-uSpeech-peripheral.patch. It changes the SP0256 ROM loading sequence (to be honest I am not quite sure about it) and adds necessary UI elements to manage sp0256_1.bin location. With the new init sequence, calling sp0256_do_frame() unconditionally didn't make much sense, so I added a simple "if" there.
Basically, I was trying to resolve the following:
1. sp0256_1.bin was always loaded and SP0256 was always initialised regardless of the uSpeech state. Removed sp0256_rdrom and implemented ROM loading logic in uspeech.c (hopefully, helps with implementing snapshot-related stuff). The ROM file is hardcoded to go to the "page 1" in SP0256, whatever that means. That's how original code was working. sp0256_init() is not used anymore.
2. Introduced menu controls to manage sp0256_1.bin settings
3. Cleaned up debugging output in sp0256.c, putting it behind ifdef/endif
I am not sure the memory allocation code is acceptable, I guess those needs to be converted to libspectrum_ routines. I'll keep looking at this.
Here is my attempt to get all bits together. This patch replaces the "sp0256-rom-ui.diff" I posted earlier. Key changes in these patches:
Thanks.
Update Jun 27 -- memory read/write fix. But Colour Clash (Romik, 1983) seems to be broken.
Last edit: Vic Chwe 2023-06-27
I've tested as many games as I could, pretty much everything seems to be working with the exception of Colour Clash. I do not understand how exactly uSpeech is supposed to be working there and quick disassembly doesn't show any access to relevant ports/addresses, but something is clearly broken when uSpeech is enabled. Any other game I tried seem to be fine.
Last edit: Vic Chwe 2023-07-03
Thank you Vic.
If there aren't different ROM versions there isn't any advantage by storing the ROM files. IMO it's OK to stick with this implementation for the time being. If we extend the SZX block, intonation high/normal would be a candidate to preserve.
It seems OK for now. If we implement other speech interfaces that use the SDP0256 chip, maybe we should treat the SDP0256 as a new Fuse module with its self-contained initialisation/destruction.
Seems good to me. I would detach uSpeech prefix name from SDP256 in ROM settings
as SP0256 chip is not only specific to uSpeech interface. Cheetah Sweet Talker and Fuller Orator also have it.
I would also rename sp0256_1.bin to a meaningful name like sp0256-al2.rom. I think there aren't interfaces that use other SP0256 chip version or that use external allophone ROMs.
I can't even play Colour Clash without uSpeech. The game is loaded in two parts (manual/game) and the later is faulty?
I will create a Git branch to ease further development.
Last edit: Sergio Baldoví 2023-07-04
Although some web sites refer uSpeech support for this title, the original documentation (the cassette sleeve) and the manual on the tape (the first part) have no reference to it, whatsoever. They only talk about joysticks (Kempston and Sinclair) support.
I can run the Romik's tzx fine on latest Fuse (Win), or do you mean "with uSpeech" instead of "without"?
Note that the addresses used by uSpeech on a speccy 16Kb (enough for Colour Clash) are 32597/32596 for the buffer pointer and 32593 for the next allophone (and below that for the remaining play buffer). Maybe this title has speech in a 16Kb speccy but not on a 48Kb one due to a shortcoming?
Last edit: Luis Faria 2023-07-04