+FarmerPotato Posted May 13 Share Posted May 13 (edited) Forth source from the Speech Education Module User's Guide The SEM was a single-board kit produced in 1982 to support experiments with the TMS5220 speech chip. It had the VM60002 "Industrial Vocabulary" PHROM. (phrase ROM or TMS6100), two serial ports, and audio out jack. User software was a speech editor, written in Forth. The serial ports were 6850s. There is an 8255 PIA. COLDIO was the Forth word that initializes them. (no source code.) The Forth source of the speech editor will be of interest to 4A users. So I'm posting in TI-99/4A Development. Most of the Forth should be compatible with the Speech Synthesizer. The 2532 EPROM in the SEM is the Forth interpreter, written in TMS7000 assembly or Forth, plus the compiled source listed here. This source was Appendix L of the manual. I don't have the complete manual. Sadly, I don't see any source code for the Forth interpreter or kernel. It would be really sweet to have a Forth cartridge for the CC-40 or ExelVision. If I find that source, I'll post in the CC-40 forum. About 7 more pages of code are in TMS7000 assembly. SPK is an entry point from Forth. SPK pops its parameters from the stack. It sends SPEAK or SPEAK EXTERNAL commands to the TMS5200. It processes speech bytes on frame boundaries. The rest of the assembly code is subroutines of SPK. SPK ends with BR *NEXT. EDIT: here are cleaner files. Syntax checked in ANS Forth, any dependencies (FIG) defined empty at the top. Probably still some typos. My comments are in lower case (except at the top) LOADMEM.fs SPEECH_EDU.fs SPEECH_EDU.asm SEM_DOCS.txt Edited May 21 by FarmerPotato Rewrote after finished the assembly code 4 2 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted May 13 Share Posted May 13 This is neat to see Erik. Thanks. There must be an underlying cross-compiler environment for this code. There are few words that have no definition. (vsp! getbits) Question: Are the Forth word names in the ROM? There is also some evidence of someone who is still learning Forth arg management on the DATA stack. : DROP2 DROP DROP ; : DROP2UNDER ( N1 N2 N3 -- N3 ) ROT ROT DROP2 ; : OVER2 ( N1 N2 N3 -- N1 N2 N3 N1 ) ROT DUP >R ROT ROT R> ; DROP2UNDER would be cleaner as : NIP SWAP DROP ; : DROP2UNDER NIP NIP ; And you get the word NIP for when you need that function. OVER2 is rather complex. It would benefit from using the PICK word. (some folks considered it a sacrilege but on 9900 PICK about as efficient as OVER) : OVER2 2 PICK ; 1 1 Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted May 13 Author Share Posted May 13 1 hour ago, TheBF said: Question: Are the Forth word names in the ROM? I look forward to dumping the ROM! 2532s. Anything you can do to test on the 4A would be welcome. (Any typos are mine.) My thoughts: VSP! VSP@ and GETBITS are the only words missing? Should be straightforward to implement in 9900 assembly. If you want to mock it up, VSP! is a no-op. Mock up GETBITS and VSP@ to return (requested bits of?) a CALL SPGET string (XB). Maybe bit reversed. Is this all FIG-Forth? In my dad's Lubbock speech papers, I found a 1982 version of the TI Forth manual. It is bound with a nice report cover. Clearly there was interest in Forth at TI. 1 Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted May 13 Author Share Posted May 13 If you read the source, you'll notice that the Speech Editor has graphical output! It makes little bar charts on the terminal. It puts a "display list" into the DAC buffer. You connect the output to an oscilloscope! 1 Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted May 13 Author Share Posted May 13 OK there are a lot of typos! I will compare and fix. I confess I used OCR as a first step. 1 Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted May 13 Author Share Posted May 13 Good thing: board has a TMX7000, which means no internal ROM. The jumpers are set for external ROM - 4K at F000. For more info on the hardware, read 2 Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted May 14 Author Share Posted May 14 I put some cleaner source files into the first post. 1 1 Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted May 20 Author Share Posted May 20 Here are the pages of TMS7000 assembly source. SPK is a Forth word, coded in assembler. It uses all the other subroutines listed here. SPK has TRAP instructions to call subroutines I don't see here. I infer that SPLDM loads VAL with a parameter from the stack. SPINC2 increments the stack pointer. SPK exits via BR *NEXT. *----------------------------------------------------------* * SPK * * STACK: ADDR BITPOINTER #FRAMES PAUSE# RPTFRMS --> .. * * PERFORM VSP "SPEAK EXTERNAL COMMAND", GIVEN THE * * STARTING ADDRESS, BITPOINTER, NUMBER OF FRAMES, AND * * NUMBER OF TIMES TO SPEAK EACH FRAME (USED BY SPEED * * COMMAND) * * * * RPTFRM - 1-BYTE REGISTER, # OF TIMES TO REPEAT EACH * * FRAME (INPUT ARG) * * FRMCNT - TEMP 1-BYTE REGISTER USED TO COUNT # OF TIMES * * FRAME HAS BEEN SPOKEN (RPTFM DOWNTO 0) * * PAUSE - 2-BYTE REGISTER USED TO HOLD FRAME # TO PAUSE * * AFTER (INPUT ARG) * * ( FORTH: * * PAUSE := #FRAMES - (PAUSEAT - SFRAME) * * TEMP1 - 2-BYTE REGISTER USED TO HOLD # OF FRAMES TO * * SPEAK * * ( FORTH: #FRAMES : = EFRAME - SFRAME + 1 ) * * TEMP3 - 2-BYTE REGISTER, MEM ADDRESS FOR NEXT BYTE OF * * SPEECH DATA (INPUT ARG) * * TEMP2 - 1-BYTE REGISTER, BIT POINTER 0-7 FOR STARTING * * BIT (INPUT ARG) * * FRAMAD - 2-BYTE REGISTER, MEM ADDRESS FOR CURRENT FRAME * * TEMP2-1 TEMPORARY BYTE LOCATION * * FRAMBT - 1-BYTE REGISTER, BIT POINTER FOR CURRENT FRAME * * ENDFRM - 1-BYTE REGISTER USED W/EXAMIN ROUTINE WHICH * * DETECTS END OF FRAME * *----------------------------------------------------------* TRAP SPLDM GET RPTFRMS MOV VAL,VAL JNE SPK1 INC VAL IF ZERO PASSED, MAKE IT 1 SPK1 EQU $ MOV VAL,RPTFRM TRAP SPINC2 TRAP SPLDM GET PAUSE# MOVD VAL,PAUSE INTO PAUSE TRAP SPINC2 TRAP SPLDM GET #FRAMES TRAP VALTO1 INTO TEMP1 TRAP SPINC2 TRAP SPLDM GET BITPOINTER MOV VAL,TEMP2 INTO TEMP2 TRAP SPINC2 TRAP SPLDM GET ADDRESS MOVD VAL, TEMP3 INTO TEMP3 TRAP SPINC2 CMP %8,TEMP2 ADJUST BIT POINTER TO BE 0-7 JN SPK2 JUMP IF LESS THAN 8 SUB %8, TEMP2 ELSE SUBTRACT 8 INC TEMP3 INCREMENT ADDRESS ADC %0,TEMP3-1 *--------------------------------------------------* * INITIALIZE ALL REMAINING REGISTERS * *--------------------------------------------------* SPK2 EQU $ MOVD TEMP3,FRAMAD FRAMAD := TEMP3 (ADDRESS) MOV TEMP2,FRAMBT FRAMBT := TEMP2 (BITPOINTER) MOV RPTFRM,FRMCNT FRMCNT := RPTFRM CALL @SPKINT FRMLEN/BITPNT/ENERGY/REPEET/PITCH CLR ENDFRM ENDERM := 0 *--------------------------------------------------* * ISSUE THE "SPEAK EXTERNAL" COMMAND TO VSP * *--------------------------------------------------* MOV %SPKEXT,A VSP SPEAK EXTERNAL COMMAND CALL @VSPOUT CALL @GNXT8 GET FIRST BYTE *--------------------------------------------------* * TOP OF "EXAMIN" LOOP * * ASSUMES A-REGISTER CONTAINS DATA TO BE EXAMINED * * ENDFRM = BITPOINTER TO START EXAMINING (0 TO 7) * *--------------------------------------------------* SPK3 EQU $ CALL @EXAMIN MOV ENDFRM,ENDFRM JNE NOTZ JUMP IF ENDFRM <> 0 CALL @VSPOUT ENDFRM = 0, SEND BYTE TO VSP CALL @GNXT8 GET NEXT BYTE JMP SPK3 NOTZ EQU $ ENDFRM <> 0 CMP %1,FRMCNT DOES FRAME NEED REPEATING? JP NOTZ2 YES! DONT CARE IF STOP FOUND MOV STOPCD,STOPCD FOUND STOP CODE ? JZ NOTZ2 NO STOP CODE BR @SPKSTP YES, FOUND STOP CODE NOTZ2 EQU $ CMP %8,ENDFRM NO, BUT IS ENDFRM=8 ? JNE SPK4 JUMP IF ENDFRM <> 8 CALL @VSPOUT ELSE SEND BYTE VSP CLR ENDFRM AND SET ENDFRM := 0 *--------------------------------------------------* * SEND FRAME AGAIN? * *--------------------------------------------------* SPK4 EQU $ DJNZ FRMCNT,SPKAA DEC FRAME COUNT *--------------------------------------------------* * NO, DON'T SEND FRAME AGAIN * *--------------------------------------------------* MOV RPTFRM,FRMCNT RESET FRMCNT AND GO ON JMP SPK5 *--------------------------------------------------* * YES, MUST SEND THIS FRAME AGAIN *--------------------------------------------------* SPK4A EQU $ MOVD FRAMAD,TEMP3 RESET SPEECH DATA POINTERS MOV FRAMBT,TEMP2 TO BEGINNING OF FRAME CALL @SPKINT INITIALIZE FRAME VARIABLES CALL @SPKCLR CLEAR UNUSED BITS IN A-REG PUSH A SAVE ORIGINAL VALUE OF A-REG CALL @GNXT8 GET 1ST 8 BITS FROM SAME FRAME MOV ENDFRM,ENDFRM ENDFRM = O ? JNE SPK4B YES, GO PACK NEW DATA POP B NO, DATA OCCUPIES ENTIRE BYTE JMP SPK4C SO JUST THROW AWAY ORIGINAL A SPK4B EQU $ MOV %8, B TEMP2 := TEMP2 + (8 - ENDFRM) SUB ENDFRM,B ADD B,TEMP2 CMP %7,TEMP2 IF TEMP2 <= 7 THEN DEC TEMP3 JP SPK4B1 ELSE TEMP2 : = TEMP2 - 8 DECD TEMP3 JMP SPK4B2 SPK4B1 EQU $ SUB %8, TEMP2 SPK4B2 EQU $ MOV ENDFRM, B SPK4B3 EQU $ CLRC SHIFT IN ZEROES RLC A DJNZ B,SPR4B3 POP B GET ORIGINAL VALUE OF A-REG OR B,A PACK IN THE (8-ENDFRM) BITS SPK4C EQU $ BR @SPK3 GO BACK TO TOP OF LOOP *--------------------------------------------------* * ARE WE AT THE "PAUSE" FRAME? * *--------------------------------------------------* SPK5 EQU $ DECD TEMP1 IF TEMP1-PAUSE THEN "PAUSE" CMP TEMP1-1,PAUSE-1 JNE SPK6 TEMP1 <> PAUSE, GO ON TO SPK6 CMP TEMP1, PAUSE JNE SPK6 TEMP1 <> PAUSE, GO ON TO SPK6 *--------------------------------------------------* * YES, WE ARE AT THE PAUSE FRAME (INSERT 10 * * SILENT FRAMES) * *--------------------------------------------------* PUSH A SAVE CURRENT BYTE CALL @SPKCLR CLEAR UNUSED BITS IN A-REG CALL @VSPOUT BYTE 1 - INCLUDES RESIDUE FROM CLR A PREVIOUS FRAME CALL @VSPOUT BYTE 2 CLR A CALL @VSPOUT BYTE 3 CLR A CALL @VSPOUT BYTE 4 MOV %>FF,TEMP2-1 DONE SHOVING OUT SILENT FRAMES MOV ENDFRM, B NOW MUST GET BACK ON TRACK SPK5A EOU $ SHIFT IN "O" BITS TO OLD A-REGISTER CLRC TO END THE 10TH ZERO-ENERGY FRAME RLC TEMP2-1 DJNZ B,SPK5A POP A GET ORIGINAL DATA AND TEMP2-1,A CLEAR THE BITS ALREADY USED UP *--------------------------------------------------* * SPOKEN ALL FRAMES? *--------------------------------------------------* SPK6 EOU $ MOV TEMP1-1,TEMP1-1 FRAME COUNTER ALREADY DEC'D JNE SPK6A JUMP IF FRAME COUNTER <> O MOV TEMP1,TEMP1 JEQ SPK6B JUMP IF FRAME COUNTER = 0 SPK6A EQU $ NOT SPOKEN ALL FRAMES YET CALL @SPKPTR RESET FRAMAD/FRAMBT POINTERS MOV ENDFRM,ENDFRM ENDFRM=0 ? JZ SPK6A1 CALL @VSPOUT JUMP IF ALREADY SENT BYTE SPK6A1 EQU $ IF ENDFRM <> 0 SEND BYTE VSP CLR ENDFRM CALL @GNXT8 GET NEXT BYTE BR @SPK3 GO BACK TO TOP OF LOOP SPK6B EOU $ YES, SPOKEN ALL FRAMES MOV ENDFRM,ENDFRM JNE SPK6B1 MOV %>F,A ENDFRM = 0 JMP SPKSTP SPK6B1 EOU $ ENDERM <> 0 CALL @SPKCLR CLEAR UNUSED BITS IN A-REGISTER MOV %8,B SUB ENDFRM,B B := (8 - ENDFRM) PUSH A SAVE ORIGINAL VALUE OF A CLR A USE A FOR BIT "OR" MASK MOV %>F,TEMP2-1 TEMP2-1 := VSP "STOP CODE" SPK6B4 EQU $ CLRC RRC TEMP2-1 SHIFT "STOP CODE" INTO RRC A A-REGISTER DJNZ B,SPK6B4 POP B GET ORIGINAL VALUE OF A OR B,A "OR" IN THE STOP CODE CMP %4,ENDFRM IF ENDFRM < 4, WHOLE STOP CODE JN SPKSTP IS IN A-REGISTER CALL @VSPOUT ELSE, SOME OF IT STILL IN TEMP2-1 MOV TEMP2-1,A *--------------------------------------------------* * STOP CODE DETECTED IN A-REGISTER *--------------------------------------------------* SPKSTP EQU $ CALL @VSPOUT SEND LAST BYTE OF DATA MOV %8,TEMP1 SEND 8 MORE BYTES NOP SPKST1 EQU $ CLR A TO GET THROUGH VSP FIFO CALL @VSPOUT DJNZ TEMP1,SPKST1 CALL @VSPTS WAIT FOR TALK STATUS LOW BR *NEXT Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted May 20 Author Share Posted May 20 And the subroutines: SPKINT INITIALIZE ALL VARIABLES USED BY SPK/EXAMIN SPKPTR FIX FRAMAD/FRAMBT SO THEY POINT TO THE NEXT FRAME SPKCLR CLEAR UNUSED BITS IN A-REG EXAMIN EXAMINE SPEECH DATA BYTE FOR PRESENCE OF END-OF-FRAME GNXT8 GET NEXT 8 SPEECH DATA BITS INTO A-REG VSPTS WAIT FOR SPEECH STATUS VSPOUT ? write a speech byte *--------------------------------------------------* * SPKINT SUBROUTINE * * INITIALIZE ALL VARIABLES USED BY SPK/EXAMIN * *--------------------------------------------------* SPKINT EQU $ MOV %49,FRMLEN CLR BITPNT CLR ENERGY CLR REPEET CLR PITCH RETS PAGE *==================================================* * GNXT8 SUBROUTINE: * * GET NEXT 8 SPEECH DATA BITS, LEAVE IN A-REG * * TEMP3 = ADDRESS * * TEMP2 = BITPOINTER (7-0) * *==================================================* GNXT8 EQU $ LDA *TEMP3 GET NEXT BYTE OF DATA INC TEMP3 ADC %0,TEMP3-1 INCREMENT DATA ADDRESS MOV TEMP2,B BIT POINTER -> B JEQ GNXT8B IF BITPNTR=0, ALREADY ALIGNED MOV A,TEMP2-1 STORE AWAY 1ST BYTE LDA *TEMP3 GET 2ND BYTE, DONT INC ADDRESS GNXT8A EQU $ RR A BIT 0 OF 2ND BYTE TO CARRY RRC TEMP2-1 SHIFT INTO TEMP RESULT DJNZ B,GNXT8A DO "BITPOINTER" TIMES MOV TEMP2-1,A GNXT8B EQU $ RETS *==================================================* * SPKPTR SUBROUTINE: * * FIX SPEECH FRAME POINTERS FRAMAD/FRAMBT * * SO THEY POINT TO THE BEGINNING OF THE * * NEXT FRAME COMING UP * * 1. FRAMAD := TEMP3 * * 2. FRAMBT := ENDFRM + TEMP2 * * 3. IF ENDFRM = 0 THEN FRAMBT := FRAMBT + 8 * * (THIS IS BECAUSE ENDFRM WAS PREVIOUSLY 8) * * 4. IF FRAMBT <= 7 THEN FRAMAD := FRMAD - 1 * * ELSE FRAMBT := FRAMBT - 8 * *==================================================* SPKPTR EQU $ MOVD TEMP3,FRAMAD MOV ENDFRM,FRAMBT ADD TEMP2,FRAMBT MOV ENDFRM,ENDFRM JNE SPKPT1 ADD %8,FRAMBT SPKPT1 EQU $ CMP %7,FRAMBT JP SPKPT2 DECD FRAMAD FRAMBT <= 7 JMP SPKPT3 SPKPT2 EQU $ FRAMBT > 7 SUB %8,FRAMBT SPKPT3 EQU $ RETS *==================================================* * SPKCLR SUBROUTINE: * * CLEAR UNUSED BITS IN A-REGISTER * *==================================================* SPKCLR EQU $ CLR TEMP2-1 USE TEMP2-1 AS BIT MASK MOV ENDFRM,B IF ENDFRM=0, JUST RETURN JZ SPKCL2 "00" IN A-REG (ALL BITS FREE) SPKCL1 EQU $ SETC E.G. 00000111 <--- SHIFT RLC TEMP2-1 "1"S LEFT DJNZ B,SPKCL1 SPKCL2 EQU $ AND TEMP2-1,A CLEAR UNUSED BITS IN A-REGISTER RETS *==================================================* * EXAMIN SUBROUTINE: * EXAMINES A SPEECH DATA BYTE FOR PRESENCE OF * * END-OF-FRAME. * INPUTS: * ENDFRM = THE BIT POSITION TO START EXAMINING, * USUALLY 0, BUT CAN BE IN RANGE 0-7 * OUTPUTS: * STOPCD = 0 IF STOP CODE NOT FOUND * STOPCD <> 0 IF STOP CODE FOUND * ENDFRM = 0 IF END-OF-FRAME NOT FOUND * ENDFRM <> 0 IF END-OF-FRAME FOUND * ENDFRM VALUE IS BIT POSITION FOR NEXT * AVAILABLE BIT IN VALUE EXAMINED * (ENDFRM=8 MEANS FRAME ENDED ON LAST BIT) * * CALLING SEQUENCE: * MOV %DATA,A MOVE SPEECH DATA TO A * MOV %8,B NUMBER OF BITS TO EXAMINE * CALL @EXAMIN CALL EXAMINE ROUTINE * MOV ENDFRM,ENDFRM CHECK ENDFRM * JNE ENDF IF NOT ZERO, END-OF-FRAME * FOUND * EXCEPTIONS AND CONDITIONS: * BEFORE SENDING FIRST BYTE OF A NEW SPEECH * PHRASE, CALLER MUST INITIALIZE: * MOV %49,FRMLEN SET FRAME LENGTH TO 49 * CLR BITPNT SET BIT POINTER TO O * CLR ENERGY SET UNPACKED ENERGY TO O * CLR REPEET SET UNPACKED REPEAT TO O * CLR PITCH SET UNPACKED PITCH TO O * CLR ENDFRM ENDFRM TO 1ST BIT POSITION * *==================================================* * *--------------------------------------------------* * BIT MASKS FOR "ORING" INTO ENERGY/PITCH REGISTERS* *--------------------------------------------------* BITO EQU >01 0000 0001 BIT1 EQU >02 0000 0010 BIT2 EQU >04 0000 0100 BIT3 EOU >08 0000 1000 BIT4 EOU >10 0001 0000 BIT5 EQU >20 0010 0000 * EXAMIN EQU $ PUSH A SAVE INPUT COPY OF "A" PUSH TEMP2-1 SAVE INPUT COPY OF "TEMP2-1" PUSH TEMP2 SAVE INPUT COPY OF "TEMP2" PUSH TEMP3 SAVE INPUT COPY OF "TEMP3" PUSH ENDFRM SAVE INPUT COPY OF "ENDFRM" MOV %8, TEMP2 TEMP2 IS THE LOOP COUNTER SUB ENDFRM,TEMP2 TEMP2 := (8 - ENDFRM) CLR TEMP2-1 CLR STOPCD * page break CLR TEMP2-1 TEMP2-1 IS # OF BITS EXAMINED CLR STOPCD ASSUME STOP CODE NOT FOUND *---------------------------------------------------* * MUST SHIFT INPUT BYTE RIGHT BY "ENDFRM" BITS * *---------------------------------------------------* MOV A, TEMP3 GET TEMP COPY MOV ENDFRM,ENDFRM ENDERM = 0 ? JZ NXTBIT YES, ALREADY SHIFTED EXAMI1 EQU $ NO, MUST SHIFT RR TEMP3 DJNZ ENDFRM, EXAMI1 *---------------------------------------------------* * ENDFRM NOW SET TO ZERO, START LOOKING AT BITS * *---------------------------------------------------* NXTBIT EQU $ CMP %11,BITPNT BIT POINTER < 11 JN NOTK YES, MUST BE ENERGY/REPEAT/PITCH BR @BP11 NO, MUST BE IN K-PARAMETERS NOTK EQU $ MOV BITPNT,B NO, MUST BE ENERGY/REPEAT/PITCH RL B MPY BY 2 TO GET TABLE OFFSET BR @JMPTAB(B) JUMP TO BPN, N=BIT POINTER *---------------------------------------------------* * JUMP TABLE FOR BIT POINTER 0-10 * *---------------------------------------------------* JMPTAB EQU $ JMP BP0 BIT POINTER IS 0 JMP BP1 BIT POINTER IS 1 JMP BP2 BIT POINTER IS 2 JMP BP3 BIT POINTER IS 3 JMP BP4 BIT POINTER IS 4 JMP BP5 BIT POINTER IS 5 JMP BP6 BIT POINTER IS 6 JMP BP7 BIT POINTER IS 7 JMP BP8 BIT POINTER IS 8 JMP BP9 BIT POINTER IS 9 JMP BP10 BIT POINTER IS 10 *---------------------------------------------------* * BIT POINTER = 0-3 "ENERGY" * *---------------------------------------------------* BP0 EQU $ MOV %BIT3,MASK 0000 1000 JMP BP03 BP1 EQU $ MOV %BIT2,MASK 0000 0100 JMP BP03 BP2 EQU $ MOV %BIT1,MASK 0000 0010 JMP BP03 BP3 EQU $ MOV %BIT0,MASK 0000 0001 BP03 EQU $ RR TEMP3 LOOK AT LSBIT OF TEMP3 JNC BP03A OR MASK,ENERGY BP03A EQU $ CMP %3,BITPNT AT END OF ENERGY BITS? JNE FRMTST NO, GO DO NEXT BIT PAGE CMP %0,ENERGY YES JNE BP03B JUMP IF ENERGY NOT ZERO MOV %3,FRMLEN ZERO ENERGY FRAME JMP FRMTST BP03B EQU $ CMP %>0F,ENERGY STOP CODE? JNE FRMTST NO, GO DO NEXT BIT MOV %3,FRMLEN STOP CODE FOUND INC STOPCD JMP FRMTST *---------------------------------------------------* * BIT POINTER = 4 "REPEAT" * *---------------------------------------------------* BP4 EQU $ CLR REPEET ASSUME NO REPEAT RR TEMP3 REPEAT BIT SET? JNC BP4A NO, JUMP INC REPEET YES, SET REPEAT=1 MOV %10,FRMLEN FRAME LENGTH SET TO 10 BP4A EQU $ JMP FRMTST *---------------------------------------------------* * BIT POINTER = 5-10 "PITCH" * *---------------------------------------------------* BP5 EQU $ MOV %BIT5,MASK 0010 0000 JMP BP510 BP6 EQU $ MOV %BIT4,MASK 0001 0000 JMP BP510 BP7 EQU $ MOV %BIT3,MASK 0000 1000 JMP BP510 BP8 EQU $ MOV %BIT2,MASK 0000 0100 JMP BP510 BP9 EQU $ MOV %BIT1,MASK 0000 0010 JMP BP510 BP10 EQU $ MOV %BIT0,MASK 0000 0001 BP510 EQU $ RR TEMP3 JNC BP510A OR MASK,PITCH BP510A EOU $ CMP %10,BITPNT AT END OF PITCH BITS? JNE FRMTST NO, GO DO NEXT BIT CMP %0,REPEET YES, CHECK IF REPEAT JNE FRMTST IF REPEAT=1, FRMLEN ALREADY 10 CMP %0,PITCH REPEAT=0, IS PITCH=0? JNE FRMTST NO. GO DO NEXT BIT (FRMLEN = 49) MOV %28,FRMLEN YES, SET FRAME LENGTH TO 28 JMP FRMTST *---------------------------------------------------* * BIT POINTER 11-49 "K-PARAMETERS" * *---------------------------------------------------* BP11 EQU $ * -- page break -- RR TEMP3 *---------------------------------------------------* * CHECK TO SEE IF AT END OF FRAME * *---------------------------------------------------* FRMTST EQU $ INC TEMP2-1 INC NUMBER OF BITS EXAMINED CMP BITPNT,FRMLEN BITPNT = FRMLEN? JEQ FRMTS1 YES, AT END OF FRAME INC BITPNT NO, INCREMENT BIT POINTER JMP BITTST FRMTS1 EQU $ CALL @SPKINT YES, AT END OF FRAME *---------------------------------------------------* * IF ENDFRM = 0 THEN SET ENDFRM TO TEMP2-1 + * * ORIGINAL ENDFRM * *---------------------------------------------------* MOV ENDFRM,ENDFRM JNE BITTST JUMP IF ENDFRM ALREADY SET POP ENDFRM ELSE SET ENDFRM TO BIT ADD TEMP2-1,ENDFRM POSITION OF FIRST END-OF-FRAME *---------------------------------------------------* * CHECK IF ALL EIGHT BITS OF "TEMP3" PROCESSED * *---------------------------------------------------* BITTST EQU $ DJNZ TEMP2,BITTS1 LOOK AT NEXT SPEECH BIT JMP BITTS2 BITTS1 EQU $ BR @NXTBIT *---------------------------------------------------* * RETURN * *---------------------------------------------------* BITTS2 EQU $ MOV ENDFRM,ENDFRM JNE BITTS3 POP A BITTS3 EQU $ POP TEMP3 POP TEMP2 POP TEMP2-1 POP A RETS * The file with all the assembly source I have: SPK and its subroutines. SPEECH_EDU.asm 1 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted May 20 Share Posted May 20 What does the TRAP instruction do? Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted May 20 Author Share Posted May 20 8 hours ago, TheBF said: What does the TRAP instruction do? Quote "TRAP is a one byte subroutine call" and "provides the most efficient means of invoking subroutines". (TMS7000 Family Data Manual) The instructions TRAP and CALL enter a subroutine, saving PC on the stack (RETS is their counterpart). The difference is that TRAP uses an index 0-23 into a table of entry vectors. CALL takes a general operand: Register indirect, Symbolic (address), Indexed. TRAP takes 14 cycles and occupies 1 byte of memory (opcodes E8-FF). CALL @LABEL takes the same # of cycles as TRAP and uses 3 bytes of memory. CALL @LABEL(Rn) takes one more cycle and also uses 3 bytes of memory. CALL *Rn is one cycle faster than TRAP, and uses one byte of memory like TRAP. The TRAP table occupies 24 words at the top of memory, FFD0 to FFFF. TRAPs 0-3 are the interrupt handlers. (actual interrupts push the status register as well.) I assume the TRAP operands shown in the code are EQU somewhere. 1 1 Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted May 21 Author Share Posted May 21 Top post now has freshest copies of all the files. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.