May 18, 2015

zxsp 0.8.pre27: Multiface ONE, 128 and +3


Three new members in the family of supported extensions: The Multiface ONE, 128 and +3 from Romantic Robots.

This time i scrutinized the circuits into depth and therefore the emulation should be near perfect. :-) There were different roms used in the MF1, evtl. also in the MF128, i don't know – i have included the most common.

The Multiface ONE had a Kempston-style joystick port which could be disabled by cutting a wire, in case another device also used this port. You can disable this port in zxsp too. If you attached the Kempston interface (e.g. you have enabled the auto-attach option in the preferences) and then at some time attach the Multiface ONE, then disabling this port is not strictly required, because an already attached USB joystick will happen to be magically plugged in both interfaces, and then both devices will react the same when a program reads a byte from the Kempston port. But disabling this port in the MF1 is probably more intuitive and leads to less unexpected misbehavior.

While looking at the circuits i noticed some interesting points:

The Multifaces do only react to an NMI generated by the own red button, not to any NMI.

The presence of the Multiface ONE could be detected by the running program if it paged in the MF1 rom, and probably at some point games started to test for it and complained if they detected this device.

The presence of the Multiface 128 could no longer be detected by the running software; Romantic Robots had added a flag which stored the visibility state of the interface, i called it the camouflage flag. Same time they wrote "PIRACY IS ILLEGAL! MULTIFACE 128 is NOT designed to encourage piracy!" into their manual – Words and actions are not always the same.

The Multiface +3 was unusable if a program mapped ram to address $0000. Romantic Robots silently did not mention this in their manual. But the circuit of the MF+3 is very clear: It has a flag which monitors the "special mode" bit written to the MMU of the Spectrum +3 and, if set, ignores any press of the button. The reason is quite clear: Amstrad had reworked the ZX Spectrum bus connector of the +3 and added a second line to disable the internal rom at address $0000 with highest comfort, but no possibility to disable ram at this address. Yes, the Spectrum was not their most beloved child…

zxsp displays the state of the most interesting flags in the Multiface, which is, for the MF1, whether an NMI is pending (and the NMI routine very likely already has been executed and any more pressing this button has no effect), for the MF128 whether it is visible and for the +3 whether the ZX Spectrum MMU was set to "special mode" which means ram at $0000 and a disabled Multiface.

The red button of all Multifaces is gated by the output of the NMI pending flip flop which is set by this button: If the button set the FF, then the FF's output immediately disabled the button. To my best understanding this is unnecessary and it does not work:
  • I believe it was meant to immediately stop the signal from the button, so that recursive NMI processing in the CPU could not happen. But the NMI is edge triggered: once active, it can be held active for years without triggering another NMI.
  • Once the FF was reset (by software) this disable signal disappeared and the FF was immediately set again, if the button was still pressed.
The last point might be tested with the real device if you press the red button and keep it pressed while you type 'r' on the keyboard to exit the Multiface menu. Then the Multiface should be immediately entered again. But it's not sure whether it will, because for this the NMI must go away for a long enough time so another edge can be detected by the Z80 CPU, but it only goes away for a tiny moment, just the round-trip time through one gate and the flip flop. Note: this is not reproduced in zxsp.

So, to all of you who owned a Multiface: Test your skills and revive memories. ;-).

     ... Kio !

April 26, 2015

zxsp 0.8.pre26: hE(ll)(oo) k(ee)(OO)

Got it?

"Hello Kio !"

Yeah, my Spectrum speaks.

Inspector for the Currah µSpeech digital speech unit
Thanks to the work of Joe Zbiciak and Frank Palazzolo, who had reverse engineered the SP0256 speech processor, i was able to implement an emulation of this chip and then of the Currah µSpeech interface in zxsp.
The SP0256-AL2 contains a cascade of six 2-pole filters, a rom with filter coefficients for British/American language and a micro sequencer, which feeds these values into the filter coefficients. All digital. The output is an 8 bit PWM.

Despite of the very comprehensive informations about the SP0256 chip on their website there were still some bits not clear to me. I filled in the gaps by own tests and looking at what other people did. (not too many of them…) And i emulated the double RC filter after the PWM output. Yeah!

I added an option to switch between the original 8 bit sound and the unrestricted approx. 14 bit output, but i can't hear any difference. :-)

At the bottom of the inspector widget i added a scroller which displays the spoken allophones.

Though most allophones are spoken as expected, i believe some are emulated wrong, e.g. "1" and "Y" sound a little bit like a "bass bump" and "?", spoken as "kw(ee)r(ee)", sounds more like "kneenee". But there is little i can do about this.

I found that there are three pairs of allophone tokens in the µSpeech unit which refer to the same allophone: "(ck)" and "(gg)" which refer to KK2, "(oo)" and "(eau)" for OW and "(aa)" and "(ay)" for allophone EY. On the other side, tokens for two allophones are missing: DH2 and GG2. Given the fact, that "CLEAR" and "CLS" are both spoken as "CLEAR", the µSpeech seemed to be released a little bit fast these days.

Technically the Currah µSpeech isn't a Z80 peripheral. It's more like a 6502 add-on. It uses memory-mapped i/o! I had to extend my Z80 emulation to handle that sort of things…

Final problem was the rom switching for this little beast: It toggle's between it's 2k rom and the ZX Spectrum's internal rom when a RST7, that is, when the regular timer interrupt is executed. Actually, the way i handled rom switching up to now could not handle this: It detected an opcode fetch at address 0x0038 in one rom, switched the rom and restarted the CPU at this address. Then it detected an opcode fetch at address 0x0038 in the other rom, switched the rom and restarted the CPU at this address. And so forth.

A final word about the Blog Editor: It's getting worse every day i write my next post. It's really so bad now, that i write my blog post in a text editor on my Mac and copy&paste it into this editor.

April 18, 2015

zxsp 0.8.0pre25: 4.75 cm/s


long time not seen…

This release brings bug fixes, improved tape handling and the ability to load C sources.

Fixed bugs

(some are only intermediate bugs, not actually present in pre24)
  • Kempston mouse interface: Mouse grabbing & tracking did no longer work in Qt 5.x
  • Investigated and fixed audio interrupt drop-outs (thanks, Apple!)
  • Investigated and fixed paintEvent() overpainting child widgets in Qt 5.4 (thanks, Qt!)
  • Investigated regular unusually long interrupt runtime: WLAN-internet bridge! (thanks, Apple!)
  • Instand loading crashed at end of tape if tape was "running"
  • Inves could not load from tape recorder
  • Crash when accessing beyond allocated tracks of floppy, e.g. on empty side
  • Save tape utterly broken, crashed in CSW buffer decoding

Tape recorder

Load and save tape is now fully supported in all models.
Spectrum-type machines can load and save .tap, and .tzx.
ZX80 machines can load and save .o, .80 and .tzx.
ZX81 machines can load and save .p, .81, .p81 and .tzx.
The Jupiter Ace can load and save .tap and .tzx.

Additionally all models can load from real audio files like .wav and .aiff, but saving to audio file is not yet supported. E.g. you can insert a .wav file in the tape recorder and choose "save as" from the context menu and save it to a .tzx file.

All models can instant-load and instant-save tapes, if the rom routines are used. Loading tape files like a snapshot, e.g. by double clicking or by reload recent file, will set the tape recorder to instant-load, so, unless custom loading routines are used, loading a tape file is instantaneous.

While playing tapes now the typical sound is audible, which was missing for a while.

Record and play back from your Mac's audio-in and audio-out device is not yet fully supported. For recording i recommend to record the audio file with Audacity, but i have not yet tested whether it suffers from dropped audio interrupts, as zxsp did and, as far i can tell, even iTunes does (for playing). For playing the tape recorder of any machine can be used, though the audio level is currently a little bit low, because i didn't want to annoy you too much every time you load a tape. :-) Of course for playing real audio files any audio program can be used as well. ;-)

Recording your old tapes into .tap or .tzx files is now very easy: Just insert the audio file into the tape recorder and choose "save as" from the context menu to save it in another format.

Load assembler and C source files

Assembler source files are assembled using a built-in version of zasm, and the result, whatever it is, is loaded. zasm supports .sna, .z80, .o, .p and .tap files.

zxsp comes with a built-in executable of sdcc, a multi-target C compiler. Take a look at the zasm manual to see how to include C source files.