* *~~Page 11: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ******************************************************************************* * * * Analysis of TI 99/4A * * * ******************************************************************************* * * * Console ROM at >0000 through >1FFF * * 20.7.84 H. Martin * * * * Edited by Lee Stewart et al., starting 09MAR2016 * * * ******************************************************************************* GPLPWR EQU >0020 GROM address of GPL power-up routine VDPWA EQU >8C02 VDP write address GRMRD EQU >9800 GROM read data GPLWS EQU >83E0 GPL workspace INTWS EQU >83C0 Interrupt workspace GPLXWS EQU >280A GPL extension workspace AORG >0000 * * Interrupt Vector Table, which must start at >0000 for the TMS9900: * RSTLNK DATA GPLWS,RESET RESET Vector (PC = >0024) INTLK1 DATA INTWS,INT1 INTERRUPT Level 1 (PC = >0900) INTLK2 DATA INTWS,INT2 INTERRUPT Level 2 (PC = >0A92) DATA >30AA Clock frequency and header SCNKEY B @KEYSCN >02B2 Keyboard scanning DATA >0008 ???LES??? DATA >1E00 ???LES??? GPLNK9 B @GPLR9 >007A GPL interpreter, if in R9 GPL-byte DATA >1E00 ???LES??? GPLNKN B @GPLNOI >0078 GPL interpreter without interrupt SCNCLR B @CLRSCN >04B2 Keyboard scanning for CLEAR * * Reset and GPL EXIT: * RESET LI 13,GRMRD >9800 Load system pointer GROM read data LI 14,>0100 System flag LI 15,VDPWA >8C02 VDP write address LI 0,GPLPWR >0020 GROM address of GPL power-up routine JMP GPLR4 >005C Enter GPL Interpreter, where * [GROM data to R4, addr to R6] GPXOFF JMP GPXFF2 [not sure why this jump, unless padding for XOP table] GPXFF2 SBZ >0000 Turns off GPL extension (never implemented) LWPI >280A Restore GPL-extension context RTWP and return to caller * * BLWP vectors for GPL extension card (never implemented), XOP1 and XOP2: * * XOP Vector Table, which must start at >0040 for the TMS9900 XOP instruction: * The TI-99/4A can only use XOP1 and XOP2, even though the TMS9900 supports * XOP0..XOP15. Furthermore, XOP1 is only available if its WP = >FFD8. Not * all TI-99/4As have this value at offset >0044 (XOP1's WP). Also, note that * XOP0 (below) is merely an indicator of where the table starts as far as the * TMS9900 is concerned and that it (also, GPLXLK) was never intended to be * implemented as an XOP. * XOP0 GPLXLK DATA GPLXWS,GPLEXT Turn on GPL extension and start (PC = >0C1C) XOP1 DATA >FFD8,>FFF8 XOP1 (WP,PC) XOP2 DATA >83A0,>8300 XOP2 (WP,PC) DATA >1100 CRU value QUIT key * *~~Page 12: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ******************************************************************************* * * * Notes to GPL interpreter: * * * * In general the registers are used as follows: * * * * D: R3=Address, R2=Data, R4HByte=Flag VDP-RAM * * S: R1=Address, R0=Data, R4LByte=Flag VPD-RAM * * GPL code is located in R9 HByte, and R5 is flag at word commands * * * ******************************************************************************* * * GPL >F8 SWGR changing to other GROMS * BL @PUSHGA Push Grom address on substack BL @PUSHGA The same once more MOV 13,@>8300(4) GROM Read data on substack instead of GROM addr MOV 2,13 New GROM read data GPLR4 MOVB *13,4 GROM data in R4 MOV 0,6 * * GPL interpreter with GROM address in R6: * GPLR6 MOVB 6,@>0402(13) Write GROM address from R0 MOVB @>83ED,@>0402(13) SZCB @>011B,@>837C Clear condition bit in GPL status * * GPL interpreter * GPLITP LIMI >0002 >0070 Permit interrupt LIMI >0000 GPLNOI MOVB *13,9 Fetch GPL byte in R9 GPLR9 JLT >0086 Negative? i.e. >80 through >FF MOVB 9,4 SRL 4,12 1. Nybble MOV @>0C36(4),5 Trick, address always even number! B *5 Execute routine * * Negative interpreter code: * CLR 4 MOV 9,5 ANDI 5,>0100 Set flag for double (word) BL @>077A Fetch D SWPB 4 Flag in R4 HByte MOV 1,3 D into the right register MOV 0,2 CI 9,>A000 JL >00B0 Jump for format 5 commands 5 COC @>0030,9 Immediate operand? JNE >00BC Not from GROM! MOV 13,1 GROM read data in R1 MOVB *1,0 Fetch data („S“, IMM Value) DEC 1 * *~~Page 13: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * BL @>07AA Fetch 2 bytes JMP >00C0 MOV 9,8 Format 5 SRL 8,8 SETO 0 Data becomes >FFFF MOV @>0BFE(8),8 Fetch address routine B *8 Execute BL @>077A Fetch source MOV 9,8 SRL 8,9 MOV @>0C4E(8),8 Fetch address routine C 2,0 Compare data D and S B *8 Execute routine * * GPL CGE: * JLT >006A Cond bit reset, if low SOCB @>011B,@>837C Set condition bit JMP >0070 Once again ! * * GPL CH: * JH >00CE Set condition bit, if high JMP >006A Reset and go on * * GPL CHE: * JHE >00CE Set condition bit if equal or greater JMP >006A Reset and go on * * GPL CGT: * JGT >00CE Set condition bit if greater JMP >006A Reset and go on * * GPL CLOG * INV 0 AND both data (INV+SZC) SZC 0,2 JEQ >00CE Set condition bit JMP >006A Reset and go on * * GPL CZ: * MOV 2,2 0? STST 4 CPU status in R4 MOVB 4,@>837C CPU status becomes GPL status JMP >0070 And go on * * GPL CARRY, OVF, H, GT: * MOV 9,0 SLA 0,12 Command in R0 last 3 bits SRL 0,13 MOVB @>837C,5 Fetch GPL status SLA 5,0 Shift to R0! JOC >00CE Set condition bit JMP >006A Reset condition bit * * GPL B: * MOVB *13,6 Fetch new GROM address JMP >0108 MOVB *13,@>83ED * *~~Page 14: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * JMP >0060 Write new address and on with reset * * GPL BS: * MOVB @>837C,4 GPL statusbyte SLA 4,2 JLT >0122 Condition bit set, then execute MOVB *13,4 Skip address in GROM JMP >006A Clear status and go on * * GPL BR: * MOVB @>837C,4 SLA 4,2 JLT >0116 Set condition bit, no execution MOVB *13,@>83F3 Fetch jump address in Lbyte R9 ANDI 9,>1FFF Eliminate command MOVB @>0002(13),6 Read high bit of actual GROM address ANDI 6,>E000 The first 3 bits only SOC 9,6 New address JMP >0060 Execute and go on * * GPL ABS: * ABS 2 Data ABS JMP >022E Execute * * GPL NEG: * NEG 2 Data NEG JMP >022E Execute * * GPL CLR: * SETO 2 First >FFFF, then invert * * GPL INV: * INV 2 Data INV JMP >022E Execute * * GPL FETCH: * MOV 4,6 Save VDP flag BL @PUSHGA Push actual GROM address on substack DECT 4 BL @>0848 Set stack pointer, write GROM address MOVB *13,2 Fetch data SRA 2,8 in R2 Lbyte INC @>8300(4) Increment GROM address on stack INCT 4 Old substack BL @>084C Write old GROM address MOV 6,4 Old R4 JMP >022E Execute * * GPL CASE: * DEC 2 JNC >006A Smaller than 0, then go on (thus new address in GROM) MOVB *13,5 Counting of „PC“ JMP >016A MOVB *13,5 JMP >0162 Loop * *~~Page 15: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * * GPL PUSH: * AB 14,@>8372 Increase data stack pointer(Attention system flag) MOVB @>8372,6 Fetch pointer SRL 6,8 MOVB @>83E5,@>8300(6) Push byte on data stack B @>0070 and go on * * GPL DECT: * SRL 0,14 * * GPL INCT: * DEC 0 -1 * * GPL INC und SUB: * NEG 0 Negate * * GPL DEC und ADD: * MOVB 5,5 JEQ >0222 Byte?, then execute A 0,2 Add word JMP >0228 Execute * * GPL AND: * INV 0 Invert SZC 0,2 Execute AND JMP >0228 and execute * * GPL OR: * SOC 0,2 Or JMP >0228 Execute * * GPL XOR: * XOR 0,2 Exclusive OR JMP >0228 Execute * * GPL ST: * MOV 0,2 R0 in R2 JMP >022E Execute * * GPL EX: * MOV 2,9 Save data S MOV 0,2 Data D in Data S BL @>0232 D write new data SWPB 4 Exchange VDP flag MOV 1,3 Exchange address JMP >01E6 Restore old data and execute * * GPL SRA: * SRA 2,0 Shift to R0 JMP >022E Execute * * GPL SLL: * SLA 2,0 JMP >022E * * GPL SRL: * MOVB 5,5 No word? JNE >01BE SB 2,2 Hbyte 0 * *~~Page 16: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * SRL 2,0 JMP >022E Execute * * GPL SRC: * MOVB 5,5 No word? JNE >01CA MOVB @>83E5,2 Lbyte in Hbyte SRC 2,0 Shift JMP >022E Execute * * GPL MUL: * MOV 2,8 Save data MOVB 5,5 Word? JNE >01D6 SB 8,8 Hbyte 0 MPY 0,8 Multiply MOVB 5,5 Word? JNE >01E0 MOVB 9,@>83F1 Hbyte R9 in Lbyte R8 MOV 8,2 New data BL @>0232 Write first data MOV 9,2 Second data in R2 JMP >022E Execute * * GPL DIV: * MOVB 5,@>837C Save R5 MOV 2,8 MOV 0,2 MOV 3,1 S address in 1 INC 1 Address +1 MOVB 5,5 Word? JEQ >01FC INC 1 Address +1 MOVB 4,4 VDP? JEQ >0206 BL @>07FA Write address VDP JMP >020A BL @>07A8 Fetch data from CPU RAM MOV 0,9 MOVB 5,5 Word? JNE >0216 MOVB @>83F1,9 Lbyte in Hbyte R9 SRA 8,8 DIV 2,8 Division JNO >01E0 No overflow, then write SOCB @>0013,@>837C Set overflow in condition bit JMP >01E0 And write data AB @>83E1,@>83E5 Lbyte R0 + Lbyte R2 STST 11 CPU status becomes MOVB 11,@>837C GPL status LI 11,>0070 Trick return GPL interpreter MOVB 4,4 VPD address? * *~~Page 17: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * JEQ >0254 MOVB @>83E7,*15 Write VDP address ORI 3,>4000 Write data MOVB 3,*15 MOVB 5,5 Word? JEQ >024A MOVB 2,@>FFFE(15) Data is in VDP RAM INC 3 MOVB @>83E5,@>FFFE(15) INC 3 B *11 To GPL interpreter MOVB 5,5 Word? JEQ >025A MOVB 2,*3+ Write data SWPB 2 MOVB 2,*3+ CI 3,>837E Was address screen buffer? JNE >0252 No, end MOV 11,6 Save return BL @>0880 Screen address from YPT and XPT MOVB 2,@>FFFE(15) Byte on screen B *6 To GPL interpreter * * GPL subinterpreter for >00 through >1F: * SLA 9,3 SRL 9,10 Table value from command MOV @>0C3E(9),4 Fetch address from table B *4 And execute * * GPL RAND: * LI 4,>6FE5 Generate random number MPY @>83C0,4 AI 5,>7AB9 MOV 5,@>83C0 Load random number seed MOVB *13,6 Fetch limit SRL 6,8 in Lbyte INC 6 +1 CLR 4 SWPB 5 DIV 6,4 MOVB @>83EB,@>8378 Random number on source JMP >02AA To GPL interpreter * * GPL BACK: * LI 7,>8700 Prepare R7 for writing in VDP register 07 MOVB *13,@>83EF Fetch colour BL @>089A Load register 7 * *~~Page 18: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * B @>0070 To GPL interpreter * * GPL SCAN (Scan keyboard with return to GPL interpreter): * LI 11,>0070 Trick with return * * Keybord scanning * KEYSCN MOV 11,@>83D8 Save R11 BL @PUSHGA Save GROM address to substack CLR 12 CRU 0 SBO >0015 Alpha lock MOVB @>8374,5 Keyboard mode SRL 5,8 MOV 5,6 JEQ >02EC 0 LI 0,>0FFF DEC 6 1 R0=>0FFF JEQ >02F4 LI 0,>F0FF DEC 6 2 R0=>F0FF JEQ >02F4 DEC 6 3 C 6,@>0072 JH >0382 >5? MOVB 6,@>8374 Keyboard mode 0 SWPB 6 MOVB 6,@>83C6 Keybord debounce (3=0, 4=1, 5=2) CLR 5 CLR 0 CLR 6 JMP >032E Mode 0,3,4,5 DATA >2925 LI 12,>0024 Mode 1,2 scan Joystick LDCR @>0405(5),3 CRU 06 and 07 LI 12,>0006 CLR 3 SETO 4 STCR 4,5 Fetch CRU SRL 4,9 JOC >0310 No fire key? MOVB @>02F1(5),@>83E7 Lbyte R3 SLA 4,1 AI 4,>16E0 GROM address Joystick table MOVB 4,@>0402(13) Write address MOVB @>83E9,@>0402(13) JMP >0322 MOVB *13,@>8376 Fetch values Y * *~~Page 19: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * MOVB *13,@>8377 and X MOV 3,3 Fire key ? JNE >03AA LI 1,>0005 Scan keys CLR 2 CLR 7 LI 12,>0024 SWPB 1 LDCR 1,3 Load CRU SWPB 1 LI 12,>0006 SETO 4 STCR 4,8 Fetch CRU INV 4 Invert bits MOV 1,1 0? JNE >0354 MOVB 4,7 ANDI 4,>0F00 SZC 0,4 JEQ >037A No key? MOV 1,1 Last loop? JNE >0360 MOV 5,5 Mode 1 or 2? JNE >037A MOV 2,2 Already a key? JNE >037A SETO 2 MOV 1,3 SLA 3,3 DEC 3 INC 3 SLA 4,1 Built key value in R3 JNC >036C MOV 1,1 JEQ >037A LI 1,>0001 Shorten loop DEC 1 JOC >0336 Smaller than 0? MOV 2,2 Key pressed? JNE >03AA CLR 6 Set pointer for no key MOVB 6,@>83C7 SETO 0 CB 0,@>83C8(5) JEQ >0394 BL @>0498 Time delay MOVB 0,@>83C8 MOVB 0,@>83C8(5) MOV 5,5 Mode 1 or 2? JNE >0478 End MOVB 0,@>83C9 MOVB 0,@>83CA JMP >0478 End * *~~Page 20: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * CB @>83E7,@>83C8(5) Same key as last time? JEQ >03E6 LI 6,>2000 Set GPL status BL @>0498 Time delay MOVB @>83E7,@>83C8 Set pointer (Lbyte R3) MOVB @>83E7,@>83C8(5) MOV 5,5 Mode 1 or 2 JNE >03E2 MOV 3,12 AI 12,>FFF8 JLT >03E2 LI 1,>0002 SRL 12,3 JOC >03DC DEC 1 MOVB @>83E7,@>83C8(1) MOVB 7,@>83C7 Last loop scanning on >83C7 MOVB @>83C7,7 LI 1,>17C0 GROM table mode 1 and 2 MOV 5,5 JNE >040E LI 1,>1790 GROM table CNTRL SLA 7,2 JOC >040E LI 1,>1760 GROM table FCTN SRL 7,15 JOC >040E LI 1,>1730 GROM table SHIFT DEC 7 JEQ >040E LI 1,>1700 GROM address table small letters A 3,1 +Key value MOVB 1,@>0402(13) Write address MOVB @>83E3,@>0402(13) JMP >041C MOVB *13,0 Values from GROM MOV 5,5 Mode 1 or 2? JNE >0478 MOVB @>83C6,@>83E7 Keyboard mode in R3 Lbyte BL @>04A2 Compare DATA >617A * *~~Page 21: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * JNE >0444 Small letter? CLR 12 MOV 3,3 Mode <4 JEQ >043E SBZ >0015 Activate ALPHA LOCK SRC 12,14 TB >0007 Scan ALPHA LOCK JEQ >0442 SB @>03B4,0 ->20 (Capital letter) SBO >0015 MOV 3,3 Mode 4 or 5 JNE >0456 BL @>04A2 Compare DATA >101F JEQ >0382 R0 between >10 and >1F CB 0,@>0587 5F? JH >0382 DEC 3 Mode 5 JNE >0478 CB 0,@>0025 0D (CR)? JEQ >0478 CB 0,@>02CA 0F? JH >046C SOCB @>0470,0 Set 1st bit JMP >0478 BL @>04A2 Compare DATA >809F JNE >0478 R0 smaller than >80 or bigger than >9F SZCB @>0470,0 Reset 1st bit MOVB 0,@>8375 ASCII value key on >8375 BL @POPGRA Restore GROM address MOVB 6,@>837C Set GPL status JEQ >0492 MOVB @>83D4,*15 Load VDP register 01 CLR @>83D6 Clear screen timeout counter MOVB @>0B61,*15 MOV @>83D8,11 Fetch return B *11 * * Time delay * LI 12,>04E2 Loop counter DEC 12 JNE >049C B *11 * * Compare RO with status EQU if R0 is in area of Hbyte and Lbyte * of the data value * MOV *11+,12 CB 0,12 JL >04B0 * *~~Page 22: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * CB 0,@>83F9 JH >04B0 CB 0,0 B *11 * * CLEAR keyboard scanning(status EQU, if pressed): * CLRSCN LI 12,>0024 Load CRU keyboard select LDCR @>0012,3 >00 SRC 12,7 LI 12,>0006 STCR 12,8 Fetch CRU CZC @>0036,12 Right key? JNE >04DC LI 12,>0024 CRU 2nd key LDCR @>0074,3 >03 SRC 12,7 LI 12,>0006 STCR 12,8 Fetch CRU CZC @>0036,12 Right key B *11 Back * * GPL FMT: * CLR 9 CLR 3 BL @>0880 Write actual screen address from XPT and YPT MOVB *13,8 Fetch 1st byte GROM LI 12,>8373 Pointer substack MOV 8,5 Save R8 IN R5 SLA 8,3 Eliminate 3 bits SRL 8,11 In Lbyte INV 8 SRL 5,12 1st Nybble MOV @>0CDC(5),5 Fetch routine address LI 2,>050A Return address SETO 4 Flag B *5 Execute routine SLA 4,5 Prepare flag C *2+,*2+ New return JMP >050A SLA 4,5 Prepare flag MOVB *13,6 Fetch byte from GROM A 3,6 Add offset MOVB 6,@>FFFE(15) Write data S 4,7 CI 7,>0320 JHE >0524 CI 7,>0300 Address too big? * *~~Page 23: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * JL >0524 AI 7,>FD00 Screen address 0 BL @>05B8 Set YPT and XPT BL @>0880 Write screen address INC 8 End format command JEQ >04E6 B *2 and on SLA 8,5 Compute format S 8,7 SETO 8 JMP >051A INC 9 INCT *12 Increase substack MOVB *12,6 Fetch last value SRL 6,8 MOVB @>83F1,@>8300(6) R8 Lbyte on Stack JMP >04E6 Next format command DECT *12 Decrease substack DEC 9 JMP >04E6 Next format command MOV 9,9 End ? JEQ >05B4 End with setting new XPT, YPT MOVB *13,4 Next byte from GROM MOVB *12,6 Fetch byte from stack MOVB *13,5 Next byte from GROM SRL 6,8 AB 14,@>8300(6) Count on stack JEQ >054A Go on MOVB 4,@>0402(13) Write GROM address MOVB 5,@>0402(13) JMP >04E6 Next format CI 8,>FFE4 End ? (>1B original) JEQ >0550 JGT >0596 MOV 13,1 CI 8,>FFE2 JEQ >058E JGT >0592 BL @>05B8 Set YPT and XPT NEG 8 MOVB *13,@>835F(8) BL @>0880 Set screen address JMP >04E6 Go on BL @>0778 Fetch address MOVB *1,3 * *~~Page 24: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * JMP >04E6 Go on BL @>0778 Fetch address LI 2,>059E Change return MOVB *1+,6 JMP >050C Write * * GPL ALL: * MOVB *13,5 Fetch ASCII BL @>08A4 Write VDP address LI 7,>0300 Screen MOVB 5,@>FFFE(15) DEC 7 JNE >05AC Loop LI 11,>0070 GPL return address SLA 7,3 MOVB 7,@>837E New YPT (0) SLA 7,8 SRL 7,3 MOVB 7,@>837F New XPT (0) B *11 and on * * GPL I/O: * MOV 0,2 Prepare address MOV 3,1 A 2,2 MOV @>0CEC(2),4 Fetch routine address CLR 9 B *4 and execute * * I/O Sound: * ANDI 14,>FFFE System flag SOC 0,14 Pointer GROM or VDP in system flag (00 or 01) MOV *3,@>83CC Load pointer sound list MOVB 14,@>83CE Load sound byte B @>0070 To GPL interpreter * * I/O CRU Input: * INC 9 Flag R9 * * I/O CRU Output * MOV *1+,12 CRU address A 12,12 Complete CLR 2 MOVB *1+,2 Number bits in 2 SLA 2,4 SOC 2,9 SRC 9,6 ORI 9,>3012 Prepare command MOVB *1,2 Fetch pointer SWPB 2 AI 2,>8300 Complete address * *~~Page 25: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * X 9 Execute JMP >05E4 To GPL interpreter * * GPL XML: * MOVB *13,9 Fetch data MOV 9,4 Prepare register for table access SRL 9,12 In R9 2nd table *2 SLA 9,1 SLA 4,4 In R4 1st table *2 SRL 4,11 A @>0CFA(9),4 Fetch table address MOV *4,4 Fetch address routine BL *4 Execute JMP >05E4 To GPL interpreter * * GPL MOVE: * MOVB 14,5 SRL 9,9 Test on IMM value JOC >062C Jump, if number immediate value BL @>077A Fetch number MOV 0,8 In R8 JMP >0634 MOVB *13,8 Fetch number SLA 4,15 Time loss MOVB *13,@>83F1 Complete number in R8 CLR 4 SLA 9,12 BL @>0758 Determine destination MOV 1,2 AB 9,9 JNC >0646 AI 4,>0003 Set VDP flag MOV 4,7 CLR 4 BL @>0758 Determine source A 4,4 R4 *2 MOV @>0CCE(4),6 Source routine in R6 A 7,7 MOV @>0CD4(7),7 Destination routine in R7 BL @PUSHGA Push GROM address on substack B *6 Execute source * * Source ROM or RAM: * MOVB *1+,11 Fetch B *7 Execute destination * * Source VDP RAM: * MOVB @>83E3,*15 Write address MOVB 1,*15 INC 1 MOVB @>FBFE(15),11 Fetch data B *7 Execute destination * * Source GROM: * MOVB 1,@>0402(13) Write GROM address * *~~Page 26: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * MOVB @>83E3,@>0402(13) INC 1 MOVB *13,11 Fetch data B *7 Execute destination * * Destination RAM: * MOVB 11,*2+ Write JMP >06CA Go on * * Destination GROM: * MOVB 2,@>0402(13) Write GROM address MOVB @>83E5,@>0402(13) INC 2 Next address MOVB 11,@>0400(13) Write into GRAM JMP >06CA Go on * * Destination VDP register: * CB @>83E5,14 R2 Lbyte >01? JNE >06AC COC @>0012,14 Version? JNE >06A8 ORI 11,>8000 Set 16k bit MOVB 11,@>83D4 Register value 1 MOVB 11,*15 Write ORI 2,>0080 VDP register MOVB @>83E5,*15 Write from Lbyte R2 INC 2 Next register JMP >06CA Go on * * Destination VDP RAM: * MOVB @>83E5,*15 Write address VDP ORI 2,>4000 Writing MOVB 2,*15 INC 2 Next address MOVB 11,@>FFFE(15) Write data DEC 8 End ? JGT >065E No, go on B @>083E Return GPL interpreter, set condition bit and * * GROM address from substack * GPL COINC: * MOV 0,8 MOV 8,3 SB 2,3 Difference Y SWPB 8 SWPB 2 SB 2,8 Difference X MOVB *13,0 Fetch mapping value SRL 0,8 * *~~Page 27: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * MOVB *13,5 Fetch coincidence table address SWPB 5 MOVB *13,5 SWPB 5 BL @PUSHGA Push GROM address on substack MOVB 5,@>0402(13) Write table address GROM SWPB 5 MOVB 5,@>0402(13) SWPB 5 MOVB *13,2 Fetch data from table JMP >06FE MOVB *13,1 JMP >0702 MOVB *13,6 JMP >0706 MOVB *13,7 MOV 0,0 Mapping 0? JEQ >0710 SRA 3,0 Seek coincidence SRA 8,0 AB 7,8 JLT >0750 AB 6,3 JLT >0750 CB 3,2 JGT >0750 CB 8,1 JGT >0750 SRL 1,8 Which table value is needed? INC 1 SRL 3,8 MPY 3,1 SRL 8,8 A 8,2 MOV 2,0 ANDI 2,>FFF8 S 2,0 SRA 2,3 A 5,2 C *2+,*2+ MOVB 2,@>0402(13) Write GROM address of the right data INC 0 MOVB @>83E5,@>0402(13) LI 2,>2000 MOVB *13,3 Fetch value SLA 3,0 Coincidence? JOC >0752 CLR 2 MOVB 2,@>837C Set GPL status JMP >06CE Return GPL interpreter with POP GROM address from * * substack * AB 9,9 Check kind JOC >077A MOVB *13,3 Fetch destination in R3 INC 4 Flag MOVB *13,@>83E7 * *~~Page 28: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * MOV 11,12 Save return AB 9,9 JNC >0772 MOVB *13,1 Fetch byte from GROM BL @>077E A 0,3 MOV 3,1 SRL 9,1 B *12 Return CLR 5 * * GPL addressing modes(fetch address and data): * MOVB *13,1 Fetch GPL byte JLT >07BA Negative? Jump at format II through V SRL 1,8 AI 1,>8300 Scratch pad address CI 1,>837D Character buffer? JNE >07A8 General CLR 10 MOV 11,6 BL @>0884 Write address screen MOV 6,11 MOVB @>FBFE(15),0 Fetch byte COC @>0072,14 Check multicolor JNE >07A4 JNC >07A2 SLA 0,4 Prepare multicolor SRL 0,4 MOVB 0,@>837D in character buffer MOVB *1,0 Fetch data from CPU MOVB 5,5 Word? JNE >07B2 SRA 0,8 B *11 Return MOVB @>0001(1),@>83E1 Fetch 2nd byte B *11 * * GPL addressing modes II through V: * MOVB *13,@>83E3 MOV 1,10 ANDI 1,>0FFF CI 1,>0F00 Extended range? JLT >07D0 No, jump SLA 1,8 MOVB *13,@>83E3 R1 address extended range SLA 10,2 Test 2nd bit(Mode II and IV) JNC >07E4 No, jump MOVB *13,6 Fetch index SRL 6,8 MOVB @>8300(6),0 Data in R0 * *~~Page 29: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * MOVB @>8301(6),@>83E1 A 0,1 R1 = Indicated address SLA 10,1 Test VDP RAM JNC >0812 No, jump INCT 4 Flag VDP SLA 10,1 Test indirect JNC >07FA No, jump MOVB @>8300(1),0 Fetch value MOVB @>8301(1),@>83E1 MOV 0,1 Value in R1 MOVB @>83E3,*15 Write address VDP MOVB 1,*15 SLA 0,8 MOVB @>FBFE(15),0 Data in R0 MOVB 5,5 Word? JEQ >07AE MOVB @>FBFE(15),@>83E1 2nd byte in R0 B *11 Return SLA 10,1 Test indirect JNC >0780 Jump if direct CI 1,>007C GPL statusbyte? JNE >0826 MOVB @>8372,1 Fetch data stack pointer SB 14,@>8372 Decrease JMP >077E Go on MOVB @>8300(1),1 Fetch from CPU RAM JMP >077E Go on * * GPL RTGR: * BL @POPGRA POP GROM address from substack MOV @>8300(4),13 Data substack new GRMRD MOVB 4,@>0400(13) Write stack value in new GROM * * GPL RTN: * SZCB @>011B,@>837C Reset condition bit * * GPL RTNC: * LI 11,>0070 Return GPL interpreter * * POP GROM address from substack and write address: * POPGRA MOVB @>8373,4 GROM address from subroutine stack SRL 4,8 DECT @>8373 Decrease stack pointer * *~~Page 30: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * MOVB @>8300(4),@>0402(13) Write GROM address MOVB @>8301(4),@>0402(13) B *11 Return MOVB *13,6 Reading from GROM LI 11,>0060 Trick return with writing GROM address from R6 MOVB *13,@>83ED R6 complete * * PUSH actual GROM address on subroutine stack * PUSHGA INCT @>8373 Increase stack pointer MOVB @>8373,4 SRL 4,8 MOVB @>0002(13),@>8300(4) Address GROM on stack MOVB @>0002(13),@>8301(4) DEC @>8300(4) Correct address B *11 Return * * Screen address from YPT and XPT for writing: * LI 10,>4000 Write * * Screen address from YPT and XPT for reading: * MOVB @>837F,7 Screen line COC @>0072,14 Check multicolor JEQ >08AA SLA 7,3 SRL 7,8 MOVB @>837E,7 Fetch row SRL 7,3 A 10,7 MOVB @>83EF,*15 Write address VDP MOVB 7,*15 S 10,7 B *11 Return * * Write on screen at 0 * LI 7,>4000 JMP >089A * * Prepare address for multicolor mode: * MOVB @>837E,0 MOV 0,8 Prepare address: SLA 8,5 SRL 8,13 SRL 0,11 SLA 0,8 A 8,0 MOV 7,8 * *~~Page 31: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ANDI 7,>3E00 SRL 7,6 A 0,7 AI 7,>0800 MOVB @>83EF,*15 Write address SLA 8,8 MOVB 7,*15 CI 11,>026A Back if not >026A (DIV) return address JNE >08A2 MOVB @>FBFE(15),0 Read Data from VDP in R0 MOVB @>837D,8 Character buffer in R8 ANDI 8,>0F00 JOC >08EC ANDI 0,>0F00 SLA 8,4 JMP >08F0 ANDI 0,>F000 ORI 7,>4000 Writing address BL @>089A Write address A 8,0 MOVB 0,@>FFFE(15) Write data B *6 Return * * Interrupt routine * INT1 LIMI >0000 Disable interrupt LWPI GPLWS Load GPLWS! CLR 12 Clear CRU COC @>0032,14 Cassette interrupt? JNE INT100 No, jump B @CASINT INT100 TB >0002 JNE INT104 Jump, if VDP interrupt LI 12,>0F00 Clear CRU SBO >0001 INT101 SBZ >0000 AI 12,>0100 CI 12,>2000 JEQ INT103 End CRU SBO >0000 CB @>4000,@>000D ROM exists JNE INT101 No, next MOV @>400C,2 Intlnk? INT102 JEQ INT101 No, next ROM * *~~Page 32: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * MOV 2,0 MOV @>0002(2),2 Fetch INT address BL *2 And execute MOV *0,2 Next Int routine JMP INT102 INT103 B @INT201 End interrupt from CRU INT104 SBO >0002 Clear VDP interrupt MOVB @>83C2,1 Fetch interrupt flag byte SLA 1,1 No interrupt permitted JNC INT105 B @INT118 Then jump INT105 SLA 1,1 JOC INT109 No sprite move permitted, then jump MOVB @>837A,12 Number sprites JEQ INT109 No sprite end SRL 12,8 LI 2,>8800 VDP RD LI 3,>8C00 VDP WD LI 8,>0780 Sprite motion table INT106 MOVB @>83F1,*15 Write address motion table MOVB 8,*15 CLR 4 MOVB *2,4 Datas Y velocity CLR 6 MOVB *2,6 Datas X velocity SRA 4,4 MOVB *2,5 Auxiliary datas SRA 5,4 A 4,5 MOVB *2,7 SRA 6,4 SRA 7,4 A 6,7 AI 8,>FB80 Address sprite descriptor table MOVB @>83F1,*15 Write address MOVB 8,*15 CLR 4 MOVB *2,4 Fetch position A 5,4 CI 4,>C0FF JLE INT108 CI 4,>E000 Compute new position JH INT108 MOV 5,5 JGT INT107 AI 4,>C000 INT107 AI 4,>2000 INT108 CLR 6 MOVB *2,6 * *~~Page 33: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * A 7,6 ORI 8,>4000 VDP address for writing MOVB @>83F1,*15 MOVB 8,*15 MOVB 4,*3 Write positions AI 8,>0482 MOVB 6,*3 SWPB 5 MOVB @>83F1,*15 Write address motion table MOVB 8,*15 SRL 5,4 MOVB 5,*3 Write auxiliary values SWPB 7 SRL 7,4 MOVB 7,*3 AI 8,>C002 New address motion table DEC 12 Last sprite? JGT INT106 No, once again INT109 SLA 1,1 JOC INT117 No sound process jump MOVB @>83CE,2 Number of sound byte JEQ INT117 None, then end SB 14,@>83CE -1 JNE INT117 Not 0, then end MOV @>83CC,3 Pointer sound list MOV 14,5 SRL 5,1 GROM or VDP? JOC INT110 1=VDP, then jump BL @PUSHGA Push GROM address on substack LI 5,>0402 A 13,5 GROM write address MOVB 3,*5 Write GROM address MOVB @>83E7,*5 MOV 13,6 Read address JMP INT111 INT110 LI 5,>8C02 VDPWA MOVB @>83E7,*5 Write VDP address MOVB 3,*5 LI 6,>8800 VDPRD INT111 MOVB *6,8 Fetch byte JEQ INT114 0? CB @>0A9C,8 JEQ INT113 >FF? Yes,switch to another(well possible)! SRL 8,8 Number A 8,3 To address INT112 MOVB *6,@>8400 Load sound process DEC 8 How many bytes? JNE INT112 Next byte INCT 3 MOVB *6,2 Fetch duration * *~~Page 34: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * JEQ INT115 JMP INT116 Go on INT113 XOR @>0378,14 Change system flags INT114 MOVB *6,3 Fetch new address LI 2,>0100 Sound byte >01 MOVB *6,@>83E7 Complete address JMP INT116 Once again INT115 SB 2,2 INT116 MOV 3,@>83CC New pointer sound list MOVB 2,@>83CE Sound byte CI 5,>8C02 From VDP? JEQ INT117 BL @POPGRA POP GROM address from substack INT117 SLA 1,1 JOC INT118 No QUIT key, then jump LI 12,>0024 Load CRU LDCR @>0012,3 SRC 12,7 LI 12,>0006 STCR 5,8 Fetch CRU CZC @>004C,5 QUIT key? JNE INT118 BLWP @RSTLNK @>0000 Software reset INT118 MOVB @>FC00(15),@>837B VDP status in copy RAM LWPI >83C0 INTWS INCT 11 Screen timeout counter JNE INT200 Not 0 * * Interrupt level 2: * INT2 MOVB 10,12 VDP register 1 SRL 12,8 ORI 12,>8160 Basis value ANDI 12,>FFBF Turn off screen MOVB @>83D9,@>8C02 Load VDP register MOVB 12,@>8C02 INT200 LWPI GPLWS GPLWS AB 14,@>8379 VDP interrupt timer (system flags!) MOV @>83C4,12 User defined interrupt JEQ INT201 None, then jump BL *12 Otherwise execute INT201 CLR 8 Clear GROM search pointer LWPI >83C0 INTWS RTWP and end interrupt * *~~Page 35: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * * XML 19 GROM DSRLNK, similar to assembler, >836D data, but correct pointers * are missing >8356 (left pointing DSR name), return to GPL occurs. * CLR 1 MOV @>83D0,12 Fetch GROM search routine (CRU!) JNE >0AF8 LI 12,>0F00 Scan CRU MOV 12,12 JEQ >0AD2 SBZ >0000 AI 12,>0100 CLR @>83D0 CI 12,>2000 JEQ >0B20 MOV 12,@>83D0 SBO >0000 LI 2,>4000 Does ROM exist? CB *2,@>000D >AA? JNE >0ACC AB @>836D,@>83E5 Add data R2 Lbyte JMP >0AFE MOV @>83D2,2 Fetch ROM search pointer SBO >0000 MOV *2,2 Check routine existing JEQ >0ACC MOV 2,@>83D2 ROM pointer next routine INCT 2 MOV *2+,9 BL @>0BE8 Check name JMP >0AF8 Not the right INC 1 BL *9 Execute routine JMP >0AF8 SBZ >0000 Turn off DSR ROM JMP >0B1C CLR *8 BL @POPGRA POP GROM address from substack! corresponds RTN B @>006A Return GPL status reset * * XML 1A GSRLNK (Search DSR in GROM): * LI 7,>83D2 ROM search pointer LI 8,>83D0 GROM search pointer BL @PUSHGA Push GROM address on substack MOV *7,1 MOV *8,2 JNE >0B3E GROM search pointer <>0, then execution LI 2,>9800 GROM read data * *~~Page 36: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * LI 1,>E000 Highest GROM CZC @>0128,1 Beginning JNE >0B60 MOV 2,*8 GROM search pointer MOVB 1,@>0402(2) Write GROM address MOVB @>83E3,@>0402(2) AB @>836D,@>83E3 Data + R1 LB MOVB 1,@>83CB Save R1 Hbyte CB *2,@>000D GROM header? JNE >0BC4 MOVB 1,@>0402(2) Write GROM LINK address MOVB @>83E3,@>0402(2) SLA 10,4 Time loss MOVB *2,3 Fetch LINK table address JMP >0B70 MOVB *2,@>83E7 MOV 3,*7 R3 on ROM search pointer (next LINK address) JEQ >0BC4 0? INCT 3 MOVB 3,@>0402(2) Write start address MOVB @>83E7,@>0402(2) JMP >0B86 MOVB *2,9 Start address in R9 SLA 10,4 MOVB *2,@>83F3 BL @>0BE8 Check name JMP >0B30 AB @>0030,@>8372 Data stack pointer +2 AB 14,@>836C Count MOVB @>8372,4 Fetch data stack pointer SRL 4,8 DECT 3 CB @>836D,@>0C04 Does program LINK? JNE >0BB0 MOV 3,9 Addresses of the programs on stack MOVB 9,@>8300(4) MOVB @>83F3,@>8301(4) MOV 2,13 Set GROM pointer BL @POPGRA POP GROM address from substack. Corresbonds RTN * *~~Page 37: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * B @>00CE Set GPL interpreter condition bit CLR 1 MOVB @>83CB,1 Fetch GROM number AI 1,>E000 ->10 MOV 1,*7 New GROM on GROM search pointer CI 1,>E000 End ? JNE >0B3E C *2+,*2+ R2 +4 Oh !, Works for differentiated GRMRD of MOV 2,*8 >04 each difference! But not supported by CI 2,>9840 16times console. JEQ >0B1A End MOVB @>8355,5 Length 0? JNE >0B3A No JMP >0B1C Go on * * Check name ( name on FAC, Length on >8355) * MOVB @>8355,5 Length 0? JEQ >0C08 CB 5,*2 Length right ? JNE >0C0A SRL 5,8 LI 6,>834A FAC CI 2,>9800 In GROM? JHE >0C00 INC 2 No, R2+1 CB *6+,*2 Compare JNE >0C0A Don’t fit, end DEC 5 Length complete ? JNE >0BF8 No, go on INCT 11 Yes, right name, return +2 B *11 * * GPL extension for future (>14->1E,>98->9F,>EE->EF,>FC->FF): * BL @>0C28 Turn on CRU B @>4020 Jump to entry address * * GPL extension for future (>1F): * BL @>0C28 Turn on CRU B @>401C Execute * * Not used up to now in operating system: * GPLEXT LWPI >2800 BL @>0C28 Turn on CRU B @>4028 Execute LI 12,>1B00 Load CRU SBO >0000 Turn on * *~~Page 38: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * B *11 Return DATA >0000 DATA >0000 DATA >0000 * * STARTTABLE * * GPL jump table 1st byte HNybble * DATA >0270 Various (>00->1F) DATA >061E MOVE (>20->3F) DATA >011A BR (>40->5F) DATA >010E BS (>60->7F) * * GPL jump table Code >00->1F * DATA >0838 RTN (>00) DATA >083E RTNC (>01) DATA >027A RAND (>02) DATA >02AE SCAN (>03) DATA >029E BACK (>04) DATA >0104 B (>05) DATA >085A CALL (>06) DATA >05A2 ALL (>07) DATA >04DE FMT (>08) DATA >00F4 H (>09) DATA >00F4 GT (>0A) DATA >0024 EXIT (>0B) DATA >00F4 CARRY (>0C) DATA >00F4 OVF (>0D) DATA >18C8 PARSE (>0E) DATA >0608 XML (>0F) DATA >1920 CONT (>10) DATA >1968 EXEC (>11) DATA >19F0 RTNB (>12) DATA >082C RTGR (>13) DATA >0C0C For extension DATA >0C0C „ DATA >0C0C „ DATA >0C0C „ DATA >0C0C „ DATA >0C0C „ DATA >0C0C „ DATA >0C0C „ DATA >0C0C „ DATA >0C0C „ DATA >0C0C „ DATA >0C14 „ (>1F) * * GPL jump table Code >80->9F * DATA >0136 ABS (>80) DATA >013A NEG (>82) DATA >0140 INV (>84) DATA >013E CLR (>86) DATA >0144 FETCH (>88) DATA >0162 CASE (>8A) DATA >016E PUSH (>8C) DATA >00EA CZ (>8E) DATA >0186 INC (>90) DATA >0188 DEC (>92) DATA >0184 INCT (>94) DATA >0182 DECT (>96) DATA >0C0C For extension DATA >0C0C „ DATA >0C0C „ DATA >0C0C „ * * GPL jump table Code >A0->FF * DATA >0188 ADD (>A0) * *~~Page 39: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * DATA >0186 SUB (>A4) DATA >01CE MUL (>A8) DATA >01EA DIV (>AC) DATA >0190 AND (>B0) DATA >0196 OR (>B4) DATA >019A XOR (>B8) DATA >019E ST (>BC) DATA >01A2 EX (>C0) DATA >00D6 CH (>C4) DATA >00DA CHE (>C8) DATA >00DE CGT (>CC) DATA >00CC CGE (>D0) DATA >00EC CEQ (>D4) DATA >00E2 CLOG (>D8) DATA >01B0 SRA (>DC) DATA >01B4 SLL (>E0) DATA >01B8 SRL (>E4) DATA >01C2 SRC (>E8) DATA >06D2 COINC (>ED, Incompletely decoded) DATA >0C0C For extension (>F0) DATA >05C8 I/O (>F6, Incompletely decoded!) DATA >004E SWGR (>F8) DATA >0C0C For extension (>FC) * * Jump table for addresses at MOVE: * DATA >0660 Source in ROM or RAM DATA >0672 Source in GROM or GRAM DATA >0664 Source in VDP RAM DATA >0682 Destination in ROM or RAM DATA >0686 Destination in GROM DATA >06BA Destination in VDP RAM DATA >0698 Destination is VDP register * * FMT format jump table * DATA >050A 0,1 Horizontal string projection DATA >0508 2,3 Vertical string projection DATA >0504 4,5 Repeat horizontal character DATA >0502 6,7 Repeat vertical character DATA >0534 8,9 Relative fixed row DATA >0532 A,B Relative fixed column DATA >053A C,D Loop values DATA >056C E,F Fixed position row and column, screen offset * * I/O jump table * DATA >05D6 Sound Grom 00 DATA >05D6 Sound VDP 01 DATA >05E8 CRU Input 02 DATA >05EA CRU Output 03 DATA >1346 Cassette Write 04 DATA >142E Cassette Read 05 DATA >1426 Cassette verify06 * * XMLLNK table 1st Nybble * DATA >0D1A Floating point routines (>0X) DATA >12A0 „XTAB“ (>1X) DATA >2000 Low memory expansion (>2X) DATA >3FC0 Basic enhancement (>3X) DATA >3FE0 Basic enhancement (>4X) DATA >4010 Probably for GPL extension (>5X) Also usable in DSR DATA >4030 Probably for GPL extension (>6X) Also usable in DSR DATA >6010 ROM modul (>7X) DATA >6030 ROM modul (>8X) DATA >7000 ROM modul (>9X) DATA >8000 Future expansion (>AX) DATA >A000 (>BX) DATA >B000 (>CX) * *~~Page 40: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * DATA >C000 (>DX) DATA >D000 (>EX) DATA >8300 Scratch PAD RAM (>FX) * * FLTAB (XMLLNK 2nd Nybble >0X) * DATA >0000 DATA >0F54 Rounding of floating point numbers 9 bytes long (>01) DATA >0FB2 Rounding of floating point numbers length @>8354 (>02) DATA >0FA4 Status EQU if FAC (word) =0 (>03) DATA >0FC2 Overflow (>8376 Byte negative toward 0 positive toward * * infinite(>04) * DATA >0FCC Set overflow number (>8375 negative or positive (>05) DATA >0D80 FADD (>06) DATA >0D7C FSUB (>07) DATA >0E88 FMUL (>08) DATA >0FF4 FDIV (>09) DATA >0D3A FCOMP (>0A) DATA >0D84 SADD (>0B) DATA >0D74 SSUB (>0C) DATA >0E8C SMULT (>0D) DATA >0FF8 SDIV (>0E) DATA >0D46 SCOMP (>0F) * * ENDTABLE * * FCOMp (XML >0A): * MOV 11,10 LI 3,>0FAA End load JMP >0D50 Execute * * Set SCOMP with direct return without GPL status: * MOV 11,3 JMP >0D4C * * SCOMP (XML >0F): * LI 3,>0FAA MOV 11,10 BL @>1FA8 Fetch number from stack of VDP LI 7,>835C ARG LI 5,>834A FAC C *7,*5+ Compare 1st word JNE >0D72 MOV *7+,6 JEQ >0D72 0? JGT >0D68 >0? MOV 5,6 Exchange if smaller 0 MOV 7,5 (Invert logic) MOV 6,7 C *7+,*5+ 2nd word JNE >0D72 C *7+,*5+ 3rd word JNE >0D72 C *7,*5 4th word B *3 Return or set GPL status byte * * SSUB (XML >0C): * MOV 11,10 BL @>1FA8 Pop number from VDP stack MOV 10,11 * * FSUB (XML (>07): * NEG @>834A Make subtraction from addition * *~~Page 41: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * * FADD (XML >06): * MOV 11,10 JMP >0D8A * * SADD (XML >0B): * MOV 11,10 BL @>1FA8 Pop number from VDP stack MOV @>835C,7 ARG in R7 JEQ >0DA4 0? MOV @>834A,8 FAC in R8 JNE >0DA8 <>0? LI 1,>FFF8 MOV @>8364(1),@>8352(1) ARG in FAC INCT 1 All 8 bytes? JLT >0D9A B @>0FA6 Set status (EQU if 0) XOR 8,7 Sign ABS @>834A Positive ABS @>835C Positive LI 3,>FFF8 8 bytes C @>8352(3),@>8364(3) Compare JGT >0DDA All o.k. JLT >0DC6 Smaller, exchange INCT 3 JNE >0DB6 Number end? JMP >0DDA MOV @>8364(3),0 Bigger number in FAC MOV @>8352(3),@>8364(3) MOV 0,@>8352(3) INCT 3 JNE >0DC6 Number end? XOR 7,8 Sign in R8 CLR 5 CLR @>8352 Clear CLR @>8364 The same MOVB 8,@>8375 Save sign (in ASCII key) CLR 6 MOVB @>834A,@>83ED Exponent in R6 Lbyte MOV 6,@>8376 Save R6 MOVB 5,@>834A * *~~Page 42: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * SB @>835C,@>83ED Difference exponent CI 6,>0007 Digit number JGT >0E84 Bigger, then end MOV 6,0 LI 8,>0100 LI 9,>6400 100 decimal LI 5,>8353 FAC +9 LI 6,>8365 ARG +9 S 0,6 Digit difference MOV 0,4 AI 4,>FFF7 Difference loop counter MOV 7,1 Negative? JLT >0E62 AB *6,*5 Add CB *5,9 Overflow? JL >0E2E SB 9,*5 -100 AB 8,@>FFFF(5) +1 on digit higher DEC 5 DEC 6 INC 4 Loop till end JLT >0E22 JMP >0E3C DEC 5 AB 8,*5 SB 9,*5 Overflow 1st digit JGT >0E38 JEQ >0E38 AB 9,*5 Repair old value MOVB @>834A,1 JEQ >0E60 INC @>8376 Increse exponent LI 1,>8352 All 1 byte up LI 2,>0009 MOVB *1,@>0001(1) DEC 1 DEC 2 JNE >0E56 Loop 8 bytes JMP >0F56 SB *6,*5 Minus JGT >0E6E Overflow? JEQ >0E6E AB 9,*5 Execute overflow SB 8,@>FFFF(5) DEC 5 DEC 6 INC 4 JLT >0E62 Loop JMP >0E7E AB 9,*5 DEC 5 * *~~Page 43: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * SB 8,*5 MOVB *5,4 Check overflow last byte JLT >0E78 JMP >0F1C Check subtraction <>0 B @>0F86 Set exponent and end * * FMUL (XML >08): * MOV 11,10 JMP >0E92 * * SMUL (XML >0D): * MOV 11,10 BL @>1FA8 Fetch ARG from VDP stack LI 3,>834A FAC LI 5,>835C ARG MOV *3,8 FAC 0? JEQ >0F2A Set 0 XOR *5,8 Sign in R8 ABS *5 ARG to small JEQ >0F2A Set 0 ABS *3 CLR 9 MOVB *3,9 AB *5,9 New exponent SWPB 9 AI 9,>FFC1 Correction MOV 9,@>8376 Save MOVB 8,@>8375 Save sign LI 5,>8352 Clear >8352->835A CLR *5+ CI 5,>835A JNE >0EBE LI 5,>8352 DEC 5 Fetch FAC MOVB *5,0 0? JEQ >0ECA Go on LI 7,>0008 Fetch ARG DEC 7 MOVB @>835C(7),0 0? JEQ >0ED4 Go on CLR 0 MPY 0,2 Trick clear R2 and R3 MOV 5,6 R5 actual value FAC absolute LI 8,>83E1 LByte R0 LI 9,>0064 Decimal 100 MOV 7,4 R7 actual value ARG relative A 7,6 MOVB *5,@>83E7 Lbyte R3 MOVB 3,*5 Toward 0 MOVB @>835C(4),*8 Lbyte R0 * *~~Page 44: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * MPY 3,0 Multiplying of values MOVB *6,@>83E5 Lbyte R2 A 2,1 Add digit DIV 9,0 Divided by 100 MOVB @>83E3,*6 Write Lbyte R1 to digit DEC 6 Integer of division to new digit AB *8,*6 DEC 4 Loop for FAC JGT >0EF4 DEC 6 DEC 5 CI 5,>834A Loop for ARG JGT >0EEA CLR @>8354 No error LI 1,>FFF7 MOVB @>8354(1),2 Result <>0 JNE >0F34 INC 1 JLT >0F20 Loop CLR @>834A Clear CLR @>834C JMP >0FA6 MOV 1,0 First digit AI 0,>0009 ARG+1 JEQ >0F56 Yes, end with rounding S 0,@>8376 Substract exponent LI 2,>834B Shift to FAC MOVB @>8354(1),*2+ INC 1 JLT >0F44 Loop MOVB 1,*2+ Additional bytes DEC 0 JGT >0F4C JMP >0F56 End with rounding * * XML >01 Rounding of floating point numbers * MOV 11,10 LI 0,>3200 Decimal 50 C @>8352,0 Compare JLT >0F86 Smaller, end LI 1,>0007 LI 2,>0100 LI 0,>6400 Decimal 100 AB 2,@>834A(1) +1 CB @>834A(1),0 JL >0F86 Smaller 100, then end SB 0,@>834A(1) Minus 100 * *~~Page 45: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * DEC 1 JGT >0F6C Next digit INC @>8376 Increase exponent MOVB 2,@>834B 1 on first digit MOV @>8376,3 Fetch exponent CI 3,>0080 To big? JHE >0FC4 Overflow MOVB @>83E7,@>834A Set exponent MOVB @>8375,2 INV 2 JLT >0FA2 Negative? No, end NEG @>834A Negate number JMP >0FA6 * * XML >03 CPU status becomes GPL status in depending of FAC(word) * MOV 11,10 MOV @>834A,1 Fetch FAC * * Store status * STST 2 MOVB 2,@>837C CPU status becomes GPL status B *10 Return * * XML >02 Rounding with digit number in >8354 * MOV 11,10 MOVB @>8354,1 Digit number in R1 SRL 1,8 Lbyte JMP >0F64 Execute LI 9,>0200 Overflow +- Infinite with error code 02 JMP >0FD2 Execution * * XML >04 Overflow * MOV 11,10 MOVB @>8376,2 Fetch sign JLT >0F2A Execute toward 0 JMP >0FCE Toward infinite * * XML >05 Set overflow on FAC * MOV 11,10 LI 9,>0100 Error code 01 LI 0,>809D MOVB @>8375,2 Fetch sign JLT >0FDE Positive? NEG 0 LI 2,>834A FAC MOV 0,*2+ Load exponent and 1 digit LI 0,>6363 Decimal 99 * *~~Page 46: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * MOV 0,*2+ Write digits MOV 0,*2+ MOV 0,*2 MOVB 9,@>8354 Error code on >8354 JMP >0FA6 End set GPL-Status * * FDIV (XML >09): * MOV 11,10 JMP >0FFE * * SDIV (XML >0E): * MOV 11,10 BL @>1FA8 Fetch number from VDP stack LI 3,>834A FAC MOV *3,8 LI 0,>835C ARG XOR *0,8 MOVB 8,@>8375 Save sign of division ABS *3 Check on >0000 FAC JEQ >0FBC Error with code >02 ABS *0 Check on >0000 ARG JEQ >0F2A End with 0000 MOVB *0,9 Exponent SB *3,9 New exponent SRA 9,8 AI 9,>0040 Correction MOV 9,@>8376 Save on >8376 LI 4,>0004 Save FAC on >8354+ LI 5,>8364 Clear at >8364 through >836B MOV *3+,@>0008(3) Execute CLR *5+ DEC 4 JGT >102C Loop MOVB 4,@>835C LI 5,>83E1 R0 Lbyte LI 6,>83E3 R1 Lbyte LI 7,>0064 CLR 2 MOVB @>8355,@>83E5 CI 2,>0031 Decimal 49 JGT >1090 INC 2 CLR 3 MOV 7,4 DIV 2,3 Divided by 100 LI 9,>835C LI 4,>0008 * *~~Page 47: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * DEC 4 DEC 9 MOVB *9,0 JEQ >1064 0? CLR 0 MOV 0,2 MOVB *9,*5 MPY 3,0 A 2,1 DIV 7,0 MOVB *6,*9 DEC 9 DEC 4 JGT >106E CI 9,>8354 JNE >108C LI 9,>8364 JMP >1060 MOVB *5,@>835C LI 6,>0008 DEC 6 R6=last digit MOVB @>8354(6),0 JEQ >1094 CLR 7 MOVB @>8355,@>83EF 1st digit R7 Lbyte MOV 7,8 MPY @>1044,8 *100 MOVB @>8356,@>83F1 2nd digit R8 Lbyte A 8,9 LI 5,>FFF7 Loop counter LI 11,>835C CLR 2 MOVB *11,@>83E5 MPY @>1044,2 *100 CLR 0 MOVB @>0001(11),@>83E1 A 0,3 DIV 7,2 Divide MPY @>1044,3 Remainder *100 MOVB @>0002(11),@>83E1 A 0,4 +Remainder MOV 2,0 MPY 8,0 C 2,@>1044 JEQ >10EA Prepare over 100 * *~~Page 48: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * S 4,1 JMP >10F0 S 4,1 DEC 2 S 9,1 JGT >10EC MOV 2,2 JEQ >1148 CLR 3 MOV 6,4 A 6,11 Next section MOV 0,3 MOVB @>8354(4),@>83E1 MPY 2,0 A 3,1 DIV @>1044,0 SB @>83E3,*11 JGT >111A JEQ >111A AB @>1045,*11 INC 0 DEC 11 DEC 4 JGT >10FC SB @>83E1,*11 JGT >1148 JEQ >1148 DEC 2 MOV 6,4 A 6,11 AB @>8354(4),*11 Add ARG CB *11,@>1045 More than 100? JL >1142 O.k. SB @>1045,*11 Minus 100 AB @>0E59,@>FFFF(11) +1 one digit higher DEC 11 DEC 4 JGT >112E MOVB @>83E5,@>8354(5) INC 11 INC 5 JLT >10BA B @>0F18 End with rounding and shifting in FAC DATA >3203 CLR 4 Convert ASCII in integer CLR 0 MOV 11,9 JMP >1172 MPY @>117A,4 *10 * *~~Page 49: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * MOV 4,4 Overflow? JNE >1184 INC 0 A 8,5 MOV 5,4 JLT >1184 BL *3 Read character AI 8,>FFD0 ASCII correction CI 8,>000A Smaller 10? JL >1162 No , go on MOV 0,0 JEQ >118E Overflow B *9 LI 9,>1190 Trick return is changed JMP >1172 Stop in spite B @>0F2A Set FAC 0 and return B *10 Return DEC 6 New end address MOV 6,@>8356 on >8356 C 12,2 No string for changing JEQ >118A Error toward 0 MOV 1,@>8376 Set +- B @>0FC4 Overflow toward +- infinite and end * * XML >11 (CSN mit Flag auf >8389 0=VDP, <>0=Grom): * MOVB @>8389,3 Check flag JEQ >11AE LI 3,>1FDA From GROM JMP >11B2 * * CSN (XML >10): * LI 3,>1FC8 Fetch from VDP MOV 11,10 MOV @>8356,6 Fetch address BL *3 Read 1st byte CLR 7 MOV 6,2 CI 8,>002B ASCII + JEQ >11CC CI 8,>002D ASCII - JNE >11D0 No sign SETO 7 Flag for minus INC 2 Fix length BL *3 Next sign CI 8,>0030 0? JEQ >11CE Then next sign MOVB 7,@>8375 Save sign * *~~Page 50: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * MOV 6,12 Address start string in R12 DEC 12 Right address SETO 7 JMP >11E6 INC 7 BL *3 Fetch character CI 8,>0030 Compare, if character 0 through 9 JL >11F2 CI 8,>0039 JLE >11E2 If yes, next character CI 8,>002E Point? JNE >1220 INC 2 Compute digit left of the point MOV 7,7 JLT >1202 JMP >120E DEC 7 BL *3 Next character CI 8,>0030 0? JEQ >1200 Go on DEC 6 MOV 6,12 BL *3 Fetch character CI 8,>0030 0? JL >121C CI 8,>0039 JLE >120E C 6,2 JEQ >118A Set 0 and error MOV 6,2 End of number CLR 4 DEC 2 Correction CLR 1 CI 8,>0045 E? JNE >124C BL *3 Sign exponent CI 8,>002B + JEQ >1242 CI 8,>002D - JNE >1240 DEC 1 JMP >1242 DEC 6 BL @>115A Fetch exponent in integer MOVB 1,1 Negative number JEQ >124C NEG 4 DEC 6 MOV 6,@>8356 End address C 12,2 JEQ >118A Set error AI 4,>0080 Correct exponent CLR 1 * *~~Page 51: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * A 7,4 MOV 4,7 SRA 4,1 Exponent :2, Basis 100!! MOV 4,@>8376 SRC 7,1 LI 5,>0008 8 digits of the number LI 0,>834B Begin number MOV 12,6 Address, begin of the number in R6 C 6,2 JEQ >1294 BL *3 CI 8,>002E Point? JEQ >1272 Next character AI 8,>FFD0 ASCII correction INV 7 First, second digit JLT >1290 MPY @>117A,8 *10 MOVB @>83F3,1 R9 Lbyte in R1 JMP >1272 Next character AB @>83F1,1 R8 Lbyte add to R1 MOVB 1,*0+ R1 on FAC CLR 1 DEC 5 All digits JNE >1272 B @>0F56 Rounding and end * * STARTTABLE * * XTAB Table XMLLNK 2nd Nybble (attention limit >1B) * DATA >11AE CSN (>10) DATA >11A2 CSN with flag on >8389 byte (0=VDP Ram, 0<>Grom) (>11) DATA >12B8 CFI (>12) DATA >1648 Name from VDP OR GROM (to 00) then search in variable list(>13) DATA >164E Build stack entry from variable list (>834A Pointer to entry) DATA >1642 Assign value to a variable(stack entry) (>15) DATA >15D6 Search var name(Name on FAC, >8359 Length, GPL return ) (>16) DATA >163C VPUSHG (>17) DATA >1F2E VPOP (>18) DATA >0AC0 GPL-DSRLNK (>19) Name on FAC, >8359 Length, GPL return DATA >0B24 GSRLNK (1A) GPL return DATA >1868 Read byte from >8342, flag >8389 (0=VDP,1=GROM), address >832C(>1B) * * ENDTABLE * * CFI (XML >12) * MOV @>834A,4 JEQ >1342 0, End CLR 0 LI 2,>834B CLR 3 ABS @>834A CLR 5 MOVB @>834A,5 Exponent in R5 CI 5,>3F00 Too small JLT >133E Set 0 end JEQ >1308 * *~~Page 52: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * CI 5,>4100 100 JLT >1302 JEQ >12F0 CI 5,>4200 10000 JH >1330 Overflow, error MOVB *2+,@>83E1 in Lbyte R0 MPY @>1320,0 *100 MOV 1,0 MOVB *2+,@>83E7 Lbyte R3 A 3,0 + MPY @>1320,0 *100 MOV 0,0 Overflow? JNE >1330 MOV 1,0 JLT >1330 MOVB *2+,@>83E7 A 3,0 CB *2+,@>1158 JLT >1324 JGT >1322 Round up MOV 4,4 Negative? JGT >1322 MOVB *2+,3 Next byte JNE >1322 CI 2,>8352 End ? JL >1314 Loop JMP >1324 Go on DATA 100 INC 0 Round up CI 0,>8000 JL >1338 JH >1330 Overflow MOV 4,4 JLT >133C MOVB @>1159,@>8354 Set error B *11 Return INV 4 Flag negative JLT >133E NEG 0 Negate MOV 0,@>834A Integer on FAC B *11 End DATA >0010 * * Cassette write (GPL I/O): * CLR 0 LI 2,>0300 LI 8,>1E19 LI 3,>0023 * *~~Page 53: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * BL @>13BA Set CRU and pointer LI 0,>13E2 Print routine LIMI >0001 Enable interrupt CLR 4 Print signal constant >300 * >00 BL *0 DEC 2 JNE >1360 Loop SETO 4 BL *0 Print signal >FF MOV 5,4 SWPB 4 BL *0 Length of the transfer 1st byte MOV 5,4 SWPB 4 BL *0 Print 2nd byte CLR 9 LI 2,>0008 CLR 4 BL *0 Print 8 times >00 DEC 2 JNE >137E SETO 4 BL *0 Print 1 time >FF MOVB @>83F5,*15 Write buffer address to VDP LI 2,>0040 Number of data blocks MOVB 10,*15 CLR 7 CLR 4 MOVB @>FBFE(15),4 Fetch byte from VDP A 4,7 Build check sum BL *0 Print byte DEC 2 64 bytes? JNE >1396 No, next byte MOV 7,4 Transfer check sum BL *0 INV 9 Loop flag JNE >137A The whole twice AI 10,>0040 Increase buffer address DEC 5 All data blocks? JNE >137A No, go on JMP >13B4 Wait for interrupt B @>155E CRU reset and end * * Pointer for cassette transfer * MOV *1+,5 Fetch number of bytes AI 5,>003F Integer >40 SRL 5,6 SOC *1,0 Address data buffer MOV 0,10 in R10 MOVB @>83E1,*15 Write VDP address CLR 1 CLR 12 MOVB 0,*15 SOC @>0032,14 >0020 Set interrupt flag * *~~Page 54: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * SBZ >0002 Interrupt enable SBZ >000C LDCR 3,15 Load CRU SBZ >0000 SBZ >0001 SBO >0003 B *11 Return * * Output of a byte to cassette recorder: * LI 6,>0008 Loop counter 8 bits INV 4 Invert byte JMP >13E8 Wait for interrupt X 8 SBZ >0019 Mag tape out XOR @>135C,8 Command to SB0 JMP >13F0 Wait for interrupt MOV 4,4 Set bit JLT >13FC Yes, then jump to next byte X 8 SBO >0019 Mag tape out XOR @>135C,8 Command to SBZ SLA 4,1 Next bit DEC 6 All 8 bits? JNE >13E8 No, go on B *11 Return * * Interrupt cassette: * CASINT SBZ >0000 Control 9901 set SBO >0003 Timer interrupt reset MOV 1,1 R1 Negative? JLT >141A LWPI >83C0 INTWS C *14,@>13F0 Compare *R14 with>10FF (JMP -2) JNE >141A INCT 14 R14+2 Trick, jump from infinite loop RTWP End LWPI >83C0 MOV @>83EC,14 R6 GPLWS becomes new R14 JMP >1418 DATA >2100 * * Cassette verify (GPL I/O): * SOC @>1344,14 Set flag verify CLR 0 Read VDP JMP >1436 * * Cassette read (GPL I/O): * SZC @>1344,14 Flag read LI 0,>4000 Write VDP LI 3,>002B CRU BL @>13BA Fetch pointer, write VDP address MOV 10,7 Data buffer in R7 CLR 0 MOVB @>1443,@>837C Set condition bit GPL status * *~~Page 55: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * LI 8,>7530 Waiting loop reception LIMI >0001 Enable interrupt LI 6,>1458 Over interrupt new PC LI 3,>002B CRU ANDI 1,>00FF DEC 8 Count down loop JEQ >155E End with error LI 2,>0030 48 MOV 0,0 JNE >146A A 2,2 R2 double BL @>1572 JMP >1472 Receive character, go on JMP >1458 Receive no character, once again DEC 2 At least R2 character JNE >146A No, next character LI 9,>7FFF LI 8,>0008 LDCR 9,15 Set CRU SBZ >0000 SBO >0003 BL @>15BA Receive character JMP >148C Receive change (bit) JMP >1484 No change DEC 8 8 Bits? JNE >1484 Once more SBO >0000 STCR 3,15 Fetch CRU S 3,9 Change MOV 9,3 SLA 9,2 A 9,3 SRL 3,6 ORI 3,>0001 Set last bit LI 10,>14B0 Trick return CI 3,>001F JLT >1454 B @>1580 Read bit BL @>1572 Receive 1 bit JMP >14B0 No change LI 2,>0007 Go on 7 bits BL @>1572 JMP >1458 Once more DEC 2 All 7? JNE >14BA No, go on LI 6,>14F8 Trick return MOV 0,0 Data block * *~~Page 56: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * JNE >152E MOVB @>1424,@>837C Set error MOV 7,0 Prepare address CLR 7 BL @>15A0 Receive number of data blocks C 5,4 Enough storage JL >155E End with error MOV 4,5 New number data blocks INC 5 NEG 7 BL @>15A0 Fetch 2nd time JNE >155E JMP >1526 Go on with 1st data block ANDI 7,>00FF Clear 1st byte NEG 7 Negate BL @>15A0 Fetch check sum JEQ >1506 O.k. (Addition must result in 0,if data o.k) MOV 5,5 Already the 2nd time JLT >155E End with error MOVB @>83E1,*15 Write VDP address NEG 5 Flag R5 MOVB 0,*15 JMP >1448 Once more from beginning MOV 5,5 1 time JLT >151A No, jump LI 2,>0049 Receive 49 character LI 6,>1516 New PC over interrupt BL @>15A0 Fetch byte DEC 2 All ? JNE >150E AI 0,>0040 New VDP address MOVB @>83E1,*15 Write address ABS 5 MOVB 0,*15 CLR 7 DEC 5 All data blocks JNE >1448 JMP >1558 End LI 2,>0040 >40 Character CLR 7 BL @>15A0 Receive SWPB 4 COC @>1344,14 >0010 JNE >154E SB @>FBFE(15),4 Verify JEQ >1552 O.k. Jump CI 5,>0001 JEQ >1552 End of data blocks ? JMP >14F8 * *~~Page 57: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * MOVB 4,@>FFFE(15) Byte in VDP DEC 2 End of data blocks ? JNE >1534 JMP >14EC MOVB @>1438,@>837C Clear condition bit GPL status SZC @>1344,14 Clear interrupt flags SZC @>0032,14 SBZ >0003 CRU reset SBO >000C SBO >0001 SBO >0002 B @>0070 To GPL interpreter MOV 11,10 JMP >1574 Wait for interrupt BL @>15BA INCT 10 No change from R1 ORI 1,>FF00 CZC @>145A,1 R1 >FF00 JEQ >158C TB >001B Mag tape in, NEQ if R1=>FF JNE >1590 JMP >1586 TB >001B Mag tape in, EQU if R1=>00 JNE >158C LDCR 3,15 Load new CRU SBZ >0000 SBO >0003 ANDI 1,>00FF R1 >00XX XOR @>145A,1 XOR with>00FF B *10 Return * * Receive byte in R4 and built check sum in R7 * LI 8,>0008 8 Bits CLR 4 MOV 11,9 SLA 4,1 BL @>1572 Fetch 1 bit JMP >15B2 See TB entry INC 4 Set bit DEC 8 JNE >15A8 All 8 bits? A 4,7 Built check sum B *9 Return TB >001B Mag tape in if EQU R1=00, then R1=FF u. B*11 JEQ >15CA if EQU R1=FF, then R1=FF u. B*11+2 CZC @>145A,1 >FF if NEQ R1=00, then R1=00 u. B*11+2 * if NEQ R1=FF, then R1=00 u. B*11 JEQ >15D0 XOR @>145A,1 B *11 * *~~Page 58: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * CZC @>145A,1 JEQ >15C4 INCT 11 B *11 DATA >6500 * * XML >16 (Search variable name), leads back to GPL * BL @>15E0 Search name DATA >006A Return reset condition bit B @>00CE Return set condition bit MOV @>833E,4 Pointer fetch var list JEQ >160A No list, end reset condition bit MOVB @>8359,3 Fetch length byte CLR 7 INC 4 MOVB @>83E9,*15 Write VDP address JMP >15F4 MOVB 4,*15 LI 10,>8800 VDP read data CB *10,3 Compare length of variable JEQ >160E Right, check name MOVB *10,6 Address next variable JMP >1602 MOVB *10,@>83ED MOV 6,4 New address in R4 JNE >15EC Go on MOV *11,11 Fetch return B *11 Return MOVB *10,6 Address next variable JMP >1612 MOVB *10,@>83ED JMP >1618 MOVB *10,5 Address name of variable MOVB 3,@>83EF Length byte in R7 Lbyte MOVB *10,2 MOVB 2,*15 Write address VDP JMP >1624 MOVB 5,*15 LI 2,>834A FAC CB *10,*2+ Compare name JNE >1606 Next variable DEC 7 JGT >162A Until length end DEC 4 MOV 4,@>834A Address on FAC shows to value of variables B @>0002(11) Return +2 * * VPUSHG (XML >17) * LI 6,>1EAA Routine address * *~~Page 59: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * JMP >1652 * * XML >15 Coordinate VDP stack entry to variable * LI 6,>1788 Routine address JMP >1652 * * XML >13 Look on FAC and in symbole list for variable name from GROM or from VDP * LI 6,>176A Routine address JMP >1652 * * XML >14 Value stack entry for variable on FAC * LI 6,>1670 Routine address MOV 11,7 Save return BL @PUSHGA Push GROM address on substack BL @>1E7A R9 Address substack, R8=>8342, actual Basic byte INCT 9 ROM return address on substack MOV 7,*9 BL *6 Execute routine MOV *9,7 Return address from substack DECT 9 BL @>1E8C Set substack pointer and >8342 BL @POPGRA POP GROM address from substack B *7 Return * * XML >14 Main part: * INCT 9 Return on substack MOV 11,*9 MOV @>834A,@>834E FAC on FAC+4 A @>1816,@>834E Add FAC+4 >0006 BL @>19F6 Fetch one byte from VDP address in R1 JLT >1696 Byte in R1 negative = string CLR @>834C No jump CI 8,>B700 Basic token ( JEQ >16CC Jump MOV *9,11 Fetch return from stack DECT 9 B *11 Return CI 8,>B700 Basic token ( JEQ >16CC Jump MOV @>15D4,@>834C >6500 on >834C (String tag) MOV @>834E,3 MOV 3,@>834A Address +6 BL @>1880 Byte in R1 from VDP * *~~Page 60: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * MOVB @>8800,@>83E3 Word pointer value variable? MOV 1,@>834E Address string MOV 1,3 Space string JEQ >16C4 Jump DEC 3 Address length BL @>1880 Fetch byte SRL 1,8 MOV 1,@>8350 Length on >8350 JMP >1690 End DATA >0007 * * Data field: * SLA 1,5 1st 5 bits way, number of dimensions SRL 1,13 MOV 1,@>834C On >834C (Number dimensions) CLR 2 Length MOV 2,@>8350 BL @>1F7E Fetch 1 byte from VDP or GROM BL @>1E9C VPUSHG with PARSE Basic interpreter until ) DATA >B700 Token ) CB @>834C,@>15D4 >65 JHE >1736 CLR @>8354 For possible error BL @>12B8 CFI MOVB @>8354,4 Error? JNE >175C End with setting error MOV @>834A,5 Pointer for variable table BL @>1F2E VPOP BL @>187C Fetch byte from VDP DATA >834E Pointer to value MOVB @>8800,@>83E3 Word in R1 C 5,1 Right value JH >175C MOVB @>8343,4 Option base value JEQ >171E DEC 5 JLT >175C JMP >1720 INC 1 MPY @>8350,1 Right address to pointer on value A 5,2 + Begin INCT @>834E DEC @>834C All dimensions? JEQ >173A * *~~Page 61: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * CI 8,>B300 Token ,? JEQ >16D6 B @>1A2C End with error CI 8,>B600 Token ) JNE >1736 BL @>1F7E VPOP BL @>187C Fetch byte from VDP DATA >834A JLT >1754 String SLA 2,3 8 (for numeric data field) A 2,@>834E Correct address value JMP >1690 End SLA 2,1 2 A 2,@>834E Correct address JMP >169C End with setting string tag on >834C LI 0,>0503 Error B @>1A30 End with error LI 0,>0603 Error JMP >1760 * * XML >13 Main part: * CLR @>8359 Length pointer 0 LI 2,>834A FAC MOV 11,1 Save return MOVB 8,*2+ R8 on FAC (at >8342) INC @>8359 Increase length byte BL @>1F7E Fetch byte from VDP or GROM JGT >1774 Until negative BL @>15E0 Search name in variable list DATA >1736 Data (Return not found) B *1 O.k. found and return * * XML >15 Main part: * MOV 11,10 BL @>1FA8 Fetch 8 bytes from stack on ARG BL @>187C Read 1 byte from VDP in R1 DATA >835C Data VDP addresses pointer CB @>835E,@>15D4 String tag? JEQ >17AA O.k. go on CB @>834C,@>15D4 String tag? JHE >1764 Error LI 2,>0008 * *~~Page 62: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * JMP >184C CB @>834C,@>15D4 String tag? JNE >1764 Error MOV @>8360,1 Address? JEQ >17D4 Set 0 BL @>187C 1 Byte in R1 DATA >835C Pointer address VDP MOVB @>8800,@>83E3 Fetch 2nd byte MOV 1,@>8360 Pointer to string C 1,@>834E JEQ >17FC String identical, end CLR 6 BL @>18AA Write R6 in VDP (string offset -3) MOV @>8350,4 Length string JEQ >17F2 0 then end MOV @>834A,3 CI 3,>001C String expression? JNE >17FE MOV @>834E,4 Pointer to string MOV @>835C,6 Pointer variable list MOV 4,1 BL @>18AA Write pointer to variable list MOV @>835C,1 Pointer variable list MOV 4,6 BL @>18AE Write R6 in VDP without offset B *10 End MOV @>8350,@>830C String length MOV @>16CA,@>8322 Error code 7 BL @>1EAA VPUSHG MOV 10,@>834A BL @>1A4A Fetch space for string (over GROM) DATA >0006 MOV @>834A,10 BL @>1F2E VPOP MOV @>834E,3 String address MOV @>831C,5 Pointer to string space MOV 5,4 * *~~Page 63: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * MOV @>8350,2 String length ORI 5,>4000 BL @>1880 1 Byte from VDP without data pointer MOVB @>83EB,*15 Write VDP address JMP >183C MOVB 5,*15 INC 5 MOVB 1,@>8C00 Write R1 in VDP INC 3 New address DEC 2 Length-1 JGT >1832 Go on JMP >17E8 End MOV @>8360,5 Value pointer MOVB @>83EB,*15 Write VDP address ORI 5,>4000 For writing MOVB 5,*15 LI 4,>834A FAC MOVB *4+,@>8C00 From FAC in VDP DEC 2 JGT >185E Until end B *10 Return * * XML >1B Read 1 byte from VDP or GROM * MOV 11,12 BL @PUSHGA Push GROM address on substack BL @>1F7E Fetch byte MOVB 8,@>8342 Read byte at >8242 (actual Basic byte) BL @POPGRA POP GROM address from substack B *12 Return * * Read 1 byte from VDP, Entry over data address pointer * MOV *11+,3 Fetch data MOV *3,3 Fetch address MOVB @>83E7,*15 Write address JMP >1886 MOVB 3,*15 JMP >188A MOVB @>8800,1 Read byte B *11 * * Fetch 8 bytes from VDP over stack entry FAC * MOVB @>834F,*15 Write address LI 2,>0008 Loop counter MOVB @>834E,*15 LI 3,>834A FAC * *~~Page 64: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * MOVB @>8800,*3+ Fetch byte DEC 2 JGT >18A0 Loop end? B *11 Return * * Write R6 in VDP (R1=Address+3), used for variable table and string pointer * AI 1,>FFFD R1-3 MOVB @>83E3,*15 Write address ORI 1,>4000 For writing MOVB 1,*15 JMP >18BA MOVB 6,@>8C00 Write 1st byte MOVB @>83ED,@>8C00 2nd byte B *11 Return DATA >19CA * * GPL PARSE * BL @>1E7A Pointer substack in R9, >8342 in R8 MOVB @>0002(13),11 Actual GRom address in R11 MOVB @>0002(13),@>83F7 AI 11,>7FFF Trick R11 1st bit is set=GROM INCT 9 CI 9,>83BA Substack full JH >191C MOV 11,*9 R11 on substack MOVB 8,7 JLT >18EC Basic token? B @>1B94 Fecth variable name and go on BL @>1F7E Fetch byte from VDP or GROM SRL 7,7 Old Basic byte AI 7,>FE92 ->B7*2 CI 7,>004C Bigger >26 (>DD) JH >194C Error MOV @>1CE2(7),7 Fetch jump JGT >1958 Positive, then jump ANDI 7,>7FFF Correct GROM address A @>8328,7 Add NUD table address (>4E84 at master console) BL @>1E8C Set substack pointer and actual Basic token MOVB 7,@>0402(13) Write GROM address MOVB @>83EF,@>0402(13) * *~~Page 65: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * B @>006A GPL interpreter with reset condition bit B @>1F22 End with error * * GPL CONT * BL @>1E7A Substack pointer in R9, Basic byte in R8 MOV *9,6 Fetch address from substack JGT >1938 Not negative, then jump ANDI 6,>7FFF GROM address clear 1st bit MOVB 6,@>0402(13) and write MOVB @>83ED,@>0402(13) MOV 13,6 CB *6,8 Compare byte in GROM with old byte JHE >19E6 CI 8,>B800 &? JEQ >195A SRL 8,7 AI 8,>FE84 ->BE*2 CI 8,>0010 Basic byte >BE->C5 JH >1A2C Jump MOV @>1D2E(8),7 Fetch routine CLR 8 BL @>1F7E Set substack pointer and actual Basic byte B *7 LI 0,>0008 GPL routine & JMP >1A30 Execute DECT 9 New substack pointer AI 7,>8001 Address +1 JMP >190A Write GROM address and to GPL interpreter * * GPL EXEC * BL @>1E7A Substack pointer in R9, Basic byte in R8 CLR @>8322 Error code MOV @>8344,0 Basic flag in R0 JEQ >19A4 Nothing,then jump LIMI >0003 Enable interrupt LIMI >0000 Disable CLR @>83D6 Clear screen time out counter BL @>0020 Clear key scan JEQ >1A26 End MOVB @>8388,0 Error flag bit SLA 0,3 Check 2nd bit * *~~Page 66: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * JLT >1A50 MOV @>832E,@>832C Line pointer on text in linee pointer BL @>1F7E Fetch 1 byte from VDP or GROM JLT >1A20 MOVB 8,@>832C Fetch line address MOVB *10,@>832D INCT 9 Increase stack pointer MOV @>18C6,*9 Value>19CA on substack BL @>1F7E Fetch 1st byte from line JLT >19B4 <0? B @>1BEA MOV 8,7 Basic token in R7 BL @>1FA0 Next byte of the line SRL 7,7 1st token in R7 Lbyte *2 AI 7,>FEBC JGT >1A2C Bigger >A2 ? MOV @>1CE0(7),7 JLT >1902 Smaller 0, then GROM address B *7 Execute routine DATA >0065 Dec 101 MOV @>8344,0 Basic run flag and Basic flag byte JEQ >1A34 No, execute direct S @>1D4E,@>832E Next line (-4) C @>832E,@>8330 Smaller then lowest end of line list? JHE >1976 Execute in the limit JMP >1A34 End program MOVB 8,8 JNE >1A2C MOV *9,7 Data from substack JLT >1960 Negative,then jump DECT 9 Decrease stack pointer B @>0002(7) and execute routine (value+2) * * GPL RTNB: * BL @>1E7A Substack pointer in R9, actual Basic byte in R8 JMP >19E6 Go on MOV 11,2 Save return BL @>187C 1 Byte from VDP in R1 DATA >834A Pointer to address MOV 1,4 SLA 1,2 Is 2nd bit set? JOC >1A2C Yes, error * *~~Page 67: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * MOV 4,1 Again original byte B *2 Return DATA >0000 DATA >0000 DATA >0000 DATA >0000 DATA >0000 DATA >0000 DATA >0000 DATA >0000 DATA >0000 DATA >0000 DATA >0000 DATA >0000 MOVB @>8389,0 Fetch GROM flag JNE >199C Jump, if in GROM LI 0,>0001 GPL routine break JMP >1A30 LI 0,>0003 GPL error routine, error code 0 MOV 0,@>8322 Set GPL routine on vector MOV @>8326,7 Fetch return address Basic B @>190A Set stack pointer, write Basic return address * * Return GPL interpreter * DECT 9 Decrease substack pointer JMP >1A34 Return Basic MOV @>1D4E,@>8322 GPL routine memory full? LI 11,>1922 Trick return >1922 INCT 9 Increase stack pointer MOV 11,*9 Return address on substack JMP >1A34 Goto Basic MOV @>0072,@>8322 GPL routine TRACE LI 11,>198E Return for substack, go on in Basic interpreter JMP >1A4A Go on MOV @>832C,@>8356 Text pointer SWPB 8 A 8,@>832C Text pointer+R8 CLR @>8354 BL @>1E90 Set stack pointer BL @>11A2 CSN BL @>1E7A Fetch substack and Basic byte in R8 C @>8356,@>832C Text pointer in Basic line * *~~Page 68: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * JNE >1A2C BL @>1F7E Fetch byte MOVB @>8354,0 Test error JNE >1A40 B @>1924 CONT CLR 3 JMP >1AC0 BL @>18DA PARSE with different return DATA >B366 BL @>1E70 String tag? CLR @>8354 BL @>12B8 CFI MOVB @>8354,0 Error? JNE >1AB0 MOV @>834A,3 JGT >1AB6 LI 0,>0203 Error code JMP >1A30 CI 8,>8500 Token GO JNE >1ACC BL @>1F7E CI 8,>B100 Token ELSE JEQ >1B6C CI 8,>A100 Token SUB JMP >1AD6 CI 8,>8600 Token GOTO JEQ >1B6C CI 8,>8700 Token GOSUB JNE >1A2C BL @>1F7E Fetch byte JMP >1AE2 Execute JMP >1A2C Error CLR 3 MOV @>832E,@>834A Pointer to actual line MOVB @>1A97,@>834C >66 MOV 3,@>8350 Save R3 BL @>1EAA VPUSHG MOV @>8350,3 Old R3 * *~~Page 69: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * JMP >1AFE CLR 3 CI 8,>C900 Token line number? JNE >1ADE Error BL @>1F7E Fetch byte MOVB 8,0 Save R8 BL @>1FA0 2nd byte and INC text pointer DEC 3 JGT >1B62 R3 >0 MOV @>8330,1 Start line table MOVB @>8389,2 GROM flag JEQ >1B2A MOVB 1,@>0402(13) Write GROM address MOV 13,2 MOVB @>83E3,@>0402(13) JMP >1B34 MOVB @>83E3,*15 Write VDP address LI 2,>8800 MOVB 1,*15 C 1,@>8332 End line list JHE >1B50 CB *2,0 Searched line ? JNE >1B4C CB *2,8 JEQ >1B56 MOVB *2,3 Jump over line address AI 1,>0004 MOVB *2,3 JMP >1B34 And go on MOVB *2,3 Jump over one bit JMP >1B42 LI 0,>0303 Error JMP >1AB4 INCT 1 Found line MOV 1,@>832E New actual line pointer DECT 9 Decrease stack B @>1976 EXEC BL @>1F7E Fetch one byte CI 8,>B300 Token , JNE >1AB0 Error BL @>1F7E Next byte JMP >1AFE Search JMP >1ADE Error BL @>1F2E VPOP * *~~Page 70: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * CB @>1A97,@>834C >66? GOSUB stack entry? JNE >1B74 Go on MOVB 8,8 JNE >1B72 Error MOV @>834A,@>832E New actual line address B @>19E6 Address of substack and execute routine LI 0,>0006 GPL routine DEF JMP >1AB4 Error BL @>176A XML >13 fetch name BL @>187C One byte from VDP in R1 DATA >834A SLA 1,1 User defined function? JLT >1B8E Yes, execute GPL routine BL @>1670 XML >14 CB @>834C,@>19CB String tag? JEQ >1BB2 BL @>1890 8 Bytes from VDP over stack entry B @>1924 CONT BL @>18DA PARSE without GROM address DATA >B367 BL @>1E70 String tag? CLR 3 CI 8,>B000 Token THEN JNE >1B72 Error NEG @>834A JNE >1B6C BL @>1F7E Fetch byte CI 8,>C900 Token line number JNE >1B72 Error INCT @>832C Text pointer BL @>1F7E Fetch byte CI 8,>8100 Token ELSE JEQ >1B6C Go on B @>19E2 Address from substack and execute BL @>176A XML >13 Fetch name BL @>1670 XML >14 Built stack entry on FAC CI 8,>BE00 Token = * *~~Page 71: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * JNE >1B72 Error BL @>1F7E Fetch byte BL @>1E9C VPUSHG with changed return DATA >8D30 BL @>1788 XML >15 Coordinate value B @>1924 CONT DATA >0000 DATA >0000 DATA >0000 DATA >0000 DATA >0000 BL @>176A XML >13 Fetch name and search MOV @>834A,4 BL @>1F2E VPOP CB @>834C,@>1BBB >67? For next entry on stack? JEQ >1C2C B @>1F78 Error C 4,@>834A JEQ >1C3A S @>1C68,@>836E >0010 JMP >1C1C BL @>1890 8 Bytes from VDP over stack entry BL @>1E8C Set stack pointer and Basic byte BL @>0D84 SADD BL @>1E7A Fetch stack pointer and Basic byte A @>1C68,@>836E >0010 BL @>1788 XML >15 Assign value S @>1EAC,@>836E >0008 BL @>0D42 SCOMP STST 4 JEQ >1C76 MOV @>836E,3 AI 3,>0010 BL @>1880 Read byte MOVB 1,1 JLT >1C96 * *~~Page 72: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * SLA 4,1 JGT >1C92 A @>1F0E,@>836E >0018 MOV @>836E,3 AI 3,>0006 BL @>1880 Read byte MOVB @>8800,@>832F Another byte in Lbyte actual line pointer MOVB 1,@>832E Complete line pointer B @>1924 CONT SLA 4,1 Negative? JGT >1C76 Go on JMP >1C92 Stop and end * * STARTTABLE * * Jump table for EXEC * DATA >1A2C DATA >1A2C ELSE DATA >1A2C (: :) DATA >1A2C ! DATA >1BB6 IF DATA >1A8E GO DATA >1AFC GOTO DATA >1AE0 GOSUB DATA >1B74 RETURN DATA >19E6 DEF DATA >19E6 DIM DATA >1A3C END DATA >8000 FOR DATA >1BEA LET DATA >8002 BREAK DATA >8004 UNBREAK DATA >8006 TRACE DATA >8008 UNTRACE DATA >8016 INPUT DATA >19E6 DATA DATA >8012 RESTORE DATA >8014 RANDOMIZE DATA >1C14 NEXT DATA >800A READ DATA >1A3C STOP DATA >803E DELETE DATA >19E6 REM DATA >1A92 ON DATA >800C PRINT DATA >800E CALL DATA >19E6 OPTION DATA >8018 OPEN DATA >801A CLOSE DATA >1A2C SUB DATA >803C DISPLAY * * Jump table for PARSE * DATA >801C ( DATA >1A2C & DATA >1A2C DATA >1A2C OR DATA >1A2C AND * *~~Page 73: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * DATA >1A2C XOR DATA >1A2C NOT DATA >1A2C = DATA >1A2C < DATA >1A2C > DATA >801E + DATA >8020 - DATA >1A2C * DATA >1A2C / DATA >1A2C ^ DATA >1A2C DATA >8010 STRING IN „“ DATA >1A5C STRING DATA >1A2C Line number DATA >804A EOF DATA >8022 ABS DATA >8024 ATN DATA >8026 COS DATA >8028 EXP DATA >802A INT DATA >802C LOG DATA >802E SGN DATA >8030 SIN DATA >8032 SQR DATA >8034 TAN DATA >8036 LEN DATA >8038 CHR$ DATA >803A RND DATA >8040 SEG$ DATA >8046 POS DATA >8044 VAL DATA >8042 STR$ DATA >8048 ASC * * Jump table CONT * DATA >1D5C = DATA >1D3E < DATA >1D4C > DATA >1DEC + DATA >1E18 - DATA >1E24 * DATA >1E30 / DATA >1E3C ^ * * ENDTABLE * LI 2,>0002 Flag in R2 0:= * 1:<> CI 8,>C000 2:< * 3:<= JNE >1D50 4:> DECT 2 5:>= JMP >1D56 LI 2,>0004 CI 8,>BE00 JNE >1D60 BL @>1F7E JMP >1D5E SETO 2 INC 2 INCT 9 MOV 2,*9 Flag on substack BL @>1E9C Return on substack and VPUSHG * *~~Page 74: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * DATA >C000 Token > MOV *9,4 Fetch flag DECT 9 MOVB @>1DA8(4),12 Fetch jump SRA 12,8 BL @>1E4A FAC and stack same type? JEQ >1DAE String jump BL @>0D42 SCOMP B @>1D82(12) Jump * * Compare result in FAC: * JGT >1D8C >= JEQ >1D8C = CLR 4 JMP >1D90 JEQ >1D86 <> LI 4,>BFFF LI 3,>834A MOV 4,*3+ CLR *3+ CLR *3+ CLR *3+ JMP >1E10 End JEQ >1D8C <= JLT >1D8C < JMP >1D86 JGT >1D8C > JMP >1D86 * * Jump * DATA >0208 DATA >1E1C DATA >2200 * * Compare string: * MOV @>834E,10 Address first string MOVB @>8351,7 Length BL @>1F2E VPOP MOV @>834E,4 Address second string MOVB @>8351,6 Length MOVB 6,5 CB 6,7 JLT >1DCA MOVB 7,5 SRL 5,8 JEQ >1DE8 MOV 10,3 INC 10 BL @>1880 Read byte from VDP MOVB 1,0 MOV 4,3 INC 4 BL @>1880 Read byte from VDP CB 1,0 JNE >1D7E Not equal, end DEC 5 * *~~Page 75: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * JGT >1DCE CB 6,7 JMP >1D7E End BL @>1E9C VPUSHG DATA >C200 Token - LI 2,>0D84 SADD CLR @>8354 BL @>1E4A FAC and stack same type? JEQ >1E6C String jump BL @>1E8C Set stack pointer BL *2 Execute addition BL @>1E7A MOVB @>8354,2 JNE >1E14 Error B @>1924 CONT B @>1A40 Error and back to Basic BL @>1E9C Vpushg DATA >C200 Token - LI 2,>0D74 SSUB JMP >1DF6 BL @>1E9C Vpushg DATA >C400 Token / LI 2,>0E8C SMUL JMP >1DF6 BL @>1E9C DATA >C400 Token / LI 2,>0FF8 SDIV JMP >1DF6 BL @>1E9C DATA >C500 Token ^ LI 0,>0005 GPL routine involution B @>1A30 * * FAC and stack entry same type? * MOV @>836E,6 Fetch VDP address from FAC stack entry INCT 6 +2 MOVB @>83ED,*15 Write address JMP >1E56 MOVB 6,*15 JMP >1E5A CB @>8800,@>19CB >65 String tag? JL >1E70 < Jump * *~~Page 76: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * JH >1E6C > Error CB @>834C,@>19CB String tag? JEQ >1E78 Return B @>1764 Set error CB @>834C,@>19CB String tag? JHE >1E6C Error B *11 Return * * Substack pointer in R9 and actual Basic byte in R8 * CLR 8 MOVB @>8342,8 Fetch Basic byte MOVB @>8373,9 Fetch substack pointer SRL 9,8 AI 9,>8300 Complete address substack B *11 Return * * Set substack pointer and Basic byte: * MOVB 8,@>8342 Set Basic byte AI 9,>7D00 MOVB @>83F3,@>8373 Set substack pointer B *11 Return * * VPUSHG with return on substack and back over GPL CONT * * For DATA comparison * INCT 9 Substack to big? CI 9,>83BA JH >1F22 Error MOV 11,*9 Return on substack LI 11,>18E4 new return address * * VPUSHG (XML >17): * LI 0,>0008 A 0,@>836E Add 8 to value stack pointer MOV @>836E,1 Fetch pointer in R1 MOVB @>83E3,*15 Write address ORI 1,>4000 For writing MOVB 1,*15 LI 1,>834A Write data MOVB *1+,@>8C00 DEC 0 8 Bytes JGT >1EC4 MOV 11,0 Save return CB @>834C,@>19CB String tag? * *~~Page 77: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * JNE >1EF2 MOV @>836E,6 Value stack pointer in R6 AI 6,>0004 +4 MOV @>834A,1 CI 1,>001C String expression? JNE >1EF2 MOV @>834E,1 Pointer to string JEQ >1EF2 BL @>18AA Mark string MOV @>836E,1 Value stack pointer AI 1,>0010 +16 C 1,@>831A Pointer end free RAM for strings JLE >1F76 O.k. End INCT 9 MOV 0,*9 Return to substack MOVB @>18F0,@>8323 GPL routine garbage collection BL @>1A4A DATA >0018 MOV *9,0 Fetch return from substack DECT 9 MOV @>836E,1 Fetch value stack pointer AI 1,>0010 Stack +16 C 1,@>831A Smaller end free RAM JLE >1F76 O.k. LI 0,>0103 Error code BL @>1E7A Set substack and Basic byte B @>1A30 Error over GPL * * VPOP (XML >18) * LI 2,>834A FAC MOV @>836E,1 Fetch pointer value stack C 1,@>8324 Basis value stack? JLE >1F78 Error MOVB @>83E3,*15 Write VDP address LI 0,>0008 8 bytes MOVB 1,*15 S 0,@>836E Increase value stack MOVB @>8800,*2+ Fetch stack entry DEC 0 8 bytes JGT >1F4A * *~~Page 78: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * MOV 11,0 Save return CB @>834C,@>19CB String tag? JNE >1F76 No, end CLR 6 MOV @>834A,3 CI 3,>001C String expression? JEQ >1EE8 Clear BL @>1880 Correct string address from variable list MOVB @>8800,@>83E3 2nd byte in R1 Lbyte MOV 1,@>834E on >834E B *0 Return LI 0,>0403 Error code JMP >1F26 Print error * * Fetch 1 byte from VDP or GROM in R8 * MOVB @>8389,8 Flag GROM JNE >1F92 Yes, jump MOVB @>832D,*15 Write VDP address LI 10,>8800 VDP read data MOVB @>832C,*15 JMP >1FA0 MOVB @>832C,@>0402(13) Write GROM address MOVB @>832D,@>0402(13) MOV 13,10 Grom read data INC @>832C New text pointer MOVB *10,8 Read byte B *11 Return * * Fetch 8 bytes from VDP stack(Address STACK=>836E) * LI 5,>FFF8 8 Bytes LI 6,>835C Address ARG MOVB @>836F,*15 Write address LI 7,>8800 VDPRD MOVB @>836E,*15 A 5,@>836E STACK -8! MOVB *7,*6+ Fetch bytes INC 5 JNE >1FC0 B *11 Return * * Read 1 byte from VDP in R8 (Address R6) * * *~~Page 79: TI99/4A INTERN (Heiner Martin)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * MOVB @>83ED,*15 Write VDP address JMP >1FCE MOVB 6,*15 Complete INC 6 MOVB @>8800,8 Read byte SRL 8,8 In Lbyte R8 B *11 Return * * Read 1 byte from GROM in R8 (Address in R6) * MOVB 6,@>0402(13) Write GROM address MOVB @>83ED,@>0402(13) INC 6 MOVB *13,8 Read byte JMP >1FD6 In Lbyte R8 and return DATA >0000 DATA >0000 DATA >0000 DATA >0000 DATA >0000 DATA >0000 DATA >0000 DATA >0000 DATA >0000 DATA >2A61 Check sum DATA >A38A * END