SPEECH hardware: consists of MOS 8706 custom ASIC and a Toshiba T6721A chip, that are making up synthethised speech out of multiple sequences of 12 bytes per (speech) frame. During speech, the ROM installs a new IRQ routine that sends 12 bytes at every IRQ to the speech chip. This means that a 200 msec long word will be made out by sending ~10x12 bytes. BASIC commands are: SAY, RATE, VOC, RDY SAY 0..260 or the appropriate word in brackets eg: SAY"HELP" RDY : function retrieving -1 if a new SAY command can be issued (speech hw not busy) VOC a,b : use external vocabulary at address 'a', the role of 'b' is unknown RATE a : speech speed (a = 1..10, default is 4) When using numeric parameters, the serial number of the spoken word (0..260) or the speech speed (1..10) will be stored at zero lap address $14/$15. MOS8706 Registers ================= $FD20 : command register (bit #0 - #3: command code; bit #7: latch command on 0->1) $FD21 : status and IRQ latch register (bits 0,1 and 7 seem to be used) - 4 kinds of system status read possible (1st 2 bits?) - 2 kinds of signals: ENDOFSPEECH, BUSY (bit 0 and 7?) bit #1 : FIFO ? bit #6 : EOS' (end of speech) from the T6721 bit #7 : DTRD $FD22 : speech data register Speech system ============= Synthesis: PARCOR, 8 KHz sampling output. Ceramic oscillator at 160 kHz. Built-in voltage type DA converter (9 bits). Number of operation bits: 15 bits. Number of filter stages:: 8 to 10 Speed of speech: 10 stages Bit rates: 2.4 (53 sec), 4.8, 9.6 kbps (96 bit per frame set by ROM = 12 bytes) Frame interval: 10 or 20 ms depending on synth condition setting (20 ms set by ROM) There's an 8 step per frame interpolator that creates intermediary parameter values out of the ones provided by the ROM. This is for all PARCOR parameters (1 pitch, 1 energy and the 10 lattice filter coefficients). ===== RAM locations accessed by the speech ROM software $d0/$d1 : serial number of word to be spoken, transformed to the address later $d2/$d3 : some speech parameter pointer address ??? $d4/$d5 : some speech data address ??? $d6/$d7 : some speech data address ??? $05f0-$05f4 : ? (used by IRQ routine) $067b-$067c : utterance lookup table address (1st parameter of VOC) $067d : 2nd parameter of VOC $067e-$0683 : 6 bytes BASIC vector backup location $0685-$068F : command buffer ? $0689 : speech speed as set by the RATE command (1..10, default: 4) $069d-$06ba : Speech ROM IRQ handler $06a7-$06a8 : IRQ vector backup location $06f9-$06fd : used during sending speech data $06fa : $0707 : some flag (more parameters coming??) $0708 : $0709 : $070a : set to 3 at $8040 $070d : some sort of flag? ===== Disassembly of the speech ROM of the Commodore 364 prototype unit The ROM is placed at the 4. lower slot (C3L) of the Commodore V364. ; Speech reset table . 8000 4c 9d 83 JMP $839d ; ROM cold start . 8003 4c 9d 83 JMP $839d ; ROM warm start (same...) . 8006 02 ??? . 8007 43 ??? 'C' ; 'CBM' needed to identify a valid lower ROM . 8008 42 ??? 'B' . 8009 4d ??? 'M' . 800a 4c ??? 'L' ; ; JUMP table ; . 800b 4c 26 84 JMP $8426 ; SRESET - Reset The Speech System/Stop Talking . 800d 4c 44 84 JMP $8444 ; SPSTAT - Get Status Of Speech Module . 8010 4c 52 84 JMP $8452 ; SAYIT - Say A Word . 8013 4c 64 84 JMP $8464 ; SPEED - Set Speaking Speed Of Synthesiser . 8016 4c 68 84 JMP $8468 ; SETTAB - Set Utterance Look Up Table Address ; start speech ; ; at this point $D0/$D1 has the nr of the word, or $D1 = $04 if ; it's a custom vocabulary ; ; the nr of the word still needs to be checked . 8019 a5 d1 LDA $d1 . 801b c9 04 CMP #$04 ; custom word data check??? . 801d 90 17 BCC $8036 . 801f e9 04 SBC #$04 . 8021 85 d1 STA $d1 . 8023 ad 7d 06 LDA $067d ; load second parameter of VOC to $070A . 8026 8d 0a 07 STA $070a . 8029 ad 7b 06 LDA $067b ; load address of word to $d2/d3? . 802c 85 d2 STA $d2 . 802e ad 7c 06 LDA $067c . 8031 85 d3 STA $d3 . 8033 4c 43 80 JMP $8043 * 8036 a9 f6 LDA #$f6 . 8038 85 d2 STA $d2 . 803a a9 92 LDA #$92 . 803c 85 d3 STA $d3 ; just load default address to $D2/$D3 ($92F6) . 803e a9 03 LDA #$03 . 8040 8d 0a 07 STA $070a * 8043 e6 d0 INC $d0 . 8045 d0 02 BNE $8049 . 8047 e6 d1 INC $d1 . 8049 e6 d0 INC $d0 . 804b d0 02 BNE $804f . 804d e6 d1 INC $d1 ; increase word count at $d0/1 by 2... . 804f 06 d0 ASL $d0 . 8051 26 d1 ROL $d1 ; ... and multiply it by 2 . 8053 20 2f 81 JSR $812f ; read voice data lookup offset, incr. $d2 pointers . 8056 48 PHA ; save to stack . 8057 20 2f 81 JSR $812f ; read voice data lookup offset 2. byte, incr. $d2 pointers . 805a 38 SEC . 805b e5 d0 SBC $d0 . 805d d0 01 BNE $8060 . 805f 18 CLC . 8060 68 PLA . 8061 e5 d1 SBC $d1 . 8063 b0 02 BCS $8067 . 8065 38 SEC . 8066 60 RTS ; . 8067 20 2f 81 JSR $812f ; . 806a 8d 09 07 STA $0709 . 806d 20 2f 81 JSR $812f . 8070 8d 08 07 STA $0708 . 8073 38 SEC . 8074 a5 d2 LDA $d2 . 8076 e9 04 SBC #$04 . 8078 48 PHA . 8079 b0 02 BCS $807d . 807b c6 d3 DEC $d3 . 807d 18 CLC . 807e 6d 08 07 ADC $0708 . 8081 8d 08 07 STA $0708 . 8084 a5 d3 LDA $d3 . 8086 6d 09 07 ADC $0709 . 8089 8d 09 07 STA $0709 . 808c 68 PLA . 808d 18 CLC . 808e 65 d0 ADC $d0 . 8090 85 d2 STA $d2 . 8092 a5 d3 LDA $d3 . 8094 65 d1 ADC $d1 . 8096 85 d3 STA $d3 . 8098 20 2f 81 JSR $812f . 809b 8d 0c 07 STA $070c . 809e 20 2f 81 JSR $812f . 80a1 18 CLC . 80a2 65 d2 ADC $d2 . 80a4 48 PHA . 80a5 ad 0c 07 LDA $070c . 80a8 65 d3 ADC $d3 . 80aa 85 d3 STA $d3 . 80ac 68 PLA . 80ad e6 d0 INC $d0 . 80af d0 02 BNE $80b3 . 80b1 e6 d1 INC $d1 . 80b3 18 CLC . 80b4 e5 d0 SBC $d0 . 80b6 85 d2 STA $d2 . 80b8 a5 d3 LDA $d3 . 80ba e5 d1 SBC $d1 . 80bc 85 d3 STA $d3 . 80be 20 2f 81 JSR $812f . 80c1 8d 8d 06 STA $068d . 80c4 4a LSR . 80c5 4a LSR ; divide by 4 . 80c6 29 fc AND #$fc . 80c8 8d 8b 06 STA $068b . 80cb 29 30 AND #$30 . 80cd 8d 07 07 STA $0707 . 80d0 20 3b 81 JSR $813b ; call init speech sub . 80d3 ad 15 03 LDA $0315 ; saves the IRQ vector at $0314/5 to $06a8/9 . 80d6 8d a8 06 STA $06a8 . 80d9 ad 14 03 LDA $0314 . 80dc 8d a7 06 STA $06a7 . 80df a9 06 LDA #$06 ; overwrites IRQ vector to $069d . 80e1 8d 15 03 STA $0315 . 80e4 a9 9d LDA #$9d . 80e6 8d 14 03 STA $0314 . 80e9 2c 21 fd BIT $fd21 ; waiting for the 1st bit of FD21 to be set high . 80ec 50 fb BVC $80e9 ; end of prevoius word is checked probably this way . 80ee a0 00 LDY #$00 . 80f0 8c 0e 07 STY $070e . 80f3 8c 0d 07 STY $070d . 80f6 b9 85 06 LDA $0685,Y ; read the init sequence bytes . 80f9 29 0f AND #$0f ; only the lowest 4 bits are connected to the 6721 . 80fb 20 14 81 JSR $8114 ; stuff the values to the "pretty please" register . 80fe c8 INY . 80ff c0 09 CPY #$09 ; loop 10 times . 8101 d0 f3 BNE $80f6 ; write a SPEECH RESET sequence to the command register . 8103 a0 00 LDY #$00 . 8105 20 78 84 JSR $8478 ; jump to feed speech paramter subroutine . 8108 a9 01 LDA #$01 ; Speech start (also releases the status ROM DATA ERROR) . 810a 20 14 81 JSR $8114 . 810d a9 03 LDA #$03 . 810f 8d 21 fd STA $fd21 ; store 3 to IRQ latch register ($FD21) . 8112 18 CLC . 8113 60 RTS ; Send speech command (into the infamous "pretty please" register) . 8114 8d 20 fd STA $fd20 ; called from $83AA . 8117 09 80 ORA #$80 ; connects to WRT line of the T6721A . 8119 8d 20 fd STA $fd20 ; on 0 -> 1 transition command gets latched . 811c 60 RTS ; set up before sending speech parameters . 811d ad 07 07 LDA $0707 . 8120 f0 07 BEQ $8129 . 8122 e6 d0 INC $d0 ; increase read low byte of address for speech data . 8124 d0 08 BNE $812e ; not zero, then return . 8126 4c 5a 81 JMP $815a . 8129 20 2f 81 JSR $812f . 812c 91 d0 STA ($d0),Y . 812e 60 RTS ; entry point for parameter fetch from Speech ROM . 812f a0 00 LDY #$00 . 8131 20 97 84 JSR $8497 ; read one byte from the Speech ROM . 8134 e6 d2 INC $d2 ; advance with the ROM pointer . 8136 d0 02 BNE $813a . 8138 e6 d3 INC $d3 . 813a 60 RTS ; init speech parameter buffer & variables (called from $80d0) . 813b a0 ff LDY #$ff . 813d 8c 02 07 STY $0702 . 8140 c8 INY . 8141 8c 00 07 STY $0700 ; $700 = 0 . 8144 8c 06 07 STY $0706 ; $706 = 0 . 8147 a9 40 LDA #$40 . 8149 8d 05 07 STA $0705 ; $705 = $40 . 814c a9 06 LDA #$06 . 814e 85 d1 STA $d1 . 8150 a9 ff LDA #$ff . 8152 85 d0 STA $d0 ; address ($D0/$D1) = $6FF . 8154 98 TYA ; AC = Y = 0 . 8155 91 d0 STA ($d0),Y ; ($6FF = 0) . 8157 c6 d0 DEC $d0 . 8159 60 RTS ; we end up here if the 2nd speech parameter is coming (?) . 815a 8a TXA . 815b 48 PHA ; save X to stack . 815c 20 94 88 JSR $8894 . 815f d0 2b BNE $818c . 8161 a0 0f LDY #$0f ; repeat 16 times . 8163 a9 f0 LDA #$f0 . 8165 85 d0 STA $d0 . 8167 a9 ff LDA #$ff . 8169 91 d0 STA ($d0),Y . 816b 88 DEY . 816c d0 fb BNE $8169 ; fill area pointed by $D0 with $FF ($06f0-$06ff) . 816e ad 0e 07 LDA $070e . 8171 d0 0d BNE $8180 ; if not zero dont use constant but go further . 8173 a9 80 LDA #$80 . 8175 91 d0 STA ($d0),Y ; ($d0),Y <- $80 . 8177 8c 0e 07 STY $070e ; 070e = 0 . 817a 8c 0d 07 STY $070d ; 070d = 0 . 817d 68 PLA . 817e aa TAX ; restore X from stack . 817f 60 RTS ; speech data decompression? . 8180 c8 INY . 8181 a9 f8 LDA #$f8 . 8183 91 d0 STA ($d0),Y ; ($d0),Y <- $F8 . 8185 88 DEY . 8186 ad 0d 07 LDA $070d . 8189 4c 75 81 JMP $8175 . 818c 48 PHA . 818d 4d 02 07 EOR $0702 . 8190 8d 02 07 STA $0702 . 8193 68 PLA . 8194 0a ASL . 8195 0a ASL ; AC = AC << 2 . 8196 30 0d BMI $81a5 ; MSB now set? jump... (original AC & $20) . 8198 b0 03 BCS $819d ; (original AC & $40 != 0)? jump... . 819a 4c 37 82 JMP $8237 . 819d 48 PHA . 819e 2c 02 07 BIT $0702 . 81a1 70 2b BVS $81ce . 81a3 50 0c BVC $81b1 . 81a5 48 PHA . 81a6 2c 02 07 BIT $0702 . 81a9 70 1d BVS $81c8 . 81ab 20 27 89 JSR $8927 . 81ae 8d 04 07 STA $0704 . 81b1 a9 92 LDA #$92 . 81b3 85 d7 STA $d7 . 81b5 ad 04 07 LDA $0704 . 81b8 0a ASL . 81b9 0a ASL . 81ba 18 CLC . 81bb 6d 04 07 ADC $0704 . 81be 69 a6 ADC #$a6 . 81c0 85 d6 STA $d6 . 81c2 90 72 BCC $8236 . 81c4 e6 d7 INC $d7 . 81c6 d0 6e BNE $8236 . 81c8 20 44 89 JSR $8944 . 81cb 8d 03 07 STA $0703 . 81ce a9 00 LDA #$00 . 81d0 85 d7 STA $d7 . 81d2 ad 03 07 LDA $0703 . 81d5 0a ASL . 81d6 26 d7 ROL $d7 . 81d8 0a ASL . 81d9 26 d7 ROL $d7 . 81db 18 CLC . 81dc 6d 03 07 ADC $0703 . 81df 90 02 BCC $81e3 . 81e1 e6 d7 INC $d7 . 81e3 0a ASL . 81e4 26 d7 ROL $d7 . 81e6 18 CLC . 81e7 6d 03 07 ADC $0703 . 81ea 90 02 BCC $81ee . 81ec e6 d7 INC $d7 . 81ee 2c 02 07 BIT $0702 . 81f1 30 38 BMI $822b . 81f3 a8 TAY . 81f4 a5 d2 LDA $d2 . 81f6 48 PHA . 81f7 a5 d3 LDA $d3 . 81f9 48 PHA . 81fa 98 TYA . 81fb 18 CLC . 81fc 6d 08 07 ADC $0708 . 81ff 85 d2 STA $d2 . 8201 ad 09 07 LDA $0709 . 8204 65 d7 ADC $d7 . 8206 85 d3 STA $d3 . 8208 a9 07 LDA #$07 . 820a 85 d7 STA $d7 . 820c a9 17 LDA #$17 . 820e 85 d6 STA $d6 ; address $0717 to $d6/$d7 . 8210 a0 00 LDY #$00 ; Y = 0 . 8212 98 TYA ; A = Y . 8213 48 PHA ; save AC to stack . 8214 20 2f 81 JSR $812f ; read bytes from Speech ROM . 8217 aa TAX ; X = A . 8218 68 PLA ; pull AC from stack . 8219 a8 TAY ; Y = A . 821a 8a TXA ; A = X . 821b 91 d6 STA ($d6),Y ; copy to $0717- . 821d c8 INY . 821e c0 0b CPY #$0b ; 12 bytes???! . 8220 d0 f0 BNE $8212 . 8222 68 PLA ; pull AC from stack . 8223 85 d3 STA $d3 . 8225 68 PLA ; pull AC from stack . 8226 85 d2 STA $d2 . 8228 4c 36 82 JMP $8236 . 822b 18 CLC . 822c 69 19 ADC #$19 . 822e 85 d6 STA $d6 . 8230 a9 8a LDA #$8a . 8232 65 d7 ADC $d7 . 8234 85 d7 STA $d7 * 8236 68 PLA . 8237 0a ASL . 8238 10 0c BPL $8246 . 823a 48 PHA . 823b 20 e4 88 JSR $88e4 . 823e 18 CLC . 823f 6d 05 07 ADC $0705 . 8242 8d 05 07 STA $0705 . 8245 68 PLA . 8246 0a ASL . 8247 10 0e BPL $8257 . 8249 48 PHA . 824a 20 e4 88 JSR $88e4 . 824d 18 CLC . 824e ed 05 07 SBC $0705 . 8251 49 ff EOR #$ff . 8253 8d 05 07 STA $0705 . 8256 68 PLA . 8257 0a ASL . 8258 10 0c BPL $8266 . 825a 48 PHA . 825b 20 06 89 JSR $8906 . 825e 18 CLC . 825f 6d 06 07 ADC $0706 . 8262 8d 06 07 STA $0706 . 8265 68 PLA . 8266 0a ASL . 8267 10 10 BPL $8279 . 8269 20 06 89 JSR $8906 . 826c 49 ff EOR #$ff . 826e 38 SEC . 826f 6d 06 07 ADC $0706 . 8272 10 02 BPL $8276 . 8274 a9 00 LDA #$00 . 8276 8d 06 07 STA $0706 . 8279 2c 02 07 BIT $0702 . 827c 50 56 BVC $82d4 . 827e a0 0a LDY #$0a . 8280 b1 d6 LDA ($d6),Y . 8282 8d 0f 07 STA $070f . 8285 29 03 AND #$03 . 8287 4a LSR . 8288 6a ROR . 8289 0d 05 07 ORA $0705 . 828c 6a ROR . 828d 8d f5 06 STA $06f5 . 8290 ae 06 07 LDX $0706 . 8293 d0 03 BNE $8298 . 8295 4c 3f 83 JMP $833f . 8298 bd 88 83 LDA $8388,X . 829b 6a ROR . 829c 8d f4 06 STA $06f4 . 829f 88 DEY . 82a0 b1 d6 LDA ($d6),Y . 82a2 99 f6 06 STA $06f6,Y . 82a5 88 DEY . 82a6 10 f8 BPL $82a0 . 82a8 c8 INY . 82a9 ad 0e 07 LDA $070e . 82ac d0 07 BNE $82b5 . 82ae a9 f4 LDA #$f4 . 82b0 85 d0 STA $d0 . 82b2 68 PLA . 82b3 aa TAX . 82b4 60 RTS . 82b5 ad 0d 07 LDA $070d . 82b8 0a ASL . 82b9 0a ASL . 82ba 0a ASL . 82bb 0a ASL . 82bc 0a ASL ; multiply by 32 ($20) and throw away? . 82bd a2 04 LDX #$04 . 82bf a9 f4 LDA #$f4 . 82c1 85 d0 STA $d0 . 82c3 b1 d0 LDA ($d0),Y . 82c5 2a ROL ; rotate left (thus multiply by 2) with carry... . 82c6 91 d0 STA ($d0),Y ; ...for all 4 bytes at $06f4 - $06f7 . 82c8 e6 d0 INC $d0 . 82ca d0 f7 BNE $82c3 . 82cc 2e 0d 07 ROL $070d . 82cf ca DEX . 82d0 d0 ed BNE $82bf ; repeat this 4 times . 82d2 f0 da BEQ $82ae . 82d4 a0 04 LDY #$04 . 82d6 ae 06 07 LDX $0706 . 82d9 f0 64 BEQ $833f . 82db bd 88 83 LDA $8388,X . 82de 0a ASL . 82df 2a ROL . 82e0 2a ROL . 82e1 8d f9 06 STA $06f9 . 82e4 2a ROL . 82e5 29 07 AND #$07 . 82e7 8d fa 06 STA $06fa . 82ea b1 d6 LDA ($d6),Y . 82ec 99 fb 06 STA $06fb,Y . 82ef 88 DEY . 82f0 10 f8 BPL $82ea . 82f2 c8 INY . 82f3 8d 0f 07 STA $070f . 82f6 29 fc AND #$fc . 82f8 99 fb 06 STA $06fb,Y . 82fb ad 0e 07 LDA $070e . 82fe f0 18 BEQ $8318 . 8300 ad f9 06 LDA $06f9 . 8303 29 f0 AND #$f0 . 8305 0d 0d 07 ORA $070d . 8308 8d f9 06 STA $06f9 . 830b 8c 0e 07 STY $070e . 830e 8c 0d 07 STY $070d . 8311 a9 f9 LDA #$f9 . 8313 85 d0 STA $d0 . 8315 68 PLA . 8316 aa TAX . 8317 60 RTS . 8318 a2 04 LDX #$04 . 831a 18 CLC . 831b a9 f9 LDA #$f9 . 831d 85 d0 STA $d0 ; set address to %06f9 . 831f b1 d0 LDA ($d0),Y . 8321 2a ROL . 8322 91 d0 STA ($d0),Y . 8324 e6 d0 INC $d0 . 8326 d0 f7 BNE $831f ; for all parameters $06f9-$06fd . 8328 2e 0d 07 ROL $070d . 832b ca DEX . 832c d0 ed BNE $831b . 832e a9 0f LDA #$0f . 8330 2d 0d 07 AND $070d . 8333 8d 0d 07 STA $070d . 8336 ee 0e 07 INC $070e . 8339 a9 fa LDA #$fa . 833b 85 d0 STA $d0 . 833d d0 d6 BNE $8315 . 833f a0 09 LDY #$09 . 8341 8a TXA . 8342 99 f6 06 STA $06f6,Y . 8345 88 DEY . 8346 10 fa BPL $8342 . 8348 a9 3f LDA #$3f . 834a 8d f5 06 STA $06f5 . 834d a9 01 LDA #$01 . 834f 8d f4 06 STA $06f4 . 8352 4c a8 82 JMP $82a8 ; called from $8894 with a JSR, so address will be on stack . 8355 68 PLA ; -> $00 . 8356 85 d4 STA $d4 . 8358 68 PLA ; -> $0C . 8359 85 d5 STA $d5 . 835b a9 01 LDA #$01 . 835d a0 01 LDY #$01 . 835f a2 00 LDX #$00 . 8361 0e 00 07 ASL $0700 . 8364 d0 0f BNE $8375 . 8366 48 PHA ; save ACC and Y . 8367 98 TYA . 8368 48 PHA . 8369 20 2f 81 JSR $812f . 836c 8d 01 07 STA $0701 . 836f 68 PLA . 8370 a8 TAY . 8371 68 PLA ; restore ACC and Y . 8372 ee 00 07 INC $0700 . 8375 c8 INY . 8376 0a ASL . 8377 4e 01 07 LSR $0701 . 837a f1 d4 SBC ($d4),Y . 837c f0 02 BEQ $8380 . 837e 10 e1 BPL $8361 . 8380 71 d4 ADC ($d4),Y . 8382 88 DEY . 8383 d0 fb BNE $8380 . 8385 a8 TAY . 8386 b1 d4 LDA ($d4),Y . 8388 60 RTS ; . 8389 02 ??? . 838a 04 ??? . 838b 06 08 ASL $08 . 838d 0a ASL . 838e 0c ??? . 838f 10 14 BPL $83a5 . 8391 18 CLC . 8392 1e 24 2e ASL $2e24,X . 8395 3a ??? . 8396 46 56 LSR $56 . 8398 6c 86 a6 JMP ($a686) . 839b cc fc ; Inititalise * 839d a2 08 LDX #$08 ; called from $8000 . 839f bd 1d 84 LDA $841d,X ; copy ROM paging routines to . 83a2 9d 85 06 STA $0685,X ; RAM area starting from $0685 . 83a5 ca DEX . 83a6 10 f7 BPL $839f . 83a8 a9 09 LDA #$09 . 83aa 20 14 81 JSR $8114 ; deals with the $FD20 . 83ad a9 06 LDA #$06 . 83af 85 d1 STA $d1 . 83b1 a9 8e LDA #$8e ; filling zero lap . 83b3 85 d0 STA $d0 . 83b5 a9 88 LDA #$88 . 83b7 85 d3 STA $d3 . 83b9 a9 37 LDA #$37 . 83bb 85 d2 STA $d2 . 83bd a0 00 LDY #$00 . 83bf b1 d2 LDA ($d2),Y ; copies data starting from $8837 . 83c1 91 d0 STA ($d0),Y ; to $068e . 83c3 e6 d2 INC $d2 . 83c5 d0 02 BNE $83c9 . 83c7 e6 d3 INC $d3 . 83c9 e6 d0 INC $d0 . 83cb d0 02 BNE $83cf . 83cd e6 d1 INC $d1 . 83cf a5 d3 LDA $d3 . 83d1 c9 88 CMP #$88 . 83d3 d0 ea BNE $83bf . 83d5 a5 d2 LDA $d2 . 83d7 c9 94 CMP #$94 . 83d9 d0 e4 BNE $83bf . 83db a0 ff LDY #$ff . 83dd a2 ff LDX #$ff . 83df ca DEX . 83e0 d0 fd BNE $83df . 83e2 88 DEY . 83e3 d0 f8 BNE $83dd ; seems to be waiting... 256x256 times . 83e5 8e 7b 06 STX $067b ; putting 0 to addresses below . 83e8 8e 7c 06 STX $067c ; NOTE: self modifying code! . 83eb 8e 7d 06 STX $067d . 83ee 8e 84 06 STX $0684 . 83f1 a9 0b LDA #$0b . 83f3 20 14 81 JSR $8114 ; calling the $FD20 stuff again . 83f6 a2 05 LDX #$05 . 83f8 bd 0c 03 LDA $030c,X ; saving original BASIC vectors . 83fb 9d 7e 06 STA $067e,X ; to area starting from $067e . 83fe ca DEX . 83ff 10 f7 BPL $83f8 . 8401 a2 05 LDX #$05 . 8403 bd 17 84 LDA $8417,X ; loading new BASIC vectors to accu . 8406 9d 0c 03 STA $030c,X ; overwriting BASIC vectors . 8409 ca DEX . 840a 10 f7 BPL $8403 ; back if not finished yet . 840c a9 06 LDA #$06 ; overwriting the BASIC symbol evaluation vector . 840e 8d 0b 03 STA $030b . 8411 a9 bb LDA #$bb . 8413 8d 0a 03 STA $030a ; to address $06BB ! . 8416 60 RTS ; return from sub . 8417 af ??? . 8418 06 a9 ASL $a9 . 841a 06 ac ASL $ac . 841c 06 02 ASL $02 . 841e 0a ASL . 841f 04 ??? . 8420 05 04 ORA $04 . 8422 06 00 ASL $00 . 8424 07 ??? . 8425 00 BRK ; ; SRESET - Reset The Speech System/Stop Talking ; ; ENTRY CONDITIONS: NONE ; ; RETURNED INFORMATION: Accumulator is destroyed. ; ; This command resets the synthesizer hardware. ; It should be included in applications programs for ; initialization purposes and may be used to stop speech ; output in mid-utterance. ; . 8426 a9 00 LDA #$00 . 8428 8d 21 fd STA $fd21 ; store 0 to $FD21 . 842b 20 44 84 JSR $8444 ; get Speech status . 842e f0 0f BEQ $843f ; skip reset if speech IRQ was not installed ; end speech job, reinstall original IRQ . 8430 08 PHP . 8431 78 SEI ; mask interrupt . 8432 ad a8 06 LDA $06a8 ; put back the original IRQ vector we just saved . 8435 8d 15 03 STA $0315 . 8438 ad a7 06 LDA $06a7 . 843b 8d 14 03 STA $0314 . 843e 28 PLP ; pull status from stack . 843f a9 02 LDA #$02 . 8441 4c 14 81 JMP $8114 ; Write Speech stop command to T6721 and RESET ; ; SPSTAT - Get Status Of Speech Module ; ; ENTRY CONDITIONS: NONE ; ; RETURNED INFORMATION: ACC=0 if ready/- 1 if busy talking. ; ; The N and Z bits of the processor status word are set accordingly. ; This command may be used to determine whether the speech module has ; completed previous "sayit" requests and whether a new "sayit" request ; can be handled immediately. ; ; Technically, it checks if speech IRQ is installed, and return zero if not. . 8444 08 PHP . 8445 a9 06 LDA #$06 . 8447 cd 15 03 CMP $0315 ; speech IRQ routine still active? . 844a f0 02 BEQ $844e . 844c a9 00 LDA #$00 . 844e 28 PLP . 844f 09 00 ORA #$00 . 8451 60 RTS ; ; SAYIT - Say A Word ; ; ENTRY CONDITIONS: ; X-reg = most significant portion of the word number. ; A-reg = least significant portion. ; ; RETURNED INFORMATION: All registers destroyed. ; ; This command initiates the synthesis of a word or phrase. ; Control is returned to the calling program almost immediately if the module ; is not already talking. If the module is talking, then control will not be ; returned until the current request can be initiated. Words number 0 through ; 255 are words which are in the speech module. Words number 256 through 4095 ; are interpreted as located in the user's program space. ; ; CAUTION: Special care should be taken to ensure that no other process in the ; system that generates IRQ's is active when the calls to the speech synthesizer ; are made. This includes the RS-232 channel and the serial bus devices. The ; RS-232 channel is the only channel which must actually be CLOSED. The serial ; bus channels may be open and may be left opened, but must not actively transmit ; data. It is recommended that programs which wish to perform series use I/O check, ; via SPSTAT to ensure that speech output is complete before initiating the operations. ; . 8452 48 PHA . 8453 20 44 84 JSR $8444 . 8456 d0 fb BNE $8453 ; loop until prev. speech finished? . 8458 68 PLA . 8459 86 d1 STX $d1 . 845b 85 d0 STA $d0 . 845d 08 PHP . 845e 78 SEI . 845f 20 19 80 JSR $8019 ; call SPEECH address calc. . 8462 28 PLP . 8463 60 RTS ; ; SPEED - Set Speaking Speed Of Synthesiser ; ; ENTRY CONDITIONS: A-reg = desired speed code from 1 ...10. ; ; RETURNED IN FORMATION: No register affected. ; ; The SPEED capability is used to speed up or slow down the speaking rate of the ; synthesizer. The range of speed variations Is from .65X decrease In the speed ; (speed code = 10) to a 1 .4X increase (speed code 1) Normal speed is speed code 4. ; . 8464 8d 89 06 STA $0689 . 8467 60 RTS ; ; SETTAB - Set Utterance Look Up Table Address ; ; ENTRY CONDITIONS: A-reg = lower byte of address. X-reg = upper byte of address. ; Y-reg = second parameter of VOC ; ; RETURNED INFORMATION: None. ; ; The SETTAB function is used to tell the speech ROM the starting memory address ; of user supplied speech data. It is identical to the BASIC VOC command. This ; command MUST be employed prior to any attempts to generate speech with utterance ; numbers greater than 255. ; . 8468 8d 7b 06 STA $067b . 846b 8e 7c 06 STX $067c . 846e 8c 7d 06 STY $067d . 8471 60 RTS ; check status/handshake . 8472 ad 21 fd LDA $fd21 ; check $FD21 . 8475 30 01 BMI $8478 ; branch if the 7th bit is set as high (speech data still expected?) . 8477 60 RTS ; else return from sub ; write speech data . 8478 20 1d 81 JSR $811d ; set up address $D0/$D1 to read next speech data from . 847b b1 d0 LDA ($d0),Y . 847d 8d 22 fd STA $fd22 ; store the value pointed by $D0-D1 to $FD22 . 8480 4c 72 84 JMP $8472 ; IRQ handler entry point (when speech is being done) . 8483 a9 03 LDA #$03 ; load 3 to accu . 8485 a0 00 LDY #$00 . 8487 2c 21 fd BIT $fd21 ; checking for the 1st 2 bits of FD21 if set high . 848a f0 04 BEQ $8490 ; return if neither of the first two bits are set (no speech event) . 848c 30 ea BMI $8478 ; branch if the 7th bit of $FD21 irq latch is set (Speech data expected?) . 848e 50 01 BVC $8491 ; branch if the 6th bit $FD21 is not set (EOS?) . 8490 60 RTS . 8491 8c 21 fd STY $fd21 ; store Y=0 to $FD21 (IRQ acknowledge?) . 8494 4c 30 84 JMP $8430 ; jump to speech stop ; read speech data from ROM to Accumulator . 8497 ae 0a 07 LDX $070a ; is set to #$03 at $8040 . 849a d0 03 BNE $849f ; custom speech data address? (?) . 849c 4c 8e 06 JMP $068e ; read Speech ROM data pointed to by $d2/$d3 . 849f 4c 91 06 JMP $0691 ; read in one byte from the custom Speech ROM ??? ; Analyse BASIC command . 84a2 ad 0c 07 LDA $070c ; speech BASIC command code? . 84a5 90 42 BCC $84e9 ; no, bail out . 84a7 c9 02 CMP #$02 . 84a9 d0 06 BNE $84b1 . 84ab a9 e0 LDA #$e0 . 84ad a0 85 LDY #$85 ; Address: $85E0 (VOC) . 84af d0 1c BNE $84cd . 84b1 c9 01 CMP #$01 . 84b3 d0 06 BNE $84bb . 84b5 a9 e3 LDA #$e3 . 84b7 a0 85 LDY #$85 ; Address: $85E3 (RATE) . 84b9 d0 12 BNE $84cd . 84bb c9 0a CMP #$0a . 84bd d0 06 BNE $84c5 . 84bf a9 e7 LDA #$e7 . 84c1 a0 85 LDY #$85 ; Address: $85E7 (SAY) . 84c3 d0 08 BNE $84cd . 84c5 c9 04 CMP #$04 . 84c7 d0 1f BNE $84e8 . 84c9 a9 ea LDA #$ea . 84cb a0 85 LDY #$85 ; Address: $85EA (RDY) . 84cd 85 22 STA $22 . 84cf 84 23 STY $23 ; command string address to ($22) . 84d1 a0 03 LDY #$03 . 84d3 b1 22 LDA ($22),Y ; loading 4 bytes pointed by $22-23 to accu . 84d5 99 13 07 STA $0713,Y ; to area starting from $0713 . 84d8 88 DEY . 84d9 10 f8 BPL $84d3 . 84db a9 07 LDA #$07 . 84dd 85 23 STA $23 . 84df a9 13 LDA #$13 . 84e1 85 22 STA $22 ; writing $0713 to zero lap address pointer . 84e3 a0 00 LDY #$00 . 84e5 18 CLC . 84e6 90 01 BCC $84e9 . 84e8 38 SEC . 84e9 48 PHA . 84ea ad 81 06 LDA $0681 . 84ed 8d cc 06 STA $06cc . 84f0 ad 80 06 LDA $0680 . 84f3 8d cb 06 STA $06cb . 84f6 68 PLA . 84f7 60 RTS . 84f8 ad 0c 07 LDA $070c . 84fb 90 67 BCC $8564 . 84fd c9 02 CMP #$02 . 84ff d0 09 BNE $850a . 8501 a9 06 LDA #$06 . 8503 48 PHA . 8504 a9 b1 LDA #$b1 . 8506 48 PHA . 8507 18 CLC . 8508 90 1d BCC $8527 . 850a c9 01 CMP #$01 . 850c d0 09 BNE $8517 . 850e a9 06 LDA #$06 . 8510 48 PHA . 8511 a9 b4 LDA #$b4 . 8513 48 PHA . 8514 18 CLC . 8515 90 10 BCC $8527 . 8517 c9 0a CMP #$0a . 8519 d0 09 BNE $8524 . 851b a9 06 LDA #$06 . 851d 48 PHA . 851e a9 b7 LDA #$b7 . 8520 48 PHA . 8521 18 CLC . 8522 90 03 BCC $8527 . 8524 38 SEC . 8525 b0 3d BCS $8564 . 8527 8c 0b 07 STY $070b . 852a ba TSX . 852b e8 INX . 852c a0 08 LDY #$08 . 852e bd 00 01 LDA $0100,X . 8531 8d 0c 07 STA $070c . 8534 bd 01 01 LDA $0101,X . 8537 9d 00 01 STA $0100,X . 853a e8 INX . 853b 88 DEY . 853c d0 f6 BNE $8534 . 853e ad 0c 07 LDA $070c . 8541 9d 00 01 STA $0100,X . 8544 a0 08 LDY #$08 . 8546 ba TSX . 8547 e8 INX . 8548 bd 00 01 LDA $0100,X . 854b 8d 0c 07 STA $070c . 854e bd 01 01 LDA $0101,X . 8551 9d 00 01 STA $0100,X . 8554 e8 INX . 8555 88 DEY . 8556 d0 f6 BNE $854e . 8558 ad 0c 07 LDA $070c . 855b 9d 00 01 STA $0100,X . 855e ae f3 05 LDX $05f3 . 8561 ac 0b 07 LDY $070b . 8564 ad 83 06 LDA $0683 . 8567 8d cc 06 STA $06cc . 856a ad 82 06 LDA $0682 . 856d 8d cb 06 STA $06cb . 8570 60 RTS . 8571 ad 0c 07 LDA $070c . 8574 90 5b BCC $85d1 . 8576 a0 02 LDY #$02 . 8578 20 a5 04 JSR $04a5 . 857b 59 e0 85 EOR $85e0,Y . 857e 29 7f AND #$7f . 8580 d0 09 BNE $858b . 8582 88 DEY . 8583 10 f3 BPL $8578 . 8585 a9 02 LDA #$02 . 8587 a0 03 LDY #$03 . 8589 d0 3d BNE $85c8 . 858b a0 03 LDY #$03 . 858d 20 a5 04 JSR $04a5 . 8590 59 e3 85 EOR $85e3,Y . 8593 29 7f AND #$7f . 8595 d0 09 BNE $85a0 . 8597 88 DEY . 8598 10 f3 BPL $858d . 859a a9 01 LDA #$01 . 859c a0 04 LDY #$04 . 859e d0 28 BNE $85c8 . 85a0 a0 02 LDY #$02 . 85a2 20 a5 04 JSR $04a5 . 85a5 59 e7 85 EOR $85e7,Y . 85a8 29 7f AND #$7f . 85aa d0 09 BNE $85b5 . 85ac 88 DEY . 85ad 10 f3 BPL $85a2 . 85af a9 0a LDA #$0a . 85b1 a0 03 LDY #$03 . 85b3 d0 13 BNE $85c8 . 85b5 a0 02 LDY #$02 . 85b7 20 a5 04 JSR $04a5 . 85ba 59 ea 85 EOR $85ea,Y . 85bd 29 7f AND #$7f . 85bf d0 0a BNE $85cb . 85c1 88 DEY . 85c2 10 f3 BPL $85b7 . 85c4 a9 04 LDA #$04 . 85c6 a0 03 LDY #$03 . 85c8 18 CLC . 85c9 90 06 BCC $85d1 . 85cb 38 SEC . 85cc a0 00 LDY #$00 . 85ce 20 a5 04 JSR $04a5 . 85d1 48 PHA . 85d2 ad 7f 06 LDA $067f . 85d5 8d cc 06 STA $06cc . 85d8 ad 7e 06 LDA $067e . 85db 8d cb 06 STA $06cb . 85de 68 PLA . 85df 60 RTS . 85e0 DB $56, $4f, $c3 ; BASIC command VOC . 85e3 DB $52, $41, $54, $c5 ; BASIC command RATE . 85e7 DB $53, $41, $D9 ; BASIC command SAY . 85ea DB $52, $44, $d9 ; BASIC command RDY ; parameter parsing * 85ed 8d 0c 07 STA $070c . 85f0 ad 84 06 LDA $0684 ; read the parameter counter . 85f3 48 PHA ; save it to stack . 85f4 a9 00 LDA #$00 . 85f6 8d 84 06 STA $0684 ; clear it . 85f9 68 PLA ; load back . 85fa c9 06 CMP #$06 ; see how many bytes we have . 85fc d0 03 BNE $8601 ; six? if not then jump . 85fe 4c a2 84 JMP $84a2 . 8601 c9 05 CMP #$05 . 8603 d0 03 BNE $8608 . 8605 4c f8 84 JMP $84f8 . 8608 c9 04 CMP #$04 . 860a d0 03 BNE $860f . 860c 4c 71 85 JMP $8571 . 860f c9 03 CMP #$03 . 8611 f0 0b BEQ $861e . 8613 c9 02 CMP #$02 . 8615 f0 37 BEQ $864e . 8617 c9 01 CMP #$01 . 8619 f0 4a BEQ $8665 . 861b 4c b0 87 JMP $87b0 . 861e 20 02 88 JSR $8802 . 8621 24 0d BIT $0d . 8623 30 3b BMI $8660 . 8625 20 0f 88 JSR $880f . 8628 a5 14 LDA $14 ; copy serial number of the word . 862a 8d 7b 06 STA $067b . 862d a5 15 LDA $15 . 862f 8d 7c 06 STA $067c . 8632 20 79 04 JSR $0479 ; read character from command buffer . 8635 c9 2c CMP #$2c ; is it ',' ? . 8637 d0 12 BNE $864b ; no... . 8639 20 73 04 JSR $0473 ; more arguments coming . 863c 20 02 88 JSR $8802 . 863f 24 0d BIT $0d . 8641 30 1d BMI $8660 . 8643 20 0f 88 JSR $880f . 8646 a5 14 LDA $14 . 8648 8d 7d 06 STA $067d . 864b 4c 25 87 JMP $8725 . 864e 20 02 88 JSR $8802 . 8651 24 0d BIT $0d . 8653 30 0b BMI $8660 . 8655 20 0f 88 JSR $880f . 8658 a5 14 LDA $14 . 865a 8d 89 06 STA $0689 . 865d 4c 25 87 JMP $8725 . 8660 a2 16 LDX #$16 . 8662 4c 32 87 JMP $8732 . 8665 20 44 84 JSR $8444 . 8668 d0 fb BNE $8665 . 866a 20 02 88 JSR $8802 . 866d 24 0d BIT $0d . 866f 30 03 BMI $8674 . 8671 4c 08 87 JMP $8708 . 8674 a9 9c LDA #$9c . 8676 8d f1 05 STA $05f1 . 8679 a9 4b LDA #$4b . 867b 8d f0 05 STA $05f0 . 867e 20 19 88 JSR $8819 . 8681 8d 10 07 STA $0710 . 8684 a0 ff LDY #$ff . 8686 8c 12 07 STY $0712 . 8689 c8 INY . 868a 20 b0 04 JSR $04b0 . 868d cc 10 07 CPY $0710 . 8690 f0 04 BEQ $8696 . 8692 c9 20 CMP #$20 . 8694 d0 f3 BNE $8689 . 8696 8c 11 07 STY $0711 . 8699 88 DEY . 869a 20 44 84 JSR $8444 . 869d d0 fb BNE $869a . 869f a9 00 LDA #$00 . 86a1 85 d4 STA $d4 . 86a3 85 d5 STA $d5 . 86a5 20 b0 04 JSR $04b0 . 86a8 29 5f AND #$5f . 86aa 18 CLC . 86ab 65 d4 ADC $d4 . 86ad 85 d4 STA $d4 . 86af 90 02 BCC $86b3 . 86b1 e6 d5 INC $d5 . 86b3 88 DEY . 86b4 cc 12 07 CPY $0712 . 86b7 f0 0e BEQ $86c7 . 86b9 a2 04 LDX #$04 ; X = 4 . 86bb a5 d5 LDA $d5 . 86bd c9 80 CMP #$80 ; AC >= #$80? then Carry = 1 . 86bf 26 d4 ROL $d4 . 86c1 2a ROL . 86c2 ca DEX . 86c3 d0 f8 BNE $86bd ; repeat 4 times . 86c5 f0 dc BEQ $86a3 ; always jump . 86c7 ad 7c 06 LDA $067c . 86ca 85 d3 STA $d3 . 86cc f0 16 BEQ $86e4 . 86ce ad 7b 06 LDA $067b . 86d1 85 d2 STA $d2 . 86d3 ad 7d 06 LDA $067d . 86d6 20 51 87 JSR $8751 ; set flag for custom vocabulary? . 86d9 e6 d1 INC $d1 . 86db e6 d1 INC $d1 . 86dd e6 d1 INC $d1 . 86df e6 d1 INC $d1 ; address += $0400 . 86e1 8a TXA . 86e2 d0 12 BNE $86f6 . 86e4 a9 f6 LDA #$f6 . 86e6 85 d2 STA $d2 . 86e8 a9 92 LDA #$92 . 86ea 85 d3 STA $d3 ; address $92f6 to $d2/$d3 . 86ec a9 03 LDA #$03 . 86ee 20 51 87 JSR $8751 . 86f1 8a TXA . 86f2 d0 02 BNE $86f6 . 86f4 f0 3a BEQ $8730 . 86f6 20 40 87 JSR $8740 . 86f9 b0 35 BCS $8730 . 86fb ac 11 07 LDY $0711 . 86fe 8c 12 07 STY $0712 . 8701 cc 10 07 CPY $0710 . 8704 d0 83 BNE $8689 . 8706 f0 10 BEQ $8718 . 8708 20 0f 88 JSR $880f . 870b a5 14 LDA $14 . 870d 85 d0 STA $d0 . 870f a5 15 LDA $15 . 8711 85 d1 STA $d1 ; copy serial number of word to $d0/$d1 . 8713 20 40 87 JSR $8740 . 8716 b0 18 BCS $8730 . 8718 20 79 04 JSR $0479 ; jump to CHRGOT . 871b c9 2c CMP #$2c ; comma? . 871d d0 06 BNE $8725 ; branch if not . 871f 20 73 04 JSR $0473 ; CHRGET . 8722 4c 65 86 JMP $8665 . 8725 a9 06 LDA #$06 . 8727 8d cc 06 STA $06cc . 872a a9 9c LDA #$9c . 872c 8d cb 06 STA $06cb . 872f 60 RTS ; back up BASIC warm start vector . 8730 a2 0e LDX #$0e . 8732 ad 01 03 LDA $0301 . 8735 8d cc 06 STA $06cc . 8738 ad 00 03 LDA $0300 . 873b 8d cb 06 STA $06cb . 873e 58 CLI . 873f 60 RTS ; * 8740 78 SEI . 8741 a5 d1 LDA $d1 . 8743 c9 04 CMP #$04 . 8745 90 07 BCC $874e . 8747 ad 7c 06 LDA $067c . 874a d0 02 BNE $874e . 874c 38 SEC . 874d 60 RTS . 874e 4c 19 80 JMP $8019 ; jump to speech start setup ; . 8751 8d 0a 07 STA $070a . 8754 a0 01 LDY #$01 . 8756 20 a2 87 JSR $87a2 ; read first speech data from ROM (compressed) . 8759 88 DEY ; Y = 0 . 875a 18 CLC . 875b 65 d2 ADC $d2 ; AC = $D2 + AC . 875d 48 PHA ; save to stack . 875e 20 a2 87 JSR $87a2 ; read next speech data (compressed) . 8761 65 d3 ADC $d3 ; ACC = $D3 + AC . 8763 85 d3 STA $d3 ; $D3 = AC . 8765 68 PLA ; restore AC from stack... . 8766 85 d2 STA $d2 ; ... save to $D2 . 8768 a2 02 LDX #$02 . 876a 84 d1 STY $d1 ; $D1 = 0 (at first) * 876c 8a TXA ; AC = X ( = 2 at first) . 876d d0 0a BNE $8779 ; not zero then jump... . 876f 8a TXA ; AC = X . 8770 f0 06 BEQ $8778 ; zero? then return . 8772 98 TYA ; AC = Y (= $D1) . 8773 46 d1 LSR $d1 . 8775 6a ROR . 8776 85 d0 STA $d0 ; divide address at $D0/$D1 by 2 . 8778 60 RTS . 8779 a2 02 LDX #$02 . 877b 20 a2 87 JSR $87a2 ; read speech data from ROM (compressed) . 877e d0 01 BNE $8781 ; not zero, than jump? . 8780 ca DEX . 8781 c5 d4 CMP $d4 . 8783 d0 0d BNE $8792 . 8785 c8 INY . 8786 20 a2 87 JSR $87a2 . 8789 d0 01 BNE $878c . 878b ca DEX . 878c c5 d5 CMP $d5 . 878e f0 df BEQ $876f . 8790 d0 07 BNE $8799 . 8792 c8 INY . 8793 20 a2 87 JSR $87a2 ; read speech data from ROM (compressed) . 8796 d0 01 BNE $8799 ; not zero? jump... . 8798 ca DEX . 8799 c8 INY . 879a d0 d0 BNE $876c ; Y <> 0 then back . 879c e6 d3 INC $d3 . 879e e6 d1 INC $d1 . 87a0 d0 ca BNE $876c * 87a2 8e 0b 07 STX $070b ; save X . 87a5 78 SEI . 87a6 20 97 84 JSR $8497 ; read speech data from ROM to accumulator . 87a9 58 CLI . 87aa ae 0b 07 LDX $070b ; restore X . 87ad 09 00 ORA #$00 ; ? . 87af 60 RTS ; . 87b0 a9 00 LDA #$00 . 87b2 85 0d STA $0d . 87b4 20 73 04 JSR $0473 ; CHRGET . 87b7 90 2c BCC $87e5 . 87b9 c9 fe CMP #$fe . 87bb d0 35 BNE $87f2 . 87bd 20 73 04 JSR $0473 ; CHRGET . 87c0 c9 04 CMP #$04 . 87c2 d0 2e BNE $87f2 . 87c4 20 73 04 JSR $0473 ; CHRGET . 87c7 ad 21 fd LDA $fd21 ; again check if the lower 2 bits of $FD21 . 87ca 29 03 AND #$03 ; is not zero . 87cc d0 04 BNE $87d2 ; branch if set . 87ce a0 ff LDY #$ff . 87d0 d0 02 BNE $87d4 ; jump always . 87d2 a0 00 LDY #$00 . 87d4 84 62 STY $62 . 87d6 84 63 STY $63 . 87d8 a2 90 LDX #$90 . 87da a9 a2 LDA #$a2 . 87dc 8d cc 06 STA $06cc . 87df a9 c9 LDA #$c9 . 87e1 8d cb 06 STA $06cb ; $c9a2 to $06cb . 87e4 60 RTS ; . 87e5 48 PHA . 87e6 a9 94 LDA #$94 . 87e8 8d cc 06 STA $06cc . 87eb a9 20 LDA #$20 . 87ed 8d cb 06 STA $06cb ; address (self-modified) at $6cb to $9420 . 87f0 68 PLA . 87f1 60 RTS ; . 87f2 20 79 04 JSR $0479 ; read byte from RAM (via CHRGOT) . 87f5 48 PHA . 87f6 a9 94 LDA #$94 . 87f8 8d cc 06 STA $06cc . 87fb a9 23 LDA #$23 . 87fd 8d cb 06 STA $06cb . 8800 68 PLA . 8801 60 RTS . 8802 a9 93 LDA #$93 . 8804 8d f1 05 STA $05f1 . 8807 a9 2c LDA #$2c . 8809 8d f0 05 STA $05f0 . 880c 4c 19 88 JMP $8819 . 880f a9 9d LDA #$9d . 8811 8d f1 05 STA $05f1 . 8814 a9 e4 LDA #$e4 . 8816 8d f0 05 STA $05f0 . 8819 8d f2 05 STA $05f2 . 881c 8e f3 05 STX $05f3 . 881f 08 PHP . 8820 68 PLA . 8821 8d f4 05 STA $05f4 - store accu to Long jump status register . 8824 a9 03 LDA #$03 - switch on this ROM (speech...) . 8826 a2 00 LDX #$00 . 8828 20 fa fc JSR $fcfa . 882b ad f4 05 LDA $05f4 - load Long jump status register to accu . 882e 48 PHA . 882f 28 PLP - copy accu to status reg . 8830 ae f3 05 LDX $05f3 - reading Long jump x register . 8833 ad f2 05 LDA $05f2 - reading Long jump accumulator . 8836 60 RTS ; this routine is copied to the RAM area $068e ; ; reads a byte from the address space of the SPEECH ROM * 8837 . 068e 8d 3f ff STA $ff3f - bank the ROM out . 0691 9d d0 fd STA $fdd0,X - bank in the ROM offset by X . 0694 b1 d2 LDA ($d2),Y - load data pointed by $d2-d3 to accu . 0696 8d 3e ff STA $ff3e - turn on ROM . 0699 8d d3 fd STA $fdd3 - bank in the 4th low ROM set (this one) . 069c 60 RTS This is the IRQ routine copied to RAM at $069d! . 8846 . 069d 8d d3 fd STA $fdd3 ; bank in the 4th low ROM set (this one) . 0670 20 83 84 JSR $8483 . 0673 8d d0 fd STA $fdd0 ; bank in the original BASIC and KERNAL ROM . 0676 4c a7 06 JMP $06a7 . 0679 ee 84 06 INC $0684 ; this addresses are patched from other places . 067c ee 84 06 INC $0684 . 067f ee 84 06 INC $0684 . 0682 ee 84 06 INC $0684 . 0685 ee 84 06 INC $0684 . 0688 ee 84 06 INC $0684 . 068b 48 PHA . 068c a9 85 LDA #$85 * 068e 8d f1 05 STA $05f1 . 0691 a9 ed LDA #$ed . 0693 8d f0 05 STA $05f0 - setting long jump address to $85ed . 0696 68 PLA . 0697 20 cd 06 JSR $06cd . 069a 4c cb 06 JMP $06cb . 069d 8d f2 05 STA $05f2 - storing Long jump accumulator . 06a0 8e f3 05 STX $05f3 - storing Long jump x register . 06a3 08 PHP - push status register to stack . 06a4 68 PLA - pull accu from stack (ie. copy status reg to accu) . 06a5 8d f4 05 STA $05f4 - storing Long jump status register . 06a8 a5 fb LDA $fb - read current bank configuration to accu . 06aa a2 03 LDX #$03 . 06ac 20 fa fc JSR $fcfa - jumping to $fc89 ROM banking routine . 06af ad f4 05 LDA $05f4 - load Long jump status register to accu . 06b2 48 PHA . 06b3 28 PLP - copy accu to stack (ie. long jump status reg to status reg) . 06b4 ae f3 05 LDX $05f3 - reading Long jump x register . 06b7 ad f2 05 LDA $05f2 - reading Long jump accumulator . 06ba 60 RTS - end of the routine copied to RAM ; . 8894 JSR $8355 ; DATA area... (approx. 14 kbyte) ; $92FA - $9501 ; ; 2 byte address lookup table for all 260 words . 92FA DB $04,$1a, $04,$4d, $04,$7d ; .... etc - bfff