* * I found this file in the web, thanks to pullmoll * ************************************************* * Revision *1.1*, /Fri Jun 18 11:08:09 2004 UTC * * by /pullmoll/ * * * ************************************************* ------------------------------------------------------------------------ ; ************************************************************************** ; * ROM listing Colour BASIC interpreter * ; ************************************************************************** ; ; This is a ROM listing of the BASIC interpreter for the EACA EG2000 ; Colour Genie computer. There are several versions of the Colour BASIC ; interpreter around. This is the most commonly used. ; ; ------------------------------------------------------------------------- ; Conventions: ; ; A,B,C,D,E, ; H,L,BC,DE, ; HL,IX,IY, ; SP,PC Identifiers of the Z80 registers ; ; BCDE Concatination of BC and DE registers to hold ; a single precision value ; ; X Accumulator X (from 411DH onwards) ; ; Y Accumulator Y (from 4127H onwards) ; ; Exp ( X ) Exponent of value in X ; ; Exp ( Y ) Exponent of value in Y ; ; Exp Exponent of any floating point value ; ; Sign Sign of a value ; ; VT Variable Type ; (02 = INT, 03 = STR, 04 = SNG, 08 = DBL) ; ; LP Line Pointer (= link) ; ; LN Line Number ; ; PTP Program Text Pointer ; ; A = B A equals B ; ; A -> B A points to B (contains address of B) ; ; A,n Bit n of register A ; ; I: List of entry parameters ; ; O: List of exit parameters ; ; SUB Subroutine ; ; -- Unused instruction ; ; '*' The following byte is multiple used ; ; --------------------------------------------------------------------------- ; Start of the BASIC interpreter ROMs ; Entry at 0000H after switch on of the computer or after + ; Cold start 00000 F3 DI ;Disable interrupts 00001 AF XOR A ;A = 0 00002 C37406 JP 0674H ;Continue at 0674H 00005 C30040 JP 4000H ;-- 00008 C30040 JP 4000H ;RST 08H: jump to 4000H and ;from there to 1C96H 0000B E1 POP HL ;-- 0000C E9 JP (HL) 0000D C30000 JP 0000H ;-- 00010 C30340 JP 4003H ;RST 10H: jump to 4003H and ;from there to 1D78H ; DCB Call for Input (AF,DE) ; ; I: DE = DCB Address ; O: A = Input byte 00013 C5 PUSH BC ;Save BC 00014 0601 LD B,01H ;DCB type: input 00016 182E JR 0046H ;Call DCB 00018 C30640 JP 4006H ;RST 18H: jump to 4006H and ;from there to 1C90H ; DCB Call for Output (AF,DE) ; ; I: DE = DCB Address ; O: A = Output byte 0001B C5 PUSH BC ;Save BC 0001C 0602 LD B,02H ;DCB type: output 0001E 1826 JR 0046H ;Call DCB 00020 C30940 JP 4009H ;RST 20H: jump to 4009H and ;from there to 25D9H ; DCB Call for Input/Output (AF,DE) (not used) ; ; I: DE = DCB Address ; O: A = Output byte 00023 C5 PUSH BC ;Save BC 00024 0604 LD B,04H ;DCB type: input/output 00026 181E JR 0046H ;Call DCB 00028 C30C40 JP 400CH ;RST 28H: jump to 400CH ;(BREAK-vector, reserved for ;DOS) ; Get byte from keyboard (AF,DE) ; ; I: - ; O: A = ASCII code of the key pressed or 00H when no key pressed 0002B 111540 LD DE,4015H ;DE -> Keyboard DCB 0002E 18E3 JR 0013H ;Continue at 0013H 00030 C30F40 JP 400FH ;RST 38H: jump to 400FH ;(reserved for DOS) ; Output a byte on the screen (AF,DE) ; ; I: A = ASCII code of the character to print on the screen ; O: - 00033 111D40 LD DE,401DH ;DE -> Screen DCB 00036 18E3 JR 001BH ;Continue at 001BH 00038 C31240 JP 4012H ;RST 38H: jump to 4012H ;(Interrupt vector, reserved ;for DOS) ; Output a byte on the printer (AF,DE) ; ; I: A = ASCII code of the character to print on the printer ; O: - 0003B 112540 LD DE,4025H ;DE -> Printer DCB 0003E 18DB JR 001BH ;Continue at 001BH 00040 C3D905 JP 05D9H ;Input of a line ;(see 05D9H) 00043 C9 RET ;-- 00044 00 NOP 00045 00 NOP 00046 C3C203 JP 03C2H ;Jump to DCB call ; Wait for keypress (AF,DE) ; ; I: - ; O: A = ASCII code of key pressed 00049 CD2B00 CALL 002BH ;Get byte from keyboard 0004C B7 OR A ;Key pressed ? (A <> 0) 0004D C0 RET NZ ;Yes: return 0004E 18F9 JR 0049H ;No: again ; Decoding table for keyboard routine ; ASCII codes of corresponding keys 00050 0D DEFB 0DH ;RETURN 00051 0D DEFB 0DH ;RETURN SHIFT 00052 1F DEFB 1FH ;CLEAR 00053 1F DEFB 1FH ;CLEAR SHIFT 00054 01 DEFB 01H ;BREAK 00055 01 DEFB 01H ;BREAK SHIFT 00056 5B DEFB 5BH ;UP ARROW 00057 1B DEFB 1BH ;UP ARROW SHIFT 00058 0A DEFB 0AH ;DOWN ARROW 00059 1A DEFB 1AH ;DOWN ARROW SHIFT 0005A 08 DEFB 08H ;LEFT ARROW 0005B 18 DEFB 18H ;LEFT ARROW SHIFT 0005C 09 DEFB 09H ;RIGHT ARROW 0005D 19 DEFB 19H ;RIGHT ARROW SHIFT 0005E 20 DEFB 20H ;SPACE BAR 0005F 20 DEFB 20H ;SPACE BAR SHIFT ; Delay loop (AF,BC) ; ; I: BC = counter (delay time = BC * 11.3 microseconds) ; O: - 00060 0B DEC BC ;Decrement counter 00061 78 LD A,B 00062 B1 OR C ;Counter zero ? 00063 20FB JR NZ,0060H ;No: loop 00065 C9 RET ; RESET entry after pressing both keys 00066 01181A LD BC,1A18H ;BC -> entry back into BASIC 00069 C3CA05 JP 05CAH ;Continue at 05CAH ; Start 4 (continuation of 05C7H) ; Prepare RAM for BASIC 0006C 31F841 LD SP,41F8H ;Set stackpointer 0006F 118040 LD DE,4080H ;Copy ROM area of 18F7H 00072 21F718 LD HL,18F7H ;to 191CH into RAM area 00075 012700 LD BC,0027H ;from 4080H to 40A6H 00078 C34001 JP 0140H ;Continue at 0140H ; Start 6 when no ROM cartridge with a BASIC program is present ; (continuation of 0149H) 0007B 210158 LD HL,5801H ;HL -> start of BASIC program 0007E 3A80F8 LD A,(0F880H) 00081 CB4F BIT 1,A ; pressed ? 00083 2009 JR NZ,008EH ;Yes: continue at 008EH 00085 22A440 LD (40A4H),HL ;Save pointer in system RAM 00088 CD4638 CALL 3846H ;FCLS ; Start 6 when a ROM cartridge with a BASIC program is present ; (continuation of 014CH) 0008B 22A440 LD (40A4H),HL ;Save pointer to start of ;program in system RAM 0008E 21E541 LD HL,41E5H ;HL -> (start of line buffer-3) ;Mark start: 00091 363A LD (HL),3AH ;':' 00093 23 INC HL 00094 70 LD (HL),B ;00H 00095 23 INC HL 00096 362C LD (HL),2CH ;'.' 00098 23 INC HL 00099 22A740 LD (40A7H),HL ;Save line buffer pointer in ;system RAM 0009C 113B01 LD DE,013BH ;DE -> error routine ;Block Disk BASIC vectors 0009F 061C LD B,1CH ;28 vectors 000A1 215241 LD HL,4152H ;HL -> vector table in RAM ;Construct vectors: ;28 times a JP 013BH in RAM 000A4 36C3 LD (HL),0C3H ;JP opcode 000A6 23 INC HL 000A7 73 LD (HL),E ;LSB of error routine address 000A8 23 INC HL 000A9 72 LD (HL),D ;MSB of error routine address 000AA 23 INC HL 000AB 10F7 DJNZ 00A4H ;Next vector ;Remaining DOS vectors are ;blocked with a RET 000AD 0615 LD B,15H ;21 vectors 000AF 36C9 LD (HL),0C9H ;Insert RET opcode 000B1 23 INC HL ;Reserve 2 bytes RAM space 000B2 23 INC HL ;so that the RET can be changed 000B3 23 INC HL ;to a JP instruction 000B4 10F9 DJNZ 00AFH ;Next vector 000B6 2AA440 LD HL,(40A4H) ;HL -> start of BASIC program 000B9 2B DEC HL ;Adjust pointer 000BA 70 LD (HL),B ;Mark start - 1 with 00H 000BB CD7038 CALL 3870H ;Initialize CRTC 000BE CD8F1B CALL 1B8FH ;Set stack pointer 000C1 CDAF06 CALL 06AFH ;Test ROM cartridge present 000C4 CDC901 CALL 01C9H ;CLS 000C7 211801 LD HL,0118H ;HL -> 'MEM SIZE' 000CA CDA728 CALL 28A7H ;Print text 000CD CDB31B CALL 1BB3H ;Print '?' and wait for ;input ; pressed ? 000D0 38F5 JR C,00C7H ;Yes: repeat input 000D2 D7 RST 10H ;Get next non-space character 000D3 B7 OR A ;Only entered ? 000D4 2013 JR NZ,00E9H ;No: an number was entered, ;continue a 00E9H 000D6 210040 LD HL,4000H ;Yes: HL -> start of RAM 000D9 23 INC HL ;HL + 1 000DA 7C LD A,H ;HL = 0000 ? 000DB B5 OR L ;(Complete memory tested) 000DC 281C JR Z,00FAH ;Yes: continue at 00FAH 000DE 7E LD A,(HL) ;Take byte from memory 000DF 47 LD B,A ;Save it in B 000E0 2F CPL ;Complement A 000E1 77 LD (HL),A ;Put it back in memory 000E2 BE CP (HL) ;Is it really in RAM ? 000E3 70 LD (HL),B ;Restore original value 000E4 28F3 JR Z,00D9H ;Yes: next byte ;No: HL -> end of RAM + 1 000E6 25 DEC H ;Subtract 256 bytes for ;SHAPE table 000E7 1811 JR 00FAH ;Continue at 00FAH ; Enter number at MEM SIZE? 000E9 CD5A1E CALL 1E5AH ;Evaluate entered number 000EC B7 OR A ;Only digits entered ? 000ED C29719 JP NZ,1997H ;No: ?SN Error 000F0 EB EX DE,HL 000F1 2B DEC HL ;HL = MEM SIZE - 1 000F2 3E8F LD A,8FH ;A = test byte 000F4 46 LD B,(HL) ;Save original byte 000F5 77 LD (HL),A ;Testbyte to (HL) 000F6 BE CP (HL) ;Is it really saved ? 000F7 70 LD (HL),B ;Put original value back 000F8 20CD JR NZ,00C7H ;No: again! ; Store memory boundaries ; HL -> highest available memory location - 1 000FA 2B DEC HL ;HL - 1 000FB 111444 LD DE,4414H ;DE = 4414H 000FE DF RST 18H ;Compare HL with DE ;MEM SIZE < 4414H ? 000FF DA7A19 JP C,197AH ;Yes: ?OM Error 00102 11CEFF LD DE,0FFCEH ;DE = -50 00105 22B140 LD (40B1H),HL ;Store TOPMEM 00108 19 ADD HL,DE ;HL = HL - 50: CLEAR 50 00109 22A040 LD (40A0H),HL ;Save start address of ;string space 0010C CD4D1B CALL 1B4DH ;NEW and CLEAR 0010F 212101 LD HL,0121H ;HL -> 'COLOUR BASIC' 00112 CDA728 CALL 28A7H ;Print text 00115 C3191A JP 1A19H ;Jump to BASIC active command ;mode ; Text 'MEM SIZE' 00118 4D454D DEFB 'MEM' 0011B 20 DEFB ' ' 0011C 53495A45 DEFB 'SIZE' 00120 00 DEFB 00H ;End of string ; Text 'COLOUR BASIC' 00121 434F4C4F5552 DEFB 'COLOUR' 00127 20 DEFB ' ' 00127 4241534943 DEFB 'BASIC' 0012D 0D DEFB 0DH ;Newline 0012E 00 DEFB 00H ;End of string ; Unused ROM space 0012F FF RST 38H ;-- 00130 FF RST 38H 00131 FF RST 38H ; X = CHECK ( Bit, Address) ; ------------------------- 00132 C36B01 JP 016BH ;Continue at 016BH ; SET Bit, Address ; ---------------- 00135 C34F01 JP 014FH ;Continue at 014FH ; RESET Bit, Address : ------------------ 00138 C35D01 JP 015DH ;Continue at 015DH ; Entry with Disk BASIC vectors disabled 0013B 1E2C LD E,2CH ;E = Errorcode for ?SN Error ;without EDIT call 0013D C3A219 JP 19A2H ;Continue at error routine ; Start 5 (Continuation of 0078H) 00140 EDB0 LDIR ;Copy 00142 2101C0 LD HL,0C001H ;HL -> ROM catridge 00145 3A00C0 LD A,(0C000H) ;ROM cartridge with 00148 B7 OR A ;a BASIC program present ? 00149 C27B00 JP NZ,007BH ;No: continue at 007BH 0014C C38B00 JP 008BH ;Yes: continue at 0088H ; Continuation of SET routine of 0135H 0014F CD8301 CALL 0183H ;Get bitnr. and address 00152 3E01 LD A,01H ;A = bit mask 00154 07 RLCA ;Shift A until specified bit 00155 10FD DJNZ 0154H ;is set in A 00157 0F RRCA ;Ajust because B was bitnr + 1 00158 47 LD B,A ;B = bit mask 00159 1A LD A,(DE) ;Take byte from memory 0015A B0 OR B ;Set bit 0015B 12 LD (DE),A ;Put byte back in memory 0015C C9 RET ; Continuation of RESET routine of 0138H 0015D CD8301 CALL 0183H ;Get bitnr. and address 00160 3EFE LD A,0FEH ;A = bit mask 00162 07 RLCA ;Shift A until specified bit 00163 10FD DJNZ 0162H ;is reset in A 00165 0F RRCA ;Ajust because B was bitnr + 1 00166 47 LD B,A ;B = bit mask 00167 1A LD A,(DE) ;Take byte from memory 00168 A0 AND B ;Reset bit 00169 12 LD (DE),A ;Put byte back in memory 0016A C9 RET ; Continuation of CHECK routine of 0132H 0016B D7 RST 10H ;Get next non-space caharacter 0016C CF RST 08H ;Next byte must be 0016D 28 DEFB '(' ;a '(' 0016E CD8301 CALL 0183H ;Get bitnr and address 00171 E5 PUSH HL ;Save PTP 00172 1A LD A,(DE) ;Get byte from memory 00173 1F RRA ;and specified bit in C-flag 00174 10FD DJNZ 0173H ;Loop 00176 21FFFF LD HL,0FFFFH ;HL = -1 (TRUE) ;Bit set ? 00179 3801 JR C,017CH ;Yes: continue at 017CH 0017B 23 INC HL ;HL = 0 (FALSE) 0017C CD9A0A CALL 0A9AH ;Write HL to X as INT 0017F E1 POP HL ;Restore PTP 00180 CF RST 08H ;Next byte must be 00181 29 DEFB ')' ;')' 00182 C9 RET ; SUB for SET, RESET and CHECK ; Get bit number and address form program text ; ; I: HL = PTP ; O: B = Bit number + 1 ; DE = Address 00183 CD1C2B CALL 2B1CH ;A = Bit number 00186 FE08 CP 08H ;Out of range ? 00188 D24A1E JP NC,1E4AH ;Yes: ?FC Error 0018B F5 PUSH AF ;Save bit number 0018C CF RST 08H ;Both parameters separated by 0018D 2C DEFB ',' ;a comma ? 0018E CD022B CALL 2B02H ;DE = address 00191 F1 POP AF ;Restore bit number 00192 47 LD B,A ;Put it in B 00193 04 INC B ;B = bit number + 1 00194 C9 RET ; Unused ROM space 00195 FF RST 38H ;-- 00196 FF RST 38H 00197 FF RST 38H 00198 FF RST 38H 00199 FF RST 38H 0019A FF RST 38H 0019B FF RST 38H 0019C FF RST 38H ; X = INKEY$ ; ---------- 0019D D7 RST 10H ;Get next non-space character 0019E E5 PUSH HL ;Save PTP 0019F 3A9940 LD A,(4099H) ;Has a key already been pressed 001A2 B7 OR A ;before ? 001A3 2006 JR NZ,01ABH ;Yes, pass value and return 001A5 CD5803 CALL 0358H ;No: key pressed now ? 001A8 B7 OR A 001A9 2811 JR Z,01BCH ;No: null string as result 001AB F5 PUSH AF ;Save key code 001AC AF XOR A ;Delete last key code 001AD 329940 LD (4099H),A 001B0 3C INC A ;Reserve a byte in 001B1 CD5728 CALL 2857H ;string space 001B4 F1 POP AF ;A = key code 001B5 2AD440 LD HL,(40D4H) ;HL -> memory for new string 001B8 77 LD (HL),A ;Save string 001B9 C38428 JP 2884H ;Set VT to STR ; No key pressed ; Return a null string as result 001BC 212819 LD HL,1928H ;HL -> null string 001BF 222141 LD (4121H),HL ;Set as result 001C2 3E03 LD A,03H ;Set VT to STR 001C4 32AF40 LD (40AFH),A 001C7 E1 POP HL ;Restore PTP 001C8 C9 RET ; CLS statement ; ------------- 001C9 3E1C LD A,1CH ;A = cursor home 001CB CD3A03 CALL 033AH ;Output A 001CE 3E1F LD A,1FH ;A = clear screen from ;cursor pos. to end 001D0 C33A03 JP 033AH :Output A ; RANDOM statement ; ---------------- 001D3 ED5F LD A,R ;A = refresh register 001D5 32AB40 LD (40ABH),A ;Put it in system RAM 001D8 C9 RET ; Issue a level change to cassette port 001D9 3A1C43 LD A,(431CH) ;A = last written value 001DC EE01 XOR 01H ;Toggle bit 0 001DE D3FF OUT (0FFH),A ;Output value to cassette port 001E0 321C43 LD (431CH),A ;and save it is system RAM 001E3 C9 RET ; blink '*' 001E4 3A2744 LD A,(4427H) ;Get '*' or ' ' from screen 001E7 EE0A XOR 0AH ;Swap '*' and ' ' 001E9 322744 LD (4427H),A ;Put it back on screen 001EC C9 RET ; Read one byte from cassette (AF) ; ; I: - ; O: A = byte read from cassette port 001ED D9 EXX ;Exchange registers 001EE 0608 LD B,08H ;Read 8 bits 001F0 1600 LD D,00H ;Put byte to 0 001F2 CDFA01 CALL 01FAH ;Read bit and shift into D 001F5 10FB DJNZ 01F2H ;Next bit 001F7 7A LD A,D ;A = complete byte read 001F8 D9 EXX ;Exchange registers 001F9 C9 RET ; Read one bit from cassette and shift into D 001FA C5 PUSH BC ;Save counter ;Wait for clock pulse: 001FB DBFF IN A,(0FFH) ;Test port FFH 001FD E601 AND 01H ;Mask level 001FF 5F LD E,A ;and save in E 00200 DBFF IN A,(0FFH) ;Test port FFH 00202 E601 AND 01H ;Mask level 00204 AB XOR E ;Compare with previous level 00205 1F RRA ;Put result in C-flag 00206 30F8 JR NC,0200H ;Search clock pulse 00208 3C INC A ;A = 1 00209 AB XOR E ;A = new level value 0020A 5F LD E,A ;Store it in E for compare 0020B 3A1243 LD A,(4312H) ;A = delay time 0020E 47 LD B,A ;Put it in B 0020F 10FE DJNZ 020FH ;Delay loop 00211 DBFF IN A,(0FFH) ;Now take new input level 00213 E601 AND 01H 00215 AB XOR E ;and compare it with previous ;level. A = 1 if a level change ;is recognized. 00216 CB22 SLA D ;Shift D 00218 B2 OR D ;and add new value 00219 57 LD D,A ;Result in D 0021A C1 POP BC ;Restore counter 0021B C9 RET ; Write the same byte twice to cassette 0021C CD1F02 CALL 021FH ;Write first byte ; Write one byte to cassette (AF) ; ; I: A = byte to be written ; O: A = byte written 0021F D9 EXX ;Save registers 00220 F5 PUSH AF ;Save byte 00221 0E08 LD C,08H ;8 bits to write 00223 57 LD D,A ;D = byte 00224 CDD901 CALL 01D9H ;Issue clock pulse 00227 3A1043 LD A,(4310H) ;A = delay value 0022A 47 LD B,A ;B = A 0022B 10FE DJNZ 022BH ;Delay loop 0022D 7A LD A,D ;A = byte 0022E 07 RLCA ;Shift next bit into C-Flag 0022F 57 LD D,A ;And save shifted value in D 00230 DCD901 CALL C,01D9H ;Bit = 1: Issue level change 00233 3A1143 LD A,(4311H) ;A = delay value 00236 47 LD B,A ;B = A 00237 10FE DJNZ 0237H ;Delay loop 00239 0D DEC C ;Decrement bit counter ;All bits done ? 0023A 20E8 JR NZ,0224H ;No: loop, issue next bit 0023C F1 POP AF ;Restore byte value 0023D D9 EXX ;Restore registers 0023E C9 RET ; Write leader and sync on cassette 0023F 06FF LD B,0FFH ;write 255 times 00241 3EAA LD A,0AAH ;the byte AAH 00243 CD1F02 CALL 021FH ;on cassette tape 00246 10FB DJNZ 0243H 00248 3E66 LD A,66H ;Sync = 66H 0024A 18D3 JR 021FH ;Write on cassette tape ; Search for leader and sync 0024C E5 PUSH HL ;Save registers 0024D D5 PUSH DE 0024E C5 PUSH BC 0024F 216935 LD HL,3569H ;HL -> colour code table 00252 110000 LD DE,0000H ;DE = 0000H 00255 3A2340 LD A,(4023H) ;A = present colour value 00258 5F LD E,A ;DE = offset in table 00259 19 ADD HL,DE ;HL -> colour code 0025A 7E LD A,(HL) ;A = colour code from table 0025B 3226F0 LD (0F026H),A ;Store in colour RAM at the 0025E 3227F0 LD (0F027H),A ;location for both asterisks 00261 01AA80 LD BC,80AAH ;B = counter = 128 ;C = byte to search for 00264 CDFA01 CALL 01FAH ;Read bit from cassette, ;shift into D and load in A 00267 B9 CP C ;Byte found ? 00268 20F7 JR NZ,0261H ;No: search again 0026A 3EFF LD A,0FFH ;Yes: invert all bits in C 0026C A9 XOR C ;so search for 55H now 0026D 4F LD C,A ;Result in C 0026E 10F4 DJNZ 0264H ;Continue search until 128 ;times AAH found 00270 CDFA01 CALL 01FAH ;Search sync (66H) 00273 FE66 CP 66H ;Found ? 00275 20F9 JR NZ,0270H ;No: continue seach 00277 3E2A LD A,2AH ;A = '*' 00279 322644 LD (4426H),A ;Put both asterisks on screen 0027C 322744 LD (4427H),A 0027F C1 POP BC ;Restore registers 00280 D1 POP DE 00281 E1 POP HL 00282 C9 RET ; Unused ROM area 00283 FF RST 38H ;-- 00284 FF RST 38H 00285 FF RST 38H 00286 FF RST 38H 00287 FF RST 38H 00288 FF RST 38H 00289 FF RST 38H 0028A FF RST 38H 0028B FF RST 38H 0028C FF RST 38H 0028D FF RST 38H 0028E FF RST 38H 0028F FF RST 38H 00290 FF RST 38H 00291 FF RST 38H 00292 FF RST 38H 00293 FF RST 38H 00294 FF RST 38H 00295 FF RST 38H 00296 FF RST 38H 00297 FF RST 38H 00298 FF RST 38H 00299 FF RST 38H 0029A FF RST 38H 0029B FF RST 38H 0029C FF RST 38H 0029D FF RST 38H 0029E FF RST 38H 0029F FF RST 38H 002A0 FF RST 38H 002A1 FF RST 38H 002A2 FF RST 38H 002A3 FF RST 38H 002A4 FF RST 38H 002A5 FF RST 38H 002A6 FF RST 38H 002A7 FF RST 38H 002A8 FF RST 38H 002A9 FF RST 38H 002AA FF RST 38H 002AB FF RST 38H ; Read start address of loaded program from tape (for SYSTEM) 002AC CD1403 CALL 0314H ;Read 2 bytes (start address) 002AF 22DF40 LD (40DFH),HL ;and store it in system RAM ; SYSTEM statement ; ---------------- 002B2 CDE241 CALL 41E2H ;DOS 002B5 318842 LD SP,4288H ;Put stack in keyboard buffer ;to get it out of the way 002B8 CDFE20 CALL 20FEH ;Start new line 002BB 3E2A LD A,2AH ;A = '*' 002BD CD2A03 CALL 032AH ;Print it 002C0 CDB31B CALL 1BB3H ;Ask for filename 002C3 DA6600 JP C,0066H ;Back to BASIC ;if key pressed 002C6 D7 RST 10H ;Get next non-space character ;Anything entered ? 002C7 CA9719 JP Z,1997H ;No: ?SN Error 002CA FE2F CP '/' ;Is it a '/' ? 002CC 284F JR Z,031DH ;Yes: continue at 031DH 002CE CD4C02 CALL 024CH ;No: search for leader and sync 002D1 CDED01 CALL 01EDH ;Get first byte from tape 002D4 FE55 CP 55H ;Is it a SYSTEM program ? 002D6 20F9 JR NZ,02D1H ;No: continue search 002D8 0606 LD B,06H ;6 characters for filename 002DA 7E LD A,(HL) ;Get character from buffer 002DB B7 OR A ;End of line ? 002DC 2809 JR Z,02E7H ;Yes: load program 002DE CDED01 CALL 01EDH ;No: load filename character 002E1 BE CP (HL) ;Same as in specified name ? 002E2 20ED JR NZ,02D1H ;No: search next file 002E4 23 INC HL ;Yes: pointer + 1 002E5 10F3 DJNZ 02DAH ;Check next filename char. 002E7 CDE401 CALL 01E4H ;Blink right asterisk 002EA CDED01 CALL 01EDH ;Read block marker from tape 002ED FE78 CP 78H ;End found ? 002EF 28BB JR Z,02ACH ;Yes: get start address and ;issue '*?' again 002F1 FE3C CP 3CH ;Start of block ? 002F3 20F5 JR NZ,02EAH ;No: search new byte 002F5 CDED01 CALL 01EDH ;Read block length 002F8 47 LD B,A ;B = block length 002F9 CD1403 CALL 0314H ;HL = block address 002FC 85 ADD A,L ;Calculate checksum 002FD 4F LD C,A ;Store in C 002FE CDED01 CALL 01EDH ;Read byte 00301 77 LD (HL),A ;Store it in memory 00302 23 INC HL ;Memory pointer + 1 00303 81 ADD A,C ;Add to checksum 00304 4F LD C,A ;Store result in C 00305 10F7 DJNZ 02FEH ;Load next byte from block 00307 CDED01 CALL 01EDH ;Block is done: get checksum 0030A B9 CP C ;Same as calculated checksum ? 0030B 28DA JR Z,02E7H ;Yes: load next block 0030D 3E43 LD A,43H ;No: A = 'C' 0030F 322644 LD (4426H),A ;Indicate checksum error 00312 18D6 JR 02EAH ;Continue loading anyway ; SUB for SYSTEM ; Load address (block address or start address) from tape ; ; I: - ; O: HL = address read from tape 00314 CDED01 CALL 01EDH ;Load LSB from tape 00317 6F LD L,A ;L = LSB of address 00318 CDED01 CALL 01EDH ;Load MSB from tape 0031B 67 LD H,A ;H = MSB of address 0031C C9 RET ; Issue '/' with SYSTEM 0031D EB EX DE,HL ;DE -> text 0031E 2ADF40 LD HL,(40DFH) ;HL = start address 00321 EB EX DE,HL ;Load DE 00322 D7 RST 10H ;Get next non-space character ;Start address entered ? 00323 C45A1E CALL NZ,1E5AH ;Yes: new value into DE 00326 208A JR NZ,02B2H ;Restart SYSTEM if rubbish ;was entered 00328 EB EX DE,HL ;Load address into HL 00329 E9 JP (HL) ;Execute program ; Output of A on screen, printer or cassette (AF,HL) ; ; I: A = ASCII value of the byte to be output ; (409CH) = output flag: 00H = screen, 01H = printer, 80H = cassette 0032A C5 PUSH BC ;Save BC 0032B 4F LD C,A ;C = output byte 0032C CDC141 CALL 41C1H ;DOS 0032F 3A9C40 LD A,(409CH) ;Test flag 00332 B7 OR A 00333 79 LD A,C ;Byte back in A 00334 C1 POP BC ;Restore BC 00335 C36405 JP 0564H ;Continue at 0564H ; Unused ROM space 00338 FF RST 38H ;-- 00339 FF RST 38H ; Output A on screen and increment POS (40A6H) 0033A D9 EXX ;Save registers 0033B F5 PUSH AF ;Save byte 0033C CD3300 CALL 0033H ;Output byte 0033F CD4803 CALL 0348H ;Calculate new POS value 00342 32A640 LD (40A6H),A ;and save it in system RAM 00345 F1 POP AF ;Restore byte 00346 D9 EXX ;Restore registers 00347 C9 RET ; Calculate new POS (AF,DE) ; I: - ; O: A = new POS value 00348 E5 PUSH HL ;Save PTP 00349 2A2040 LD HL,(4020H) ;HL = cursor address 0034C 110044 LD DE,4400H ;DE -> start of screen memory 0034F B7 OR A ;C-flag = 0 00350 C3D904 JP 04D9H ;Continue at 04D9H ; Unused ROM space 00353 FF RST 38H ;-- 00354 FF RST 38H ; Calculate new POS (as 0348H) 00355 C39D30 JP 309DH ;continue at 309DH ; Keyboard scan (AF) ; (as 002B but with DOS and saving DE) 00358 CDC441 CALL 41C4H ;DOS 0035B D5 PUSH DE ;Save DE 0035C CD2B00 CALL 002BH ;Scan keyboard 0035F D1 POP DE ;Restore DE 00360 C9 RET ; Input of a line with max. 240 characters in line buffer (AF,DE,HL) ; ; I: - ; O: C-flag = 1: key pressed. ; HL -> start of line buffer - 1 00361 AF XOR A ;A = 00H 00362 329940 LD (4099H),A ;Delete last key code 00365 32A640 LD (40A6H),A ;POS = 0 00368 CDAF41 CALL 41AFH ;DOS 0036B C5 PUSH BC ;Save BC 0036C 2AA740 LD HL,(40A7H) ;HL -> start of line buffer 0036F 06F0 LD B,0F0H ;B = max. number of characters 00371 CDD905 CALL 05D9H ;Enter line 00374 F5 PUSH AF ;Save flags 00375 48 LD C,B ;C = number of entered chars. 00376 0600 LD B,00H ;BC = length of line 00378 09 ADD HL,BC ;HL -> last character + 1 00379 3600 LD (HL),00H ;Terminate line with 00H 0037B 2AA740 LD HL,(40A7H) ;HL -> start of line buffer 0037E F1 POP AF ;Restore flags 0037F C1 POP BC ;Restore BC 00380 2B DEC HL ;Adjust HL for RST 10H ; pressed ? 00381 D8 RET C ;Yes: return 00382 AF XOR A ;C-flag = 0 00383 C9 RET ; Wait for key pressed (AF) ; (as 0049H but with DOS and save DE) 00384 CD5803 CALL 0358H ;Get key 00387 B7 OR A ;New key pressed ? 00388 C0 RET NZ ;Yes: return 00389 18F9 JR 0384H ;No: wait for key pressed ; End output to printer (AF) ; ; I: - ; O: PPOS = 0 (Printer POS) 0038B AF XOR A ;Set output flag 0038C 329C40 LD (409CH),A ;to screen output 0038F 3A9B40 LD A,(409BH) ;A = PPOS 00392 B7 OR A ;Zero ? 00393 C8 RET Z ;Yes: return 00394 3E0D LD A,0DH ;No: CR to printer 00396 D5 PUSH DE ;Save DE 00397 CD9C03 CALL 039CH ;Output CR 0039A D1 POP DE ;Restore DE 0039B C9 RET ; Print one character on printer and intercept control characters 0039C F5 PUSH AF ;Save registers 0039D D5 PUSH DE 0039E C5 PUSH BC 0039F 4F LD C,A ;Save character in C 003A0 1E00 LD E,00H ;E = 00H for new PPOS 003A2 FE0C CP 0CH ;Is it a Form Feed ? 003A4 2810 JR Z,03B6H ;Yes: PPOS to 0 and print ;character 003A6 FE0A CP 0AH ;Is it a Line Feed ? 003A8 2003 JR NZ,03ADH ;No: continue test 003AA 3E0D LD A,0DH ;Convert LF into CR 003AC 4F LD C,A ;Store it in C 003AD FE0D CP 0DH ;Is it a Carriage Return ? 003AF 2805 JR Z,03B6H ;Yes: PPOS to 0 and print ;character 003B1 3A9B40 LD A,(409BH) ;No: get PPOS 003B4 3C INC A ;and increment 003B5 5F LD E,A ;Store in E 003B6 7B LD A,E ;Save new PPOS 003B7 329B40 LD (409BH),A ;in system RAM 003BA 79 LD A,C ;A = character to print 003BB CD3B00 CALL 003BH ;Print it 003BE C1 POP BC ;Restore registers 003BF D1 POP DE 003C0 F1 POP AF 003C1 C9 RET ; DCB call (AF) (see 0046H) ; ; I: A = character (when output) ; B = DCB type ; DE -> DCB ; O: A = character (when input) 003C2 E5 PUSH HL ;Save registers 003C3 DDE5 PUSH IX 003C5 D5 PUSH DE 003C6 DDE1 POP IX ;IX -> DCB 003C8 D5 PUSH DE ;Adjust stack 003C9 21DD03 LD HL,03DDH ;HL = new return address 003CC E5 PUSH HL ;Put it in stack 003CD 4F LD C,A ;Save character in C 003CE 1A LD A,(DE) ;Load DCB type 003CF A0 AND B ;Mask unused bits 003D0 B8 CP B ;Same as indicated type ? 003D1 C23340 JP NZ,4033H ;No: false DCB type, set A ;to 00H and back to program ;(4033H is used by DOS) 003D4 FE02 CP 02H ;DCB type = output ? 003D6 DD6E01 LD L,(IX01H) ;HL = address of DCB routine 003D9 DD6602 LD H,(IX02H) 003DC E9 JP (HL) ;Execute DCB routine ; End of DCB routine 003DD D1 POP DE ;Restore registers 003DE DDE1 POP IX 003E0 E1 POP HL 003E1 C1 POP BC 003E2 C9 RET ; Keyboard routine (called by DCB) 003E3 CDAF06 CALL 06AFH ;ROM catrigde present ? ;Yes: start ROM program 003E6 3A80F8 LD A,(0F880H) ;Scan keyboard 003E9 FE12 CP 12H ; and pressed ? 003EB 200D JR NZ,03FAH ;No: continue at 03FAH 003ED CDA938 CALL 38A9H ;FGR 003F0 3A40F8 LD A,(0F840H) ;Scan keyboard 003F3 CB57 BIT 2,A ; pressed ? 003F5 28F9 JR Z,03F0H ;No: wait for 003F7 CDB038 CALL 38B0H ;LGR 003FA 213640 LD HL,4036H ;HL -> temporary memory 003FD 0101F8 LD BC,0F801H ;BC = first keyboard address 00400 1600 LD D,00H ;Line counter = 0 00402 0A LD A,(BC) ;Scan keyboard 00403 5F LD E,A ;Result in E 00404 AE XOR (HL) ;Set only the bits for those ;keys, that have changed since ;last scan 00405 73 LD (HL),E ;Store new code for next scan 00406 A3 AND E ;Set only the bit for the key ;key that was newly pressed ;since last scan 00407 2010 JR NZ,0419H ;Was a key pressed ? ;Yes: find ASCII code of key 00409 14 INC D ;No: line counter + 1 0040A 2C INC L ;Buffer pointer + 1 0040B CB01 RLC C ;Update keyboard address 0040D 30F3 JR NC,0402H ;Scan next keyboard address 0040F 3A80F8 LD A,(0F880H) ;Scan keyboard 00412 CB5F BIT 3,A ; pressed ? 00414 C2D404 JP NZ,04D4H ;Yes: continue at 04D4H 00417 AF XOR A ;A = 00H 00418 C9 RET ; Find ASCII code of key 00419 5F LD E,A ;Bit value to E 0041A 211840 LD HL,4018H ;HL = flag byte 0041D 3A80F8 LD A,(0F880H) ;Scan keyboard 00420 CB4F BIT 1,A ; pressed ? 00422 C2C904 JP NZ,04C9H ;Yes: continue at 04C9H 00425 CB67 BIT 4,A ; pressed ? 00427 C2D004 JP NZ,04D0H ;Yes: continue at 04D0H 0042A 3E07 LD A,07H ;Was the key in the last ;keyboard address and was not ;intercepted ? 0042C BA CP D ;Line counter = 7 ? 0042D 28E8 JR Z,0417H ;Yes: the key pressed was ;the key (code = 00H) 0042F 7A LD A,D ;Multiply D by 8 00430 07 RLCA ;* 2 00431 07 RLCA ;* 2 00432 07 RLCA ;* 2 00433 57 LD D,A ;Because there are 8 keys per ;keyboard address 00434 0E01 LD C,01H ;C = mask for calculation 00436 79 LD A,C ;A = bit mask 00437 A3 AND E ;Mask key code ;Key newly pressed ? 00438 2005 JR NZ,043FH ;Yes: continue at 043FH 0043A 14 INC D ;Increment D to establish value ;of key in keyboard matrix 0043B CB01 RLC C ;Shift mask for next test 0043D 18F7 JR 0436H ; D now indicates the value of the key in the keyboard matrix ; @ has value 00H, A has value 01H etc., upto the space bar which has ; a value of 37H 0043F 3A80F8 LD A,(0F880H) ;Scan keyboard 00442 47 LD B,A ;Save value in B 00443 7A LD A,D ;A = matrix value 00444 C640 ADD A,40H ;Matrix value + 40H gives ;correct ASCII code for the ;kes '@' to 'F4' (ASCII codes ;40H to 5FH) 00446 FE60 CP 60H ;Value in range ? 00448 3013 JR NC,045DH ;No: continue at 045DH 0044A CB08 RRC B ; pressed ? 0044C 3031 JR NC,047FH ;No: key code is ok 0044E C620 ADD A,20H ;Add 20H to get lower case 00450 57 LD D,A ;Save value 00451 3A40F8 LD A,(0F840H) ;Scan keyboard 00454 E610 AND 10H ; + down arrow pressed ? 00456 7A LD A,D ;Restore value 00457 2826 JR Z,047FH ;No: key code is ok 00459 D660 SUB 60H ;Convert value to control code 0045B 1822 JR 047FH ;Continue at 047FH ; Numbers, special characters or control characters were pressed: ; A has a value between 60H (for '0') and 77H (for space bar) 0045D D670 SUB 70H ;Control character pressed ? 0045F 3010 JR NC,0471H ;Yes: continue at 0471H 00461 C640 ADD A,40H ;Adjust code 00463 FE3C CP 3CH ;',' '-' '.' or '/' pressed ? 00465 3802 JR C,0469H ;No: correct ASCII code is ;in A, continue at 0469H 00467 EE10 XOR 10H ;Yes: With these keys, the ;symbols are swapped. This has ;to be corrected with XOR 10H ;(see ASCII table) 00469 CB08 RRC B ; pressed ? 0046B 3012 JR NC,047FH ;No: pass on ASCII code 0046D EE10 XOR 10H ;Yes: exchange codes from :20H to 2FH with 30H to 3FH 0046F 180E JR 047FH ; Control key pressed ; Take ASCII code from table at 0050H 00471 07 RLCA ;A = A * 2 as table offset 00472 CB08 RRC B ; pressed ? 00474 3001 JR NC,0477H ;No: offset is ok 00476 3C INC A ;Adjust offset 00477 215000 LD HL,0050H ;HL -> table with ASCII codes 0047A 5F LD E,A ;DE = offset 0047B 1600 LD D,00H 0047D 19 ADD HL,DE ;Set pointer on key code 0047E 7E LD A,(HL) ;A = key code ; The correct ASCII code in now in A. Only the key has to be ; checked. 0047F 211840 LD HL,4018H ;HL = flag byte 00482 CB76 BIT 6,(HL) ; active ? ;(graphic characters) 00484 2824 JR Z,04AAH ;No: finish routine 00486 FE2B CP 2BH ;ASCII code < 2BH 00488 3820 JR C,04AAH ;Yes: these keys have no ;graphic character 0048A FE30 CP 30H ;ASCII code between 2BH, 2FH 0048C 3004 JR NC,0492H ;No: check further 0048E D62B SUB 2BH ;Yes: subtract 2BH 00490 1816 JR 04A8H ;and add C0H so that '+' gets ;code C0H and '/' gets code ;C4H 00492 FE3B CP 3BH ;Code smaller then ':' ? 00494 3814 JR C,04AAH ;Yes: no graphic character 00496 FE5B CP 5BH ;Code bigger then 'Z' ? 00498 3004 JR NC,049EH ;Yes: clear - 0049A D636 SUB 36H ;':' to 'Z' becomes 05H to 24H 0049C 180A JR 04A8H ;Add C0H for graphic char. 0049E FE60 CP 60H ; - ? 004A0 3808 JR C,04AAH ;Yes: finish routine 004A2 FE7B CP 7BH ;+ - + ? 004A4 3004 JR NC,04AAH ;Yes: finish routine 004A6 D63B SUB 3BH ;''' to 'z' becomes 25H to 3FH 004A8 C6C0 ADD A,0C0H ;Add C0H for graphic char. ; Now A contains the right ASCII code from 01H to FFH 004AA 322440 LD (4024H),A ;Save ASCII code for repeat 004AD 57 LD D,A ;Save for delay loop 004AE 010020 LD BC,2000H ;Call delay loop for 004B1 CD6000 CALL 0060H ;debouncing purposes 004B4 7A LD A,D ;Restore ASCII code 004B5 FE0D CP 0DH ; pressed ? 004B7 2807 JR Z,04C0H ;Yes: deactivate 004B9 FE01 CP 01H ; 004BD C0 RET NZ ;Done when not pressed 004BE EF RST 28H ;RST 28H when pressed ;(used by DOS) 004BF C9 RET ; Deactivate 004C0 211840 LD HL,4018H ;HL -> flag byte 004C3 CBB6 RES 6,(HL) ;Clear MOD SEL flag 004C5 FE01 CP 01H ; pressed ? 004C7 18F4 JR 04BDH ;Continue at 04DBH ; pressed 004C9 3E40 LD A,40H ;Set bit 6 (MOD SEL flag) 004CB AE XOR (HL) ;Toggle MOD SEL flag 004CC 77 LD (HL),A ;Save it in system RAM 004CD AF XOR A ;Return no value 004CE 18DD JR 04ADH ;Finish routine ; pressed 004D0 CBFE SET 7,(HL) ;Set CTRL flag 004D2 18F9 JR 04CDH ;Pass no value ; pressed 004D4 3A2440 LD A,(4024H) ;A = last character code 004D7 18A6 JR 047FH ;Use it for further processing ; Compute POS (continuation of 0350H) 004D9 ED52 SBC HL,DE ;HL = screen position of cursor 004DB 112800 LD DE,0028H ;DE = number of chars/line 004DE B7 OR A ;Clear C-flag 004DF ED52 SBC HL,DE ;Subtract 40 from HL 004E1 30FB JR NC,04DEH ;until HL < 0 004E3 19 ADD HL,DE ;Adjust HL: HL = cursor ;position within line 004E4 7D LD A,L ;A = POS 004E5 E1 POP HL ;Restore PTP 004E6 C9 RET ; Printer routine (activated by DCB call) 004E7 79 LD A,C ;A = ASCII code of character ;to be printed. 004E8 B7 OR A ;Null character ? 004E9 283E JR Z,0529H ;Yes: Just wait for printer 004EB FE0B CP 0BH ;Vertical Tab character ? 004ED 280A JR Z,04F9H ;Yes: incorporate line counter 004EF FE0C CP 0CH ;Form Feed character ? 004F1 201B JR NZ,050EH ;No: Print character 004F3 AF XOR A ;A = maximum number of lines 004F4 DDB603 OR (IX+03H) ;per page. A = 0 ? 004F7 2815 JR Z,050EH ;Yes: send 00H to printer 004F9 DD7E03 LD A,(IX+03H) ;A = max. number of lines/page 004FC DD9604 SUB (IX+04H) ;minus number of already ;printed lines. 004FF 47 LD B,A ;B = number of lines remaining ;until next page 00500 CD2905 CALL 0529H ;Printer ready ? 00503 20FB JR NZ,0500H ;No: wait for printer 00505 0E0A LD C,0AH ;C = Line Feed (0AH) 00507 CD3C05 CALL 053CH ;Output C to printer 0050A 10F4 DJNZ 0500H ;Until next line 0050C 1816 JR 0524H ;Line counter = 0 ; Print character 0050E CD2905 CALL 0529H ;Printer ready ? 00511 20FB JR NZ,050EH ;No: wait for printer 00513 CD3C05 CALL 053CH ;Print character in C 00516 FE0D CP 0DH ;was it a Carriage Return 00518 C0 RET NZ ;No: done 00519 DD3404 INC (IX+04H) ;Increment line counter 0051C DD7E04 LD A,(IX+04H) ;A = number of printed lines 0051F DDBE03 CP (IX+03H) ;Page full ? 00522 79 LD A,C ;Printed character back in A 00523 C0 RET NZ ;No: done 00524 DD360400 LD (IX+04H),00H ;Line counter = 0 00528 C9 RET ; Printer ready ? (AF) ; ; I: - ; O: Z-flag = 1 when printer is ready 00529 3E07 LD A,07H ;Select register 7 0052B D3F8 OUT (0F8H),A ;of the PSG 0052D 3E7F LD A,7FH ;Set port A to output 0052F D3F9 OUT (0F9H),A ;and port B to input 00531 3E0F LD A,0FH ;Select port B 00533 D3F8 OUT (0F8H),A 00535 DBF9 IN A,(0F9H) ;Get printer status 00537 E6EF AND 0EFH ;Mask status bits 00539 FE2F CP 2FH ;and set Z-flag 0053B C9 RET ; C to printer without checking 0053C 3E07 LD A,07H ;Select register 7 0053E D3F8 OUT (0F8H),A ;of the PSG 00540 3E7F LD A,7FH ;I/O port A on output and 00542 D3F9 OUT (0F9H),A ;I/O port B on input 00544 3E0E LD A,0EH ;Select register 14 (port A) 00546 D3F8 OUT (0F8H),A 00548 79 LD A,C ;Output byte 00549 D3F9 OUT (0F9H),A 0054B 3E07 LD A,07H ;Put both ports on output 0054D D3F8 OUT (0F8H),A 0054F 3EFF LD A,0FFH 00551 D3F9 OUT (0F9H),A 00553 3E0F LD A,0FH ;To port B 00555 D3F8 OUT (0F8H),A 00557 AF XOR A ;Output 00H 00558 D3F9 OUT (0F9H),A 0055A 3E0F LD A,0FH ;Then to port B 0055C D3F8 OUT (0F8H),A 0055E 3E01 LD A,01H ;Ouput 01H and indicate to 00560 D3F9 OUT (0F9H),A ;printer that a byte has been ;send 00562 79 LD A,C ;Character back in A 00563 C9 RET ; Output routine (continuation of 0335H) ;Output to cassette ? 00564 FA1F02 JP M,021FH ;Yes: continue at 021FH ;Output to printer ? 00567 C29C03 JP NZ,039CH ;Yes: continue at 039CH 0056A C33A03 JP 033AH ;Output to screen ; Start 2 (continuation of 06ACH) 0056D 31F841 LD SP,41F8H ;Set stack pointer 00570 AF XOR A ;Clear port 255 (NBGRD, CHAR 1, 00571 D3FF OUT (0FFH),A ;and LGR) 00573 2100F4 LD HL,0F400H ;Clear colour memory 00576 1101F4 LD DE,0F401H 00579 01FF03 LD BC,03FFH 0057C 3600 LD (HL),00H 0057E EDB0 LDIR 00580 0EFF LD C,0FFH ;C = port address 00582 ED78 IN A,(C) ;Parameters for NTSC standard 00584 E608 AND 08H ;(have no effect in PAL) 00586 47 LD B,A 00587 D3FC OUT (0FCH),A 00589 ED78 IN A,(C) 0058B E608 AND 08H 0058D 211137 LD HL,3711H ;-- 00590 110038 LD DE,3800H ;DE -> CRTC table for PAL ;standard 00593 A8 XOR B 00594 00 NOP 00595 00 NOP 00596 D3FD OUT (0FDH),A 00598 ED78 IN A,(C) 0059A E608 AND 08H 0059C 216935 LD HL,3569H ;HL -> colour code table 0059F A8 XOR B 005A0 1812 JR 05B4H ;Continue at 05B4H ; Unused routine (only for computers with NTSC standard) 005A2 D3FE OUT (0FEH),A 005A4 ED78 IN A,(C) 005A6 E608 AND 08H 005A8 210A37 LD HL,370AH 005AB A8 XOR B 005AC 2006 JR NZ,05B4H 005AE 213137 LD HL,3731H 005B1 112338 LD DE,3823H ; Start 3 (continuation of 05A0H) 005B4 E5 PUSH HL ;Save HL 005B5 EB EX DE,HL ;HL -> CRTC table 005B6 11F042 LD DE,42F0H ;DE -> system RAM 005B9 012300 LD BC,0023H ;BC = table size (35 bytes) 005BC EDB0 LDIR ;Copy table into sytem RAM 005BE E1 POP HL ;Restore HL 005BF 119043 LD DE,4390H ;DE -> colour code table 005C2 011000 LD BC,0010H ;BC = table size (16 colours) 005C5 EDB0 LDIR ;Copy into system RAM 005C7 C36C00 JP 006CH ;Continue at 006CH ; Reset 2 (continuation of 0069H) 005CA AF XOR A ;A = 0; 005CB D3ED OUT (0EDH),A ; 005CD 3A04F8 LD A,(0F804H) ;Read keyboard 005D0 CB57 BIT 2,A ; pressed ? 005D2 C20000 JP NZ,0000H ;Yes: cold start 005D5 C3C006 JP 06C0H ;No: warm start 005D8 FF RST 38H ;-- ; Input of one line incl. cursor control, FKEY evaluation und presentation ; of the entered character on screen (AF, BC, DE, HL). ; The input is terminated by or . ; The End Of Line is indicated in the buffer by a 0DH character ; ; I: HL -> input buffer to store the entered characters. ; B = Maximum number of characters allowed to be entered. ; (more characters are not accepted. The input must be terminated ; by or ) ; O: HL -> start of input buffer ; DE = 401DH (from 0033H call) ; B = number of entered characters ; C = B from start ; A = last character entered (0DH or 01H) ; C-flag = 1 when input was terminated with 005D9 E5 PUSH HL ;Save buffer address 005DA 3E0E LD A,0EH ;A = Cursor on 005DC CD3300 CALL 0033H ;Output character 005DF 48 LD C,B ;C = max. number of characters 005E0 C30030 JP 3000H ;Continue at 3000H for FKEY ;evaluation 005E3 FE20 CP 20H ;Control key entered ? 005E5 3025 JR NC,060CH ;No: store character 005E7 FE0D CP 0DH ; ? 005E9 CA6206 JP Z,0662H ;Yes: continue at 0662H 005EC FE1F CP 1FH ; ? 005EE 2829 JR Z,0619H ;Yes: continue at 0619H 005F0 FE01 CP 01H ; ? 005F2 286D JR Z,0661H ;Yes: continue at 0661H 005F4 11E005 LD DE,05E0H ;Set new return address 005F7 D5 PUSH DE ;to 05E0H 005F8 FE08 CP 08H ;Backspace (arrow left) ? 005FA 2834 JR Z,0630H ;Yes: continue at 0630H 005FC FE18 CP 18H ;Delete line ;(shift-arrow left) ? 005FE 282B JR Z,062BH ;Yes: continue at 062BH 00600 FE09 CP 09H ;TAB (arrow right) ? 00602 2842 JR Z,0646H ;Yes: continue at 0646H 00604 FE19 CP 19H ;Shift-arrow right ? (32 ;characters/line in GENIE I) 00606 2839 JR Z,0641H ;Yes: continue at 0641H 00608 FE0A CP 0AH ;New Line (arrow down) ? 0060A C0 RET NZ ;No: control character has no ;function, get new character 0060B D1 POP DE ;Remove return address from ;stack 0060C 77 LD (HL),A ;Store character in buffer 0060D 78 LD A,B ;Entering of characters 0060E B7 OR A ;still allowed ? 0060F 28CF JR Z,05E0H ;No: get new character 00611 7E LD A,(HL) ;Get character from buffer 00612 23 INC HL ;Buffer pointer + 1 00613 CD3300 CALL 0033H ;Output character 00616 05 DEC B ;Character counter - 1 00617 18C7 JR 05E0H ;Get next character ; pressed 00619 CDC901 CALL 01C9H ;CLS 0061C 41 LD B,C ;Restart character counter 0061D E1 POP HL ;HL -> start of buffer 0061E E5 PUSH HL ;Save pointer again 0061F C3E005 JP 05E0H ;Get next character ; Delete line 00622 CD3006 CALL 0630H ;Delete character 00625 2B DEC HL ;Buffer pointer - 1 00626 7E LD A,(HL) ;A = last character 00627 23 INC HL ;Increment buffer pointer 00628 FE0A CP 0AH ;Has a new line already been ;started ? 0062A C8 RET Z ;Yes: then only delete until ;here ; + pressed 0062B 78 LD A,B ;Have characters been 0062C B9 CP C ;entered already ? 0062D 20F3 JR NZ,0622H ;Yes: delete line 0062F C9 RET ; pressed 00630 78 LD A,B ;Character counter still on 00631 B9 CP C ;initial value ? 00632 C8 RET Z ;Yes: done 00633 2B DEC HL ;Buffer pointer - 1 00634 7E LD A,(HL) ;Get previous character 00635 FE0A CP 0AH ;New line started ? 00637 23 INC HL ;Buffer pointer + 1 00638 C8 RET Z ;Yes: return 00639 2B DEC HL ;No: buffer pointer + 1 0063A 3E08 LD A,08H ;A = backspace character 0063C CD3300 CALL 0033H ;Output byte 0063F 04 INC B ;Character counter + 1 00640 C9 RET ; + pressed 00641 3E17 LD A,17H ;17H was code for switching to ;32 characters/lines 00643 C33300 JP 0033H ;Output byte ;(has no effect on the ;Colour Genie) ; pressed 00646 CD4803 CALL 0348H ;A = POS 00649 E607 AND 07H ;Calculate last TAB position 0064B 2F CPL ;Negate value 0064C 3C INC A ;adjust to 2 complement 0064D C608 ADD A,08H ;+8 gives number of characters ;until next TAB position 0064F 5F LD E,A ;E = counter 00650 78 LD A,B ;Is it allowed to enter more 00651 B7 OR A ;characters ? 00652 C8 RET Z ;No: return 00653 3E20 LD A,20H ;A = space character 00655 77 LD (HL),A ;Put it in buffer 00656 23 INC HL ;Buffer pointer + 1 00657 D5 PUSH DE ;Save DE 00658 CD3300 CALL 0033H ;Output byte 0065B D1 POP DE ;Restore DE 0065C 05 DEC B ;Character counter - 1 0065D 1D DEC E ;TAB counter - 1 0065E C8 RET Z ;Return when done 0065F 18EF JR 0650H ;Next character in buffer ; pressed 00661 37 SCF ;Set C-flag = 1 and treat it ;further like ; pressed 00662 F5 PUSH AF ;Save flags 00663 3E0D LD A,0DH ;A = Carriage Return 00665 77 LD (HL),A ;Put it in buffer 00666 CD3300 CALL 0033H ;Output byte 00669 3E0F LD A,0FH ;A = cursor off 0066B CD3300 CALL 0033H ;Output character 0066E 79 LD A,C ;Calculate the number of 0066F 90 SUB B ;entered characters 00670 47 LD B,A ;Result in B 00671 F1 POP AF ;Restore flags 00672 E1 POP HL ;HL -> start of buffer 00673 C9 RET ; Start 1 00674 3E08 LD A,08H ;CHAR 2, NBGRD and LGR 00676 D3FF OUT (0FFH),A ;Output to port 00678 321C43 LD (431CH),A ;Save port status 0067B 21D206 LD HL,06D2H ;HL -> start of block 0067E 110040 LD DE,4000H ;DE -> destination system RAM 00681 013600 LD BC,0036H ;BC = 54 bytes 00684 EDB0 LDIR ;Initialize system RAM 00686 3D DEC A ;Repeat until A = 00H 00687 3D DEC A 00688 20F1 JR NZ,067BH 0068A 0627 LD B,27H ;Clear the next 39 bytes 0068C 12 LD (DE),A 0068D 13 INC DE 0068E 10FC DJNZ 068CH 00690 21AB34 LD HL,34ABH ;HL -> function key defaults 00693 115043 LD DE,4350H ;DE -> function key RAM space 00696 013800 LD BC,0038H ;BC = size to copy 00699 EDB0 LDIR ;Copy function key definitions 0069B 3E01 LD A,01H ;Set SCALE = 1 0069D 321443 LD (4314H),A 006A0 213039 LD HL,3930H ;Set pointer on table with 006A3 228C43 LD (438CH),HL ;Colour BASIC statements in ;system RAM 006A6 21DB39 LD HL,39DBH ;Set pointer on vector table 006A9 228E43 LD (438EH),HL ;in system RAM 006AC C36D05 JP 056DH ;Continue at 05D6H 006AF 3A00C0 LD A,(0C000H) ;Take first byte of ROM ;cartridge space 006B2 FE43 CP 'C' ;Program there ? 006B4 CA01C0 JP Z,0C001H ;Yes: execute program 006B7 3A00C0 LD A,(0C000H) ;Take first byte of ROM ;cartridge space 006BA FE44 CP 'D' ;Program there ? 006BC CA01C0 JP Z,0C001H ;Yes: execute program 006BF C9 RET 006C0 3A00C0 LD A,(0C000H) ;Take first byte of ROM ;cartridge space 006C3 FE43 CP 'C' ;Program there ? 006C5 CA01C0 JP Z,0C001H ;Yes: execute program 006C8 C3AE19 JP 19AEH ; Unused ROM space 006CB FF RST 38H ;-- 006CC FF RST 38H 006CD FF RST 38H 006CE FF RST 38H 006CF FF RST 38H 006D0 FF RST 38H 006D1 FF RST 38H ; The following block of code is copied into system RAM at 4000H to initialize ; the vectors and DCBs located there 006D2 C3961C JP 1C96H ;RST 08H vector 006D5 C3781D JP 1D78H ;RST 10H vector 006D8 C3901C JP 1C90H ;RST 18H vector 006DB C3D925 JP 25D9H ;RST 20H vector 006DE C9 RET ;RST 28H vector (BREAK vector) 006DF 00 NOP 006E0 00 NOP 006E1 C9 RET ;RST 30H vector 006E2 00 NOP 006E3 00 NOP 006E4 FB EI ;RST 38H vector 006E5 C9 RET 006E6 00 NOP 006E7 01 DEFB 01H ;Initialization data for 006E8 E303 DEFW 03E3H ;contructing keyboard DCB 006EA 00 DEFB 00H 006EB 07 DEFB 07H 006EC 40 DEFB 40H 006ED 20 DEFB 20H 006EE 49 DEFB 47H 006EF 07 DEFB 07H ;Initialization data for 006F0 E430 DEFW 30E4H ;contructing screen DCB 006F2 0044 DEFW 4400H 006F4 01 DEFB 01H 006F4 01 DEFB 01H 006F4 03 DEFB 01H 006F7 06 DEFB 06H ;Initialization data for 006F8 E704 DEFW 04E7H ;contructing printer DCB 006FA 43 DEFB 43H 006FB 00 DEFB 00H 006FC 00 DEFB 00H 006FD 50 DEFB 50H 006FE 52 DEFB 52H 006FF C30050 JP 5000H ; 00702 C7 RST 00H ; 00703 00 NOP 00704 00 NOP 00705 3E00 LD A,00H ;False DCB vector 00707 C9 RET ; X = X + 0.5 (SNG) 00708 218013 LD HL,1380H ;HL -> Constant 0.5 ; X = X + (HL) 0070B CDC209 CALL 09C2H ;BCDE = (HL) 0070E 1806 JR 0716H ;X = X + BCDE ; X = (HL) - X (SNG) 00710 CDC209 CALL 09C2H ;BCDE = (HL) ; X = BCDE - X (SNG) 00713 CD8209 CALL 0982H ;X = -X ; X = BCDE + X (SNG) 00716 78 LD A,B ;A = Exp (BCDE) 00717 B7 OR A ;BCDE = 0 ? 00718 C8 RET Z ;Yes: result already in X 00719 3A2441 LD A,(4124H) ;A = Exp (X) 0071C B7 OR A ;X = 0 ? 0071D CAB409 JP Z,09B4H ;Yes: X = BCDE 00720 90 SUB B ;A = Exp (X) - Exp (BCDE) ;Largest value in X ? 00721 300C JR NC,072FH ;Yes: continue at 072FH 00723 2F CPL ;A = -A 00724 3C INC A ;A is the difference of the ;exponents 00725 EB EX DE,HL ;Save DE 00726 CDA409 CALL 09A4H ;(SP) = X ;(2nd operand on stack) 00729 EB EX DE,HL ;Restore DE 0072A CDB409 CALL 09B4H ;X = BCDE (1st operand) 0072D C1 POP BC ;BCDE = 2nd operand 0072E D1 POP DE ;X is now the operand with ;the biggest exponent ;A contains the differnce ;between the exponents 0072F FE19 CP 19H ;Difference bigger then 24 ? ;(difference between the ;operands bigger then 2^24) 00731 D0 RET NC ;Yes: BCDE is too small, the ;sum would not change X 00732 F5 PUSH AF ;Save exponent difference 00733 CDDF09 CALL 09DFH ;Adjust mantissas 00736 67 LD H,A ;H, 7 = 0, if signs are not ;equal 00737 F1 POP AF ;Restore exponent difference 00738 CDD707 CALL 07D7H ;Shifting CDE to the right by ;A bits: bring mantissa of BCDE ;on the same exponent as X 0073B B4 OR H ;A,7 = 0 when unequal signs 0073C 212141 LD HL,4121H ;HL -> X ;Signs equal ? 0073F F25407 JP P,0754H ;No: continue at 0754H 00742 CDB707 CALL 07B7H ;Add mantissas ;Overflow ? 00745 D29607 JP NC,0796H ;No: continue at 0796H 00748 23 INC HL ;HL -> Exp (X) 00749 34 INC (HL) ;Exp (X) + 1 (adjust Exp ;for overflow) ;Exponent overflow ? 0074A CAB207 JP Z,07B2H ;Yes: ?OV Error 0074D 2E01 LD L,01H ;Divide Mantissa by 2 0074F CDEB07 CALL 07EBH ;because Exponent incremented 00752 1842 JR 0796H ;Round CDE and store in X ; Unequal signs 00754 AF XOR A ;B = -B 00755 90 SUB B 00756 47 LD B,A 00757 7E LD A,(HL) ;Subtract Mantissa 00758 9B SBC A,E 00759 5F LD E,A 0075A 23 INC HL 0075B 7E LD A,(HL) 0075C 9A SBC A,D 0075D 57 LD D,A 0075E 23 INC HL 0075F 7E LD A,(HL) ;Subtract MSBs 00760 99 SBC A,C 00761 4F LD C,A ;Underflow ? ; SFLOAT: Convert CDEB in 2-exp format and store in X ; The mantissa is shifted to the left by one bit until ; the highest bit = 1 and the exponent is as small as possible 00762 DCC307 CALL C,07C3H ;Invert Mantissa (CDEB) when ;over or underflow 00765 68 LD L,B ;HL = LSBs 00766 63 LD H,E ;Manstissa now in CDHL 00767 AF XOR A ;A = 00H 00768 47 LD B,A ;B = counter 00769 79 LD A,C ;A = MSB 0076A B7 OR A ;MSB = 0 ? 0076B 2018 JR NZ,0785H ;No: continue shifting 0076D 4A LD C,D ;C << D << H << L << 00H 0076E 54 LD D,H ;(Shift Mantissa left bytewise) 0076F 65 LD H,L ;until MSB <> 0 00770 6F LD L,A 00771 78 LD A,B 00772 D608 SUB 08H ;Counter - 8 (8 bits shifted) 00774 FEE0 CP 0E0H ;Counter = -32 ? 00776 20F0 JR NZ,0768H ;No: continue shifting ;Shifted 4 times: ;Mantissa is now 0, result = 0 ; X = 0 (SNG) 00778 AF XOR A ;A = 00H 00779 322441 LD (4124H),A ;Exp (X) = 00H, X = 0 0077C C9 RET ; Shift Mantissa CDHL bitwise to the left until highest bit = 1 0077D 05 DEC B ;Counter - 1 (shift 1 bit) 0077E 29 ADD HL,HL ;HL = HL * 2 (= shift left) 0077F 7A LD A,D 00780 17 RLA ;D = D * 2, C-flag = overflow 00781 57 LD D,A 00782 79 LD A,C ;C = C + C + C-flag 00783 8F ADC A,A 00784 4F LD C,A ;Highest bit of C = 1 ? 00785 F27D07 JP P,077DH ;No: continue shifting 00788 78 LD A,B ;A = negative number of times ;that has been shifted 00789 5C LD E,H ;Mantissa = CDEB 0078A 45 LD B,L 0078B B7 OR A ;Anything shifted ? 0078C 2808 JR Z,0796H ;Yes: continue at 0796H 0078E 212441 LD HL,4124H ;HL -> Exp (X) 00791 86 ADD A,(HL) ;A = new Exponent 00792 77 LD (HL),A ;Save Exponent ;Old Exponent to small ? 00793 30E3 JR NC,0778H ;Yes: X = 0 ;Exponent = 0 ? 00795 C8 RET Z ;Yes: return ; Round CDEB and store in X ; Exp (X) and sign are kept 00796 78 LD A,B ;A = LSB 00797 212441 LD HL,4124H ;HL -> Exp (X) 0079A B7 OR A ;Highest bit of LSB = 1 ? 0079B FCA807 CALL M,07A8H ;Yes: round up CDE 0079E 46 LD B,(HL) ;B = Exp (X) 0079F 23 INC HL 007A0 7E LD A,(HL) ;A = Sign flag 007A1 E680 AND 80H ;Clear sign bit 007A3 A9 XOR C 007A4 4F LD C,A ;BCDE is negative in case ;sign flag was 00H 007A5 C3B409 JP 09B4H ;X = BCDE ; Round CDE and write overflow to Exp (X) 007A8 1C INC E ;LSB + 1 ;Overflow ? 007A9 C0 RET NZ ;No: return 007AA 14 INC D ;Next byte + 1 ;Overflow ? 007AB C0 RET NZ ;No: return 007AC 0C INC C ;MSB + 1 ;Overflow ? 007AD C0 RET NZ ;No: return 007AE 0E80 LD C,80H ;Set highest bit of Mantissa 007B0 34 INC (HL) ;and increment Exp (X) ;Overflow ? 007B1 C0 RET NZ ;No: return ; ?OV Error 007B2 1E0A LD E,0AH ;E = error code for ?OV error 007B4 C3A219 JP 19A2H ;Continue at error routine ; CDE = CDE + (HL) (SNG) ; Fixed point (Mantissa) addition 007B7 7E LD A,(HL) ;A = (HL) 007B8 83 ADD A,E ;A = E + (HL) 007B9 5F LD E,A ;E = E + (HL) 007BA 23 INC HL ;Next byte 007BB 7E LD A,(HL) 007BC 8A ADC A,D ;Now add with carry 007BD 57 LD D,A 007BE 23 INC HL ;Last byte 007BF 7E LD A,(HL) 007C0 89 ADC A,C 007C1 4F LD C,A 007C2 C9 RET ; Invert Mantissa of CDEB and Sign flag (4125H) 007C3 212541 LD HL,4125H ;HL -> Sign flag 007C6 7E LD A,(HL) ;A = Sign Flag 007C7 2F CPL ;Invert 007C8 77 LD (HL),A ;and store 007C9 AF XOR A ;A = 00H 007CA 6F LD L,A ;L = 00H 007CB 90 SUB B 007CC 47 LD B,A ;B = 00H - B 007CD 7D LD A,L ;A = 00H 007CE 9B SBC A,E ;E = 00H - E - C-flag 007CF 5F LD E,A 007D0 7D LD A,L ;Same with D 007D1 9A SBC A,D 007D2 57 LD D,A 007D3 7D LD A,L ;and with C 007D4 99 SBC A,C 007D5 4F LD C,A 007D6 C9 RET ; Shift CDE by A bits to the right. B becomes LSB 007D7 0600 LD B,00H ;Overflow on 00H 007D9 D608 SUB 08H ;More as 8 shifts ? 007DB 3807 JR C,07E4H ;No: shift bitwise ;Yes: shift bytewise 007DD 43 LD B,E 007DE 5A LD E,D 007DF 51 LD D,C 007E0 0E00 LD C,00H ;00H >> C >> D >> E >> B 007E2 18F5 JR 07D9H ;Loop ; Shift bitwise 007E4 C609 ADD A,09H ;Reverse SUB and adjust by 1 007E6 6F LD L,A ;L = counter 007E7 AF XOR A ;A = 00H 007E8 2D DEC L ;Counter - 1 ;Counter = 0 ? 007E9 C8 RET Z ;Yes: return 007EA 79 LD A,C ;Shift right CDE by one bit 007EB 1F RRA 007EC 4F LD C,A 007ED 7A LD A,D ;Shift D 007EE 1F RRA 007EF 57 LD D,A 007F0 7B LD A,E ;Shift E 007F1 1F RRA 007F2 5F LD E,A 007F3 78 LD A,B ;Shift B 007F4 1F RRA 007F5 47 LD B,A ;Overflow in B 007F6 18EF JR 07E7H ;Loop ; Constant 1 (SNG) 007F8 00 DEFB 00H 007F9 00 DEFB 00H 007FA 00 DEFB 00H 007FB 81 DEFB 81H ; Table of SNG coefficients for LOG function 007FC 03 DEFB 03H ;3 Coefficients 007FD AA DEFB AAH ;0.598979 approx. 007FE 56 DEFB 56H ;2 / ( 5*LOG(2) ) 007FF 19 DEFB 19H 00800 80 DEFB 80H 00801 F1 DEFB F1H ;0.961471 approx. 00802 22 DEFB 22H ;2 / ( 3*LOG(2) ) 00803 76 DEFB 76H 00804 80 DEFB 80H 00805 45 DEFB 45H ;2.88539 approx. 00806 AA DEFB AAH ;2 / ( 1*LOG(2) ) 00807 38 DEFB 38H 00808 82 DEFB 82H ; X = LOG ( X ) ; ------------- ; Calculates the natural logarithm of X ; ; I: X = numerical value (<> 0) ; O: X = LOG (numerical value) 00809 CD5509 CALL 0955H ;TEST2 0080C B7 OR A ;Argument = 0 ? 0080D EA4A1E JP PE,1E4AH ;Yes: ?FC Error 00810 212441 LD HL,4124H ;HL -> Exp (argument) 00813 7E LD A,(HL) ;A = Exp (argument) 00814 013580 LD BC,8035H ;BCDE = 0.707107 = SQR(2)/2 00817 11F304 LD DE,04F3H ;Conversion Arg = x * 2 ^ n 0081A 90 SUB B ;Exp (Arg) - 128 = n (B is 128) 0081B F5 PUSH AF ;save n 0081C 70 LD (HL),B ;X = x (set Exp to 80H) 0081D D5 PUSH DE ;Save BCDE 0081E C5 PUSH BC 0081F CD1607 CALL 0716H ;X = X + BCDE = X+1/2*SQR(2) 00822 C1 POP BC ;Restore BCDE 00823 D1 POP DE 00824 04 INC B ;Exp(BCDE) + 1 ;BCDE = BCDE * 2 + SQR(2) 00825 CDA208 CALL 08A2H ;X = BCDE / X = SQR(2) / X 00828 21F807 LD HL,07F8H ;HL -> 1.0 0082B CD1007 CALL 0710H ;X = (HL) - X = 1.0 - X 0082E 21FC07 LD HL,07FCH ;HL -> numeric table 00831 CD9A14 CALL 149AH ;Compute row1 00834 018080 LD BC,8080H ;BCDE = -0.5 00837 110000 LD DE,0000H 0083A CD1607 CALL 0716H ;X = BCDE + X = X - 0.5 0083D F1 POP AF ;Restore n 0083E CD890F CALL 0F89H ;X = X + n ;and multiply with LOG(2) ; X = X * LOG(2) 00841 013180 LD BC,8031H ;BCDE = 0.693147 = LOG(2) 00844 111872 LD DE,7218H ; SMUL: X = BCDE * X ; Multiply two single precision numbers ; ; I: BCDE = 1st factor ; X = 2nd factor ; O: X = product 00847 CD5509 CALL 0955H ;TEST2 0084A C8 RET Z ;X = 0: result = 0 0084B 2E00 LD L,00H ;Flag = 0 (MUL indication) 0084D CD1409 CALL 0914H ;Process exponent 00850 79 LD A,C ;Save CDE (1st factor) in 00851 324F41 LD (414FH),A ;system RAM from 414FH onwards 00854 EB EX DE,HL 00855 225041 LD (4150H),HL 00858 010000 LD BC,0000H ;BCDE = 00000000H 0085B 50 LD D,B 0085C 58 LD E,B 0085D 216507 LD HL,0765H ;Put new return address 00860 E5 PUSH HL ;to 0765H 00861 216908 LD HL,0869H ;Put new return address twice 00864 E5 PUSH HL ;to 0869H 00865 E5 PUSH HL 00866 212141 LD HL,4121H ;HL -> 2nd factor 00869 7E LD A,(HL) ;A = next byte of mantissa of ;the 2nd factor 0086A 23 INC HL ;Pointer + 1 0086B B7 OR A ;Byte = 00H ? 0086C 2824 JR Z,0892H ;Yes: continue at 0892H 0086E E5 PUSH HL ;Save pointer 0086F 2E08 LD L,08H ;L = counter for 8 bits 00871 1F RRA ;Shift next bit into C-flag 00872 67 LD H,A ;Save byte in H 00873 79 LD A,C ;A = MSB ;Bit set by last shift ? 00874 300B JR NC,0881H ;No: continue at 0881H 00876 E5 PUSH HL ;Save HL 00877 2A5041 LD HL,(4150H) ;CDE = CDE + 1st factor 0087A 19 ADD HL,DE 0087B EB EX DE,HL 0087C E1 POP HL ;Restore HL 0087D 3A4F41 LD A,(414FH) 00880 89 ADC A,C ;A = MSB 00881 1F RRA ;CDEB one bit to the right 00882 4F LD C,A 00883 7A LD A,D ;Shift D 00884 1F RRA 00885 57 LD D,A 00886 7B LD A,E ;Shift E 00887 1F RRA 00888 5F LD E,A 00889 78 LD A,B ;Shift B 0088A 1F RRA 0088B 47 LD B,A 0088C 2D DEC L ;Counter - 1 0088D 7C LD A,H ;Byte back into A 0088E 20E1 JR NZ,0871H ;Check next bit 00890 E1 POP HL ;HL -> X 00891 C9 RET ;RET twice to 0896H and ;once to 0765H ; SUB for SMUL ; Shift CDEB 1 byte to the right and fill with 00H 00892 43 LD B,E ;00H >> C >> D >> E >> B 00893 5A LD E,D 00894 51 LD D,C 00895 4F LD C,A 00896 C9 RET ; SDIV10: X = X / 10 ; Divides number in X BY 10 ; ; I: X = single precision number ; O: X = number / 10 00897 CDA409 CALL 09A4H ;(SP) = X 0089A 21D80D LD HL,0DD8H ;HL -> 10 ; X = (SP) / (HL) 0089D CDB109 CALL 09B1H ;X = BCDE = (HL) ; X = (SP) / X 008A0 C1 POP BC ;BCDE = (SP) 008A1 D1 POP DE ; SDIV: X = BCDE / X ; Divides 2 single precision numbers ; ; I: BCDE = dividend ; X = divisor ; O: X = quotient 008A2 CD5509 CALL 0955H ;TEST2 ;X = 0 ? 008A5 CA9A19 JP Z,199AH ;Yes: ?/0 Error 008A8 2EFF LD L,0FFH ;Flag = FFH (DIV marker) 008AA CD1409 CALL 0914H ;Process exponent and sign 008AD 34 INC (HL) ;Adjust exponents 008AE 34 INC (HL) 008AF 2B DEC HL ;HL -> MSB (X) 008B0 7E LD A,(HL) ;Store divisor in RAM 008B1 328940 LD (4089H),A ;MSB at 4089H 008B4 2B DEC HL 008B5 7E LD A,(HL) 008B6 328540 LD (4085H),A ;1st LSB at 4085H 008B9 2B DEC HL 008BA 7E LD A,(HL) 008BB 328140 LD (4081H),A ;2nd LSB at 4081H 008BE 41 LD B,C ;BHL = CDE 008BF EB EX DE,HL ;BHL = mantissa of dividend 008C0 AF XOR A ;A = 00H 008C1 4F LD C,A ;CDE = 000000H 008C2 57 LD D,A ;(Result is computed in CDE) 008C3 5F LD E,A 008C4 328C40 LD (408CH),A ;(408C) = 00H 008C7 E5 PUSH HL ;Save dividend 008C8 C5 PUSH BC 008C9 7D LD A,L ;A = 2nd LSB of dividend 008CA CD8040 CALL 4080H ;BHL = BHL - X (subtract ;mantissa of dividend and ;divisor) ;A = (408CH) 008CD DE00 SBC A,00H ;A = A - C-flag (subtract ;borrow from last subtract ;from MSB 008CF 3F CCF ;Invert C-flag 008D0 3007 JR NC,08D9H ;Yes: continue at 08D9H 008D2 328C40 LD (408CH),A ;No: write MSB back 008D5 F1 POP AF ;Remove dividend from stack 008D6 F1 POP AF 008D7 37 SCF ;C-flag = 1: jump is not 008D8 D2C1E1 JP NC,0E1C1H ;executed * 008D9 C1 POP BC :Dividend back to BHL * 008DA E1 POP HL ;(C-flag = 0 because of 08D0H) 008DB 79 LD A,C ;A = MSB of result 008DC 3C INC A ;Bit 7 of A = 1 ? 008DD 3D DEC A ;(S-flag is influenced) 008DE 1F RRA ;Shift C-flag to bit 7 of A ;for round routine 008DF FA9707 JP M,0797H ;Yes: done, round CDE upwards ;(if C-flag was 1) and write ;result in X 008E2 17 RLA ;Shift back and shift C-flag ;into result 008E3 7B LD A,E ;(C << C << E << C-flag) 008E4 17 RLA 008E5 5F LD E,A 008E6 7A LD A,D 008E7 17 RLA 008E8 57 LD D,A 008E9 79 LD A,C 008EA 17 RLA 008EB 4F LD C,A 008EC 29 ADD HL,HL ;Shift dividend 1 bit left 008ED 78 LD A,B 008EE 17 RLA ;Overflow from HL to B 008EF 47 LD B,A 008F0 3A8C40 LD A,(408CH) ;Overflow of dividend-shift 008F3 17 RLA ;to 408CH (MSB of dividend) 008F4 328C40 LD (408CH),A 008F7 79 LD A,C ;CDE = 000000H ? 008F8 B2 OR D 008F9 B3 OR E 008FA 20CB JR NZ,08C7H ;No: process next bit ;Yes: 008FC E5 PUSH HL ;Save HL 008FD 212441 LD HL,4124H ;HL -> Exp (X) 00900 35 DEC (HL) ;X = X / 2 ;Underflow ? 00901 E1 POP HL ;Restore HL first 00902 20C3 JR NZ,08C7H ;No: process next bit 00904 C3B207 JP 07B2H ;Yes: ?OV Error ; SUB for SMUL, SDIV, DMUL and DDIV ; Process exponents and signs ; Entry for DDIV 00907 3EFF LD A,0FFH ;Flag = FFH * 00909 2EAF LD L,AFH ;-- ; Entry for DMUL 0090A AF XOR A ;Flag = 00H 0090B 212D41 LD HL,412DH ;HL -> MSB (Y) 0090E 4E LD C,(HL) ;C = MSB (Y) 0090F 23 INC HL ;HL -> Exp (Y) 00910 AE XOR (HL) ;DMUL: A = Exp (Y) ;DDIV: A = -Exp (Y) - 1 00911 47 LD B,A ;B = Exp 00912 2E00 LD L,00H ;Continue as with SMUL ; Entry for SMUL (L=00H) and SDIV (L=FFH) 00914 78 LD A,B ;A = Exp (BCDE) 00915 B7 OR A ;BCDE = 0 ? 00916 281F JR Z,0937H ;Yes: result = 0 00918 7D LD A,L ;A = flag 00919 212441 LD HL,4124H ;HL -> Exp (X) 0091C AE XOR (HL) ;SMUL: A = EXP (X) ;SDIV: A = -Exp (X) - 1 0091D 80 ADD A,B ;SMUL: A = Exp (Y) + Exp (X) ;SDIV: A = Exp (Y) - Exp (X) -1 0091E 47 LD B,A ;B = new Exp 0091F 1F RRA ;Shift C-flag into A, bit 7 00920 A8 XOR B ;XOR with B ;A, bit 7 = 0 when an overflow ;or underflow occurs to C-flag ;and A, bit 7 at the addition ;of the exponents. (if both ;exponents were positive (i.e. ;> 80H), only an oveflow to ;C-flag occurs; A, bit 7 ;becomes 0! ) 00921 78 LD A,B ;A = new exponent 00922 F23609 JP P,0936H ;Under/overflow: continue at ;0936H 00925 C680 ADD A,80H ;Add offset to Exp 00927 77 LD (HL),A ;Store new exponent in Exp (X) ;Exponent = 0 ? 00928 CA9008 JP Z,0890H ;Yes: done, continue ar 0890H 0092B CDDF09 CALL 09DFH ;Adjust mantissas 0092E 77 LD (HL),A ;Save signflag 0092F 2B DEC HL ;HL = 4124H 00930 C9 RET ; Entry from Exp (X) when X > 127 or LSB (X) > 7DH ; If X < 0, then set X = 0 else ?OV Error 00931 CD5509 CALL 0955H ;TEST2 00934 2F CPL ;If X < 0 then A positive ; else A negative 00935 E1 POP HL ;Remove RET address 00936 B7 OR A ;Set flags 00937 E1 POP HL ;Remove RET address 00938 F27807 JP P,0778H ;A positive then X = 0 0093B C3B207 JP 07B2H ;Else ?OV Error ; SMUL10: X = X * 10 ; Multiplies number in X with 10 ; ; I: X = single precision number ; O: X = number * 10 0093E CDBF09 CALL 09BFH ;BCDE = X 00941 78 LD A,B ;BCDE = 0 ? 00942 B7 OR A 00943 C8 RET Z ;Yes: result = 0 00944 C602 ADD A,02H ;Exp + 2: BCDE = BCDE * 4 ;Exp overflow ? 00946 DAB207 JP C,07B2H ;Yes: ?OV Error 00949 47 LD B,A ;Set Exp in BCDE 0094A CD1607 CALL 0716H ;X = X + BCDE = X + 4*X = 5 * X 0094D 212441 LD HL,4124H ;HL -> Exp (X) 00950 34 INC (HL) ;Exp (X) + 1: X = X * 2 ;Overflow ? 00951 C0 RET NZ ;No: done, return 00952 C3B207 JP 07B2H ;?OV Error ; TEST2: SNG function for X ; Test single or double precision number in X if smaller, ; equal or greater then zero ; ?TM Error when X contains a STR ; ; I: X = single or double precision number to be tested ; O: if X < 0: A = FFH, C-flag = 1, Z-flag = 0, S-flag = 1 ; O: if X = 0: A = 00H, C-flag = 0, Z-flag = 1, S-flag = 0, P/V-flag = 1 ; O: if X > 0: A = 01H, C-flag = 0, Z-flag = 0, S-flag = 0 00955 3A2441 LD A,(4124H) ;A = Exp (X) 00958 B7 OR A ;X = 0 ? 00959 C8 RET Z :Yes: return 0095A 3A2341 LD A,(4123H) ;A,7 = sign 0095D FE2F CP 2FH ;-- ; Entry from compare routines * 0095D 2F CPL 0095F 17 RLA ;C-flag = sign 00960 9F SBC A,A ;A = FFH if X<0 else A = 00H ;X < 0 ? 00961 C0 RET NZ ;Yes: return 00962 3C INC A ;X > 0: A = 01H 00963 C9 RET ; FLOATA: convert A single precision number ; ; I: A = number ; O: X = numerical value of A in single precision 00964 0688 LD B,88H ;B = Exp for 2 ^ 8 00966 110000 LD DE,0000H ;LSBs = 0 ; FLOAT: convert a binary number into single precision ; 1. Binary number of 8 bits: ; I: B = 88H (Exp for 2 ^ 8) ; A = binary value ; DE = 0000H ; 2. Binary number of 16 bits: (see also CINT) ; I: B = 90H (Exp for 2 ^ 16) ; A = MSB of 16 bit value ; D = LSB of 16 bit value ; E = 0000H ; 3. Binary number of 24 bits: ; I: B = 98H (Exp for 2 ^ 24) ; A = MSB of 24 bit value ; DE = LSBs of 24 bit value ; O: X = single precision number 00969 212441 LD HL,4124H ;HL -> Exp (X) 0096C 4F LD C,A ;C = 8 bit value 0096D 70 LD (HL),B ;Set exponent 0096E 0600 LD B,00H ;B = 00H (becomes LSB at 0762H) 00970 23 INC HL ;HL -> sign-flag 00971 3680 LD (HL),80H ;Set sign-flag to 80H 00973 17 RLA ;Sign-bit to C-flag (for 0762H) 00974 C36207 JP 0762H ;SFLOAT conversion CDEB to X ; X = ABS (X) ; ----------- 00977 CD9409 CALL 0994H ;TEST1 :X is positive ? 0097A F0 RET P ;Yes: return 0097B E7 RST 20H ;TSTTYP ;INT type ? 0097C FA5B0C JP M,0C5BH ;Yes: continue at 0C5BH ;STR type ? 0097F CAF60A JP Z,0AF6H ;Yes: ?TM error ; SDNEG: X = -X ; Negate number in X ; ; I: X = single of double precision number ; O: X = negated number 00982 212341 LD HL,4123H ;HL -> MSB of X 00985 7E LD A,(HL) ;A = MSB of X 00986 EE80 XOR 80H ;Invert sign bit 00988 77 LD (HL),A ;Store MSB of X 00989 C9 RET ; X = SNG (X) ; ----------- 0098A CD9409 CALL 0994H ;TEST1 0098D 6F LD L,A ;L = SNG(value) (FFH,00H,01H) 0098E 17 RLA ;Highest bit to C-flag 0098F 9F SBC A,A ;A = 00 when positive result ;else A = FFH 00990 67 LD H,A ;Now HL = A 00991 C39A0A JP 0A9AH ;Write HL to X as INT ; TEST1: As SNG function, but result in A ; Test number in X if smaller, equal or greater then zero ; ?TM Error when X contains a STR ; ; I: X = number to be tested ; O: if X < 0: A = FFH, C-flag = 1, Z-flag = 0, S-flag = 1 ; O: if X = 0: A = 00H, C-flag = 0, Z-flag = 1, S-flag = 0, P/V-flag = 1 ; O: if X > 0: A = 01H, C-flag = 0, Z-flag = 0, S-flag = 0 00994 E7 RST 20H ;TSTTYP ;STR type ? 00995 CAF60A JP Z,0AF6H ;Yes: ?TM Error ;INT type ? 00998 F25509 JP P,0955H ;No: SNG or DBL so TEST2 0099B 2A2141 LD HL,(4121H) ;HL = X (INT) 0099E 7C LD A,H ;HL = 0000 ? 0099F B5 OR L 009A0 C8 RET Z ;Yes: return 009A1 7C LD A,H ;A = MSB of X ;if H < 0 then A, bit 7 = 1 ; else A, bit 7 = 0 009A2 18BB JR 095FH :Continue inside TEST2 ; (SP) = X (SNG) ; (Save value in X) 009A4 EB EX DE,HL ;Save HL 009A5 2A2141 LD HL,(4121H) ;HL = LSB (X) 009A8 E3 EX (SP),HL ;Put LSBs on stack 009A9 E5 PUSH HL ;Save RET address 009AA 2A2341 LD HL,(4123H) ;Same with MSB and Exp 009AD E3 EX (SP),HL 009AE E5 PUSH HL 009AF EB EX DE,HL ;Restore HL 009B0 C9 RET ; X = BCDE = (HL) (SNG) 009B1 CDC209 CALL 09C2H ;BCDE = (HL) ; X = BCDE (SNG) 009B4 EB EX DE,HL ;HL = LSBs 009B5 222141 LD (4121H),HL ;Store in X 009B8 60 LD H,B ;HL = MSB and Exp 009B9 69 LD L,C 009BA 222341 LD (4123H),HL ;Store in X 009BD EB EX DE,HL ;Restore HL 009BE C9 RET ; BCDE = X (SNG) 009BF 212141 LD HL,4121H ;HL -> X ; BCDE = (HL) (SNG) 009C2 5E LD E,(HL) ;E = LSB 009C3 23 INC HL 009C4 56 LD D,(HL) ;D = LSB + 1 009C5 23 INC HL 009C6 4E LD C,(HL) ;C = MSB 009C7 23 INC HL 009C8 46 LD B,(HL) ;B = Exp 009C9 23 INC HL 009CA C9 RET ; (HL) = X (SNG) 009CB 112141 LD DE,4121H ;DE -> X 009CE 0604 LD B,04H ;B = size of SNG variable 009D0 1805 JR 09D7H ;Continue at 09D7H ; (DE) = (HL) ; Copy memory from (HL) to (DE), counter = (40AFH) 009D2 EB EX DE,HL ; As above but from (DE) to (HL) 009D3 3AAF40 LD A,(40AFH) ;A = variable type in X ; Copy routine: copies A bytes from (DE) to (HL) 009D6 47 LD B,A ;Save in B as counter ; Copy B bytes from (DE) to (HL) 009D7 1A LD A,(DE) ;Copy byte from (DE) 009D8 77 LD (HL),A ;to (HL) 009D9 13 INC DE ;Origin pointer + 1 009DA 23 INC HL ;Destiniation pointer + 1 009DB 05 DEC B ;All bytes done ? 009DC 20F9 JR NZ,09D7H ;No: next byte 009DE C9 RET ; Sign processing for basic arithmatic operations ; Set proper mantissas of X and BCDE (highest bit to 1) ; and adjust sign ; ; I: X = single or double precision number ; BCDE = single or double precision number ; 0: Correct mantissa of X and BCDE (highest bit = 1) ; If both signs are the same then A, bit 7 = 1 else A, bit 7 = 0 009DF 212341 LD HL,4123H ;HL -> MSB of X 009E2 7E LD A,(HL) ;A = MSB of X 009E3 07 RLCA ;C-flag and A, bit 0 = Sign X 009E4 37 SCF ;C-flag = 1 009E5 1F RRA ;A, bit 7 = C-flag = 1, ;C-flag = A, bit 0 = sign 009E6 77 LD (HL),A ;Correct Mantissa 009E7 3F CCF ;Invert C-flag 009E8 1F RRA ;A, bit 0 = inverted sign 009E9 23 INC HL 009EA 23 INC HL ;HL = 4125H (sign-flag) 009EB 77 LD (HL),A ;Save sign flag 009EC 79 LD A,C ;Same with BCDE but leave sign 009ED 07 RLCA 009EE 37 SCF 009EF 1F RRA 009F0 4F LD C,A 009F1 1F RRA 009F2 AE XOR (HL) ;XOR both signs 009F3 C9 RET ; X = Y (SNG,DBL) 009F4 212741 LD HL,4127H ;HL -> LSB of Y ; X = (HL) (SNG,DBL) 009F7 11D209 LD DE,09D2H ;DE = address of copy routine ;(HL) to (DE) 009FA 1806 JR 0A02H ;Continue at 0A02H ; Y = X (SNG,DBL) 009FC 212741 LD HL,4127H ;HL -> LSB of Y ; (HL) = X (SNG,DBL) 009FF 11D309 LD DE,09D3H ;DE = address of copy routine ;(DE) to (HL) 00A02 D5 PUSH DE ;Put address on stack as ;new RET address 00A03 112141 LD DE,4121H ;DE -> X (SNG) 00A06 E7 RST 20H ;TSTTYP ;SNG ? 00A07 D8 RET C ;Yes: ok 00A08 111D41 LD DE,411DH ;DE -> X (DBL) 00A0B C9 RET ; CP X , BCDE (SNG) ; ; I: - ; O: if X < BCDE then A = FFH, C-flag = 1, Z-flag = 0, S-flag = 1 ; if X = BCDE then A = 00H, C-flag = 0, Z-flag = 1, S-flag = 0 ; if X > BCDE then A = 01H, C-flag = 0, Z-flag = 0, S-flag = 0 00A0C 78 LD A,B ;BCDE = 0 ? 00A0D B7 OR A 00A0E CA5509 JP Z,0955H ;Yes: TEST2 00A11 215E09 LD HL,095EH ;Set new RET address to TEST2 00A14 E5 PUSH HL 00A15 CD5509 CALL 0955H ;TEST2 00A18 79 LD A,C ;A = MSB (BCDE) ;X = 0 ? 00A19 C8 RET Z ;Yes: goto TEST2 (only test ;BCDE) 00A1A 212341 LD HL,4123H ;HL -> MSB (X) 00A1D AE XOR (HL) ;Compare signs 00A1E 79 LD A,C ;A = MSB (BCDE) 00A1F F8 RET M ;Goto TEST2, when both signs ;are not equal (only test BCDE) 00A20 CD260A CALL 0A26H ;Compare X and BCDE bytewise 00A23 1F RRA ;A, bit 7 = C-flag 00A24 A9 XOR C ;XOR with sign of BCDE 00A25 C9 RET ;Continue at TEST2 ; SUB for CP ; Compare X and BCDE bytewise 00A26 23 INC HL ;Compare Exp 00A27 78 LD A,B 00A28 BE CP (HL) 00A29 C0 RET NZ ;If not equal: return 00A2A 2B DEC HL :Same with MSBs 00A2B 79 LD A,C 00A2C BE CP (HL) 00A2D C0 RET NZ 00A2E 2B DEC HL ;1st LSB 00A2F 7A LD A,D 00A30 BE CP (HL) 00A31 C0 RET NZ 00A32 2B DEC HL ;2nd LSB 00A33 7B LD A,E 00A34 96 SUB (HL) ;Subtract, so that A = 00H ;in case E = (HL) 00A35 C0 RET NZ 00A36 E1 POP HL ;Remove RET address (0A23H) 00A37 E1 POP HL ;Remove RET address (095E) 00A38 C9 RET ;Return with A = 00H, Z-flag = 1 ; CP HL , DE (INT) ; ; I: - ; O: if HL < DE then A = FFH, C-flag = 1, Z-flag = 0, S-flag = 1 ; if HL = DE then A = 00H, C-flag = 0, Z-flag = 1, S-flag = 0 ; if HL > DE then A = 01H, C-flag = 0, Z-flag = 0, S-flag = 0 00A39 7A LD A,D ;Compare signs 00A3A AC XOR H 00A3B 7C LD A,H ;A = MSB (HL) 00A3C FA5F09 JP M,095FH ;If signs are not equal: ;continue at TEST2 00A3F BA CP D ;Compare MSBs 00A40 C26009 JP NZ,0960H ;If not equal: goto TEST2 00A43 7D LD A,L ;Compare LSBs 00A44 93 SUB E ;Subtract, so that A = 00H ;in case E = L 00A45 C26009 JP NZ,0960H ;If not equal: goto TEST2 00A48 C9 RET ; CP X , (DE) (DBL) ; ; I: - ; O: if X < (DE) then A = FFH, C-flag = 1, Z-flag = 0, S-flag = 1 ; if X = (DE) then A = 00H, C-flag = 0, Z-flag = 1, S-flag = 0 ; if X > (DE) then A = 01H, C-flag = 0, Z-flag = 0, S-flag = 0 00A49 212741 LD HL,4127H ;HL -> Y 00A4C CDD309 CALL 09D3H ;Copy (DE) to (HL) 00A4F 112E41 LD DE,412EH ;DE -> Exp (Y) 00A52 1A LD A,(DE) ;A = Exp (Y) 00A53 B7 OR A ;Y = 0 ? 00A54 CA5509 JP Z,0955H ;Yes: execute TEST2 00A57 215E09 LD HL,095EH ;Set new RET address 00A5A E5 PUSH HL ;to TEST2 00A5B CD5509 CALL 0955H ;TEST2 00A5E 1B DEC DE ;DE = MSB (Y) 00A5F 1A LD A,(DE) ;A = MSB (Y) 00A60 4F LD C,A ;C = MSB (Y) (for TEST2) ;X = 0 ? 00A61 C8 RET Z ;Yes: TEST2 using Y 00A62 212341 LD HL,4123H ;HL -> MSB (X) 00A65 AE XOR (HL) ;Compare signs 00A66 79 LD A,C ;A = MSB (Y) ;Signs not equal ? 00A67 F8 RET M ;Yes: TEST2 00A68 13 INC DE ;DE = Exp (Y) 00A69 23 INC HL ;HL = Exp (X) 00A6A 0608 LD B,08H ;B = counter for 8 bytes 00A6C 1A LD A,(DE) ;Compare X and Y bytewise 00A6D 96 SUB (HL) ;Byte from X = Byte from Y ? 00A6E C2230A JP NZ,0A23H ;No: contineu at 0A23H 00A71 1B DEC DE ;Pointer on Y - 1 00A72 2B DEC HL ;Pointer on X - 1 00A73 05 DEC B ;Counter - 1 00A74 20F6 JR NZ,0A6CH ;Compare next byte from X and Y 00A76 C1 POP BC ;Remove RET address (095EH) 00A77 C9 RET ; CP X , Y (DBL) ; ; I: - ; O: if X < Y then A = FFH, C-flag = 1, Z-flag = 0, S-flag = 1 ; if X = Y then A = 00H, C-flag = 0, Z-flag = 1, S-flag = 0 ; if X > Y then A = 01H, C-flag = 0, Z-flag = 0, S-flag = 0 00A78 CD4F0A CALL 0A4FH ;Compare X and Y 00A7B C25E09 JP NZ,095EH ;If X <> Y then goto TEST2 00A7E C9 RET ; X = CINT (X) ; ------------ 00A7F E7 RST 20H ;TSTTYP 00A80 2A2141 LD HL,(4121H) ;HL -> X ;INT type ? 00A83 F8 RET M ;Yes: return ;STR type ? 00A84 CAF60A JP Z,0AF6H ;Yes: ?TM Error ;DBL type ? 00A87 D4B90A CALL NC,0AB9H ;Yes: convert to SNG 00A8A 21B207 LD HL,07B2H ;Set new return address 00A8D E5 PUSH HL ;to 07B2H (= ?OV Error) 00A8E 3A2441 LD A,(4124H) ;A = Exp (X) 00A91 FE90 CP 90H ;Exp > (2 ^ 16) ? (16 bit) 00A93 300E JR NC,0AA3H ;Yes: continue at 0AA3H 00A95 CDFB0A CALL 0AFBH ;DE = INT (X) 00A98 EB EX DE,HL ;HL = INT value 00A99 D1 POP DE ;Remove new return address ; This routine writes the contents of HL into the X register as INT ; ; I: HL = integer value ; O: X = integer value ; A = VT of X (INT) 00A9A 222141 LD (4121H),HL ;Write HL in X ; Set VT to INT 00A9D 3E02 LD A,02H ;A = type code INT 00A9F 32AF40 LD (40AFH),A ;Save VT 00AA2 C9 RET ; Continuation of CINT (X) ; X = -32768 ? (Is it still within the INT format ?) 00AA3 018090 LD BC,9080H ;BCDE = -32768 00AA6 110000 LD DE,0000H 00AA9 CD0C0A CALL 0A0CH ;Compare X and BCDE ;X = BCDE ? 00AAC C0 RET NZ ;No: ?OV Error 00AAD 61 LD H,C ;HL = -32768 00AAE 6A LD L,D 00AAF 18E8 JR 0A99H ;Remove RET address and ;set X = HL ; X = CSNG (X) ; ------------ 00AB1 E7 RST 20H ;TSTTYP ;SNG type ? 00AB2 E0 RET PO ;Yes: return ;INT type ? 00AB3 FACC0A JP M,0ACCH ;Yes: continue at 0ACCH ;STR type ? 00AB6 CAF60A JP Z,0AF6H ;Yes: ?TM Error ;DBL type: 00AB9 CDBF09 CALL 09BFH ;BCDE = X 00ABC CDEF0A CALL 0AEFH ;VT = SNG 00ABF 78 LD A,B ;BCDE = 0 ? 00AC0 B7 OR A 00AC1 C8 RET Z ;Yes: ok 00AC2 CDDF09 CALL 09DFH ;Adjust mantissas 00AC5 212041 LD HL,4120H 00AC8 46 LD B,(HL) ;B = 3rd LSB (X) with DBL 00AC9 C39607 JP 0796H ;X = BCDE and round ; X = CSNG (X) (INT) 00ACC 2A2141 LD HL,(4121H) ;HL = INT value ; X = CSNG (HL) (INT) 00ACF CDEF0A CALL 0AEFH ;VT = SNG 00AD2 7C LD A,H ;A = MSB (HL) 00AD3 55 LD D,L ;D = LSB (HL) 00AD4 1E00 LD E,00H ;E = 00H 00AD6 0690 LD B,90H ;B = 90H (Exp = 2 ^ 16) 00AD8 C36909 JP 0969H ;SFLOAT (X) ; X = CDBL (X) ; ------------ 00ADB E7 RST 20H ;TSTTYP ;DBL type ? 00ADC D0 RET NC ;Yes: return ;STR type ? 00ADD CAF60A JP Z,0AF6H ;Yes: ?TM Error ;INT type ? 00AE0 FCCC0A CALL M,0ACCH ;Yes: CSGN 00AE3 210000 LD HL,0000H 00AE6 221D41 LD (411DH),HL ;Set 4 LSBs to zero 00AE9 221F41 LD (411FH),HL ; Set VT to DBL 00AEC 3E08 LD A,08H ;A = type code for DBL 00AEE 013E04 LD BC,043EH ;-- ; Set VT to SNG * 00AEF 3E04 LD A,04 ;A = type code for SNG 00AF1 C39F0A JP 0A9FH ;VT = A ; Test if X is string type. If not: ?TM Error else return 00AF4 E7 RST 20H ;TSTTYP ;STR type ? 00AF5 C8 RET Z ;Yes: return 00AF6 1E18 LD E,18H ;E = error code for ?TM Error 00AF8 C3A219 JP 19A2H ;Continue at error routine ; SUB for INT, FIX, CINT ; I: X = SNG value with Exp <= 98H (2 ^ 24) ; (so with fractional part) ; A = Exp (X) ; O: DE = INT value of X 00AFB 47 LD B,A ;BCDE = A 00AFC 4F LD C,A 00AFD 57 LD D,A 00AFE 5F LD E,A 00AFF B7 OR A ;Zero ? 00B00 C8 RET Z ;Yes: return with DE = 0000H 00B01 E5 PUSH HL ;Save HL 00B02 CDBF09 CALL 09BFH ;BCDE = X 00B05 CDDF09 CALL 09DFH ;Adjust mantissas 00B08 AE XOR (HL) ;A, bit 7 = Sign of BCDE or X 00B09 67 LD H,A ;H, bit 7 = Sign (X) ;X negative ? 00B0A FC1F0B CALL M,0B1FH ;Yes: round BCDE 00B0D 3E98 LD A,98H ;A = Exp (2 ^ 24) ;(24 bit mantissa, no fraction) 00B0F 90 SUB B ;A = 98H - Exp (X) 00B10 CDD707 CALL 07D7H ;Shift CDE to the right for ;A bits (B becomes LSB) ;Shift out franctional part 00B13 7C LD A,H ;A, bit 7 = Sign (X) 00B14 17 RLA ;C-flag = sign ;X negative ? 00B15 DCA807 CALL C,07A8H ;Yes: round up X 00B18 0600 LD B,00H ;Clear LSB ;X negative ? 00B1A DCC307 CALL C,07C3H ;Yes: Invert CDEB 00B1D E1 POP HL ;Restore HL 00B1E C9 RET ; Round down BCDE 00B1F 1B DEC DE ;Round LSBs 00B20 7A LD A,D ;Test LSBs 00B21 A3 AND E ;Was DE = 0000H ? 00B22 3C INC A ;Yes: then A now is 00H 00B23 C0 RET NZ ;Done when LSBs <> 0 00B24 0B DEC BC ;Round MSBs 00B25 C9 RET ; X = FIX (X) ; ----------- 00B26 E7 RST 20H ;TSTTYP ;INT type ? 00B27 F8 RET M ;Yes: return 00B28 CD5509 CALL 0955H ;TEST2 ;X < 0 ? 00B2B F2370B JP P,0B37H ;No: X = INT(X) 00B2E CD8209 CALL 0982H ;X = -X 00B31 CD370B CALL 0B37H ;X = INT(X) 00B34 C37B09 JP 097BH ;X = ABS (X) and RET ; X = INT (X) ; ----------- 00B37 E7 RST 20H ;TSTTYP ;INT type ? 00B38 F8 RET M ;Yes: return ;DBL type ? 00B39 301E JR NC,0B59H ;Yes: continue at 0B59H ;STR type ? 00B3B 28B9 JR Z,0AF6H ;Yes: ?TM Error ; X = INT (X) (SNG) ; ; I: X = single precision value ; O: X = single precision value without fractional part ; A = LSB of integer value of X 00B3D CD8E0A CALL 0A8EH ;X = CINT (X) (SNG) 00B40 212441 LD HL,4124H ;HL -> Exp (X) 00B43 7E LD A,(HL) ;A = Exp (X) 00B44 FE98 CP 98H ;Exp >= (2 ^ 24) ? ;Yes: X has no fraction 00B46 3A2141 LD A,(4121H) ;A = LSB of X 00B49 D0 RET NC ;Done when Exp (X) >= 98H 00B4A 7E LD A,(HL) ;A = Exp (X) 00B4B CDFB0A CALL 0AFBH ;Remove fractional part 00B4E 3698 LD (HL),98H ;Set Exp to 2 ^ 24 00B50 7B LD A,E ;A = LSB 00B51 F5 PUSH AF ;Save LSB 00B52 79 LD A,C ;A = MSB 00B53 17 RLA ;Sign to C-flag 00B54 CD6207 CALL 0762H ;SFLOAT conversion CDEB to X 00B57 F1 POP AF ;LSB back to A 00B58 C9 RET ; X = INT (X) (DBL) 00B59 212441 LD HL,4124H ;HL -> Exp (X) 00B5C 7E LD A,(HL) ;A = Exp (X) 00B5D FE90 CP 90H ;Exp (X) < (2 ^ 16) 00B5F DA7F0A JP C,0A7FH ;Yes: execute CINT ;Exp (X) = (2 ^ 16) 00B62 2014 JR NZ,0B78H ;No: continue at 0B78H 00B64 4F LD C,A ;C = 90H (Exp = 2 ^ 16!) 00B65 2B DEC HL ;HL = MSB (X) 00B66 7E LD A,(HL) ;A = MSB (X) 00B67 EE80 XOR 80H ;A = 00H, if X = -32768 00B69 0606 LD B,06H ;Test remaining 6 bytes 00B6B 2B DEC HL ;Pointer - 1 00B6C B6 OR (HL) ;Test byte 00B6D 05 DEC B ;Counter - 1 00B6E 20FB JR NZ,0B6BH ;Next byte 00B70 B7 OR A ;All bytes = 00H ? 00B71 210080 LD HL,8000H ;HL = -32768 (INT value) 00B74 CA9A0A JP Z,0A9AH ;Yes: Write HL to X as INT 00B77 79 LD A,C ;A = Exp (X) = 90H (because ;of 0B64H) 00B78 FEB8 CP 0B8H ;Exp >= (2 ^ 56) ? ;(56 bit mantissa) 00B7A D0 RET NC ;Yes: no fractional part 00B7B F5 PUSH AF ;Save Exp 00B7C CDBF09 CALL 09BFH ;BCDE = X (SNG) 00B7F CDDF09 CALL 09DFH ;Adjust mantissas 00B82 AE XOR (HL) ;A, bit 7 = Sign of X or BCDE 00B83 2B DEC HL ;HL -> Exp (X) 00B84 36B8 LD (HL),0B8H ;Set Exp to 2 ^ 56 00B86 F5 PUSH AF ;Save sign ;X negative ? 00B87 FCA00B CALL M,0BA0H ;Yes: round X 00B8A 212341 LD HL,4123H ;HL -> MSB (X) 00B8D 3EB8 LD A,0B8H ;A = Exp for 2 ^ 56 00B8F 90 SUB B ;Compute Exp-difference 00B90 CD690D CALL 0D69H ;(HL) - (HL-7) (corresponds ;with X) and shift A bits to ;the right: shift out the ;fractional part 00B93 F1 POP AF ;Restore sign ;X negative ? 00B94 FC200D CALL M,0D20H ;Yes: round up mantissa of X 00B97 AF XOR A ;A = 00H 00B98 321C41 LD (411CH),A ;Clear LSB-underflow of X 00B9B F1 POP AF ;Restore Exp in A 00B9C D0 RET NC ;Done when CALLed from 12B8H ;(Otherwise C-flag = 1 because ;of 0B7AH) 00B9D C3D80C JP 0CD8H ;Continue at DFLOAT ; Round down mantissa of X (DBL) 00BA0 211D41 LD HL,411DH ;HL -> X 00BA3 7E LD A,(HL) ;A = byte of X 00BA4 35 DEC (HL) ;Round down 00BA5 B7 OR A ;Was the byte 00H ? 00BA6 23 INC HL ;Pointer + 1 00BA7 28FA JR Z,0BA3H ;Yes: next byte 00BA9 C9 RET ; SUB for array size calculation with DIM ; DE = DE * BC 00BAA E5 PUSH HL ;Save PTP 00BAB 210000 LD HL,0000H ;Result = 0000H 00BAE 78 LD A,B ;BC = 0 ? 00BAF B1 OR C 00BB0 2812 JR Z,0BC4H ;Yes: return with result = 0 00BB2 3E10 LD A,10H ;A = counter for 16 bit 00BB4 29 ADD HL,HL ;Shift result to the left ;Overflow ? 00BB5 DA3D27 JP C,273DH ;Yes: ?BS Error 00BB8 EB EX DE,HL ;Save HL 00BB9 29 ADD HL,HL ;Highest bit of DE to C-flag 00BBA EB EX DE,HL ;Restore HL 00BBB 3004 JR NC,0BC1H ;Jump when bit = 0 00BBD 09 ADD HL,BC ;Add BC to result ;Overflow ? 00BBE DA3D27 JP C,273DH ;Yes: ?BS Error 00BC1 3D DEC A ;Counter - 1 00BC2 20F0 JR NZ,0BB4H ;Next bit 00BC4 EB EX DE,HL ;Result in DE 00BC5 E1 POP HL ;Restore PTP 00BC6 C9 RET ; ISUB: X = HL = DE - HL (INT) ; ; I: DE = Original value ; HL = Subtractor ; O: HL = Difference when in INT range ; X = difference (automatic conversion to SNG format when result not ; in INT range) 00BC7 7C LD A,H ;A = MSB of HL 00BC8 17 RLA ;C-flag - sign of HL 00BC9 9F SBC A,A ;If HL >= 0 then A = 00H ; else A = FFH 00BCA 47 LD B,A ;B = A 00BCB CD510C CALL 0C51H ;HL = = HL, C-flag = 1 00BCE 79 LD A,C ;A = 00H (C = 00H by 0C51H) 00BCF 98 SBC A,B ;if HL was >= 0 then A = FFH else A = 00H 00BD0 1803 JR 0BD5H ;Continue at IADD ;(do a DE = DE + (-HL) ; IADD: X = HL = DE + HL (INT) ; ; I: DE = 1st sum argument ; HL = 2nd sum argument ; O: HL = sum when in INT range ; X = sum (automatic conversion to SNG format when result not ; in INT range) 00BD2 7C LD A,H ;Calculate sign-flag 00BD3 17 RLA ;(See ISUB) 00BD4 9F SBC A,A 00BD5 47 LD B,A ;If HL >= 0 then B = 00H ; else B = FFH 00BD6 E5 PUSH HL ;Save 2nd sum argument 00BD7 7A LD A,D ;Calculate sign of 2nd arg. 00BD8 17 RLA 00BD9 9F SBC A,A 00BDA 19 ADD HL,DE ;Perform addition 00BDB 88 ADC A,B ;Process sign-flags and 00BDC 0F RRCA ;overflow 00BDD AC XOR H ;A, bit 7 is set, when an ;overflow occurs in case of ;both are equal or when no ;overflow occurs in case of ;both signs are not equal ;A, bit 7 = 0 ? 00BDE F2990A JP P,0A99H ;Yes: result is ok ;No: 00BE1 C5 PUSH BC ;Save sign flag of 2nd arg. 00BE2 EB EX DE,HL ;HL = 1st sum argument 00BE3 CDCF0A CALL 0ACFH ;X = CSNG (HL) 00BE6 F1 POP AF ;Restore sign flag 00BE7 E1 POP HL ;Restore 2nd sum argument 00BE8 CDA409 CALL 09A4H ;(SP) = X = 1st argument 00BEB EB EX DE,HL ;DE = 2nd argument 00BEC CD6B0C CALL 0C6BH ;X = SFLOAT (DE) 00BEF C38F0F JP 0F8FH ;X = X + (SP) (addition in ;SNG format) ; IMUL: X = HL = DE * HL (INT) ; ; I: DE = multiplicant ; HL = multiplicator (both values in INT format) ; O: HL = product when in INT range ; X = product (automatic conversion to SNG format when result not ; in INT range) 00BF2 7C LD A,H ;HL = 0000H ? 00BF3 B5 OR L 00BF4 CA9A0A JP Z,0A9AH ;Yes: Result = 0 00BF7 E5 PUSH HL ;Save multiplicator 00BF8 D5 PUSH DE ;Save multiplicant 00BF9 CD450C CALL 0C45H ;Clear sign, make both numbers ;positive 00BFC C5 PUSH BC ;Save sign flag (B, bit 7 = 0 ;in case both signs are equal) 00BFD 44 LD B,H ;BC = HL 00BFE 4D LD C,L 00BFF 210000 LD HL,0000H ;Result = 0 00C02 3E10 LD A,10H ;A = counter for 16 bits 00C04 29 ADD HL,HL ;Shift result to the left ;Overflow ? 00C05 381F JR C,0C26H ;Yes: continue at 0C26H 00C07 EB EX DE,HL ;Next bit form De to C-flag 00C08 29 ADD HL,HL 00C09 EB EX DE,HL 00C0A 3004 JR NC,0C10H ;Jump if bit not set 00C0C 09 ADD HL,BC ;Add BC to result if bit set ;Overflow ? 00C0D DA260C JP C,0C26H ;Yes: continue at 0C26H 00C10 3D DEC A ;Counter - 1 00C11 20F1 JR NZ,0C04H ;Next bit 00C13 C1 POP BC ;Restore sign flag 00C14 D1 POP DE ;Restore multiplicant 00C15 7C LD A,H ;Result negative ? 00C16 B7 OR A 00C17 FA1F0C JP M,0C1FH ;Yes: continue at 0C1FH 00C1A D1 POP DE ;Restore multiplicator 00C1B 78 LD A,B ;A = sign-flag 00C1C C34D0C JP 0C4DH ;Set sign of result ; Overflow into bit 15 (sign bit) ; Because both factors were made positive, the result must also be positive. ; This means that the 16th bit must be 0. 00C1F EE80 XOR 80H ;A = 00H when H = 80H 00C21 B5 OR L ;HL = 8000 = 32768 ? ;(no sign) 00C22 2813 JR Z,0C37H ;Yes: continue at 0C37H ;No: 00C24 EB EX DE,HL ;HL = multiplicant 00C25 01C1E1 LD BC,0E1C1H ;-- ; Overflow at IMUL ; Convert both factors to SNG format and then perform a SMUL * 00C26 C1 POP BC ;B = sign-flag * 00C27 E1 POP HL ;HL = Multiplicant 00C28 CDCF0A CALL 0ACFH ;X = CSNG (HL) 00C2B E1 POP HL ;HL = Multiplicator 00C2C CDA409 CALL 09A4H ;(SP) = X 00C2F CDCF0A CALL 0ACFH ;X = CSNG (HL) 00C32 C1 POP BC ;BCDE = (SP) 00C33 D1 POP DE 00C34 C34708 JP 0847H ;X = BCDE * X (SNG) ; The result is 32768 (unsigned) 00C37 78 LD A,B ;A = sign-flag 00C38 B7 OR A ;Signs not equal ? 00C39 C1 POP BC ;Correct stack 00C3A FA9A0A JP M,0A9AH ;Yes: result = 8000H = -32768 ;No: result = +32768 00C3D D5 PUSH DE ;Save DE 00C3E CDCF0A CALL 0ACFH ;X = CSNG (HL) = -32768 00C41 D1 POP DE ;Restore DE 00C42 C38209 JP 0982H ;X = -X (result = +32768) ; Sign test at IMUL: ; Clear sign at DE and HL (make both positive) ; ; I: DE = multiplicant ; HL = multiplicator ; O: DE = ABS (multiplicator) ; HL = ABS (multiplicant) ; If both signs are equal then B, bit 7 = 0 ; else B, bit 7 = 1 00C45 7C LD A,H ;Sign from HL 00C46 AA XOR D ;XORed with sign from D 00C47 47 LD B,A ;Result in B, bit 7 00C48 CD4C0C CALL 0C4CH ;HL = ABS (HL) 00C4B EB EX DE,HL ;Same with DE 00C4C 7C LD A,H ;HL >= 0 ? 00C4D B7 OR A 00C4E F29A0A JP P,0A9AH ;Yes: ok ; X = HL = -HL (INT) ; ; I: HL = INT value ; O: HL = negative INT value ; X = HL and VT = INT 00C51 AF XOR A ;A = 00H 00C52 4F LD C,A ;C = 00H 00C53 95 SUB L 00C54 6F LD L,A ;L = 00H - L 00C55 79 LD A,C ;A = 00H 00C56 9C SBC A,H 00C57 67 LD H,A ;H = 00H - H - C-flag 00C58 C39A0A JP 0A9AH ;Write HL to X as INT ; X = -X (INT) ; Conversion to SNG, when X = -32768. This because +32768 is no longer ; in the INT range. 00C5B 2A2141 LD HL,(4121H) ;HL = X 00C5E CD510C CALL 0C51H ;X = HL = -HL 00C61 7C LD A,H ;HL used to be -32768 ? 00C62 EE80 XOR 80H 00C64 B5 OR L 00C65 C0 RET NZ ;No : value ok 00C66 EB EX DE,HL ;DE = value 00C67 CDEF0A CALL 0AEFH ;VT = SNG 00C6A AF XOR A ;A = 0 00C6B 0698 LD B,98H ;B = Exp (2 ^ 24) 00C6D C36909 JP 0969H ;SFLOAT (X) ; X = X - Y = X + (-Y) (DBL) 00C70 212D41 LD HL,412DH ;HL -> MSB (Y) 00C73 7E LD A,(HL) ;A = MSB (Y) 00C74 EE80 XOR 80H ;Y = -Y 00C76 77 LD (HL),A ;Store MSB (Y) ; X = X + Y (DBL) 00C77 212E41 LD HL,412EH ;HL -> Exp (Y) 00C7A 7E LD A,(HL) ;A = Exp (Y) 00C7B B7 OR A ;Exp (Y) = 0 ? 00C7C C8 RET Z ;Yes: X is the result 00C7D 47 LD B,A ;B = Exp (Y) 00C7E 2B DEC HL HL -> MSB (Y) 00C7F 4E LD C,(HL) ;C = MSB (Y) 00C80 112441 LD DE,4124H ;DE -> Exp (X) 00C83 1A LD A,(DE) ;A = Exp (X) 00C84 B7 OR A ;X = 0 ? (Exp (X) = 0) 00C85 CAF409 JP Z,09F4H ;Yes: X = Y 00C88 90 SUB B ;A = Exp (X) - Exp (Y) ;Exp (X) >= Exp (Y) 00C89 3016 JR NC,0CA1H ;Yes: continue at 0CA1H ;No: swap X and Y 00C8B 2F CPL ;A = -A 00C8C 3C INC A ;A + 1 for 2 complement 00C8D F5 PUSH AF ;Save Exp-difference 00C8E 0E08 LD C,08H ;Swap 8 bytes 00C90 23 INC HL ;HL -> Exp (Y) 00C91 E5 PUSH HL ;Save pointer 00C92 1A LD A,(DE) ;Swap bytes from (DE) 00C93 46 LD B,(HL) ;and (HL) 00C94 77 LD (HL),A 00C95 78 LD A,B 00C96 12 LD (DE),A 00C97 1B DEC DE ;Pointer - 1 00C98 2B DEC HL ;Pointer - 1 00C99 0D DEC C ;Counter - 1 00C9A 20F6 JR NZ,0C92H ;Next byte 00C9C E1 POP HL ;Restore pointer on Exp (X) 00C9D 46 LD B,(HL) ;B = Exp (X) 00C9E 2B DEC HL 00C9F 4E LD C,(HL) ;C = MSB (X) 00CA0 F1 POP AF ;Restore Exp-difference ;In X now the larger argument 00CA1 FE39 CP 39H ;Exp-diff. > (2 ^ 56) 00CA3 D0 RET NC ;Yes: Y is too small, the sum ;would not alter X 00CA4 F5 PUSH AF ;Save Exp-difference 00CA5 CDDF09 CALL 09DFH ;Adjust mantissas 00CA8 23 INC HL ;HL -> Exp (X) 00CA9 3600 LD (HL),00H ;Set Exp to 0 00CAB 47 LD B,A ;B = sign-flag 00CAC F1 POP AF ;Restore Exp-difference 00CAD 212D41 LD HL,412DH ;HL -> Y 00CB0 CD690D CALL 0D69H ;Shift (HL) upto (HL-7) A bits ;to the right. This results ;in the same exponent for ;X and Y 00CB3 3A2641 LD A,(4126H) ;Copy underflow 00CB6 321C41 LD (411CH),A ;to X 00CB9 78 LD A,B ;A = sign-flag 00CBA B7 OR A ;Equal signs ? 00CBB F2CF0C JP P,0CCFH ;No: continue at 0CCFH 00CBE CD330D CALL 0D33H ;Add mantissas ;Overflow ? 00CC1 D20E0D JP NC,0D0EH ;No: continue at 0D0EH 00CC4 EB EX DE,HL ;Overflow: HL -> Exp (X) 00CC5 34 INC (HL) ;Exp (X) + 1 ;Overflow ? 00CC6 CAB207 JP Z,07B2H ;Yes: ?OV Error 00CC9 CD900D CALL 0D90H ;X = X / 2, because the Exp + 1 ;means an X * 2 00CCC C30E0D JP 0D0EH ;Continue at 0D0EH ; Unequal signs: subtract mantissas 00CCF CD450D CALL 0D45H ;Subtract mantissas 00CD2 212541 LD HL,4125H ;HL -> sign-flag ;Onderflow ? 00CD5 DC570D CALL C,0D57H ;Yes: negate mantissa of X ; DFLOAT (DBL) ; Shift DBL-mantissa to the left until the highest bit of the mantissa ; is 1 and the exponent is as small as possible 00CD8 AF XOR A ;A = 00H 00CD9 47 LD B,A ;B = shift-counter 00CDA 3A2341 LD A,(4123H) ;A = MSB (X) 00CDD B7 OR A ;MSB = 0 ? 00CDE 201E JR NZ,0CFEH ;No: test bits of MSB ;Yes: Shift X by 1 byte to the ;left 00CE0 211C41 LD HL,411CH ;HL -> underflow (X) 00CE3 0E08 LD C,08H ;C = counter for 8 bytes 00CE5 56 LD D,(HL) ;Get new byte 00CE6 77 LD (HL),A ;Use old byte 00CE7 7A LD A,D ;old byte = new byte 00CE8 23 INC HL ;Pointer + 1 00CE9 0D DEC C ;Counter - 1 00CEA 20F9 JR NZ,0CE5H ;Next byte 00CEC 78 LD A,B ;A = shift-counter 00CED D608 SUB 08H ;Subtract 8 (for 8 bits) 00CEF FEC0 CP 0C0H ;-64 reached ? (already 8 ;bytes shifted ?) 00CF1 20E6 JR NZ,0CD9H ;No: test MSB again 00CF3 C37807 JP 0778H ;Yes: all bytes of X were 00H ;Set X = 0 ; Continue shifting bitwise 00CF6 05 DEC B ;Shift-counter - 1 00CF7 211C41 LD HL,411CH ;HL -> Underflow (X) 00CFA CD970D CALL 0D97H ;Shift X by 1 bit to the left 00CFD B7 OR A ;A = new MSB, bit 7 = 1 ? 00CFE F2F60C JP P,0CF6H ;No: shift again 00D01 78 LD A,B ;A = shift-counter 00D02 B7 OR A ;Anything shifted ? 00D03 2809 JR Z,0D0EH ;No: X ready 00D05 212441 LD HL,4124H ;HL -> Exp (X) 00D08 86 ADD A,(HL) ;Subtract number of shifted 00D09 77 LD (HL),A ;bits from exponent ;Overflow ? 00D0A D27807 JP NC,0778H ;No: X = 0 00D0D C8 RET Z ;Done when exponent = 0 00D0E 3A1C41 LD A,(411CH) ;A = underflow byte 00D11 B7 OR A ;A, bit 7 = 1 00D12 FC200D CALL M,0D20H ;Yes: round up X 00D15 212541 LD HL,4125H ;HL -> sign-flag 00D18 7E LD A,(HL) ;A = sign-flag 00D19 E680 AND 80H ;Mask sign. A, bit 7 = 1 when ;equal sign 00D1B 2B DEC HL 00D1C 2B DEC HL ;HL -> MSB (X) 00D1D AE XOR (HL) ;XOR with MSB (X) 00D1E 77 LD (HL),A ;Save new MSB incl. sign 00D1F C9 RET ; Round up X (DBL) 00D20 211D41 LD HL,411DH ;HL -> LSB of X (DBL) 00D23 0607 LD B,07H ;B = mantissa size of DBL 00D25 34 INC (HL) ;Increment LSB ;Overflow ? 00D26 C0 RET NZ ;No: return 00D27 23 INC HL ;Next byte 00D28 05 DEC B ;Counter - 1 ;All mantissa bytes done ? 00D29 20FA JR NZ,0D25H ;No: increment next mantissa ;byte 00D2B 34 INC (HL) ;Increment Exp (X) ;Overflow ? 00D2C CAB207 JP Z,07B2H ;Yes: ?OV Error 00D2F 2B DEC HL ;HL -> MSB mantissa 00D30 3680 LD (HL),80H ;Set mantissa to negative 00D32 C9 RET ; Add mantissas of X and Y. Result in X 00D33 212741 LD HL,4127H ;HL -> LSB of Y (DBL) 00D36 111D41 LD DE,411DH ;DE -> LSB of X (DBL) 00D39 0E07 LD C,07H ;C = mantissa size of DBL 00D3B AF XOR A ;A = 0 00D3C 1A LD A,(DE) ;A = mantissa byte X 00D3D 8E ADC A,(HL) ;A = A + mantissa byte Y ; + C-flag 00D3E 12 LD (DE),A ;Store result in X 00D3F 13 INC DE ;Pointer to X + 1 00D40 23 INC HL ;Pointer to Y + 1 00D41 0D DEC C ;Counter - 1 ;All mantissa bytes done ? 00D42 20F8 JR NZ,0D3CH ;No, add next mantissa bytes 00D44 C9 RET ; Subtract mantissas of X and Y. Result in X 00D45 212741 LD HL,4127H ;HL -> LSB of Y (DBL) 00D48 111D41 LD DE,411DH ;DE -> LSB of X (DBL) 00D4B 0E07 LD C,07H ;C = mantissa size of DBL 00D4D AF XOR A ;A = 0 00D4E 1A LD A,(DE) ;A = mantissa byte X 00D4F 9E SBC A,(HL) ;A = A - mantissa byte Y ; - C-flag 00D50 12 LD (DE),A ;Store result in X 00D51 13 INC DE ;Pointer to X + 1 00D52 23 INC HL ;Pointer to Y + 1 00D53 0D DEC C ;Counter - 1 ;All mantissa bytes done ? 00D54 20F8 JR NZ,0D4EH ;No, add next mantissa bytes 00D56 C9 RET ; Negate mantissa of X (incl. underflow) and sign 00D57 7E LD A,(HL) ;A = sign-flag 00D58 2F CPL ;Negation 00D59 77 LD (HL),A ;Save sign-flag 00D5A 211C41 LD HL,411CH ;HL -> underflow (X) 00D5D 0608 LD B,08H ;Negate 9 bytes 00D5F AF XOR A ;A = 00H 00D60 4F LD C,A ;C = 00H 00D61 79 LD A,C ;A = C 00D62 9E SBC A,(HL) ;A = A - (HL) - C-flag 00D63 77 LD (HL),A ;Save difference 00D64 23 INC HL ;Pointer + 1 00D65 05 DEC B ;Counter - 1 00D66 20F9 JR NZ,0D61H ;Next byte 00D68 C9 RET ; Shift (HL) upto (HL-7) by A bits to the right 00D69 71 LD (HL),C ;Save MSB 00D6A E5 PUSH HL ;Save pointer 00D6B D608 SUB 08H ;More then 8 bits to shift ? 00D6D 380E JR C,0D7DH ;No: shift bits at 0D7DH 00D6F E1 POP HL ;Restore pointer 00D70 E5 PUSH HL ;And save it again 00D71 110008 LD DE,0800H ;Fill 8 bytes mantissa with 00H 00D74 4E LD C,(HL) ;C = new byte 00D75 73 LD (HL),E ;(HL) = old byte 00D76 59 LD E,C ;Old byte = new byte 00D77 2B DEC HL ;Pointer - 1 00D78 15 DEC D ;Counter - 1 00D79 20F9 JR NZ,0D74H ;Shift next byte 00D7B 18EE JR 0D6BH ;Shift anything more ? ; Shift bitwise 00D7D C609 ADD A,09H ;Reverse the SUB 08H 00D7F 57 LD D,A ;D = counter 00D80 AF XOR A ;A = 00H 00D81 E1 POP HL ;Restore pointer 00D82 15 DEC D ;Counter - 1 00D83 C8 RET Z ;RET when done 00D84 E5 PUSH HL ;Save pointer 00D85 1E08 LD E,08H ;8 bytes mantissa ;(with underflow) 00D87 7E LD A,(HL) ;A = byte 00D88 1F RRA ;shift right (incl. C-flag) 00D89 77 LD (HL),A ;Save byte 00D8A 2B DEC HL ;Pointer - 1 00D8B 1D DEC E ;Counter - 1 00D8C 20F9 JR NZ,0D87H ;Next byte 00D8E 18F0 JR 0D80H ;Any more to shift ? ; Shift mantissa of X one bit to the right 00D90 212341 LD HL,4123H ;HL -> mantissa 00D93 1601 LD D,01H ;D = counter for 1 bit 00D95 18ED JR 0D84H ;Continue at 0D84H ; Shift (HL) to (HL+7) one bit to the right 00D97 0E08 LD C,08H ;8 bits Mantissa (with ;underflow) 00D99 7E LD A,(HL) ;A = byte 00D9A 17 RLA ;shift incl. carry 00D9B 77 LD (HL),A ;Store byte 00D9C 23 INC HL ;Pointer + 1 00D9D 0D DEC C ;Counter - 1 00D9E 20F9 JR NZ,0D99H ;Shift next byte 00DA0 C9 RET ; DMUL: X = X * Y (DBL) ; ; I: X = 1st factor (DBL) ; Y = 2nd factor (DBL) ; O: X = product (DBL) 00DA1 CD5509 CALL 0955H ;TEST2 ;X = 0 ? 00DA4 C8 RET Z ;Yes: return 00DA5 CD0A09 CALL 090AH ;process exponent and sign 00DA8 CD390E CALL 0E39H ;Save mantissa of 1st factor in ;414AH and clear mantissa of X 00DAB 71 LD (HL),C ;Underflow of X = 0 00DAC 13 INC DE ;DE -> LSB of 1st factor 00DAD 0607 LD B,07H ;Process 7 bytes mantissa 00DAF 1A LD A,(DE) ;A = byte from mantissa 00DB0 13 INC DE ;Pointer + 1 00DB1 B7 OR A ;No bit set ? 00DB2 D5 PUSH DE ;Save pointer 00DB3 2817 JR Z,0DCCH ;Yes: shift X 1 byte to the ;right and get next byte from ;1st factor 00DB5 0E08 LD C,08H ;8 bits per byte 00DB7 C5 PUSH BC ;Save counter 00DB8 1F RRA ;Test next bit ;Bit = 1 ? 00DB9 47 LD B,A ;Save byte first 00DBA DC330D CALL C,0D33H ;Yes: add mantissa of X and Y 00DBD CD900D CALL 0D90H ;Shift mantissa of X one bit ;to the right (next position) 00DC0 78 LD A,B ;Restore byte 00DC1 C1 POP BC ;Restore counter 00DC2 0D DEC C ;Bit counter - 1 00DC3 20F2 JR NZ,0DB7H ;Test next bit 00DC5 D1 POP DE ;Restore pointer 00DC6 05 DEC B ;Byte counter - 1 00DC7 20E6 JR NZ,0DAFH ;Test next byte 00DC9 C3D80C JP 0CD8H ;Continue at DFLOAT ; Shift mantissa of X one byte to the right 00DCC 212341 LD HL,4123H ;HL -> mantissa of X 00DCF CD700D CALL 0D70H ;Shift one byte to the right 00DD2 18F1 JR 0DC5H ;Back to DMUL ; Constant 10 (DBL, SNG) 00DD4 00 DEFB 00H ;Constant 10 (DBL) 00DD5 00 DEFB 00H 00DD6 00 DEFB 00H 00DD7 00 DEFB 00H 00DD8 00 DEFB 00H ;Constant 10 (SNG) 00DD9 00 DEFB 00H 00DDA 20 DEFB 20H 00DDB 84 DEFB 84H ; X = X / 10 (DBL) 00DDC 11D40D LD DE,0DD4H ;DE -> Constant 10 (DBL) 00DDF 212741 LD HL,4127H ;HL -> Y 00DE2 CDD309 CALL 09D3H ;Copy (DE) to (HL): Y = 10 ; DDIV: X = X / Y (DBL) ; ; I: X = dividend (DBL) ; Y = divisor (DBL) ; O: X = quotient 00DE5 3A2E41 LD A,(412EH) ;A = Exp (X) 00DE8 B7 OR A ;zero ? 00DE9 CA9A19 JP Z,199AH ;Yes: ?/0 Error 00DEC CD0709 CALL 0907H ;Process exponent and sign 00DEF 34 INC (HL) ;Adjust exponent 00DF0 34 INC (HL) ;(see also SDIV) 00DF1 CD390E CALL 0E39H ;Save dividend and set mantissa ;of X to 0 00DF4 215141 LD HL,4151H ;HL -> underflow of dividend 00DF7 71 LD (HL),C ;Clear underflow byte 00DF8 41 LD B,C ;Unterflow flag = 0 00DF9 114A41 LD DE,414AH ;DE -> LSB of dividend 00DFC 212741 LD HL,4127H ;HL -> LSB of divisor 00DFF CD4B0D CALL 0D4BH ;Subtract mantissas 00E02 1A LD A,(DE) ;A = undeflow byte 00E03 99 SBC A,C ;A = A - C-flag (C-flag = 0) 00E04 3F CCF ;Invert C-flag ;Underflow ? 00E05 380B JR C,0E12H ;No: continue at 0E12H ;Yes: reverse last subtract 00E07 114A41 LD DE,414AH ;DE -> LSB of dividend 00E0A 212741 LD HL,4127H ;HL -> LSB of divisor 00E0D CD390D CALL 0D39H ;Add mantissas 00E10 AF XOR A ;C-flag = 0 00E11 DA1204 JP C,0412H ;-- * 00E12 12 LD (DE),A ;No underflow: write back ;undeflow byte * 00E13 04 INC B ;Underflow flag = 1 00E14 3A2341 LD A,(4123H) ;A = MSB of quotient 00E17 3C INC A 00E18 3D DEC A 00E19 1F RRA ;Shift bit 7 of A to C-flag ;for rounding purposes 00E1A FA110D JP M,0D11H ;Done when highest bit = 1 00E1D 17 RLA ;Shift back bit 7 of A 00E1E 211D41 LD HL,411DH ;HL -> LSB of quotient 00E21 0E07 LD C,07H ;7 bytes mantissa 00E23 CD990D CALL 0D99H ;Shift quotient one bit to the ;left 00E26 214A41 LD HL,414AH ;HL -> LSB of dividend 00E29 CD970D CALL 0D97H ;Shift dividend one bit to the ;left 00E2C 78 LD A,B ;A = underflow byte 00E2D B7 OR A ;Underflow occured ? 00E2E 20C9 JR NZ,0DF9H ;No: process next bit ;Yes: 00E30 212441 LD HL,4124H ;HL -> Exp (quotient) 00E33 35 DEC (HL) ;Quotient = Quotient / 2 ;Exp = 0 ? 00E34 20C3 JR NZ,0DF9H ;No: process next bit ;Yes: 00E36 C3B207 JP 07B2H ;?OV Error ; SUB for DDIV ; Save mantissa of X to 414AH to 4150H and set as result X to zero 00E39 79 LD A,C ;A = MSB (Y) 00E3A 322D41 LD (412DH),A ;Write back MSB (Y) 00E3D 2B DEC HL ;HL -> MSB (X) 00E3E 115041 LD DE,4150H ;DE -> temp. memory space 00E41 010007 LD BC,0700H ;Copy 7 bytes, set to 00H 00E44 7E LD A,(HL) ;A = byte from X 00E45 12 LD (DE),A ;Save it in (DE) 00E46 71 LD (HL),C ;Clear mantissa of X 00E47 1B DEC DE ;Pointer to temp. - 1 00E48 2B DEC HL ;Pointer to X - 1 00E49 05 DEC B ;Counter - 1 00E4A 20F8 JR NZ,0E44H ;Next byte 00E4C C9 RET ; X = X * 10 (DBL) 00E4D CDFC09 CALL 09FCH ;Y = X 00E50 EB EX DE,HL ;HL + 1 -> Exp (X) 00E51 2B DEC HL ;HL -> Exp (X) 00E52 7E LD A,(HL) ;A = Exp (X) 00E53 B7 OR A ;X = 0 ? 00E54 C8 RET Z ;Yes: done, return 00E55 C602 ADD A,02H ;A = Exp(X) + 2 ;Overflow ? 00E57 DAB207 JP C,07B2H ;Yes: ?OV Error 00E5A 77 LD (HL),A ;Store Exp: X = X * 4 00E5B E5 PUSH HL ;Save pointer 00E5C CD770C CALL 0C77H ;X = X + Y (now: X = X * 5) 00E5F E1 POP HL ;Restore pointer 00E60 34 INC (HL) ;Exp + 1: X = X * 2 ;(results in X = X * 10) 00E61 C0 RET NZ ;Return if no overflow 00E62 C3B207 JP 07B2H ;?OV Error ; Convert string to number (DBL) ; (like VAL function) ; ; I: HL -> string ; O: X = number (DBL) 00E65 CD7807 CALL 0778H ;X = 0 00E68 CDEC0A CALL 0AECH ;set VT to DBL 00E6B F6AF OR 0AFH ;Set flag <> 0 ; Convert string in a number according to type (INT, SNG, DBL) ; (like VAL function) ; ; I: HL -> string ; O: X = number * 00E6C AF XOR A ;Set flag = 0 ;First, the routine will ;attempt to convert to an INT. ;In case of overflow, it will ;attempt to convert to SNG or ;to DBL 00E6D EB EX DE,HL ;DE -> string 00E6E 01FF00 LD BC,00FFH ;B = 00 (number of positions ;after the decimal point) ;C = FFH (floating point flag: ;see 0EE4H and 0F29H) 00E71 60 LD H,B ;HL = 0000H 00E72 68 LD L,B ;(HL is initial value) 00E73 CC9A0A CALL Z,0A9AH ;Write HL to X as INT 00E76 EB EX DE,HL ;HL = pointer, DE = 0000H 00E77 7E LD A,(HL) ;A = string character 00E78 FE2D CP '-' ;Test for negative sign ;(Negative: Z-flag = 1) 00E7A F5 PUSH AF ;Save sign ;Negative sign ? 00E7B CA830E JP Z,0E83H ;Yes: continue at 0E83H 00E7E FE2B CP '+' ;Positive sign ? 00E80 2801 JR Z,0E83H ;Yes: continue at 0E83H 00E82 2B DEC HL ;Pointer - 1 for RST 10H 00E83 D7 RST 10H ;A = next non-space character ;Digit ? 00E84 DA290F JP C,0F29H ;Yes: continue at 0F29H 00E87 FE2E CP '.' ;'.' ? 00E89 CAE40E JP Z,0EE4H Yes: continue at 0EE4H 00E8C FE45 CP 'E' ;'E' ? 00E8E 2814 JR Z,0EA4H ;Yes: continue at 0EA4H 00E90 FE25 CP '%' ;'%' ? (INT indicator) 00E92 CAEE0E JP Z,0EEEH ;Yes: continue at 0EEEH 00E95 FE23 CP '#' ;'#' ? (DBL indicator) 00E97 CAF50E JP Z,0EF5H ;Yes: continue at 0EF5H 00E9A FE21 CP '!' ;'!' ? (SNG indicator) 00E9C CAF60E JP Z,0EF6H ;Yes: continue at 0EF6H 00E9F FE44 CP 'D' ;'D' ? 00EA1 2024 JR NZ,0EC7H ;No: No digit or special ;character recognized: ;end of number string reached 00EA3 B7 OR A ;Yes: Set Z-flag = 0 ; 'E' (Z-flag = 1) or 'D' (Z-flag = 0) 00EA4 CDFB0E CALL 0EFBH ;Convert X to SNG (Z-flag = 1) ;or DBL (Z-flag = 0) 00EA7 E5 PUSH HL ;Save pointer 00EA8 21BD0E LD HL,0EBDH ;Set new RET address to 0EBDH 00EAB E3 EX (SP),HL ;and restore pointer 00EAC D7 RST 10H ;A = next character following ;'D' or 'E' 00EAD 15 DEC D ;D = FFH (-1) 00EAE FECE CP 0CEH ;'-' (BASIC token) ? 00EB0 C8 RET Z ;Yes: continue at 0EBDH 00EB1 FE2D CP '-' ;'-' ? 00EB3 C8 RET Z ;Yes: continue at 0EBDH 00EB4 14 INC D ;D = 00H (0) 00EB5 FECD CP 0CDH ;'+' (BASIC token) ? 00EB7 C8 RET Z ;Yes: continue at 0EBDH 00EB8 FE2B CP '+' ;'+' ? 00EBA C8 RET Z ;Yes: continue at 0EBDH 00EBB 2B DEC HL ;Pointer - 1 (for RST 10H) 00EBC F1 POP AF ;Remove RET address (0EBDH) 00EBD D7 RST 10H ;A = Exponent character ;Digit found ? 00EBE DA940F JP C,0F94H ;yes: continue at 0F94H ;No: exponent finished 00EC1 14 INC D ;Exponent negative ? (D was FFH) 00EC2 2003 JR NZ,0EC7H ;No: continue at 0EC7H ;Yes: 00EC4 AF XOR A ;Negate exponent 00EC5 93 SUB E ;A = 00H - E 00EC6 5F LD E,A ;E = correct exponent ; Number in X is ready: process exponent / floating point / sign 00EC7 E5 PUSH HL ;Save pointer 00EC8 7B LD A,E ;A = exponent 00EC9 90 SUB B ;A = difference between ;exponent and number of ;positions after the decimal ;point. ;Larger than exponent ? 00ECA F40A0F CALL P,0F0AH ;Yes: multiply X with 10 00ECD FC180F CALL M,0F18H ;No: divide X by 10 and ;difference + 1 ;Difference = 0 ? 00ED0 20F8 JR NZ,0ECAH ;No: continue processing 00ED2 E1 POP HL ;Restore pointer 00ED3 F1 POP AF ;Restore sign 00ED4 E5 PUSH HL ;Save pointer ;Negative sign ? 00ED5 CC7B09 CALL Z,097BH ;Yes: X = -X 00ED8 E1 POP HL ;Restore pointer 00ED9 E7 RST 20H ;TSTTYP ;DBL type ? 00EDA E8 RET PE ;Yes : return 00EDB E5 PUSH HL ;Save pointer 00EDC 219008 LD HL,0890H ;Set RET address to POP HL 00EDF E5 PUSH HL ;(to restore pointer) 00EE0 CDA30A CALL 0AA3H ;X = -32768 ? ;Yes: convert X to INT 00EE3 C9 RET ;RET and restore pointer ; '.' found 00EE4 E7 RST 20H ;TSTTYP 00EE5 0C INC C ;If point found for the first ;time then C = 00H else C > 00H ;Number done (C > 0) ? 00EE6 20DF JR NZ,0EC7H ;Yes: continue at 0EC7H ;X in INT format ? 00EE8 DCFB0E CALL C,0EFBH ;Yes: convert to SNG 00EEB C3830E JP 0E83H ;Get next character ; '%' (INT indicator) found 00EEE E7 RST 20H ;TSTTYP ;INT type ? 00EEF F29719 JP P,1997H ;No: ?SN Error 00EF2 23 INC HL ;Pointer + 1 00EF3 18D2 JR 0EC7H ;Number is ready ; '#' (DBL indicator) found 00EF5 B7 OR A ;Z-flag = 0 ; '!' (SNG indicator) found 00EF6 CDFB0E CALL 0EFBH ;Convert number to SNG ;(Z-flag=1) or DBL (Z-flag=0) 00EF9 18F7 JR 0EF2H ;Pointer + 1, number is ready ; Conversion into SNG or DBL ; ; I: Z-flag = 1: X = CSNG ( X ) ; Z-flag = 0: X = CDBL ( X ) ; O: - 00EFB E5 PUSH HL ;Save registers 00EFC D5 PUSH DE 00EFD C5 PUSH BC 00EFE F5 PUSH AF ;Convert to SNG ? 00EFF CCB10A CALL Z,0AB1H ;Yes: CSNG 00F02 F1 POP AF ;Restore flags ;Convert to DBL ? 00F03 C4DB0A CALL NZ,0ADBH ;Yes: CDBL 00F06 C1 POP BC ;Restore registers 00F07 D1 POP DE 00F08 E1 POP HL 00F09 C9 RET ; X = X * 10 (SNG,DBL) ; Type conform multiplication with 10 of X ; Used at processing of the exponent and fractional part ; ; I: X = number (SNG or DBL format) ; O: X = X * 10 ; A = A - 1 (for exponent and fractional part processing) ;Difference between exponent ;and fractional part = 0 ? ;(Z-flag = 1) 00F0A C8 RET Z ;Yes: done, return 00F0B F5 PUSH AF ;Save difference 00F0C E7 RST 20H ;TSTTYP 00F0D F5 PUSH AF ;Save flags ;SNG type ? 00F0E E43E09 CALL PO,093EH ;Yes: X = X * 10 (SNG) 00F11 F1 POP AF ;Restore flags ;DBL type ? 00F12 EC4D0E CALL PE,0E4DH ;Yes: X = X * 10 (DBL) 00F15 F1 POP AF ;Restore difference 00F16 3D DEC A ;Difference - 1 00F17 C9 RET ; X = X / 10 (SNG,DBL) ; Type conform division by 10 of X ; ; I: X = number (SNG or DBL format) ; O: X = X / 10 ; A = A + 1 (for exponent and fractional part processing) 00F18 D5 PUSH DE ;Save registers 00F19 E5 PUSH HL 00F1A F5 PUSH AF 00F1B E7 RST 20H ;TSTTYP 00F1C F5 PUSH AF ;Save flags ;SNG type ? 00F1D E49708 CALL PO,0897H ;Yes: X = X / 10 (SNG) 00F20 F1 POP AF ;Restore flags ;DBL type ? 00F21 ECDC0D CALL PE,0DDCH ;Yes: X = X / 10 (DBL) 00F24 F1 POP AF ;Restore registers 00F25 E1 POP HL 00F26 D1 POP DE 00F27 3C INC A ;Difference + 1 00F28 C9 RET ; Process digit (C-flag = 1 because of previous RST 10H) 00F29 D5 PUSH DE ;Save exponent flags 00F2A 78 LD A,B ;A = number of fractional ;positions 00F2B 89 ADC A,C ;C = FFH ;If no fractional part ;recognized then ;C = FFH + C-flag (1), so A ;remains the same else ;C = 00H + C-flag (1) = 1, so ;the number of positions behind ;the decimal pointer is ;incremented by one 00F2C 47 LD B,A ;Result in B 00F2D C5 PUSH BC ;Save BC 00F2E E5 PUSH HL ;Save pointer 00F2F 7E LD A,(HL) ;A = digit (ASCII: '0' to '9') 00F30 D630 SUB 30H ;A = value (numerical: 0 to 9) 00F32 F5 PUSH AF ;Save digit 00F33 E7 RST 20H ;TSTTYP ;X still INT type ? 00F34 F25D0F JP P,0F5DH ;No: continue at 0F5DH ; Insert new digit into INT number 00F37 2A2141 LD HL,(4121H) ;HL -> X (INT number) 00F3A 11CD0C LD DE,0CCDH ;DE = 3277 (approx. 32767/10) 00F3D DF RST 18H ;Current number already larger ;than 3277 ? 00F3E 3019 JR NC,0F59H ;Yes, inserting the new digit ;will cause the number to ;go outside of the INT range: ;the number has to be ;converted to SNG 00F40 54 LD D,H ;DE = number 00F41 5D LD E,L 00F42 29 ADD HL,HL ;HL = HL * 2 = number * 2 00F43 29 ADD HL,HL ;HL = HL * 2 = number * 4 00F44 19 ADD HL,DE ;HL = HL + DE = number * 5 00F45 29 ADD HL,HL ;HL = HL * 2 = number * 10 00F46 F1 POP AF ;Restore digit value 00F47 4F LD C,A ;BC = digit value ;(B = fractional part = 0, ;because the number is INT) 00F48 09 ADD HL,BC ;HL = number + new digit value 00F49 7C LD A,H ;New number > 32767 00F4A B7 OR A 00F4B FA570F JP M,0F57H ;Yes: convert number to SNG 00F4E 222141 LD (4121H),HL ;X = HL = new number 00F51 E1 POP HL ;Restore pointer 00F52 C1 POP BC ;Restore decimal point 00F53 D1 POP DE ;Restore exponent flag 00F54 C3830E JP 0E83H ;Get next digit ; Overflow of INT 00F57 79 LD A,C ;A = digit value 00F58 F5 PUSH AF ;Save it 00F59 CDCC0A CALL 0ACCH ;X = CSNG ( X ) 00F5C 37 SCF ;Set C-flag to 1 for indicate ;SNG processing ; Insert new digit into SNG (C-flag = 1) or DBL (c-flag = 0) number ;DBL ? 00F5D 3018 JR NC,0F77H ;Yes: continue at 0F77H 00F5F 017494 LD BC,9474H ;BCDE = 1E+6 00F62 110024 LD DE,2400H 00F65 CD0C0A CALL 0A0CH ;Compare X and BCDE ;X already >= 1E+6 ? 00F68 F2740F JP P,0F74H ;Yes: convert X to DBL, because ;the new number X gets more ;than 6 positions and will go ;outide the SNG range 00F6B CD3E09 CALL 093EH ;X = X * 10 00F6E F1 POP AF ;A = digit value 00F6F CD890F CALL 0F89H ;X = X + A (SNG) 00F72 18DD JR 0F51H ;Get next digit ; Overflow of SNG 00F74 CDE30A CALL 0AE3H ;X = CDBL ( X ) ; Insert new digit into DBL number 00F77 CD4D0E CALL 0E4DH ;X = X * 10 (DBL) 00F7A CDFC09 CALL 09FCH ;Y = X 00F7D F1 POP AF ;A = digit value 00F7E CD6409 CALL 0964H ;X = A 00F81 CDE30A CALL 0AE3H ;X = CDBL ( X ) 00F84 CD770C CALL 0C77H ;X = X + Y 00F87 18C8 JR 0F51H ;Get next digit ; X = X + A (SNG) 00F89 CDA409 CALL 09A4H ;(SP) = X 00F8C CD6409 CALL 0964H ;X = A ; X = X + (SP) (SNG) 00F8F C1 POP BC ;BCDE = (SP) 00F90 D1 POP DE 00F91 C31607 JP 0716H ;X = X + BCDE ; Digit found after 'E' or 'D' 00F94 7B LD A,E ;A = current exponent 00F95 FE0A CP 0AH ;Exponent >= 10 ? ;Already two exponent postions ;recognized ? ;(one position can only give ;a maximum of 9) 00F97 3009 JR NC,0FA2H ;Yes: set exponent to 48 to ;force an overflow 00F99 07 RLCA ;A = A * 2 = exponent * 2 00F9A 07 RLCA ;A = A * 2 = exponent * 4 00F9B 83 ADD A,E ;A = A * E = exponent * 5 00F9C 07 RLCA ;A = A * 2 = exponent * 10 00F9D 86 ADD A,(HL) ;Insert new exponent digit 00F9E D630 SUB 30H ;Subtract 30H, because an ;ASCII value was inserted ;(Result is always positive, ;because (HL) is in the range ;from 30H to 39H ('0' to '9')) 00FA0 5F LD E,A ;E = new exponent 00FA1 FA1E32 JP M,321EH ;-- (positive result!) * 00FA1 1E32 LD E,32H ;Exponent = 48 at overflow 00FA4 C3BD0E JP 0EBDH ;Get next exponent digit ; Print 'in' followed by number in HL (routine for Error and Break) 00FA7 E5 PUSH HL ;Save number 00FA8 212419 LD HL,1924H ;HL -> ' in ' 00FAB CDA728 CALL 28A7H ;Print text 00FAE E1 POP HL ;Restore number ; Print HL as decimal number (routine for printing line numbers with LIST) 00FAF CD9A0A CALL 0A9AH ;Write HL to X as INT 00FB2 AF XOR A ;A = 00H: no formatting 00FB3 CD3410 CALL 1034H ;Store formatting byte and ;clear sign 00FB6 B6 OR (HL) ;A = 20H (bit 7 of A = 0) 00FB7 CDD90F CALL 0FD9H ;Generate unformatted string 00FBA C3A628 JP 28A6H ;Print string ; Conversion of X into an unformatted string (for PRINT) ; (like STR$ function) ; ; I: X = number ; O: HL -> string (= 4130H) 00FBD AF XOR A ;Clear format byte ; Conversion of X into a formatted string (for PRINT USING) ; (like STR$ function) ; ; I: X = number ; A = formatting code: Bit 7 = 1: do a format ; Bit 6 = 1: print ',' for separation of thousands ; Bit 5 = 1: fill leading spaces with '*' ; Bit 4 = 1: print '$' in front of number ; Bit 3 = 1: print sign (also '+') ; Bit 2 = 1: print sign behind number ; Bit 1 = -: not used ; Bit 0 = 1: print exponent ; ; O: HL -> start of string (= 4130H) ; DE -> end of string 00FBE CD3410 CALL 1034H ;Store format byte ;Clear sign position in buffer ;and set HL to start of buffer ;( = 4130H) 00FC1 E608 AND 08H ;Sign requested ? 00FC3 2802 JR Z,0FC7H ;No: continue at 0FC7H 00FC5 362B LD (HL),2BH ;First set sign to '+' 00FC7 EB EX DE,HL ;Save HL in DE 00FC8 CD9409 CALL 0994H ;TEST1 00FCB EB EX DE,HL ;Restore HL ;X positive ? 00FCC F2D90F JP P,0FD9H ;Yes: leave sign as it is 00FCF 362D LD (HL),2DH ;Set sign to '-' 00FD1 C5 PUSH BC ;Save BC 00FD2 E5 PUSH HL ;Save HL 00FD3 CD7B09 CALL 097BH ;X = -X ;(X is processed as a positive ;value because the sign is ;already in the buffer) 00FD6 E1 POP HL ;Restore HL 00FD7 C1 POP BC ;Restore BC 00FD8 B4 OR H ;Z-flag = 0 ;X is now positive ;Z-flag = 1 in case X = 0 00FD9 23 INC HL ;Pointer + 1 00FDA 3630 LD (HL),30H ;Put '0' in buffer 00FDC 3AD840 LD A,(40D8H) ;A = format byte 00FDF 57 LD D,A ;Save it in D 00FE0 17 RLA ;C-flag = bit 7 of A 00FE1 3AAF40 LD A,(40AFH) ;A = VT ;Formatting required ? 00FE4 DA9A10 JP C,109AH ;Yes: continue at 109AH ;Number is zero ? 00FE7 CA9210 JP Z,1092H ;Yes: done, continue at 1092H 00FEA FE04 CP 04H ;Is X an INT (VT < 4) ? 00FEC D23D10 JP NC,103DH ;No: continue at 103DH ; Convert INT number to unformatted string 00FEF 010000 LD BC,0000H ;B = 0: do not generate a ;decimal point ;C = 0: no separator of ;thousands 00FF2 CD2F13 CALL 132FH ;Convert number into ;unformatted string using 5 ;digits (incl. leading zeroes) ; Delete leading zeroes or replace them by '*' 00FF5 213041 LD HL,4130H ;HL -> buffer 00FF8 46 LD B,(HL) ;B = sign (' ' or '-') 00FF9 0E20 LD C,' ' ;C = ' ' 00FFB 3AD840 LD A,(40D8H) ;A = format byte 00FFE 5F LD E,A ;E = format byte 00FFF E620 AND 20H ;Fill space with '*' ? 01001 2807 JR Z,100AH ;No: continue at 100AH 01003 78 LD A,B ;A = sign 01004 B9 CP C ;Sign = ' ' ? 01005 0E2A LD C,'*' ;C = '*' 01007 2001 JR NZ,100AH ;No: sign = '-', goto 100AH 01009 41 LD B,C ;Replace sign (' ') by '*' 0100A 71 LD (HL),C ;Write ' ' or '*' into buffer 0100B D7 RST 10H ;A = next character ;End of string ? 0100C 2814 JR Z,1022H ;Yes: continue at 1022H 0100E FE45 CP 'E' ;'E' found ? 01010 2810 JR Z,1022H ;Yes: string end ('E' does ;not belong to INT format) 01012 FE44 CP 'D' ;'D' found ? 01014 280C JR Z,1022H ;Yes: string end ('D' does ;not belong to INT format) 01016 FE30 CP '0' ;Leading zero ? 01018 28F0 JR Z,100AH ;Yes: replace by ' 'or '*' 0101A FE2C CP ',' ;',' found ? 0101C 28EC JR Z,100AH ;Yes: replace by ' ' or '*' 0101E FE2E CP '.' ;'.' found 01020 2003 JR NZ,1025H ;No: continue at 1025H 01022 2B DEC HL ;Yes: decimal point found 01023 3630 LD (HL),30H ;Replace by '0' 01025 7B LD A,E ;A = format byte 01026 E610 AND 10H ;'$' in front of number ? 01028 2803 JR Z,102DH ;No: continue at 102DH 0102A 2B DEC HL ;Yes: insert '$' 0102B 3624 LD (HL),'$' 0102D 7B LD A,E ;A = format byte 0102E E604 AND 04H ;Print sign behind number ? 01030 C0 RET NZ ;Yes: string is ready, return 01031 2B DEC HL ;No: put back sign in front of 01032 70 LD (HL),B ;number 01033 C9 RET ; Save format byte, set HL to start of buffer and clear sign 01034 32D840 LD (40D8H),A ;Save format byte in system RAM 01037 213041 LD HL,4130H ;HL -> start of buffer 0103A 3620 LD (HL),' ' ;Clear sign in buffer 0103C C9 RET ; X is in floating point format ; Generate unformatted string 0103D FE05 CP 05H ;if SNG then C-flag = 1 ; else C-flag = 1 0103F E5 PUSH HL ;Save pointer 01040 DE00 SBC A,00H ;If SNG then A = 3 ;if DBL then A = 8 01042 17 RLA ;* 2 gives the number of ;decimal positions to be ;generated - 1 01043 57 LD D,A ;D = A 01044 14 INC D ;D = maximum number of ;positions (7 for SNG, ;17 for DBL) 01045 CD0112 CALL 1201H ;Scale X to 6 / 16 positions ;A = exponent offset ;( = number of decimal point ;shifts to the left during ;scaling) 01048 010003 LD BC,0300H ;B = 3 (decimal point pos. + 1) ;C = 0 (no thousands separator) 0104B 82 ADD A,D ;A = exponent-offset + maximum ;number of positions = ;10-exponent + 2 ;10-exponent < -2 ? 0104C FA5710 JP M,1057H ;Yes: continue at 1057H 0104F 14 INC D ;Position mnumber + 1 smaller 01050 BA CP D ;than 10-exponent + 2 01051 3004 JR NC,1057H ;Yes: continue at 1057H 01053 3C INC A ;10-exponent + 3 = ;decimal point position + 1 01054 47 LD B,A ;B = decimal point pos. + 1 01055 3E02 LD A,02H ;A = 2 because of SUB 02H: ;no 10-exponent is printed 01057 D602 SUB 02H ;A = 10-exponent 01059 E1 POP HL ;Restore buffer pointer 0105A F5 PUSH AF ;Save 10-exponent 0105B CD9112 CALL 1291H ;Set ',' and '.', B - 1 0105E 3630 LD (HL),'0' ;Use '0' 01060 CCC909 CALL Z,09C9H ;Pointer + 1 when decimal point ;set 01063 CDA412 CALL 12A4H ;Convert X into unformatted ;string with 7 / 17 positions ;Use decimal point after B ;positions 01066 2B DEC HL ;Pointer - 1 01067 7E LD A,(HL) ;A = character 01068 FE30 CP '0' ;Trailing zero ? 0106A 28FA JR Z,1066H ;Yes: pointer = last character ;unequal to '0'. (trailing ;zeroes are represented by ;10-exponent) 0106C FE2E CP '.' ;Last character is the decimal ;point ? ;Yes: leave pointer alone, ;decimal point is deleted 0106E C4C909 CALL NZ,09C9H ;No: pointer + 1 01071 F1 POP AF ;Restore 10-exponent ;10-exponent = 0 ? 01072 281F JR Z,1093H ;Yes: done, continue at 1093H ; Use 10-exponent ; A = 10-exponent 01074 F5 PUSH AF ;Save 10-exponent 01075 E7 RST 20H ;TSTTYP 01076 3E22 LD A,22H ;A = ASCII value of 'D' / 2 01078 8F ADC A,A ;A = A *2 + C-flag ;A = 'E' (X in SNG format) ;A = 'D' (X in DBL format) 01079 77 LD (HL),A ;Put correct exponent character ;in buffer 0107A 23 INC HL ;Pointer + 1 0107B F1 POP AF ;Restore 10-exponent 0107C 362B LD (HL),'+' ;Assume positve sign ;10-exponent > 0 ? 0107E F28510 JP P,1085H ;Yes: continue at 1085H 01081 362D LD (HL),'-' ;Use '-' instead 01083 2F CPL ;Negate exponent (so treat it 01084 3C INC A ;as a positive number) 01085 062F LD B,2FH ;B = ASCII value of '0' - 1 01087 04 INC B ;B + 1 (next digit in the ;tenth position 01088 D60A SUB 0AH ;Subtract 10 for 10-exponent ;10-exponent < 10 ? 0108A 30FB JR NC,1087H ;No: increment digit again 0108C C63A ADD A,3AH ;+ 3AH gives correct ASCII ;value for remaining position 0108E 23 INC HL ;Pointer + 1 0108F 70 LD (HL),B ;Set first position of exp. 01090 23 INC HL ;Pointer + 1 01091 77 LD (HL),A ;Set second position of exp. ; Terminate string with 00H 01092 23 INC HL ;Pointer + 1 01093 3600 LD (HL),00H ;Terminate with 00H 01095 EB EX DE,HL ;DE -> end of string 01096 213041 LD HL,4130H ;HL -> start of string 01099 C9 RET ; Formatting required ; ; I: A= VT ; BC = position counter before and after decimal point ; D = format byte ; HL -> buffer 0109A 23 INC HL ;Pointer + 1 0109B C5 PUSH BC ;Save counters 0109C FE04 CP 04H ;X in INT format ? 0109E 7A LD A,D ;A = format byte 0109F D20911 JP NC,1109H ;No: continue at 1109H ; Convert INT number into formatted string 010A2 1F RRA ;C-flag = bit 0 of A ;Use 10-exponent ? 010A3 DAA311 JP C,11A3H ;Yes: continue at 11A3H ;(convert number to SNG) 010A6 010306 LD BC,0603H ;B = maximum number of ;positions before decimal point ;C = counter for thousands ;separation 010A9 CD8912 CALL 1289H ;Set C = 0 if no thousands ;separation required 010AC D1 POP DE ;Restore counters ;D = number of positions ;before decimal point ;E = number of positions ;after decimal point 010AD 7A LD A,D ;A = number of positions ;before decimal point 010AE D605 SUB 05H ;More then 4 positions ? 010B0 F46912 CALL P,1269H ;Yes: use corresponding number ;of leading zeroes 010B3 CD2F13 CALL 132FH ;Convert X into 5 digit string 010B6 7B LD A,E ;E = number of positions ;after decimal point 010B7 B7 OR A ;Any positions at all ? 010B8 CC2F09 CALL Z,092FH ;Yes: buffer pointer -1 010BB 3D DEC A ;Any positions required ? 010BC F46912 CALL P,1269H ;Yes: use corresponding number ;of zeroes 010BF E5 PUSH HL ;Save pointer on end of buffer 010C0 CDF50F CALL 0FF5H ;Delete leading zeroes or ;replace them by '*' 010C3 E1 POP HL ;Restore buffer pointer ;Sign in front ? 010C4 2802 JR Z,10C8H ;yes: continue at 10C8H 010C6 70 LD (HL),B ;Set sign behind the number 010C7 23 INC HL ;Pointer + 1 010C8 3600 LD (HL),00H ;Terminate string 010CA 212F41 LD HL,412FH ;HL -> Start of buffer - 1 010CD 23 INC HL ;Pointer + 1 010CE 3AF340 LD A,(40F3H) ;A = LSB of buffer address of ;decimal point 010D1 95 SUB L ;-LSB of current buffer pointer 010D2 92 SUB D ;Equals the requested number of ;positions before the decimal ;point ? 010D3 C8 RET Z ;Yes: done, return ; Shift string in buffer ; Delete a position before the decimal point (means deleting a space) 010D4 7E LD A,(HL) ;Get next character from buffer 010D5 FE20 CP ' ' ;Is it a leading space ? 010D7 28F4 JR Z,10CDH ;Yes: skip it, next character 010D9 FE2A CP '*' ;'*' in front of number ? 010DB 28F0 JR Z,10CDH ;Yes: skip it, next character 010DD 2B DEC HL ;Pointer - 1 010DE E5 PUSH HL ;Save pointer ;(now points on sign character ;or the first digit or '$') 010DF F5 PUSH AF ;Save character on stack 010E0 01DF10 LD BC,10DFH ;Set new RET address to 10DFH 010E3 C5 PUSH BC 010E4 D7 RST 10H ;Search start of number string ;and get next character 010E5 FE2D CP '-' ;'-' found ? 010E7 C8 RET Z ;Yes: save character, next ;character 010E8 FE2B CP '+' ;'+' found ? 010EA C8 RET Z ;Yes: save character, next ;character 010EB FE24 CP '$' ;'$' found ? 010ED C8 RET Z ;Yes: save character, next ;character 010EE C1 POP BC ;Remove RET adress 010EF FE30 CP '0' ;Leading zero found ? 010F1 200F JR NZ,1102H ;No: field overflow! ;Yes: 010F3 23 INC HL ;Pointer + 1, skip leading zero 010F4 D7 RST 10H ;Get next character ;Is it a digit ? 010F5 300B JR NC,1102H ;No: field overflow! ;Yes: 010F7 2B DEC HL ;Pointer - 1 (string starts ;one position earlier in ;the buffer) 010F8 012B77 LD BC,772BH ;-- * 010F8 2B DEC HL ;Buffer pointer - 1 * 010F8 77 LD (HL),A ;Store character back into ;the buffer 010FB F1 POP AF ;Get character from stack ;Start of string reached ? 010FC 28FB JR Z,10F9H ;No: store next character ;Yes: 010FE C1 POP BC ;Remove buffer pointer from ;stack 010FF C3CE10 JP 10CEH ;Number of positions now ok ? ; Field overflow ; More positions before decimal point are generated as there are reqeusted 01102 F1 POP AF ;Get character from stack ;Last character ? 01103 28FD JR Z,1102H ;No: get next character ;Yes: 01105 E1 POP HL ;Restore buffer pointer to ;start of string 01106 3625 LD (HL),'%' ;Use '%' to indicate overflow 01108 C9 RET ; Formatting requested ; X is in floating point format 01109 E5 PUSH HL ;Save pointer 0110A 1F RRA ;C-flag = bit 0 of A ;Exponent output requested ? 0110B DAAA11 JP C,11AAH ;Yes: continue at 11AAH ;X in SNG format ? 0110E 2814 JR Z,1124H ;Yes: continue at 1124H ; X in DBL format ; Generate number string without exponent ; (X must not have more that 16 positions before the decimal point. This ; means that X must be smaller than 1D+16) 01110 118413 LD DE,1384H ;DE -> 1D+16 01113 CD490A CALL 0A49H ;CP X,(DE) = CP X,1D+16 01116 1610 LD D,10H ;D = maximum number of ;positions (16) ;X < 1D+16 ? 01118 FA3211 JP M,1132H ;Yes: continue at 1132H ; Field overflow with floating point number 0111B E1 POP HL ;Restore buffer pointer 0111C C1 POP BC ;Restore counters 0111D CDBD0F CALL 0FBDH ;Generate unformatted string 01120 2B DEC HL ;Buffer pointer - 1 01121 3625 LD (HL),'%' ;Use '%' in front of string ;to indicate overflow 01123 C9 RET ; X has SNG format 01124 010EB6 LD BC,0B60EH ;BCDE = 1E+16 01127 11CA1B LD DE,1BCAH 0112A CD0C0A CALL 0A0CH ;CP X,BCDE = CP X,1E+16 ;X > 1E+16 ? 0112D F21B11 JP P,111BH ;Yes: field overflow 01130 1606 LD D,06H ;D = maximum number of ;positions (6) 01132 CD5509 CALL 0955H ;TEST2 (number = 0 ?) 01135 C40112 CALL NZ,1201H ;No: scale number to 6 or 16 ;positions 01138 E1 POP HL ;Restore pointer 01139 C1 POP BC ;Restore counters on number of ;positions before and after ;the decimal point ;Did scale operation extend ? 0113A FA5711 JP M,1157H ;Yes: continue at 1157H ; The scale operation resulted in truncation (no fractional digits) ; A = exponent offset ( > 0 ) 0113D C5 PUSH BC ;Save counters 0113E 5F LD E,A ;E = exponent offset 0113F 78 LD A,B ;A = number of positions before ;the decimal point 01140 92 SUB D ;- maximum number of positions 01141 93 SUB E ;- exponent offset 01142 F46912 CALL P,1269H ;Use corresponding number of ;leading zeroes 01145 CD7D12 CALL 127DH ;Compute decimal point position ;and thousand separation 01148 CDA412 CALL 12A4H ;Convert floating point number ;into unformatted string 0114B B3 OR E ;A = exponent offset 0114C C47712 CALL NZ,1277H ;Set corresponding number ;of trailing zeroes (because ;10-exponent is not used) 0114F B3 OR E ;A = exponent offset 01150 C49112 CALL NZ,1291H ;Use decimal point if necessary 01153 D1 POP DE ;Restore positions counters 01154 C3B610 JP 10B6H ;Number of positions ok ? ; The scale operation resulted in extension (fractional digits presents) ; A = exponent offset ( < 0 ) 01157 5F LD E,A ;E = exponent offset 01158 79 LD A,C ;A = number of requested ;positions after the decimal ;point 01159 B7 OR A ;Any positions requested ? 0115A C4160F CALL NZ,0F16H ;Yes: A - 1 (because of ;decimal point) 0115D 83 ADD A,E ;A = number of positions ;after the decimal point ;+ exponent offset ;= negative number of the ;superfluous generated ;positions at scaling 0115E FA6211 JP M,1162H ;If too many positions ;generated then leave A as it is 01161 AF XOR A ;else set A = 0 01162 C5 PUSH BC ;Save position counters 01163 F5 PUSH AF ;Save number of positions ;generated too many 01164 FC180F CALL M,0F18H ;X = X / 10 , A + 1 01167 FA6411 JP M,1164H ;Reverse scaling until the ;requested number of positions ;behind the decimal point is ;reached 0116A C1 POP BC ;B = neagative number of ;positions generated too many 0116B 7B LD A,E ;A = exponent offset 0116C 90 SUB B ;+ number of positions ;generated too many 0116D C1 POP BC ;Restore position counters 0116E 5F LD E,A ;E = exponent offset ( < 0!) 0116F 82 ADD A,D ;Is the exponent offset + the ;maximum number of requested ;positions before the decimal ;point < 0 ? (this means no ;positions before the decimal ;point) 01170 78 LD A,B ;A = number of positions ;before the decimal point 01171 FA7F11 JP M,117FH ;Yes: continue at 117FH 01174 92 SUB D ;A = number of positions before ;decimal point - maximum number ;of positions before decimal ;point 01175 93 SUB E ;- exponent offset 01176 F46912 CALL P,1269H ;Set corresponding number ;of leading zeroes in buffer 01179 C5 PUSH BC ;Saev position counters 0117A CD7D12 CALL 127DH ;Compute decimal point ;position and counter for ;thousands separation 0117D 1811 JR 1190H ;continue at 1190H ; No positions before decimal point present (only a fractional part, see 116EH) 0117F CD6912 CALL 1269H ;Simulate requested field ;length before decimal point ;by using leading zeroes 01182 79 LD A,C ;A = number of requested ;positions behind the decimal ;point + 1 01183 CD9412 CALL 1294H ;Set decinal point, C = B 01186 4F LD C,A ;Write field length after ;decimal point back to C 01187 AF XOR A ;A = 0 01188 92 SUB D ;A = A - maximum number of ;positions 01189 93 SUB E ;+ exponent offset (+ because ;E < 0) 0118A CD6912 CALL 1269H ;Set corresponding number of ;trailing zeroes after the ;decimal point 0118D C5 PUSH BC ;Save position counters 0118E 47 LD B,A ;B = 0 (A = 0 because of 1269H) 0118F 4F LD C,A ;C = 0: use no decimal point ;and no separation of thousands 01190 CDA412 CALL 12A4H ;Generate unformatted string 01193 C1 POP BC ;Restore position counters 01194 B1 OR C ;A = requested number of ;positions behing the decimal ;point. ;Any positions behind the ;decimal point specified ? 01195 2003 JR NZ,119AH ;Yes: leave buffer pointer as ;it is (buffer pointer points ;at the last string char! ) 01197 2AF340 LD HL,(40F3H) ;No: set buffer pointer to the ;position of the decimal ;point (= end of string!) 0119A 83 ADD A,E ;A = number of requested ;positions behind the decimal ;point + 1 + exponent offset 0119B 3D DEC A ;Adjust because of + 1 0119C F46912 CALL P,1269H ;Set corresponding number of ;trailing zeroes after the ;decimal point 0119F 50 LD D,B ;D = number of requested ;positions before decimal point 011A0 C3BF10 JP 10BFH ;Continue at 10BFH ; INT number using exponential format ; For this, X has to be converted to SNG format 011A3 E5 PUSH HL ;Save buffer pointer 011A4 D5 PUSH DE ;Save format byte 011A5 CDCC0A CALL 0ACCH ;X = CSNG ( X ) 011A8 D1 POP DE ;Restore format byte 011A9 AF XOR A ;A = 0 (Z-flag = 1 because ;X in SNG format) ; SNG or DBL number using exponential format ;SNG number ? 011AA CAB011 JP Z,11B0H ;Yes: continue at 11B0H 011AD 1E10 LD E,10H ;E = maximum number of ;positions (16) 011AF 011E06 LD BC,061EH ;-- * 011B0 1E06 LD E,06H ;E = maximum number of ;positions (16) 011B2 CD5509 CALL 0955H ;TEST2. X = 0 ? 011B5 37 SCF ;C-flag = 1 011B6 C40112 CALL NZ,1201H ;No, scale X to 6 (SNG) or ;16 (DBL) positions 011B9 E1 POP HL ;Restore buffer pointer 011BA C1 POP BC ;Restore position counters 011BB F5 PUSH AF ;Save exponent offset 011BC 79 LD A,C ;A = number of positions behind ;the decimal point 011BD B7 OR A ;Any positions behind decimal ;point specified ? 011BE F5 PUSH AF ;Save number of positions 011BF C4160F CALL NZ,0F16H ;Yes: A - 1 (because of decimal ;point) 011C2 80 ADD A,B ;+ number of positions in front ;of the decimal point 011C3 4F LD C,A ;C = total length 011C4 7A LD A,D ;A = format byte 011C5 E604 AND 04H ;Print sign behind number ? 011C7 FE01 CP 01H ;No: C-flag = 1 011C9 9F SBC A,A ;If not then A = FFH (-1) 011CA 57 LD D,A ;D = A 011CB 81 ADD A,C ;A = total length, left alone ;if sign is to printed in front ;else decrement it by 1 011CC 4F LD C,A ;C = total length 011CD 93 SUB E ;A = requested total length ;of string - maximum number ;of positions 011CE F5 PUSH AF ;Save difference 011CF C5 PUSH BC ;Save total length ;Is the requested number of ;positions < generated number ;of positions 011D0 FC180F CALL M,0F18H ;Yes: X = X / 10, A - 1 011D3 FAD011 JP M,11D0H ;Scale X according to ;difference 011D6 C1 POP BC ;Restore total length 011D7 F1 POP AF ;Restore difference 011D8 C5 PUSH BC ;Save total length 011D9 F5 PUSH AF ;Save difference ;Total length > number of ;positions ? 011DA FADE11 JP M,11DEH ;Yes: continue at 11DEH 011DD AF XOR A ;A = 0 011DE 2F CPL ;A = positive difference 011DF 3C INC A 011E0 80 ADD A,B ;+ number of requested ;positions on front of ;decimal point 011E1 3C INC A ;+ 1 011E2 82 ADD A,D ;-1 if case of sign being ;printed in front of the number 011E3 47 LD B,A ;= decomal point position 011E4 0E00 LD C,00H ;Set no thousands separation 011E6 CDA412 CALL 12A4H ;Generate unformatted string 011E9 F1 POP AF ;Restore position difference 011EA F47112 CALL P,1271H ;Use corresponding number ;of trailing zeroes 011ED C1 POP BC ;Restore position counters 011EE F1 POP AF ;A = requested number of ;positions behind the decimal ;point. ;Any positions requested ? 011EF CC2F09 CALL Z,092FH ;No: buffer pointer - 1 ;(remove decimal point again) 011F2 F1 POP AF ;Restore exponent offset ;X = 0 ? (see 11B5H) 011F3 3803 JR C,11F8H ;Yes: 10-exponent is also 0 ;No: 011F5 83 ADD A,E ;Add maximum number of ;positions 011F6 90 SUB B ;subtract number of already ;generated positions in front ;of decimal point 011F7 92 SUB D ;Reverse addition of 11E2H ;= 10-exponent 011F8 C5 PUSH BC ;Save number of positions in ;front of decimal point 011F9 CD7410 CALL 1074H ;Use 10-exponent 011FC EB EX DE,HL ;HL = end pointer 011FD D1 POP DE ;D = number of requested ;positions 011FE C3BF10 JP 10BFH ;Continue at 10BFH ; Scaling: ; Scale X to 6 (SNG) or 16 (DBL) positions in front of decimal point ; O: A = 10-exponent offset 01201 D5 PUSH DE ;Save DE 01202 AF XOR A ;Exponent offset = 00H 01203 F5 PUSH AF ;Save exponent offset 01204 E7 RST 20H ;TSTTYP ;X in SNG format ? 01205 E22212 JP PO,1222H ;Yes: continue at 1222H ; X in DBL format 01208 3A2441 LD A,(4124H) ;A = Exp (X) 0120B FE91 CP 91H ;X >= 2 ^ 16 ? 0120D D22212 JP NC,1222H ;Yes: continue at 1222H 01210 116413 LD DE,1364H ;DE -> 1D+10 01213 212741 LD HL,4127H ;HL -> Y 01216 CDD309 CALL 09D3H ;(HL) = (DE): Y = 1D+10 01219 CDA10D CALL 0DA1H ;X = X * Y - X * 1D+10 0121C F1 POP AF ;Restore exponent offset 0121D D60A SUB 0AH ;Exponent offset - 10 ;(shifted 10 decimal positions) 0121F F5 PUSH AF ;Save exponent offset 01220 18E6 JR 1208H ;Repeat until X >= 2 ^ 16 ; X in SNG format / X >= 65536 when in DBL format 01222 CD4F12 CALL 124FH ;Divide X by 10 until ;X < 1E+6 (SNG) or ;X < 1D+16 (DBL) ; X is now < 1E+6 (SNG) or < 1D+16 (DBL) 01225 E7 RST 20H ;TSTTYP ;X in DBL format ? 01226 300B JR NC,1233H ;Yes: continue at1233H ; X has SNG format 01228 014391 LD BC,9143H ;BCDE = 1E+5 0122B 11F94F LD DE,4FF9H 0122E CD0C0A CALL 0A0CH ;CP X,BCDE = CP X,1E+5 01231 1806 JR 1239H ;Continue at 1239H ; X has DBL format 01233 116C13 LD DE,136CH ;DE -> 1D+15 01236 CD490A CALL 0A49H ;CP X,(DE) = CP X,1D+15 ;X >= 1D+15 (DBL) ? ;X >= 1E+5 (SNG) ? 01239 F24B12 JP P,124BH ;Yes: done 0123C F1 POP AF ;Restore exponent offset 0123D CD0B0F CALL 0F0BH ;X = X + 10 (SNG,DBL), A - 1 01240 F5 PUSH AF ;Save exponent offset 01241 18E2 JR 1225H ;Repeat until X >= 1E+5 (SNG) X >= 1D+15 (DBL) ; X >= 1E+6 (SNG) or X >= 1D+16 (DBL) ; (Continuation of 124FH) 01243 F1 POP AF ;Restore exponent offset 01244 CD180F CALL 0F18H ;X = X / 10, A + 1 01247 F5 PUSH AF ;Save exponent offset 01248 CD4F12 CALL 124FH ;Test again ; Scaling finished ; ; 1E+5 <= X < 1E+6 (SNG) ; 1D+15 <= X < 1D+16 (DBL) 0124B F1 POP AF ;Restore exponent offset 0124C B7 OR A ;C-flag = 0 (for 11B5H) 0124D D1 POP DE ;Restore DE 0124E C9 RET ; Divide X by 10 until X < 1E+6 (SNG) or X < 1D+16 (DBL) 0124F E7 RST 20H ;TSTTYP ;X in DBL format ? 01250 EA5E12 JP PE,125EH ;Yes: continue at 125EH ; X has SNG format 01253 017494 LD BC,9474H ;BCDE = 1E+6 01256 11F823 LD DE,23F8H 01259 CD0C0A CALL 0A0CH ;CP X,BCDE = CP X,1E+6 0125C 1806 JR 1264H ;Continue at 1264H ; X has DBL format 0125E 117413 LD DE,1374H ;DE -> 1D+16 01261 CD490A CALL 0A49H ;CP X,(DE) = CP X, 1D+16 01264 E1 POP HL ;HL = RET address ;X >= 1E+6 (SNG) ? ;X >= 1D+16 (DBL) ? 01265 F24312 JP P,1243H ;Yes: continue at 1243H 01268 E9 JP (HL) ;RET ; Write A zeroes into buffer from (HL) onwards ; (positions after the decimal point) 01269 B7 OR A ;Counter = 0 ? 0126A C8 RET Z ;Yes: done, return 0126B 3D DEC A ;Counter - 1 0126C 3630 LD (HL),'0' ;Put a '0' into buffer 0126E 23 INC HL ;Pointer + 1 0126F 18F9 JR 126AH ;Done ? ; Write A zeroes into buffer from (HL) onwards and set ',' and '.' ; (positions before the decimal point) ;Counter zero ? 01271 2004 JR NZ,1277H ;No: continue at 1277H 01273 C8 RET Z ;Yes: done, return 01274 CD9112 CALL 1291H ;Set ',' and '.' 01277 3630 LD (HL),'0' ;Put a '0' into buffer 01279 23 INC HL ;Pointer + 1 0127A 3D DEC A ;Counter - 1 0127B 18F6 JR 1273H ;Done ? ; Establish decimal point position and counter for thousands separation 0127D 7B LD A,E ;A = exponent offset 0127E 82 ADD A,D ;+ maimum number of generated ;positions 0127F 3C INC A ;+ 1 01280 47 LD B,A ;= decimal point position ;(=number of positions before ;the decimal point) ;Ccompute counter for thousands ;separation 01281 3C INC A ;+ 1 01282 D603 SUB 03H ;A = A DIV 3 01284 30FC JR NC,1282H ;(Integer division) 01286 C605 ADD A,05H ;+5 01288 4F LD C,A ;Results in counter for ;thousands separation 01289 3AD840 LD A,(40D8H) ;A = format byte 0128C E640 AND 40H ;Thousands separation required? 0128E C0 RET NZ ;Yes: B and C are ok, return 0128F 4F LD C,A ;Set C to 0 01290 C9 RET ; Set ',' and '.' ; ; I: B = number of remaining positions before the decimal point (until ; decimal point) ; C = number of remaining digits until next thousand separation ; C = 0: do not separate thousands 01291 05 DEC B ;Positions before decimal ;point - 1 ;Decimal point reached ? 01292 2008 JR NZ,129CH ;No: set ',' 01294 362E LD (HL),'.' ;Put '.' into buffer ; Save buffer pointer to decimal point ; Do not separate thousands 01296 22F340 LD (40F3H),HL ;Save buffer pointer 01299 23 INC HL ;Pointer + 1 0129A 48 LD C,B ;C = 0 (no thousand separation) 0129B C9 RET ; Decimal point not reached yet: insert thousands separation 0129C 0D DEC C ;Next thousand position ;reached ? 0129D C0 RET NZ ;No: done, return 0129E 362C LD (HL),',' ;Yes, put ',' into buffer 012A0 23 INC HL ;Pointer + 1 012A1 0E03 LD C,03H ;Counter = 3 for next ;thousands position 012A3 C9 RET ; Convert floating point number to unformatted string 012A4 D5 PUSH DE ;Save DE 012A5 E7 RST 20H ;TSTTYP ;SNG ? 012A6 E2EA12 JP PO,12EAH ;Yes: continue at 12EAH ; X in DBL format (and 1D+15 <= X < 1D+16 !) ; Generate unformatted string with 17 positions ; (10 positions using DBL-mantissas, 2 positions using SNG-mantissas ; and 5 positions with INT-format) 012A9 C5 PUSH BC ;Save position counters 012AA E5 PUSH HL ;Save buffer pointer 012AB CDFC09 CALL 09FCH ;Y = X 012AE 217C13 LD HL,137CH ;HL -> Constant 0.5 (DBL) 012B1 CDF709 CALL 09F7H ;X = (HL) = 0.5 012B4 CD770C CALL 0C77H ;X = X + Y = 0.5 + Y ;(Round up X) 012B7 AF XOR A ;C-flag = 0 012B8 CD7B0B CALL 0B7BH ;Clear positions behind the ;decimal point 012BB E1 POP HL ;Restore buffer pointer 012BC C1 POP BC ;Restore position counters 012BD 118C13 LD DE,138CH ;DE -> DBL-mantissas 012C0 3E0A LD A,0AH ;A = counter (10 DBL-mantissas ;from (DE) onwards) 012C2 CD9112 CALL 1291H ;Set ',' and '.' 012C5 C5 PUSH BC ;Save position counters 012C6 F5 PUSH AF ;Save mantissa counter 012C7 E5 PUSH HL ;Save buffer pointer 012C8 D5 PUSH DE ;Save mantissa pointer 012C9 062F LD B,2FH ;B = ASCII '0' - 1 012CB 04 INC B ;Next digit 012CC E1 POP HL ;HL = mantissa pointer 012CD E5 PUSH HL ;Save it again 012CE CD480D CALL 0D48H ;X = X - (HL): subtract ;mantissa. ;Underflow ? 012D1 30F8 JR NC,12CBH ;No: next digit 012D3 E1 POP HL ;Yes: restore mantissa pointer 012D4 CD360D CALL 0D36H ;X = X + (HL): reverse last ;subtract 012D7 EB EX DE,HL ;DE = mantissa pointer 012D8 E1 POP HL ;HL = buffer pointer 012D9 70 LD (HL),B ;Insert digit in buffer 012DA 23 INC HL ;Update buffer pointer to next ;position 012DB F1 POP AF ;Restore maintissa counter 012DC C1 POP BC ;Restore position counters 012DD 3D DEC A ;Mantissa counter - 1 012DE 20E2 JR NZ,12C2H ;Next decimal position 012E0 C5 PUSH BC ;Save position counters 012E1 E5 PUSH HL ;Save buffer pointer 012E2 211D41 LD HL,411DH ;HL -> X (DBL) 012E5 CDB109 CALL 09B1H ;X = BCDE = (HL) (SNG) ;Shift the remaining LSBs of ;the DBL number into X as a ;SNG number 012E8 180C JR 12F6H ;The remaining decimal ;positions are processed in ;SNG format (because now ;X < 1D+6) ; X in SNG format (and 1E+5 <= X < 1E+6 !) ; Generate unformatted string with 7 positions ; (2 positions using SNG-mantissas and the remaining 5 positions with ; INT-format) 012EA C5 PUSH BC ;Save position counters 012EB E5 PUSH HL ;Save buffer pointers 012EC CD0807 CALL 0708H ;X = X + 0.5 (adjust mantissa) 012EF 3C INC A ;A <> 0 (for 0AFBH) 012F0 CDFB0A CALL 0AFBH ;Clear all positions behind ;the decimal point 012F3 CDB409 CALL 09B4H ;X = BCDE ;(BCDE is the result of 0AFBH) 012F6 E1 POP HL ;Restore buffer pointer 012F7 C1 POP BC ;Restore position counters 012F8 AF XOR A ;C-flag = 0 012F9 11D213 LD DE,13D2H ;DE -> mantissas 012FC 3F CCF ;C-flag = 1 at first itteration ;after that C-flag = 0 012FD CD9112 CALL 1291H ;Set ',' and '.' 01300 C5 PUSH BC ;Save position counters 01301 F5 PUSH AF ;Save repeat flag 01302 E5 PUSH HL ;Save buffer pointer 01303 D5 PUSH DE ;Save mantissa pointer 01304 CDBF09 CALL 09BFH ;BCDE = X 01307 E1 POP HL ;Mantissa pointer back to HL 01308 062F LD B,2FH ;B = '0' - 1 0130A 04 INC B ;next digit 0130B 7B LD A,E ;CDE = CDE - (HL): 0130C 96 SUB (HL) ;Subtract mantissa 0130D 5F LD E,A 0130E 23 INC HL 0130F 7A LD A,D 01310 9E SBC A,(HL) 01311 57 LD D,A 01312 23 INC HL 01313 79 LD A,C 01314 9E SBC A,(HL) 01315 4F LD C,A 01316 2B DEC HL ;HL -> start of mantissa 01317 2B DEC HL ;Underflow ? 01318 30F0 JR NC,130AH ;No: next digit 0131A CDB707 CALL 07B7H ;CDE= CDE + (HL): ;reverse last subtract 0131D 23 INC HL ;Mantissa pointer + 1 0131E CDB409 CALL 09B4H ;X = BCDE: new value to X 01321 EB EX DE,HL ;DE = mantissa pointer 01322 E1 POP HL ;Restore buffer pointer 01323 70 LD (HL),B ;Store digit 01324 23 INC HL ;Buffer pointer + 1 01325 F1 POP AF ;Restore repeat flag 01326 C1 POP BC ;Restore position counters ;Repeat ? 01327 38D3 JR C,12FCH ;Yes: back to 12FCH (there are ;only 2 mantissas in the SNG ;format) 01329 13 INC DE ;Mantissa pointer + 2 0132A 13 INC DE ;(for INT processing) 0132B 3E04 LD A,04H ;Process 4 mantissas ;(the first mantissa with 10000 ;is also in the SNG format) 0132D 1806 JR 1335H ;Process remaining 4 digits ;in INT-format ; X in INT-format (and 0 <= X < 32768 !) ; Generate unfomratted string with 5 positions 0132F D5 PUSH DE ;Save DE 01330 11D813 LD DE,13D8H ;DE -> Mantissas 01333 3E05 LD A,05H ;5 Mantissas 01335 CD9112 CALL 1291H ;Set '.' and ',' 01338 C5 PUSH BC ;Save position counters 01339 F5 PUSH AF ;Save mantissa counter 0133A E5 PUSH HL ;Save buffer pointer 0133B EB EX DE,HL ;HL = mantissa pointer 0133C 4E LD C,(HL) ;BC = mantissa 0133D 23 INC HL 0133E 46 LD B,(HL) 0133F C5 PUSH BC ;Save mantissa 01340 23 INC HL ;HL -> next mantissa 01341 E3 EX (SP),HL ;Save mantissa pointer, ;HL = mantissa 01342 EB EX DE,HL ;DE = mantissa 01343 2A2141 LD HL,(4121H) ;HL = X 01346 062F LD B,2FH ;B = ASCII '0' - 1 01348 04 INC B ;Next digit 01349 7D LD A,L ;HL = HL - DE 0134A 93 SUB E 0134B 6F LD L,A 0134C 7C LD A,H 0134D 9A SBC A,D 0134E 67 LD H,A ;Underflow ? 0134F 30F7 JR NC,1348H ;No: next digit ;Yes: 01351 19 ADD HL,DE ;Reverse subtract 01352 222141 LD (4121H),HL ;and store new value in X 01355 D1 POP DE ;Restore mantissa pointer 01356 E1 POP HL ;Restore buffer pointer 01357 70 LD (HL),B ;Insert digit 01358 23 INC HL ;Buffer pointer + 1 01359 F1 POP AF ;Restore mantissa counter 0135A C1 POP BC ;Restore position counters 0135B 3D DEC A ;Mantissa counter - 1 0135C 20D7 JR NZ,1335H ;Next mantissa 0135E CD9112 CALL 1291H ;Set ',' and '.' 01361 77 LD (HL),A ;Terminate string with 00H 01362 D1 POP DE ;Restore DE 01363 C9 RET ; Floating point constants 01364 00 DEFB 00H ;1D+10 01365 00 DEFB 00H 01366 00 DEFB 00H 01367 00 DEFB 00H 01368 F9 DEFB F9H ;1E+10 01369 02 DEFB 02H 0136A 15 DEFB 15H 0136B A2 DEFB A2H 0136C FD DEFB FDH ;1D+15 0136D FF DEFB FFH 0136E 9F DEFB 9FH 0136F 31 DEFB 31H 01370 A9 DEFB A9H ;1E+15 01371 5F DEFB 5FH 01372 63 DEFB 63H 01373 B2 DEFB B2H 01374 FE DEFB FEH ;1D+16 01375 FF DEFB FFH 01376 03 DEFB 03H 01377 BF DEFB BFH 01378 C9 DEFB C9H ;1E+16 01379 1B DEFB 1BH 0137A 0E DEFB 0EH 0137B B6 DEFB B6H 0137C 00 DEFB 00H ;0.5 (DBL) 0137D 00 DEFB 00H 0137E 00 DEFB 00H 0137F 00 DEFB 00H 01380 00 DEFB 00H ;0.5 (SNG) 01381 00 DEFB 00H 01382 00 DEFB 00H 01383 80 DEFB 80H 01384 00 DEFB 00H ;1D+16 01385 00 DEFB 00H 01386 04 DEFB 04H 01387 BF DEFB BFH 01388 C9 DEFB C9H ;1E+16 01389 1B DEFB 1BH 0138A 0E DEFB 0EH 0138B B6 DEFB B6H ; Fixed point constants (mantissas for number conversion) ; LSB MSB ;1000000000000000 0138C 0080C6A47E8D03 DEFB 00H,80H,C6H,A4H,7EH,8DH,03H ;1D+15 ;100000000000000 01393 00407A10F35A00 DEFB 00H,40H,7AH,10H,F3H,5AH,00H ;1D+14 ;10000000000000 0139A 00A0724E180900 DEFB 00H,A0H,72H,4EH,18H,09H,00H ;1D+13 ;1000000000000 013A1 0010A5D4E80000 DEFB 00H,10H,A5H,D4H,E8H,00H,00H ;1D+12 ;100000000000 013A8 00E87648170000 DEFB 00H,E8H,76H,48H,17H,00H,00H ;1D+11 ;10000000000 013AF 00E40B54020000 DEFB 00H,E4H,0BH,54H,02H,00H,00H ;1D+10 ;1000000000 013B6 00CA9A3B000000 DEFB 00H,CAH,9AH,3BH,00H,00H,00H ;1D+9 ;100000000 013BD 00E1F505000000 DEFB 00H,E1H,F5H,05H,00H,00H,00H ;1D+8 ;10000000 013C4 80969800000000 DEFB 80H,96H,98H,00H,00H,00H,00H ;1D+7 ;1000000 013CB 40420F00000000 DEFB 40H,42H,0FH,00H,00H,00H,00H ;1D+6 ;100000 013D2 A08601 DEFB A0H,86H,01H ;1E+5 ;10000 013D5 102700 DEFB 10H,27H,00H ;1E+4 ;1000 013D8 E803 DEFB E8H,03H ;INT ;100 013DC 6400 DEFB 64H,00H ;10 013DE 0A00 DEFB 0AH,00H ;1 013E0 0100 DEFB 01H,00H ; SUB for SQR and ATN ; Negate the result of the routine (X = -X) 013E2 218209 LD HL,0982H ;HL -> Routine for X = -X 013E5 E3 EX (SP),HL ;Save HL as RET address on ;stack 013E6 E9 JP (HL) ;Back to caller (SQR or ATN) ; X = SQR ( X ) = X ^ 0.5 ; ----------------------- ; 013E7 CDA409 CALL 09A4H ;(SP) = X 013EA 218013 LD HL,1380H ;HL -> constant 0.5 013ED CDB109 CALL 09B1H ;X = BCDE = (HL) 013F0 1803 JR 13F5H ;Compute (SP) ^ X ; X = (SP) ^ X 013F2 CDB10A CALL 0AB1H ;X = CSNG (X) (Exponent) 013F5 C1 POP BC ;BCDE = (SP) (Base) 013F6 D1 POP DE 013F7 CD5509 CALL 0955H ;TEST2 013FA 78 LD A,B ;A = Exp (Base) ;Exponent zero ? 013FB 283C JR Z,1439H ;Yes: compute Exp(0) = 1 ;Exponent > 0 013FD F20414 JP P,1404H ;Yes: continue at 1404H 01400 B7 OR A ;Base = zero ? ;(with negative exponent) 01401 CA9A19 JP Z,199AH ;Yes: ?/0 Error 01404 B7 OR A ;Base = zero ? ;(with negative exponent) 01405 CA7907 JP Z,0779H ;Yes: ?/0 Error 01408 D5 PUSH DE ;Save Base 01409 C5 PUSH BC 0140A 79 LD A,C ;A = MSB (Base) 0140B F67F OR 7FH ;Test sign 0140D CDBF09 CALL 09BFH ;BCDE = X ;Positive Base ? 01410 F22114 JP P,1421H ;Yes: continue at 1421H 01413 D5 PUSH DE ;Save Exponent 01414 C5 PUSH BC 01415 CD400B CALL 0B40H ;X = INT (X) = INT ( Exponent) 01418 C1 POP BC ;Restore exponent 01419 D1 POP DE 0141A F5 PUSH AF ;Save LSB (X) 0141B CD0C0A CALL 0A0CH ;CP X,BCDE ;CP INT(Exponent), Exponent ;Exponent an integer ? 0141E E1 POP HL ;Restore LSB (X) 0141F 7C LD A,H ;A = LSB (X) = INT (Exponent) ;(because exponent < 88) 01420 1F RRA ;C-flag = A, bit 0 (lowest bit ;of the exponent) ;Exponent odd ? 01421 E1 POP HL ;X = (SP) = Base 01422 222341 LD (4123H),HL 01425 E1 POP HL 01426 222141 LD (4121H),HL ;Exponent odd ? 01429 DCE213 CALL C,13E2H ;Yes: negate result when ;exponent is odd with negative ;base ;Exponent an integer ? 0142C CC8209 CALL Z,0982H ;Yes: make base positive when ;exponent is integer. 0142F D5 PUSH DE ;Save Exponent 01430 C5 PUSH BC 01431 CD0908 CALL 0809H ;X = LOG (X) (logaritm of Base) 01434 C1 POP BC ;Restore Exponent 01435 D1 POP DE 01436 CD4708 CALL 0847H ;X = BCDE * X ; = Exponent * LOG (Base) ;Now compute the following: ;EXP ( Exponent * LOG (Base) ) ; X = EXP ( X ) ; ------------- ; Only computable for -88.7228 <= X <= 87.3365 01439 CDA409 CALL 09A4H ;(SP) = X: Save argument 0143C 013881 LD BC,8138H ;BCDE = 1/4427 = 1 / LOG(2) 0143F 113BAA LD DE,0AA3BH 01442 CD4708 CALL 0847H ;X = BCDE * argument ; = argument / LOG(2) 01445 3A2441 LD A,(4124H) ;A = Exp (X) 01448 FE88 CP 88H ;Exp (X) >= 88H ? ;means: X >= 2 ^ 8 ? ;means: argument/LOG(2) > 127 ;(or argument/LOG(2) < -128) ? ;means: argument > 88.0297 ;(or argument < -88.7228) ? 0144A D23109 JP NC,0931H ;Yes: ?OV Error if ;argument > 88.0297, ;Result = 0 if ;argument < 88.7228) 0144D CD400B CALL 0B40H ;A = X = INT (X) ;( X = INT( argument/LOG(2) ) ) ;( = 2-exponent of result ) 01450 C680 ADD A,80H ;A > 7DH ? (A + 82H > FFH) 01452 C602 ADD A,02H ;means: INT(arg./LOG(2)) > 125? ;means X > 87.3365 ? 01454 DA3109 JP C,0931H ;Yes: ?OV Error ;No: 01457 F5 PUSH AF ;Save 2-exponent + offset (80H) ;+ 2 01458 21F807 LD HL,07F8H ;HL -> Constant 1 (SNG) 0145B CD0B07 CALL 070BH ;X = X + HL = X + 1 0145E CD4108 CALL 0841H ;X = X * LOG(2) 01461 F1 POP AF ;Restore 2-exponent 01462 C1 POP BC ;BCDE = (SP) = argument 01463 D1 POP DE 01464 F5 PUSH AF ;Save 2-exponent 01465 CD1307 CALL 0713H ;X = BCDE - X 01468 CD8209 CALL 0982H ;X = -X 0146B 217914 LD HL,1479H ;HL -> coefficients 0146E CDA914 CALL 14A9H ;Series calculation 2 01471 110000 LD DE,0000H ;DE = 0000H 01474 C1 POP BC ;B = 2-exponent + 2 01475 4A LD C,D ;C = 00H 01476 C34708 JP 0847H ;X = BCDE * X ; = (2 ^ 2 + 2-exponent) * X ; Coefficients for EXP ; '!' means faculty of the number (3! = 1 * 2 * 3) 01479 08 DEFB 08H ;8 coefficients 0147A 40 DEFB 40H ;-1.41361E-4 = -1/7076 0147B 2E DEFB 2EH ;approx. -1/5040 = -1/7! 0147C 94 DEFB 94H 0147D 74 DEFB 74H 0147E 70 DEFB 70H ;1.32988E-3 = 1/752 0147F 4F DEFB 4FH ;approx. 1/720 = 1/6! 01480 2E DEFB 2EH 01481 77 DEFB 77H 01482 6E DEFB 6EH ;=8.30136E-3 = -1/120 01483 02 DEFB 02H = -1/5! 01484 88 DEFB 88H 01485 7A DEFB 7AH 01486 E6 DEFB E6H ;0.0416574 = 1/24 01486 A0 DEFB A0H = 1/4! 01488 2A DEFB 2AH 01489 7C DEFB 7CH 0148A 50 DEFB 50H ;-0.166665 = -1/6 0148B AA DEFB AAH = -1/3! 0148C AA DEFB AAH 0148D 7E DEFB 7EH 0148E FF DEFB FFH ;0.5 = 1/2 0148F FF DEFB FFH = 1/2! 01490 7F DEFB 7FH 01491 7F DEFB 7FH 01492 00 DEFB 00H ;-1 = -1/1! 01493 00 DEFB 00H 01494 80 DEFB 80H 01495 81 DEFB 81H 01496 00 DEFB 00H ;1 01497 00 DEFB 00H 01498 00 DEFB 00H 01499 81 DEFB 81H ; Series calculation 1 ; Calculate Taylor-series of the following form: ; ; y = k1*x + k2*x*x*x + k3*x*x*x*x*x... (k1, k2, k3 are coefficients) ; ; I: HL -> coefficients table ; The first byte of the table indicates the number of coefficients ; in the table. Then the coefficients follow, in an inverted ; order (k1 last) ; X = factor in series (x in the example) ; O: X = result of series calculation (y in the example) 0149A CDA409 CALL 09A4H ;(SP) = X 0149D 11320C LD DE,0C32H ;DE = address of X = X * (SP) 014A0 D5 PUSH DE ;Save as new RET address 014A1 E5 PUSH HL ;Save table pointer 014A2 CDBF09 CALL 09BFH ;BCDE = X 014A5 CD4708 CALL 0847H ;X = BCDE * X = X * X 014A8 E1 POP HL ;Restore table pointer and ;Series calulation 2 using ;X * X and multiply result ;again with X ; Series calculation 2 ; Calculate Taylor-series of the following form: ; ; y = k1 + k2*x + k3*x*x*x... (k1, k2, k3 are coefficients) ; ; I: HL -> coefficients table ; The first byte of the table indicates the number of coefficients ; in the table. Then the coefficients follow, in an inverted ; order (k1 last) ; X = factor in series (x in the example) ; O: X = result of series calculation (y in the example) 014A9 CDA409 CALL 09A4H ;(SP) = X 014AC 7E LD A,(HL) ;A = number of coefficients 014AD 23 INC HL ;HL -> 1st number (last ;coefficient in the series) 014AE CDB109 CALL 09B1H ;X = BCDE = (HL) = 1st coeff. 014B1 06F1 LD B,0F1H ;-- * 014B1 F1 POP AF ;Restore counter 014B3 C1 POP BC ;BCDE = X 014B4 D1 POP DE 014B5 3D DEC A ;Any more coefficients ? 014B6 C8 RET Z ;No: done, return 014B7 D5 PUSH DE ;Save BCDE 014B8 C5 PUSH BC 014B9 F5 PUSH AF ;Save counter 014BA E5 PUSH HL ;Save pointer 014BB CD4708 CALL 0847H ;Result = result + BCDE 014BE E1 POP HL ;Restore pointer 014BF CDC209 CALL 09C2H ;BCDE = (HL) = coefficient 014C2 E5 PUSH HL ;Save pointer 014C3 CD1607 CALL 0716H ;Result = result + BCDE 014C6 E1 POP HL ;Restore pointer 014C7 18E9 JR 14B2H ;Calculate next term ; X = RND ( X ) ; ------------- ; For X > 1: RND ( X ) = INT( RND(0) * INT(X) + 1 ) 014C9 CD7F0A CALL 0A7FH ;X = HL = CINT( argument ) 014CC 7C LD A,H ;Argument negative ? 014CD B7 OR A 014CE FA4A1E JP M,1E4AH ;Yes: ?FC Error 014D1 B5 OR L ;Argument = 0 ? 014D2 CAF014 JP Z,14F0H ;Yes: compute RND (0) 014D5 E5 PUSH HL ;Save argument 014D6 CDF014 CALL 14F0H ;Compute RND (0) 014D9 CDBF09 CALL 09BFH ;BCDE = X = RND (0) 014DC EB EX DE,HL ;(SP) = BCDE, HL = argument 014DD E3 EX (SP),HL 014DE C5 PUSH BC 014DF CDCF0A CALL 0ACFH ;X = CSNG (HL) 014E2 C1 POP BC ;BCDE = (SP) = RND (0) 014E3 D1 POP DE 014E4 CD4708 CALL 0847H ;X = X * BCDE ; = argument * RND (0) 014E7 21F807 LD HL,07F8H ;HL -> Constant 1 (SNG) 014EA CD0B07 CALL 070BH ;X = X + (HL) = X + 1 014ED C3400B JP 0B40H ;X = CINT (X) ; X = RND ( 0 ) ; = last random number * 0.253514 + 0.022228 (ignore carry) 014F0 219040 LD HL,4090H ;HL -> multiplicator 014F3 E5 PUSH HL ;Save pointer 014F4 110000 LD DE,0000H ;CDE = 000000H 014F7 4B LD C,E ;(Result in CDE) 014F8 2603 LD H,03H ;H = byte counter ;(3 bytes mantissa) 014FA 2E08 LD L,08H ;L = bit counter ;(8 bits per byte) 014FC EB EX DE,HL ;Shift CDE 1 bit to the left 014FD 29 ADD HL,HL ;(for multiplication) 014FE EB EX DE,HL 014FF 79 LD A,C 01500 17 RLA 01501 4F LD C,A 01502 E3 EX (SP),HL ;Save counter, restore pointer 01503 7E LD A,(HL) ;Shift next bit of 01504 07 RLCA ;multiplicator into C-flag 01505 77 LD (HL),A 01506 E3 EX (SP),HL ;Save pointer, restore counter ;Next bit = 1 ? 01507 D21615 JP NC,1516H ;No: continue at 1516H ;Yes: 0150A E5 PUSH HL ;Save pointer 0150B 2AAA40 LD HL,(40AAH) ;HL = LSBs of last random ;number 0150E 19 ADD HL,DE ;Add to result 0150F EB EX DE,HL 01510 3AAC40 LD A,(40ACH) ;A = MSB of last random number 01513 89 ADC A,C ;Add to result 01514 4F LD C,A 01515 E1 POP HL ;Restore counter 01516 2D DEC L ;Bit counter - 1 ;All bits done ? 01517 C2FC14 JP NZ,14FCH ;No: process next bit ;Yes: 0151A E3 EX (SP),HL ;Save counter, restore pointer 0151B 23 INC HL ;Pointer + 1 (process next byte ;of the multiplicator) 0151C E3 EX (SP),HL ;Save pointer, restore counter 0151D 25 DEC H ;Byte counter - 1 ;All 3 bytes processed ? 0151E C2FA14 JP NZ,14FAH ;No: process next byte ;Yes: 01521 E1 POP HL ;Remove pointer from stack 01522 2165B0 LD HL,0B065H ;and add 05B065H (=0.022228) 01525 19 ADD HL,DE ;to mantissa 01526 22AA40 LD (40AAH),HL ;Store new random number 01529 CDEF0A CALL 0AEFH ;Set VT = SNG 0152C 3E05 LD A,05H ;Adjust MSB 0152E 89 ADC A,C 0152F 32AC40 LD (40ACH),A ;And store it 01532 EB EX DE,HL ;CDE = mantissa of new random ;number 01533 0680 LD B,80H ;Set exponent = 80H 01535 212541 LD HL,4125H ;HL -> sign flag 01538 70 LD (HL),B ;Sign-flag = 80H ;(generate a positive number ;at SFLOAT) 01539 2B DEC HL ;HL -> Exp (X) 0153A 70 LD (HL),B ;Exp (X) = 80H (result < 1) 0153B 4F LD C,A ;Use MSB in BCDE 0153C 0600 LD B,00H ;LSB of CDEB = 00H 0153E C36507 JP 0765H ;Convert CDEB into SNG format ;and store in X (SFLOAT) ; X = COS ( X ) ; ------------- ; X = COS (X) = SIN (X + PI / 2). PI = 3.14159 01541 218B15 LD HL,158BH ;HL -> PI/2 01544 CD0B07 CALL 070BH ;X = argument + PI/2 ; X = SIN ( X ) ; ------------- 01547 CDA409 CALL 09A4H ;(SP) = argument 0154A 014983 LD BC,8349H ;BCDE = 6.28319 = 2*PI 0154D 11DB0F LD DE,0FDBH ;Sace X into the range of ;-1 to 1 01550 CDB409 CALL 09B4H ;X = BCDE = 2*PI 01553 C1 POP BC ;BCDE = argument 01554 D1 POP DE 01555 CDA208 CALL 08A2H ;X = X / BCDE = argument/(2*PI) 01558 CDA409 CALL 09A4H ;(SP) = X = argument/(2*PI) 0155B CD400B CALL 0B40H ;X = INT (X) ; = INT ( argument / (2*PI) ) 0155E C1 POP BC ;BCDE = argument / (2*PI) 0155F D1 POP DE 01560 CD1307 CALL 0713H ;X = BCDE - X ;= arg./(2*PI)-INT(arg./(2*PI)) ;(remove multiples of 2*PI) ;The argument (X) is now ;between -1 (corresponds to ;-2*PI) and 1 (corresponds to ;+2*PI) 01563 218F15 LD HL,158FH ;HL -> 1/4 01566 CD1007 CALL 0710H ;X = (HL) - X = 1/4 - X 01569 CD5509 CALL 0955H ;TEST2: X >= 0 ? (arg. > PI/2) 0156C 37 SCF ;C-flag = 1 0156D F27715 JP P,1577H ;Yes: continue at 1577H ;No: 01570 CD0807 CALL 0708H ;X = X + 1/2 01573 CD5509 CALL 0955H ;TEST2: X >= 0 ? (arg < PI/2) 01576 B7 OR A ;C-flag = 0 (for 1582H) 01577 F5 PUSH AF ;Save flags 01578 F48209 CALL P,0982H ;Yes: X = -X 0157B 218F15 LD HL,158FH ;HL -> 1/4 0157E CD0B07 CALL 070BH ;X = X + (HL) = X + 1/4 01581 F1 POP AF ;Restore flags 01582 D48209 CALL NC,0982H ;if (1/4-X) > 0 then X = -X 01585 219315 LD HL,1593H ;HL -> coefficients 01588 C39A14 JP 149AH ;Calculate series 1 0158B DB DEFB DBH ;Constant 1.5708 = PI / 2 0158C 0F DEFB 0FH 0158D 49 DEFB 49H 0158E 81 DEFB 81H 0158F 00 DEFB 00H ;Constant 0.25 = 1/4 01590 00 DEFB 00H 01591 00 DEFB 00H 01592 7F DEFB 7FH ; Coefficient table for SIN and COS ; '!' means faculty of the number (3! = 1 * 2 * 3) 01593 05 DEFB 05H ;5 coefficients 01594 BA DEFB BAH ;39.7107 01595 D7 DEFB D7H ;= ((2*PI) ^ 9) / 9! 01596 1E DEFB 1EH 01597 86 DEFB 86H 01598 64 DEFB 64H ;-76.575 01599 26 DEFB 26H ;= - ((2*PI) ^ 7) / 7! 0159A 99 DEFB 99H 0159B 87 DEFB 87H 0159C 58 DEFB 58H ;81.6022 0159D 34 DEFB 34H ;= ((2*PI) ^ 5) / 5! 0159E 23 DEFB 23H 0159F 87 DEFB 87H 015A0 E0 DEFB E0H ;-41.3417 015A1 5D DEFB 5DH ;= - ((2*PI) ^ 3) / 3! 015A2 A5 DEFB A5H 015A3 86 DEFB 86H 015A4 DA DEFB DAH ;6.28319 = 2*PI 015A5 0F DEFB 0FH ;= ((2*PI) ^ 1) / 1! 015A6 49 DEFB 49H 015A7 83 DEFB 83H ; X = TAN ( X ) ; ------------- ; X = TAN (X) = SIN (X) / COS (X) 015A8 CDA409 CALL 09A4H ;(SP) = argument 015AB CD4715 CALL 1547H ;X = SIN (argument) 015AE C1 POP BC ;BCHL = argument 015AF E1 POP HL 015B0 CDA409 CALL 09A4H ;(SP) = X = SIN (argument) 015B3 EB EX DE,HL ;BCDE = argument 015B4 CDB409 CALL 09B4H ;X = BCDE = argument 015B7 CD4115 CALL 1541H ;X = COS (argument) 015BA C3A008 JP 08A0H ;Result = (SP) / X ;= SIN (arg.) / COS (arg.) ; X = ATN ( X ) ; ------------- 015BD CD5509 CALL 0955H ;TEST2: argument < 0 ? 015C0 FCE213 CALL M,13E2H ;Yes: negate restult afterwards 015C3 FC8209 CALL M,0982H ;and continue processing with ;positive argument 015C6 3A2441 LD A,(4124H) ;A = Exp (argument) 015C9 FE81 CP 81H ;Argument < 1 ? 015CB 380C JR C,15D9H ;Yes: continue at 15D9H 015CD 010081 LD BC,8100H ;BCDE = 1.0 015D0 51 LD D,C 015D1 59 LD E,C 015D2 CDA208 CALL 08A2H ;X = BCDE / X = 1 / argument 015D5 211007 LD HL,0710H ;HL = address of X = (HL) - X 015D8 E5 PUSH HL ;Save as new RET address 015D9 21E315 LD HL,15E3H ;HL -> coefficient table 015DC CD9A14 CALL 149AH ;Calculate series 1 015DF 218B15 LD HL,158BH ;HL -> PI/2 015E2 C9 RET ;Result = PI/2 - X if ;argument was > 1 ;(Series calculation is only ;correct for -1 < X < 1) ; Coefficients for ATN 015E3 09 DEFB 09H ;9 coefficients 015E4 4A DEFB 4AH ;2.86623E-3 approx. 1/349 015E5 D7 DEFB D7H 015E6 3B DEFB 3BH 015E7 78 DEFB 78H 015E8 02 DEFB 02H ;-0.0161657 approx. -1/62 015E9 6E DEFB 6EH 015EA 84 DEFB 84H 015EB 7B DEFB 7BH 015EC FE DEFB FEH ;0.0429096 approx. 1/23 015ED C1 DEFB C1H 015EE 2F DEFB 2FH 015EF 7C DEFB 7CH 015F0 74 DEFB 74H ;-0.0752896 approx. -1/11 015F1 31 DEFB 31H 015F2 9A DEFB 9AH 015F3 7D DEFB 7DH 015F4 84 DEFB 84H ;0.106563 approx. 1/9 015F5 3D DEFB 3DH 015F6 5A DEFB 5AH 015F7 7D DEFB 7DH 015F8 C8 DEFB C8H ;-0.142089 approx. -1/7 015F9 7F DEFB 7FH 015FA 91 DEFB 91H 015FB 7E DEFB 7EH 015FC E4 DEFB E4H ;0.199936 = 1/5 015FD BB DEFB BBH 015FE 4C DEFB 4CH 015FF 7E DEFB 7EH 01600 6C DEFB 6CH ;-0.333331 = 1/3 01601 AA DEFB AAH 01602 AA DEFB AAH 01603 7F DEFB 7FH 01604 00 DEFB 00H ;1.0 = 1/1 01605 00 DEFB 00H 01606 00 DEFB 00H 01607 81 DEFB 81H ; Address table for Level II and Disk BASIC functions (tokens D7H to FAH) 01608 8A09 DEFW 098AH ;SNG 0160A 370B DEFW 0B37H ;INT 0160C 7709 DEFW 0977H ;ABS 0160E D427 DEFW 27D4H ;FRE 01610 EF2A DEFW 2AEFH ;INP 01612 F527 DEFW 27F5H ;POS 01614 E713 DEFW 13E7H ;SQR 01616 C914 DEFW 14C9H ;RND 01618 0908 DEFW 0809H ;LOG 0161A 3914 DEFW 1439H ;EXP 0161C 4115 DEFW 1541H ;COS 0161E 4715 DEFW 1547H ;SIN 01620 A815 DEFW 15A8H ;TAN 01622 BD15 DEFW 15BDH ;ATN 01624 AA2C DEFW 2CAAH ;PEEK 01626 5241 DEFW 4152H ;CVI 01628 5841 DEFW 4158H ;CVS 0162A 5E41 DEFW 415EH ;CVD 0162C 6141 DEFW 4161H ;EOF 0162E 6441 DEFW 4164H ;LOC 01630 6741 DEFW 4167H ;LOF 01632 6A41 DEFW 416AH ;MKI$ 01634 6D41 DEFW 416DH ;MKS$ 01636 7041 DEFW 4170H ;MKD$ 01638 7F0A DEFW 0A7FH ;CINT 0163A B10A DEFW 0AB1H ;CSNG 0163C DB0A DEFW 0ADBH ;CDBL 0163E 260B DEFW 0B26H ;FIX 01640 032A DEFW 2A03H ;LEN 01642 3628 DEFW 2836H ;STR$ 01644 C52A DEFW 2AC5H ;VAL 01646 0F2A DEFW 2A0FH ;ASC 01648 1F2A DEFW 2A1FH ;CHR$ 01649 612A DEFW 2A61H ;LEFT$ 0164A 912A DEFW 2A91H ;RIGHT$ 0164E 9A2A DEFW 2A9AH ;MID$ ; Table for keywords of Level II and Disk BASIC 01650 C54E44 DEFB 80H+'E','ND' ;END 01653 C64F52 DEFB 80H+'F','OR' ;FOR 01656 D245534554 DEFB 80H+'R','ESET' ;RESET 0165B D34554 DEFB 80H+'S','ET' ;SET 0165E C34C53 DEFB 80H+'C','LS' ;CLS 01661 C34D44 DEFB 80H+'C','MD' ;CMD 01664 D2414E444F4D DEFB 80H+'R','ANDOM ;RANDOM 0166A CE455854 DEFB 80H+'N','EXT' ;NEXT 0166E C4415441 DEFB 80H+'D','ATA' ;DATA 01672 C94E505554 DEFB 80H+'I','NPUT' ;INPUT 01677 C4494D DEFB 80H+'D','IM' ;DIM 0167A D2454144 DEFB 80H+'R','EAD' ;READ 0167E CC4554 DEFB 80H+'L','ET' ;LET 01681 C74F544F DEFB 80H+'G','OTO' ;GOTO 01685 D2554E DEFB 80H+'R','UN' ;RUN 01688 C946 DEFB 80H+'I','F' ;IF 0168A D24553544F5245 DEFB 80H+'R','ESTORE' ;RESTORE 01691 C74F535542 DEFB 80H+'G','OSUB' ;GOSUB 01696 D2455455524E DEFB 80H+'R','ETURN' ;RETURN 0169C D2454D DEFB 80H+'R','EM' ;REM 0169F D3544F50 DEFB 80H+'S','TOP' ;STOP 016A3 C54C5345 DEFB 80H+'E','LSE' ;ELSE 016A7 D4524F4E DEFB 80H+'T','RON' ;TRON 016AB D4524F4646 DEFB 80H+'T','ROFF' ;TROFF 016B0 C44546535452 DEFB 80H+'D','EFSTR' ;DEFSTR 016B6 C44546494E54 DEFB 80H+'D','EFINT' ;DEFINT 016BC C44546534E47 DEFB 80H+'D','EFSNG' ;DEFSNG 016C2 C4454644424C DEFB 80H+'D','EFDBL' ;DEFDBL 016C8 CC494E45 DEFB 80H+'L','INE' ;LINE 016CC C5444954 DEFB 80H+'E','DIT' ;EDIT 016D0 C552524F52 DEFB 80H+'E','RROR' ;ERROR 016D5 D24553554D45 DEFB 80H+'R','ESUME' ;RESUME 016DB CF5554 DEFB 80H+'O','UT' ;OUT 016DE CF4E DEFB 80H+'O','N' ;ON 016E0 CF50454E DEFB 80H+'O','PEN' ;OPEN 016E4 C649454C44 DEFB 80H+'F','IELD' ;FIELD 016E9 C74554 DEFB 80H+'G','ET' ;GET 016EC D05554 DEFB 80H+'P','UT' ;PUT 016EF C34C4F5345 DEFB 80H+'C','LOSE' ;CLOSE 016F4 CC4F4144 DEFB 80H+'L','OAD' ;LOAD 016F8 CD45524745 DEFB 80H+'M','ERGE' ;MERGE 016FD CE414D45 DEFB 80H+'N','AME' ;NAME 01701 CB494C4C DEFB 80H+'K','ILL' ;KILL 01705 CC534554 DEFB 80H+'L','SET' ;LSET 01709 D2534554 DEFB 80H+'R','SET' ;RSET 0170D D3415645 DEFB 80H+'S','AVE' ;SAVE 01711 D3595354454D DEFB 80H+'S','YSTEM' ;SYSTEM 01717 CC5052494E54 DEFB 80H+'L','PRINT' ;LPRINT 0171D C44546 DEFB 80H+'D','EF' ;DEF 01720 D04F4B45 DEFB 80H+'P','OKE' ;POKE 01724 D052494E54 DEFB 80H+'P','RINT' ;PRINT 01729 C34F4E54 DEFB 80H+'C','ONT' ;CONT 0172D CC495354 DEFB 80H+'L','IST' ;LIST 01731 CC4C495354 DEFB 80H+'L','LIST' ;LLIST 01736 C4454C455445 DEFB 80H+'D','ELETE' ;DELETE 0173C C155544F DEFB 80H+'A','UTO' ;AUTO 01740 C34C454152 DEFB 80H+'C','LEAR' ;CLEAR 01745 C34C4F4144 DEFB 80H+'C','LOAD' ;CLOAD 0174A C353415645 DEFB 80H+'C','SAVE' ;CSAVE 0174F CE4557 DEFB 80H+'N','EW' ;NEW 01752 D4414228 DEFB 80H+'T','AB(' ;TAB( 01756 D44F DEFB 80H+'T','0' ;TO 01758 C64E DEFB 80H+'F','N' ;FN 0175A D553494E47 DEFB 80H+'U','SING' ;USING 0175F D64152505452 DEFB 80H+'V','ARPTR' ;VARPTR 01765 D55352 DEFB 80H+'U','SR' ;USR 01768 C5524C DEFB 80H+'E','RN' ;ERN 0176B C55252 DEFB 80H+'E','RR' ;ERR 0176E D35452494E4724 DEFB 80H+'S','TRING$' ;STRING$ 01775 C94E535452 DEFB 80H+'I','NSTR' ;INSTR 0177A C34845434B DEFB 80H+'C','HECK' ;CHECK 0177F D4494D4524 DEFB 80H+'T','IME$' ;TIME$ 01784 CD454D DEFB 80H+'M','EM' ;MEM 01787 C94E4B455924 DEFB 80H+'I','NKEY$' ;INKEY$ 0178D D448454E DEFB 80H+'T','HEN' ;THEN 01791 CE4F54 DEFB 80H+'N','OT' ;NOT 01794 D3544550 DEFB 80H+'S','TEP' ;STEP 01798 AB DEFB 80H+'+' ;+ 01799 AD DEFB 80H+'-' ;- 0179A AA DEFB 80H+'*' ;* 0179B AF DEFB 80H+'/' ;/ 0179C DB DEFB 80H+'[' ;[ 0179D C14E44 DEFB 80H+'A','ND' ;AND 017A0 CF52 DEFB 80H+'O','R' ;OR 017A2 BE DEFB 80H+'>' ;> 017A3 BD DEFB 80H+'=' ;= 017A4 BC DEFB 80H+'<' ;< 017A5 D3474E DEFB 80H+'S','GN' ;SNG 017A8 C94E54 DEFB 80H+'I','NT' ;INT 017AB C14253 DEFB 80H+'A','BS' ;ABS 017AE C65245 DEFB 80H+'F','RE' ;FRE 017B1 C94E50 DEFB 80H+'I','NP' ;INP 017B4 D04F53 DEFB 80H+'P','OS' ;POS 017B7 D35152 DEFB 80H+'S','QR' ;SQR 017BA D24E44 DEFB 80H+'R','ND' ;RND 017BD CC4F47 DEFB 80H+'L','OG' ;LOG 017C0 C55850 DEFB 80H+'E','XP' ;EXP 017C3 C34F53 DEFB 80H+'C','OS' ;COS 017C6 D3494E DEFB 80H+'S','IN' ;SIN 017C9 D4414E DEFB 80H+'T','AN' ;TAN 017CC C1544E DEFB 80H+'A','TN' ;ATN 017CF D045454B DEFB 80H+'P','EEK' ;PEEK 017D3 C35649 DEFB 80H+'C','VI' ;CVI 017D6 C35653 DEFB 80H+'C','VS' ;CVS 017D9 C35644 DEFB 80H+'C','VD' ;CVD 017DC C54F46 DEFB 80H+'E','OF' ;EOF 017DF CC4F43 DEFB 80H+'L','OC' ;LOC 017E2 CC4F46 DEFB 80H+'L','OF' ;LOF 017E5 CD4B4924 DEFB 80H+'M','KI$' ;MKI$ 017E9 CD4B5324 DEFB 80H+'M','KS$' ;MKS$ 017ED CD4B4424 DEFB 80H+'M','KD$' ;MKD$ 017F1 C3494E54 DEFB 80H+'C','INT' ;CINT 017F5 C3534E47 DEFB 80H+'C','SNG' ;CSNG 017F9 C344424C DEFB 80H+'C','DBL' ;CDBL 017FD C64958 DEFB 80H+'F','IX' ;FIX 01800 CC454E DEFB 80H+'L','EN' ;LEN 01803 D3545224 DEFB 80H+'S','TR$' ;STR$ 01807 D6414C DEFB 80H+'V','AL' ;VAL 0180A C15343 DEFB 80H+'A','SC' ;ASC 0180D C3485224 DEFB 80H+'C','HR$' ;CHR$ 01811 CC45465424 DEFB 80H+'L','EFT$' ;LEFT$ 01816 D24947485424 DEFB 80H+'R','IGHT$' ;RIGHT$ 0181C CD494424 DEFB 80H+'M','ID$' ;MID$ 01820 A7 DEFB 80H+27H ;' 01821 80 DEFB 80H ;End of table ; Address table for Level II and Disk BASIC statements (tokens 80H to BBH) 01822 AE1D DEFW 1DAEH ;END 01824 A11C DEFW 1CA1H ;FOR 01826 3801 DEFW 0138H ;RESET 01828 3501 DEFW 0135H ;SET 0182A C901 DEFW 01C9H ;CLS 0182C 7341 DEFW 4173H ;CMD 0182E D301 DEFW 01D3H ;RANDOM 01830 B622 DEFW 22B6H ;NEXT 01832 051F DEFW 1F05H ;DATA 01834 9A21 DEFW 219AH ;INPUT 01836 0826 DEFW 2608H ;DIM 01838 EF21 DEFW 21EFH ;READ 0183A 211F DEFW 1F21H ;LET 0183C C21E DEFW 1EC2H ;GOTO 0183E A31E DEFW 1EA3H ;RUN 01840 3920 DEFW 2039H ;IF 01842 911D DEFW 1D91H ;RESTORE 01844 B11E DEFW 1EB1H ;GOSUB 01846 DE1E DEFW 1EDEH ;RETURN 01848 071F DEFW 1F07H ;REM 0184A A91D DEFW 1DA9H ;STOP 0184C 071F DEFW 1F07H ;ELSE 0184E F71D DEFW 1DF7H ;TRON 01850 F81D DEFW 1DF8H ;TROFF 01852 001E DEFW 1E00H ;DEFSTR 01854 031E DEFW 1E03H ;DEFINT 01856 061E DEFW 1E06H ;DEFSNG 01858 091E DEFW 1E09H ;DEFDBL 0185A A341 DEFW 41A3H ;LINE 0185C 602E DEFW 2E60H ;EDIT 0185E F41F DEFW 1FF4H ;ERROR 01860 AF1F DEFW 1FAFH ;RESUME 01862 FB2A DEFW 2AFBH ;OUT 01864 6C1F DEFW 1F6CH ;ON 01866 7941 DEFW 4179H ;OPEN 01868 7C41 DEFW 417CH ;FIELD 0186A 7F41 DEFW 417FH ;GET 0186C 8241 DEFW 4182H ;PUT 0186E 8541 DEFW 4185H ;CLOSE 01870 8841 DEFW 4188H ;LOAD 01872 8B41 DEFW 418BH ;MERGE 01874 8E41 DEFW 418EH ;NAME 01876 9141 DEFW 4191H ;KILL 01878 9741 DEFW 4197H ;LSET 0187A 9A41 DEFW 419AH ;RSET 0187C A041 DEFW 41A0H ;SAVE 0187E B202 DEFW 02B2H ;SYSTEM 01880 6720 DEFW 2067H ;LPRINT 01882 5B41 DEFW 415BH ;DEF 01884 B12C DEFW 2CB1H ;POKE 01886 6F20 DEFW 206FH ;PRINT 01888 E41D DEFW 1DE4H ;CONT 0188A 2E2B DEFW 2B2EH ;LIST 0188C 292B DEFW 2B29H ;LLIST 0188E C62B DEFW 2BC6H ;DELETE 01890 0820 DEFW 2008H ;AUTO 01892 7A1E DEFW 1E7AH ;CLEAR 01894 1F2C DEFW 2C1FH ;CLOAD 01896 F52B DEFW 2BF5H ;CSAVE 01898 491B DEFW 1B49H ;NEW ; Prioritytable for operators ; highest value corresponds with highest proirity 0189A 79 DEFB 79H ;+ 0189B 79 DEFB 79H ;- 0189C 7C DEFB 7CH ;* 0189D 7C DEFB 7CH ;/ 0189E 7F DEFB 7FH ;Exponent 0189F 50 DEFB 50H ;AND 018A0 46 DEFB 46H ;OR ; Address table for type conversion 018A1 DB0A DEFW 0ADBH ;0ADBH: CDBL 018A3 0000 DEFW 0000H ;0000H: unused entry in table 018A5 7F0A DEFW 0A7FH ;0A7FH: CINT 018A7 F40A DEFW 0AF4H ;0AF4H: ?TM error when no ; string in X 018A9 B10A DEFW 0AB1H ;0AB1H: CSNG ; Address table for basic arithmatic and comparisons ; 1. double precision 018AB 770C DEFW 0C77 ; + (X = X + Y) 018AD 700C DEFW 0C70 ; - (X = X - Y) 018AF A10D DEFW 0DA1 ; * (X = X * Y) 018B1 E50D DEFW 0DE5 ; / (X = X / Y) 018B3 780A DEFW 0A78 ; Compare (CP X , Y) ; 2. single precision 018B5 1607 DEFW 0716 ; + (X = BCDE + X) 018B7 1307 DEFW 0713 ; - (X = BCDE - X) 018B9 4708 DEFW 0847 ; * (X = BCDE * X) 018BB A208 DEFW 08A2 ; / (X = BCDE / X) 018BD 0C0A DEFW 0A0C ; Compare (CP X , BCDE) ; 3. integer 018BF D20B DEFW 0BD2 ; + (X = DE + HL) 018C1 C70B DEFW 0BC7 ; - (X = DE - HL) 018C3 F20B DEFW 0BF2 ; * (X = DE * HL) 018C5 9024 DEFW 2490 ; / (X = DE / HL) 018C7 390A DEFW 0A39 ; Compare (CP HL , DE) ; Table with character combinations for error messages 018C9 4E46 DEFB 'NF' 018CB 534E DEFB 'SN' 018CD 5247 DEFB 'RG' 018CF 4F44 DEFB 'OD' 018D1 4643 DEFB 'FC' 018D3 4F46 DEFB 'OF' 018D5 4F4D DEFB 'OM' 018D7 554C DEFB 'UL' 018D9 4253 DEFB 'BS' 018DB 4444 DEFB 'DD' 018DD 2F30 DEFB '/0' 018DF 4944 DEFB 'ID' 018E1 544D DEFB 'TM' 018E3 4F53 DEFB 'OS' 018E5 4C53 DEFB 'LS' 018E7 5354 DEFB 'ST' 018E9 434E DEFB 'CN' 018EB 4E52 DEFB 'NR' 018ED 5257 DEFB 'RW' 018EF 5545 DEFB 'UE' 018F1 4D4F DEFB 'MO' 018F3 4644 DEFB 'FD' 018F5 534E DEFB 'SN' ; Following 39 bytes are copied into system RAM from 4080H onwards 018F7 D600 SUB 00H 018F9 6F LD L,A 018FA 7C LD A,H 018FB DE00 SBC A,00H 018FD 67 LD H,A 018FE 78 LD A,B 018FF DE00 SBC A,00H 01901 47 LD B,A 01902 3E00 LD A,00H 01904 C9 RET 01905 4A LD C,D 01906 1E40 LD E,40H 01908 E64D AND 4DH 0190A DB00 IN A,(00H) 0190C C9 RET 0190D D300 OUT (00H),A 0190F C9 RET 01910 00 DEFB 00H 01911 00 DEFB 00H 01912 00 DEFB 00H 01913 00 DEFB 00H 01914 28 DEFB 28H 01914 1E DEFB 1EH 01916 00 DEFB 00H 01917 4C DEFB 4CH 01918 43 DEFB 43H 01919 FE DEFB FEH 01919 FF DEFB FFH 0191B 01 DEFB 01H 0191C 48 DEFB 48H ; Text ' Error' 0191D 204572726F72 DEFB ' Error' 01923 00 DEFB 00H ;End of string ; Text ' in ' 01924 2069 DEFB ' in ' 01928 00 DEFB 00H ;End of string ; Text 'READY' 01929 5245414459 DEFB 'READY' 0192E 0D DEFB 0DH ;Carriage Return 0192F 00 DEFB 00H ;End of string ; Text 'Break' 01930 427265616B DEFB 'Break' 01935 00 DEFB 00H ;End of string ; SUB for FOR, NEXT and RETURN ; Retrieves data from stack ; ; I: DE = VARPTR of new loop variable when a new FOR-TO loop is started ; DE = VARPTR of the variable indicated with NEXT ; DE = 0000H when NEXT with no variable ; O: DE = unchanged ; HL = 'stackpointer' on FOR-TO-stack + 1 (when Z-flag = 0) ; HL = 'stackpointer' on FOR-TO-stack + 3 (when Z-flag = 1) ; Z-flag = 0 when no FOR-TO-stack found or when the variable is not used ; in a loop ; Z-flag = 1 when call from NEXT or if the variable had already been used ; in a loop 01936 210400 LD HL,0004H 01939 39 ADD HL,SP ;HL = SP + 4 ;HL is now like stack pointer ;after 2 POPs 0193A 7E LD A,(HL) ;Get marker form stack 0193B 23 INC HL ;"stack pointer" + 1 0193C FE81 CP 81H ;FOR marker found ? 0193E C0 RET NZ ;No: done, return ;Yes: 0193F 4E LD C,(HL) ;BC = VARPTR of loop variable 01940 23 INC HL 01941 46 LD B,(HL) 01942 23 INC HL 01943 E5 PUSH HL ;save "stack pointer" 01944 69 LD L,C ;HL -> loop variable 01945 60 LD H,B 01946 7A LD A,D ;DE = 0000H (call from NEXT) ? 01947 B3 OR E 01948 EB EX DE,HL ;DE = VARPTR of loop variable ;found in stack ;HL = VARPTR of new loop ;variable ;Call from NEXT ? 01949 2802 JR Z,194DH ;Yes: done 0194B EB EX DE,HL ;Swap DE and HL 0194C DF RST 18H ;Compare both VARPTRs 0194D 010E00 LD BC,000EH ;BC = offset to next ;FOR-TO-stack 01950 E1 POP HL ;Restore "stack pointer" 01951 C8 RET Z ;Done if searched VARPTR found 01952 09 ADD HL,BC ;Increment "stack pointer" to ;next FOR-TO-stack. ;(Every FOR-TO-loop requires ;17 bytes of stack space. HL ;was already incremented by 3 ;(193BH, 1940H, 1942H). Add ;0EH (14) to get 17) 01953 18E5 JR 193AH ;Continue search in stack ; Move program text for insertion of a new line ; Copies memory from (BC) to (HL) until BC = DE ; ; I: BC -> old program end (before move) ; DE = LP of new line ; HL -> new program end (after move) ; O: DE = LP on new line ; HL = DE 01955 CD6C19 CALL 196CH ;Enough free memory available ? 01958 C5 PUSH BC ;Swap BC and HL 01959 E3 EX (SP),HL ;(because of RST 18H) 0195A C1 POP BC 0195B DF RST 18H ;New line reached ? 0195C 7E LD A,(HL) ;Copy byte from old location 0195D 02 LD (BC),A ;to new location 0195E C8 RET Z ;Yes: done, return 0195F 0B DEC BC ;Pointer - 1 01960 2B DEC HL 01961 18F8 JR 195BH ;Copy next byte ; Test if sufficient memory space is available ; ?OM Error if less than 2 * C bytes are available ; ; I: C = number of required bytes 01963 E5 PUSH HL ;Save PTP 01964 2AFD40 LD HL,(40FDH) ;HL -> start of free memory 01967 0600 LD B,00H ;BC = number of required bytes 01969 09 ADD HL,BC ;HL - HL + 2 * BC 0196A 09 ADD HL,BC 0196B 3EE5 LD A,0E5H ;-- ; Is there sufficient free space from (HL) onwards ? ; ; I: HL -> free memory space 0196B E5 PUSH HL ;Save HL ;HL now points to the new ;start of free memory 0196D 3EC6 LD A,0C6H ;HL = FFC6H - HL 0196F 95 SUB L 01970 6F LD L,A 01971 3EFF LD A,0FFH 01973 9C SBC A,H ;HL > FFC6H 01974 3804 JR C,197AH ;Yes: ?OM Error 01976 67 LD H,A ;MSB back to H 01977 39 ADD HL,SP ;HL = SP + (FFC6 - HL) 01978 E1 POP HL ;Restore HL 01979 D8 RET C ;If room until stack then ;return else ?OM Error 0197A 1E0C LD E,0CH ;E = error code for ?OM Error 0197C 1824 JR 19A2H ;Continue at error routine ; End program without 'END' 0197E 2AA240 LD HL,(40A2H) ;HL = current LN 01981 7C LD A,H ;Was a program finished ? 01982 A5 AND L ;(is LN <> 65535) 01983 3C INC A 01984 2808 JR Z,198EH ;No: go via 198EH to END 01986 3AF240 LD A,(40F2H) ;ON ERROR GOTO flag set ? 01989 B7 OR A 0198A 1E22 LD E,22H ;E = error code for ?NR error 0198C 2014 JR NZ,19A2H ;Flag set: ?NR Error 0198E C3C11D JP 1DC1H ;Continue at END ; ?SN Error in DATA line 01991 2ADA40 LD HL,(40DAH) ;HL = DATA LN 01994 22A240 LD (40A2H),HL ;Store as current LN ; ?SN Error 01997 1E02 LD E,02H ;E = error code for ?SN Error 01999 011E14 LD BC,141EH ;-- ; ?/0 Error * 0199A 1E14 LD E,14H ;E = error code for ?/0 Error 0199C 011E00 LD BC,001EH ;-- ; ?NF Error * 0199D 1E00 LD E,00H ;E = error code for ?NF Error 0199F 011E24 LD BC,241EH ;-- ; ?RW Error * 019A0 1E24 LD E,24H ;E = error code for ?RW Error ; Error routine ; Displays the error code and line number and aborts program ; ; I: E = (error code - 1) * 2 ; O: - (returns to active command mode or to error handling routine if ; ON ERROR GOTO was active 019A2 2AA240 LD HL,(40A2H) ;HL = current LN 019A5 22EA40 LD (40EAH),HL ;Save as ERL 019A8 22EC40 LD (40ECH),HL ;and '.' (current LN) 019AB 01B419 LD BC,19B4H ;19B4H = new return address 019AE 2AE840 LD HL,(40E8H) ;HL = last SP value 019B1 C39A1B JP 1B9AH ;Reinitialize stack 019B4 C1 POP BC ;Correct stack 019B5 7B LD A,E ;A = error code 019B6 4B LD C,E ;C = error code 019B7 329A40 LD (409AH),A ;Save error code as ERR 019BA 2AE640 LD HL,(40E6H) ;HL = PTP before error 019BD 22EE40 LD (40EEH),HL ;Save PTP for RESUME 019C0 EB EX DE,HL ;DE = PTP 019C1 2AEA40 LD HL,(40EAH) ;HL = LN 019C4 7C LD A,H ;LN = FFFH (65535 ?) 019C5 A5 AND L 019C6 3C INC A 019C7 2807 JR Z,19D0H ;Yes: error on active command ;mode level, continue at 19D0H 019C9 22F540 LD (40F5H),HL ;Save LN for CONT 019CC EB EX DE,HL ;HL = PTP 019CD 22F740 LD (40F7H),HL ;Save PTP for CONT 019D0 2AF040 LD HL,(40F0H) ;HL = LN of ON ERROR GOTO 019D3 7C LD A,H ;ON ERROR GOTO active ? 019D4 B5 OR L ;(LN <> 0 ?) 019D5 EB EX DE,HL ;DE = LN 019D6 21F240 LD HL,40F2H ;HL = ON ERROR GOT flag 019D9 2808 JR Z,19E3H ;No: continue at 19E3H 019DB A6 AND (HL) ;ON ERROR GOTO Flag set ? 019DC 2005 JR NZ,19E3H ;No: continue at 19E3H 019DE 35 DEC (HL) ;Flag - 1 (as counter ;for RESUME) 019DF EB EX DE,HL ;HL = PTP of ON ERROR GOTO line 019E0 C3361D JP 1D36H ;Continue program at (HL) ; Issue error 019E3 AF XOR A ;Clear ON ERROR GOTO flag 019E4 77 LD (HL),A 019E5 59 LD E,C ;E = Error code 019E6 CDF920 CALL 20F9H ;Start at new line 019E9 21C918 LD HL,18C9H ;HL -> Error codes table 019EC CDA641 CALL 41A6H ;DOS 019EF 57 LD D,A ;DE = offset in error table 019F0 3E3F LD A,3FH ;A = '?' 019F2 CD2A03 CALL 032AH ;Print it 019F5 19 ADD HL,DE ;HL -> Error code text 019F6 7E LD A,(HL) ;Print both characters 019F7 CD2A03 CALL 032AH ;Print 1st error character 019FA D7 RST 10H ;A = 2nd character 019FB CD2A03 CALL 032AH ;Print 2nd error character 019FE 211D19 LD HL,191DH ;HL -> ' Error' 01A01 E5 PUSH HL ;Save HL 01A02 2AEA40 LD HL,(40EAH) ;HL = ERL 01A05 E3 EX (SP),HL ;Save ERL and restore text ;pointer ; Entry for STOP (see 1DDEH) 01A06 CD7935 CALL 3579H ;Give text and sound 01A09 E1 POP HL ;Restore ERL 01A0A 11FEFF LD DE,0FFFEH ;Error originates from ;MEM SIZE? ;(ERL = 65534) 01A0D DF RST 18H ;Compare HL and DE 01A0E CA7406 JP Z,0674H ;Yes: back to start 1 01A11 7C LD A,H ;Error originates from program? 01A12 A5 AND L ;(ERL <> 65535) 01A13 3C INC A 01A14 C4A70F CALL NZ,0FA7H ;Yes: print ' in ' and LN 01A17 3EC1 LD A,0C1H ;Back into BASIC * 01A18 C1 POP BC ;-- ; Entry into active command mode 01A19 CD8B03 CALL 038BH ;End output to printer, ;next output to screen 01A1C CDAC41 CALL 41ACH ;DOS 01A1F 00 NOP ;-- 01A20 00 NOP 01A21 00 NOP 01A22 CDF920 CALL 20F9H ;Finish screen output 01A25 212919 LD HL,1929H ;HL -> READY text 01A28 CD9238 CALL 3892H ;Set LGR, NBGRD and print text 01A2B 3A9A40 LD A,(409AH) ;A = last error code 01A2E D602 SUB 02H ;Was it ?SN Error ? 01A30 CC532E CALL Z,2E53H ;Yes: call EDIT 01A33 21FFFF LD HL,0FFFFH ;Set current LN to 65535 01A36 22A240 LD (40A2H),HL 01A39 3AE140 LD A,(40E1H) ;AUTO active ? 01A3C B7 OR A 01A3D 2837 JR Z,1A76H ;No: goto normal command mode ; Process AUTO 01A3F 2AE240 LD HL,(40E2H) ;HL = AUTO-LN 01A42 E5 PUSH HL ;Save LN 01A43 CDAF0F CALL 0FAFH ;Print LN 01A46 D1 POP DE ;DE = LN 01A47 D5 PUSH DE ;Save LN 01A48 CD2C1B CALL 1B2CH ;Search LN and test if already :present 01A4B 3E2A LD A,'*' ;A = '*' ;LN already present ? 01A4D 3802 JR C,1A51H ;Yes: continue at 1A51H 01A4F 3E20 LD A,20H ;A = ' ' 01A51 CD2A03 CALL 032AH ;Print it 01A54 CD6103 CALL 0361H ;Input line 01A57 D1 POP DE ;Restore LN ; pressed ? 01A58 3006 JR NC,1A60H ;No: accept line 01A5A AF XOR A ;A = 00H 01A5B 32E140 LD (40E1H),A ;Switch off AUTO 01A5E 18B9 JR 1A19H ;Back to active command mode ; Accept AUTO line 01A60 2AE440 LD HL,(40E4H) ;HL = diffence to next LN 01A63 19 ADD HL,DE ;Calculate next AUTO-LN 01A64 38F4 JR C,1A5AH ;Abort AUTO if next LN ;becomes larger than 65535 01A66 D5 PUSH DE ;Save current LN 01A67 11F9FF LD DE,0FFF9H ;DE = 65530 (maximum LN + 1) 01A6A DF RST 18H ;Compare new LN with 65530 01A6B D1 POP DE ;Restore current LN ;new LN too large (> 65529) ? 01A6C 30EC JR NC,1A5AH ;Yes: abort AUTO 01A6E 22E240 LD (40E2H),HL ;Store next LN 01A71 F6FF OR 0FFH ;Set A <> 0 01A73 C3EB2F JP 2FEBH ;Accept line by EDIT routine ; Normal command or line input in active command mode 01A76 3E3E LD A,3EH ;A = '>' 01A78 CD2A03 CALL 032AH ;Print it 01A7B CD6103 CALL 0361H ;Input line ; pressed ? 01A7E DA331A JP C,1A33H ;Yes: back to active ;command mode 01A81 D7 RST 10H ;A = 1st character of ;entered line 01A82 3C INC A ;A = 00H ? 01A83 3D DEC A ;(no 'OR A' so that C-flag is ;not infuenced) 01A84 CA331A JP Z,1A33H ;Yes: back to active command ;mode 01A87 F5 PUSH AF ;Save flags 01A88 CD5A1E CALL 1E5AH ;Decode number 01A8B 2B DEC HL ;Set HL back to the 01A8C 7E LD A,(HL) ;All following spaces are 01A8D FE20 CP 20H ;last digit of the number 01A8F 28FA JR Z,1A8BH 01A91 23 INC HL ;HL -> first character in line 01A92 7E LD A,(HL) ;A = character 01A93 FE20 CP 20H ;Space ? 01A95 CCC909 CALL Z,09C9H ;Yes: HL + 1, the first space ;is not used because LIST ;automaticcaly inserts a space ;after the line number 01A98 D5 PUSH DE ;Save LN 01A99 CDC01B CALL 1BC0H ;Tokenize line 01A9C D1 POP DE ;Restore LN 01A9D F1 POP AF ;Restore flags 01A9E 22E640 LD (40E6H),HL ;Save HL as current PTP 01AA1 CDB241 CALL 41B2H ;DOS ;LN indicated ? 01AA4 D25A1D JP NC,1D5AH ;No: execute line directly ; Use line to program 01AA7 D5 PUSH DE ;Save LN 01AA8 C5 PUSH BC ;Save length of line 01AA9 AF XOR A ;A = 00H 01AAA 32DD40 LD (40DDH),A ;Clear STOP-flag 01AAD D7 RST 10H ;A = 1st character of tokenized ;line 01AAE B7 OR A ;A = 00H ? ;(No program text entered ;behind the line number ? ) 01AAF F5 PUSH AF ;Save flags 01AB0 EB EX DE,HL ;Save pointer 01AB1 22EC40 LD (40ECH),HL ;Save LN as '.'-LN 01AB4 EB EX DE,HL ;Restore pointer 01AB5 CD2C1B CALL 1B2CH ;LN already used in program ? 01AB8 C5 PUSH BC ;Save LP 01AB9 DCE42B CALL C,2BE4H ;Yes: delete line 01ABC D1 POP DE ;Restore LP 01ABD F1 POP AF ;Restore flags 01ABE D5 PUSH DE ;Save LP ;Z-flag = 1 (see 1AAEH) ? 01ABF 2827 JR Z,1AE8H ;Yes: the line had only to be ;deleted. Now only the LPs in ;the program have to be renewed 01AC1 D1 POP DE ;Restore LP 01AC2 2AF940 LD HL,(40F9H) ;HL -> program end 01AC5 E3 EX (SP),HL ;HL = length of line 01AC6 C1 POP BC ;BC -> program end 01AC7 09 ADD HL,BC ;HL -> new program end 01AC8 E5 PUSH HL ;Save pointer 01AC9 CD5519 CALL 1955H ;Make room for new line 01ACC E1 POP HL ;Restore pointer to new program 01ACD 22F940 LD (40F9H),HL ;end and store it in system RAM 01AD0 EB EX DE,HL ;HL = new LP 01AD1 74 LD (HL),H ;Set LP to next line <> 0 01AD2 D1 POP DE ;Restore LN 01AD3 E5 PUSH HL ;Save LP 01AD4 23 INC HL ;LP + 2 01AD5 23 INC HL 01AD6 73 LD (HL),E ;Insert new LP in program 01AD7 23 INC HL 01AD8 72 LD (HL),D 01AD9 23 INC HL 01ADA EB EX DE,HL ;DE -> free space for line text 01ADB 2AA740 LD HL,(40A7H) ;HL -> line buffer 01ADE EB EX DE,HL ;HL -> program ;DE -> new line + 2 01ADF 1B DEC DE ;DE - 2 01AE0 1B DEC DE 01AE1 1A LD A,(DE) ;copy byte from buffer 01AE2 77 LD (HL),A ;into program 01AE3 23 INC HL ;Pointer + 1 01AE4 13 INC DE 01AE5 B7 OR A ;End of line reached ? 01AE6 20F9 JR NZ,1AE1H ;No: continue copy ;Yes: 01AE8 D1 POP DE ;DE = LP of new line 01AE9 CDFC1A CALL 1AFCH ;Renew all LPs in program ;from DE onwards 01AEC CDB541 CALL 41B5H ;DOS 01AEF CD5D1B CALL 1B5DH ;CLEAR 01AF2 CDB841 CALL 41B8H ;DOS 01AF5 C3331A JP 1A33H ;Back to active command mode ; Renew all LPs in program 01AF8 2AA440 LD HL,(40A4H) ;HL = start of program 01AFB EB EX DE,HL ;DE = start of program ; Renew all LPs in program from DE onwards 01AFC 62 LD H,D ;HL = LP 01AFD 6B LD L,E 01AFE 7E LD A,(HL) ;LP to next line = 0 ? 01AFF 23 INC HL 01B00 B6 OR (HL) ;(end of program reached ?) 01B01 C8 RET Z ;Yes: done, return ;No: 01B02 23 INC HL ;Increment HL to line text 01B03 23 INC HL 01B04 23 INC HL 01B05 AF XOR A ;A = 00H 01B06 BE CP (HL) ;Search for 00H (end of line) 01B07 23 INC HL ;Pointer + 1 01B08 20FC JR NZ,1B06H ;Continue search 01B0A EB EX DE,HL ;DE = LP on next line 01B0B 73 LD (HL),E ;Set line 01B0C 23 INC HL 01B0D 72 LD (HL),D 01B0E 18EC JR 1AFCH ;Process next line ; Decode line numbers at LIST and DELETE ; (LIST. , LIST FF , LIST FF-LL , LIST FF- , LIST -LL etc. ) ; ; I: HL = PTP on character following command (line number in ASCII format) ; O: BC -> first line (FF in example) ; DE = starting LN (FF in example) (default = 0) ; HL -> next line (after FF) ; (SP) = end-LN (LL in example) (default = 65529) 01B10 110000 LD DE,0000H ;Default first LN = 0 01B13 D5 PUSH DE ;Save first LN ;LNs indicated ? 01B14 2809 JR Z,1B1FH ;No: continue at 1B1FH ;Yes: 01B16 D1 POP DE ;Restore first LN 01B17 CD4F1E CALL 1E4FH ;Decode first LN 01B1A D5 PUSH DE ;Save first LN ;( = 0 if '-' indicated) ;Only 1 LN indicated ? 01B1B 280B JR Z,1B28H ;Yes: continue at 1B1FH 01B1D CF RST 08H ;'-' indicated ? 01B1E CE DEFB 0CEH ;'-' token 01B1F 11FAFF LD DE,FFFAH ;Default last LN = 65529 01B22 C44F1E JP Z,1E4FH ;Decode last LN 01B25 C29719 JR NZ,1997 ;?SN Error ? 01B28 EB EX DE,HL ;HL = last LN 01B29 D1 POP DE ;Restore first LN 01B2A E3 EX (SP),HL ;Save last LN 01B2B E5 PUSH HL ;RET address back on stack ; Search line number DE in program ; ; I: DE = line number of line to be searched ; O: BC -> searched line (if line found) or program end (line not found) ; DE = line number ; HL -> next line ; Z-flag = 1, C-flag = 1: search succesfull ; Z-flag = 1, C-flag = 0: BC -> program end ; Z-flag = 0, C-flag = 0: BC -> line with largerst LN < searched LN 01B2C 2AA440 LD HL,(40A4H) ;HL -> first program lline 01B2F 44 LD B,H ;BC = LP 01B30 4D LD C,L 01B31 7E LD A,(HL) ;LP to next line = 0 ? 01B32 23 INC HL 01B33 B6 OR (HL) 01B34 2B DEC HL ;Reverse INC HL 01B35 C8 RET Z ;Yes: done, return 01B36 23 INC HL ;Increment HL to line number 01B37 23 INC HL 01B38 7E LD A,(HL) ;HL = line number 01B39 23 INC HL 01B3A 66 LD H,(HL) 01B3B 6F LD L,A 01B3C DF RST 18H ;Compare with line number ;to be searched for 01B3D 60 LD H,B ;LP back to HL 01B3E 69 LD L,C 01B3F 7E LD A,(HL) ;HL -> next line 01B40 23 INC HL 01B41 66 LD H,(HL) 01B42 6F LD L,A 01B43 3F CCF ;C-flag = 1 for succesfull ;search 01B44 C8 RET Z ;Done if line found 01B45 3F CCF ;Reverse C-flag again 01B46 D0 RET NC ;RET if LN found > ;LN to be searched for 01B47 18E6 JR 1B2FH ;Check next line ; NEW statement ; ------------- 01B49 C0 RET NZ ;?SN Error ? 01B4A CDC901 CALL 01C9H ;CLS 01B4D 2AA440 LD HL,(40A4H) ;HL -> start of BASIC program 01B50 CDF81D CALL 1DF8H ;TROFF 01B53 32E140 LD (40E1H),A ;Switch off AUTO 01B56 77 LD (HL),A ;Set LP to second line 01B57 23 INC HL ;to zero 01B58 77 LD (HL),A 01B59 23 INC HL 01B5A 22F940 LD (40F9H),HL ;Program end = program start+2 ; Entry for RUN without line number (RET on program loop) 01B5D 2AA440 LD HL,(40A4H) ;HL -> BASIC program start 01B60 2B DEC HL ;HL - 1 ; CLEAR without argument 01B61 22DF40 LD (40DFH),HL ;Store PTP to first/next ;command 01B64 061A LD B,1AH ;DEFSNG A-Z (B = 26) 01B66 210141 LD HL,4101H ;HL -> DEF table 01B69 3604 LD (HL),04H ;Set type code on SNG 01B6B 23 INC HL ;Pointer + 1 01B6C 10FB DJNZ 1B69H ;Loop 01B6E AF XOR A ;A = 00H 01B6F 32F240 LD (40F2H),A ;Clear ON ERROR GOTO flag 01B72 6F LD L,A ;HL = 0000H 01B73 67 LD H,A 01B74 22F040 LD (40F0H),HL ;ON ERROR GOTO LN = 0 01B77 22F740 LD (40F7H),HL ;CONT PTP = 0 01B7A 2AB140 LD HL,(40B1H) ;HL = TOPMEM 01B7D 22D640 LD (40D6H),HL ;Address of last string in ;string space = TOPMEM ;(delete all strings) 01B80 CD911D CALL 1D91H ;RESTORE 01B83 2AF940 LD HL,(40F9H) ;HL -> BASIC program end 01B86 22FB40 LD (40FBH),HL ;End of variable tables 01B89 22FD40 LD (40FDH),HL ;is end of BASIC program: ;Delete all variables 01B8C CDBB41 CALL 41BBH ;DOS 01B8F C1 POP BC ;BC = return address 01B90 2AA040 LD HL,(40A0H) ;HL -> start of string memory 01B93 2B DEC HL ;HL - 2 01B94 2B DEC HL 01B95 22E840 LD (40E8H),HL ;Set new program stack 01B98 23 INC HL 01B99 23 INC HL 01B9A F9 LD SP,HL ;SP = start of string memory 01B9B 21B540 LD HL,40B5H ;HL -> start of string table 01B9E 22B340 LD (40B3H),HL ;Set pointer to first free ;position in string table 01BA1 CD8B03 CALL 038BH ;End output to printer 01BA4 CD6921 CALL 2169H ;Next output to screen 01BA7 AF XOR A ;A = 0 01BA8 67 LD H,A ;HL = 0000H 01BA9 6F LD L,A 01BAA 32DC40 LD (40DCH),A ;Release array variables 01BAD E5 PUSH HL ;Put HL on stack 01BAE C5 PUSH BC ;Set new return address 01BAF 2ADF40 LD HL,(40DFH) ;HL = entry address SYSTEM 01BB2 C9 RET ; SUB for INPUT ; Print '? ' and input line 01BB3 3E3F LD A,3FH ;A = '?' 01BB5 CD2A03 CALL 032AH ;Print it 01BB8 3E20 LD A,20H ;A = ' ' 01BBA CD2A03 CALL 032AH ;Print it 01BBD C36103 JP 0361H ;Input line ; SUB for active command mode ; Tokenize program text in line buffer ; Text pointer = pointer on entered text ; Buffer pointer = pointer on tokenized text ; ; I: HL = text pointer ; O: BC = number of required memory bytes (line length) ; DE -> end of tokenized text ; HL -> start of tokenized text - 1 01BC0 AF XOR A ;A = 00H 01BC1 32B040 LD (40B0H),A ;Allow tokenizing 01BC4 4F LD C,A ;Counter = 0 01BC5 EB EX DE,HL ;DE = text pointer 01BC6 2AA740 LD HL,(40A7H) ;HL -> start of line buffer 01BC9 2B DEC HL 01BCA 2B DEC HL 01BCB EB EX DE,HL ;DE = buffer pointer ;HL = text pointer 01BCC 7E LD A,(HL) ;A = text character 01BCD FE20 CP 20H ;Space ? 01BCF CA5B1C JP Z,1C5BH ;Yes: store character ;No: 01BD2 47 LD B,A ;B = character 01BD3 FE22 CP 22H ;Start of a string ? 01BD5 CA771C JP Z,1C77H ;Yes: continue at 1C77H ;No: 01BD8 B7 OR A ;End of line reached ? 01BD9 CA7D1C JP Z,1C7DH ;Yes: continue at 1C7DH ;No: 01BDC 3AB040 LD A,(40B0H) ;Tokenizing allowed ? 01BDF B7 OR A 01BE0 7E LD A,(HL) ;A = text character 01BE1 C25B1C JP NZ,1C5BH ;No: accept character ;Yes: 01BE4 FE3F CP '?' ;Is it '?' 01BE6 3EB2 LD A,0B2H ;A = PRINT token 01BE8 CA5B1C JP Z,1C5BH ;Yes: store PRINT token ;No: 01BEB 7E LD A,(HL) ;A = text character 01BEC FE30 CP '0' ;Is it a digit ? 01BEE 3805 JR C,1BF5H ;No: tokenize character ;Yes: 01BF0 FE3C CP 3CH ;Character before '<' ? 01BF2 DA5B1C JP C,1C5BH ;Yes: accept character (the ;characters '<' , '=' and '>' ;are tokenized) ; Tokenize character / text 01BF5 D5 PUSH DE ;Save buffer pointer 01BF6 114F16 LD DE,164FH ;DE -> Keyword table 01BF9 C5 PUSH BC ;Save counter 01BFA 013D1C LD BC,1C3DH ;Set new RET address 01BFD C5 PUSH BC ;to 1C3DH 01BFE 067F LD B,7FH ;B = token counter 01C00 7E LD A,(HL) ;A = text character 01C01 FE61 CP 'a' ;Character < 'a' ? 01C03 3807 JR C,1C0CH ;Yes: continue at 1C0CH 01C05 FE7B CP 'z'+1 ;Character > 'z' ? 01C07 3003 JR NC,1C0CH ;Yes: continue at 1C0CH 01C09 E65F AND 5FH ;Convert to upper case 01C0B 77 LD (HL),A ;Store character 01C0C 4E LD C,(HL) ;C = text character 01C0D EB EX DE,HL ;HL = table pointer 01C0E 23 INC HL ;Table pointer + 1 01C0F B6 OR (HL) ;Next keyword reached ? 01C10 F20E1C JP P,1C0EH ;No: increment HL to next ;keyword 01C13 04 INC B ;Yes: token counter + 1 01C14 7E LD A,(HL) ;A = table character 01C15 CDE238 CALL 38E2H ;Intercept Colour BASIC ;keywords 01C18 B9 CP C ;Compare text character with ;table character; the same ? 01C19 20F3 JR NZ,1C0EH ;No: increment table pointer ;to next keyword and check ;again 01C1B EB EX DE,HL ;DE = table pointer ;HL = buffer pointer on first ;character 01C1C E5 PUSH HL ;Save buffer pointer 01C1D 13 INC DE ;Get next character 01C1E 1A LD A,(DE) ;from table 01C1F B7 OR A ;Next keyword reached ? 01C20 FA391C JP M,1C39H ;Yes: Put token in B ;No: 01C23 4F LD C,A ;C = table character 01C24 78 LD A,B ;A = token counter 01C25 FE8D CP 8DH ;At GOTO token ? 01C27 2002 JR NZ,1C2BH ;No: continue at 1C2BH 01C29 D7 RST 10H ;Increment text pointer to next ;character (GOTO can also be ;written as GO TO !) 01C2A 2B DEC HL ;HL - 1 because of HL + 1 ;in the RST 10H 01C2B 23 INC HL ;Text pointer + 1 01C2C 7E LD A,(HL) ;A = next character 01C2D FE61 CP 'a' ;Lower case ? 01C2F 3802 JR C,1C33H ;No: ok, continue at 1C33H 01C31 E65F AND 5FH ;Convert to upper case 01C33 B9 CP C ;Text character the same as ;table character 01C34 28E7 JR Z,1C1DH ;Yes: compare next character ;No: 01C36 E1 POP HL ;Set text pointer back to first ;character 01C37 18D3 JR 1C0CH ;And compare with next keyword ; Compare ended succesfully 01C39 48 LD C,B ;C = token 01C3A F1 POP AF ;Remove text pointer from stack 01C3B EB EX DE,HL ;DE = text pointer 01C3C C9 RET ; Store token or character 01C3D EB EX DE,HL ;HL = text pointer 01C3E 79 LD A,C ;A = token 01C3F C1 POP BC ;Restore character counter 01C40 D1 POP DE ;Restore buffer pointer 01C41 EB EX DE,HL ;DE = text pointer ;HL = buffer pointer 01C42 FE95 CP 95H ;'ELSE' token ? 01C44 363A LD (HL),3AH ;Put ':' in buffer 01C46 2002 JR NZ,1C4AH ;No: do not use ':' ;Yes: 01C48 0C INC C ;Counter + 1 01C49 23 INC HL ;Buffer pointer + 1: ; ':' is used 01C4A FEFB CP 0FBH ;Apostroph ? (REM) 01C4C 200C JR NZ,1C5AH ;No: implement token ;Yes: 01C4E 363A LD (HL),':' ;Put ':' in buffer 01C50 23 INC HL ;Buffer poiner + 1 01C51 0693 LD B,93H ;B = 'REM' token 01C53 70 LD (HL),B ;Put token in buffer 01C54 23 INC HL ;Buffer pointer + 1 01C55 EB EX DE,HL ;DE = buffer pointer 01C56 0C INC C ;Counter + 1 (for ':') 01C57 0C INC C ;Counter + 1 (for 'REM') 01C58 181D JR 1C77H ;Use all characters until end ;of line (REM line) ; Use token or character in A 01C5A EB EX DE,HL ;DE = buffer pointer 01C5B 23 INC HL ;Text pointer + 1 01C5C 12 LD (DE),A ;Store token in buffer 01C5D 13 INC DE ;Buffer pointer + 1 01C5E 0C INC C ;Counter + 1 01C5F D63A SUB ':' ;':' ? (SUBtract !!) 01C61 2804 JR Z,1C67H ;Yes: release tokenizing and ;tokenize next character 01C63 FE4E CP 4EH ;'DATA' token ? ;(4EH + 3AH = 88H) 01C65 2003 JR NZ,1C6AH ;No: leave flag, continue at ;1C6AH 01C67 32B040 LD (40B0H),A ;Yes: block tokenizing (A=4EH) 01C6A D659 SUB 59H ;'REM' token ? (SUBtract !!) 01C6C C2CC1B JP NZ,1BCCH ;No: tokenize next character ;Yes: 01C6F 47 LD B,A ;Set B = 0 as compare char. ; Use all characters until end of line or until character = B 01C70 7E LD A,(HL) ;A = text character 01C71 B7 OR A ;End of line reached ? 01C72 2809 JR Z,1C7DH ;Yes: done, continue ar 1C7DH ;No: 01C74 B8 CP B ;Same as compare character ? 01C75 28E4 JR Z,1C5BH ;Yes: implement character. ;No: 01C77 23 INC HL ;Text pointer + 1 01C78 12 LD (DE),A ;Store character in buffer 01C79 0C INC C ;Counter + 1 01C7A 13 INC DE ;Buffer pointer + 1 01C7B 18F3 JR 1C70H ;Next character ; Line completely tokenized 01C7D 210500 LD HL,0005H ;Add 5 bytes to total length 01C80 44 LD B,H ;(2 bytes line pointer, 2 bytes 01C81 09 ADD HL,BC ;line number, 1 byte line end) 01C82 44 LD B,H ;BC = number of bytes required 01C83 4D LD C,L ;in memory 01C84 2AA740 LD HL,(40A7H) ;HL -> line buffer 01C87 2B DEC HL ;HL -> tokenized line - 1 01C88 2B DEC HL 01C89 2B DEC HL 01C8A 12 LD (DE),A ;Terminate tokenized line 01C8B 13 INC DE ;with 3 times 00H 01C8C 12 LD (DE),A 01C8D 13 INC DE 01C8E 12 LD (DE),A 01C8F C9 RET ; SUB RST 18H: 16 bit compare ; Compares DE with HL and set flags according to result ; (like CP HL,DE) 01C90 7C LD A,H ;A = MSB of HL 01C91 92 SUB D ;Subtract MSB of DE ;H = D ? 01C92 C0 RET NZ ;No: return 01C93 7D LD A,L ;Same with LSBs 01C94 93 SUB E 01C95 C9 RET ; SUB RST 08H: syntax check ; Compare the byte in (HL) with the byte following the RST 08H in memory. ; If they are equal then a RST 10H is executed and the routine returns to ; the normal RET-address + 1 (because the compare byte is located at the ; RET-address). If both bytes are not equal a ?SN Error is generated 01C96 7E LD A,(HL) ;A = text character 01C97 E3 EX (SP),HL ;HL -> compare character 01C98 BE CP (HL) ;The same ? 01C99 23 INC HL ;HL + 1 for RET-address 01C9A E3 EX (SP),HL ;RET-address on stack 01C9B CA781D JP Z,1D78H ;Yes: equal so RST 10H ;No: 01C9E C39719 JP 1997H ;?SN Error ; FOR statement ; ------------- 01CA1 3E64 LD A,64H ;A <> 0 01CA3 32DC40 LD (40DCH),A ;Block array variables 01CA6 CD211F CALL 1F21H ;Execute LET (set loop ;variable and initialize it) 01CA9 E3 EX (SP),HL ;Save PTP, HL = RET-address ;DE = VARPTR on loop variable 01CAA CD3619 CALL 1936H ;Already a FOR-TO-loop active ;using this variable ? 01CAD D1 POP DE ;Restore PTP 01CAE 2005 JR NZ,1CB5H ;No: continue at 1CB5H ;Yes: 01CB0 09 ADD HL,BC ;HL = HL + 14 (BC = 000EH) 01CB1 F9 LD SP,HL ;Terminate previous loop using ;this variable (delete from ;stack) 01CB2 22E840 LD (40E8H),HL ;Save new SP 01CB5 EB EX DE,HL ;HL = PTP 01CB6 0E08 LD C,08H ;Are there 16 bytes (2*C) free? 01CB8 CD6319 CALL 1963H ;(17 bytes are needed) 01CBB E5 PUSH HL ;Save PTP 01CBC CD051F CALL 1F05H ;Increment PTP to next command ;(PTP is then pointing on the ;first command within the loop) 01CBF E3 EX (SP),HL ;Save new PTP, HL = old PTP 01CC0 E5 PUSH HL ;Save PTP 01CC1 2AA240 LD HL,(40A2H) ;HL= current LN 01CC4 E3 EX (SP),HL ;Save LN, restore PTP 01CC5 CF RST 08H ;Next byte must be the 01CC6 BD DEFB 0BDH ;'TO' token 01CC7 E7 RST 20H ;TSTTYP ;STR type ? 01CC8 CAF60A JP Z,0AF6H ;Yes: ?TM Error ;DBL type ? 01CCB D2F60A JP NC,0AF6H ;Yes: ?TM Error 01CCE F5 PUSH AF ;Save type code - 3 01CCF CD3723 CALL 2337H ;X = final value of loop 01CD2 F1 POP AF ;Restore type code 01CD3 E5 PUSH HL ;Save PTP ;Loop in SNG format ? 01CD4 F2EC1C JP P,1CECH ;Yes: continue at 1CECH ; INT loop 01CD7 CD7F0A CALL 0A7FH ;Convert final value to INT 01CDA E3 EX (SP),HL ;Save final value, restore PTP 01CDB 110100 LD DE,0001H ;DE = default step value (1) 01CDE 7E LD A,(HL) ;A = next character 01CDF FECC CP 0CCH ;'STEP' token ? 01CE1 CC012B CALL Z,2B01H ;Yes: DE = step value 01CE4 D5 PUSH DE ;Save step value 01CE5 E5 PUSH HL ;Save PTP 01CE6 EB EX DE,HL ;HL = step value 01CE7 CD9E09 CALL 099EH ;A = SGN (step value) 01CEA 1822 JR 1D0EH ;Continue at 1D0EH ; SNG loop 01CEC CDB10A CALL 0AB1H ;Convert final value to SGN 01CEF CDBF09 CALL 09BFH ;BCDE = X = final value 01CF2 E1 POP HL ;Restore PTP 01CF3 C5 PUSH BC ;Save final value 01CF4 D5 PUSH DE 01CF5 010081 LD BC,8100H ;BCDE = default step value (1) 01CF8 51 LD D,C 01CF9 5A LD E,D 01CFA 7E LD A,(HL) ;A = next character 01CFB FECC CP 0CCH ;'STEP' token ? 01CFD 3E01 LD A,01H ;A = SNG (default step value) 01CFF 200E JR NZ,1D0FH ;No: continue at 1D0FH ;Yes: 01D01 CD3823 CALL 2338H ;X = step value 01D04 E5 PUSH HL ;Save PTP 01D05 CDB10A CALL 0AB1H ;X = CSGN (X) 01D08 CDBF09 CALL 09BFH ;BCDE = X = step value 01D0B CD5509 CALL 0955H ;A = SNG(step value) ; FOR stack wrap up 01D0E E1 POP HL ;Restore PTP 01D0F C5 PUSH BC ;Save step value 01D10 D5 PUSH DE ;(for SNG loop) 01D11 4F LD C,A ;C = SGN (step value) 01D12 E7 RST 20H ;TSTTYP (step value) 01D13 47 LD B,A ;B = type code - 3 01D14 C5 PUSH BC ;Save type code and ;SNG (step value) 01D15 E5 PUSH HL ;Save PTP 01D16 2ADF40 LD HL,(40DFH) ;HL = VARPTR of loop variable 01D19 E3 EX (SP),HL ;Save VARPTR, restore PTP 01D1A 0681 LD B,81H ;B = 'FOR' token 01D1C C5 PUSH BC ;Mark stack 01D1D 33 INC SP ;Remove LSB ; Program loop ; Return address after execution of a command in the program ; HL (PTP) must point to end of command (':') to end of line (00H) 01D1E CD5803 CALL 0358H ;Get key 01D21 B7 OR A ;Key pressed ? 01D22 C4A01D CALL NZ,1DA0H ;Yes: +<@> or ? 01D25 22E640 LD (40E6H),HL ;Save PTP 01D28 ED73E840 LD (40E8H),SP ;Save SP 01D2C 7E LD A,(HL) ;A = next character 01D2D FE3A CP 3AH ;= ':' ? 01D2F 2829 JR Z,1D5AH ;Yes: ok, continue at 1DA5H ;No: 01D31 B7 OR A ;= 00H ? (end of line) 01D32 C29719 JP NZ,1997H ;No: ?SN Error ; Start new line 01D35 23 INC HL ;PTP + 1 01D36 7E LD A,(HL) ;Test pointer to next line 01D37 23 INC HL 01D38 B6 OR (HL) ;= 0000H (end of program) ? 01D39 CA7E19 JP Z,197EH ;Yes: end program. ;No: 01D3C 23 INC HL ;DE = line number 01D3D 5E LD E,(HL) 01D3E 23 INC HL 01D3F 56 LD D,(HL) 01D40 EB EX DE,HL ;HL = LN, DE = PTP 01D41 22A240 LD (40A2H),HL ;Store current LN 01D44 3A1B41 LD A,(411BH) ;TRACE active ? 01D47 B7 OR A ;(411BH) <> 0 ? 01D48 280F JR Z,1D59H ;No: continue at 1D59H ; Execute TRACE 01D4A D5 PUSH DE ;Save PTP 01D4B 3E3C LD A,3CH ;A = '<' 01D4D CD2A03 CALL 032AH ;Print it 01D50 CDAF0F CALL 0FAFH ;Print HL as decimal number ;(line number) 01D53 3E3E LD A,3EH ;A = '>' 01D55 CD2A03 CALL 032AH ;Print it 01D58 D1 POP DE ;Restore PTP 01D59 EB EX DE,HL ;HL = PTP, DE = LN 01D5A D7 RST 10H ;Next character to A 01D5B 111E1D LD DE,1D1EH ;Set new RET address 01D5E D5 PUSH DE ;to 1D1EH 01D5F C8 RET Z ;RET when end of line reached 01D60 D680 SUB 80H ;Token found ? 01D62 DA211F JP C,1F21H ;No: interpret character as ;a variable, continue at LET 01D65 FE3C CP 3CH ;Statement or function ? 01D67 C3C039 JP 39C0H ;Colour-keyword found ? 01D6A 07 RLCA ;A = token-number * 2 01D6B 4F LD C,A ;BC = offset for address table 01D6C 0600 LD B,00H 01D6E EB EX DE,HL ;DE = PTP 01D6F 212218 LD HL,1822H ;HL -> address table 01D72 09 ADD HL,BC ;Add offset 01D73 4E LD C,(HL) ;Load command address in BC 01D74 23 INC HL 01D75 46 LD B,(HL) 01D76 C5 PUSH BC ;Put address on stack for RET 01D77 EB EX DE,HL ;HL = PTP ; SUB RST 10H: increment PTP to next character <> 20H (space) ; ; I: HL = PTP ; O: HL = PTP (+1 at least) ; A = character at (HL) ; C-flag = 1 if digit found ; Z-flag = 1 if end of command (':') or end of line (00H) found 01D78 23 INC HL ;PTP + 1 01D79 7E LD A,(HL) ;A = next character 01D7A FE3A CP ':' ;Character > digit ? 01D7C D0 RET NC ;Yes: done (Z-flag = 1 in ;case of ':') 01D7D FE20 CP 20H ;Space ? 01D7F CA781D JP Z,1D78H ;Yes: get next character 01D82 FE0B CP 0BH ;Character > 0AH ? 01D84 3005 JR NC,1D8BH ;Yes: continue at 1D8BH 01D86 FE09 CP 09H ;Character > 08H ? 01D88 D2781D JP NC,1D78H ;Yes: get next character 01D8B FE30 CP '0' ;Digit found? 01D8D 3F CCF ;Yes: C-flag = 1 01D8E 3C INC A ;End of line reached ? 01D8F 3D DEC A ;(A = 00H) ;Yes: Z-flag = 1 01D90 C9 RET ; RESTORE statement ; ----------------- 01D91 EB EX DE,HL ;DE = PTP 01D92 2AA440 LD HL,(40A4H) ;HL = start of program 01D95 2B DEC HL ;Hl = HL - 1 01D96 22FF40 LD (40FFH),HL ;DATA pointer = ;start of program - 1 01D99 EB EX DE,HL ;HL = PTP 01D9A C9 RET ; +<@> or pressed ? 01D9B CD5803 CALL 0358H ;Get key 01D9E B7 OR A ;Key pressed ? 01D9F C8 RET Z ;No: return 01DA0 FE60 CP 60H ;+<@> pressed ? 01DA2 CC8403 CALL Z,0384H ;Yes: freeze until new key ;pressed. 01DA5 329940 LD (4099H),A ;Save ASCII code of last key 01DA8 3D DEC A ; pressed ? (01H) ; STOP statement ; -------------- 01DA9 C0 RET NZ ;No: done, return or ?SN Error ; pressed 01DAA 3C INC A ;A = 01H (key code of BREAK) 01DAB C3B41D JP 1DB4H ;Continue at 1DB4H ; END statement ; ------------- 01DAE C0 RET NZ ;?SN Error ? 01DAF F5 PUSH AF ;Save A (A = 00H !) 01DB0 CCBB41 CALL Z,41BBH ;DOS 01DB3 F1 POP AF ;Restore A 01DB4 22E640 LD (40E6H),HL ;Store PTP in system RAM 01DB7 21B540 LD HL,40B5H ;Reset string table pointer 01DBA 22B340 LD (40B3H),HL 01DBD 21F6FF LD HL,0FFF6H ;-- ; Entry for STOP in case was pressed during INPUT * 01DBE F6FF OR 0FFH ;A <> 0, Z-flag = 0 01DC0 C1 POP BC ;Remove RET-address 01DC1 2AA240 LD HL,(40A2H) ;HL = current LN 01DC4 E5 PUSH HL ;Save current LN 01DC5 F5 PUSH AF ;Save flags 01DC6 7D LD A,L ;LN = 65535 ? 01DC7 A4 AND H ;(Active command mode) 01DC8 3C INC A 01DC9 2809 JR Z,1DD4H ;Yes: no CONT possible ;No: 01DCB 22F540 LD (40F5H),HL ;Store LN and PTP for CONT 01DCE 2AE640 LD HL,(40E6H) 01DD1 22F740 LD (40F7H),HL 01DD4 CD8B03 CALL 038BH ;End output to printer 01DD7 CDF920 CALL 20F9H ;Start new line 01DDA F1 POP AF ;Restore flags 01DDB 213019 LD HL,1930H ;HL -> 'Break' ;STOP ? 01DDE C2061A JP NZ,1A06H ;Yes: continue at 1A06H ;No: 01DE1 C3181A JP 1A18H ;END, back to active command ;mode ; CONT statement ; -------------- 01DE4 2AF740 LD HL,(40F7H) ;HL = previous PTP 01DE7 7C LD A,H ;HL = 0000H ? 01DE8 B5 OR L 01DE9 1E20 LD E,20H ;E = error code for ?CN Error 01DEB CAA219 JP Z,19A2H ;Yes: ?CN Error 01DEE EB EX DE,HL ;DE = PTP 01DEF 2AF540 LD HL,(40F5H) ;HL = previous LN 01DF2 CDA038 CALL 38A0H ;Save as current LN and program ;CRTC on last values 01DF5 EB EX DE,HL ;HL = PTP 01DF6 C9 RET ;Execute next command ; TRON statement ; -------------- 01DF7 3EAF LD A,AFH ;A <> 0 (trace on) ; TROFF statement ; --------------- * 01DF8 AF XOR A ;A = 0 (trace off) 01DF9 321B41 LD (411BH),A ;Update TRON/TROFF flag 01DFC C9 RET 01DFD F1 POP AF ;-- 01DFE E1 POP HL 01DFF C9 RET ; DEFSTR statement ; ---------------- 01E00 1E03 LD E,03H ;E = VT for STR 01E02 011E02 LD BC,021EH ;-- ; DEFINT statement ; ---------------- * 01E03 1E02 LD E,02H ;E = VT for INT 01E05 011E04 LD BC,041EH ;-- ; DEFSNG statement ; ---------------- * 01E06 1E04 LD E,04H ;E = VT for SNG 01E08 011E08 LD BC,081EH ;-- ; DEFDBL statement ; ---------------- * 01E09 1E08 LD E,08H ;E = VT for DBL 01E0B CD3D1E CALL 1E3DH ;Check if valid var letter 01E0E 019719 LD BC,1997H ;First set new return address 01E11 C5 PUSH BC ;to 1997H (= ?SN Error) 01E12 D8 RET C ;Invalid character: return 01E13 D641 SUB 'A' ;A = offset for table 01E15 4F LD C,A ;C = A 01E16 47 LD B,A ;B = A 01E17 D7 RST 10H ;Get next character 01E18 FECE CP 0CEH ;Token for '-' ? 01E1A 2009 JR NZ,1E25H ;No: set table ;Yes: 01E1C D7 RST 10H ;Get 2nd letter 01E1D CD3D1E CALL 1E3DH ;Letter found ? 01E20 D8 RET C ;No: ?SN Error ;Yes 01E21 D641 SUB 'A' ;A = offset for table 01E23 47 LD B,A ;B = A 01E24 D7 RST 10H ;Increment PTP to next char. 01E25 78 LD A,B ;A = offset of 2nd letter 01E26 91 SUB C ;- offset of 1st letter 01E27 D8 RET C ;?SN Error if the letters were ;not in alphabetical order 01E28 3C INC A ;A = counter 01E29 E3 EX (SP),HL ;Save PTP, remove RET-address 01E2A 210141 LD HL,4101H ;HL -> table 01E2D 0600 LD B,00H ;BC = offset to 1st letter 01E2F 09 ADD HL,BC ;HL -> 1st letter entry 01E30 73 LD (HL),E ;Set VT in table 01E31 23 INC HL ;Pointer + 1 01E32 3D DEC A ;Counter - 1 01E33 20FB JR NZ,1E30H ;Set next table entry 01E35 E1 POP HL ;Restore PTP 01E36 7E LD A,(HL) ;A = next character 01E37 FE2C CP ',' ;Comma indicated ? 01E39 C0 RET NZ ;No: done, return ;Yes: 01E3A D7 RST 10H ;Get next character 01E3B 18CE JR 1E0BH ;And repeat DEF ; Test if ASCII character at (HL) is an upper case letter (A-Z) ; ; I: HL -> ASCII character ; O: A = ASCII value of character ; C-flag is 1 if not A-Z 01E3D 7E LD A,(HL) ;A = character 01E3E FE41 CP 'A' ;Can it be an letter ? 01E40 D8 RET C ;No: return 01E41 FE5B CP 'Z'+1 ;Is it a upper case letter ? 01E43 3F CCF ;No: C-flag = 1 01E44 C9 RET ; Convert argument at (HL) to INT number. If negative number then ?FC Error 01E45 D7 RST 10H ;Increment PTP 01E46 CD022B CALL 2B02H ;Get argument 01E49 F0 RET P ;If positive then return ; ?FC Error 01E4A 1E08 LD E,08H ;E = error code for ?FC Error 01E4C C3A219 JP 19A2H ;Continue at error routine ; Decode line number (number of '.') 01E4F 7E LD A,(HL) ;A = character 01E50 FE2E CP '.' ;'.' found ? 01E52 EB EX DE,HL 01E53 2AEC40 LD HL,(40ECH) ;DE = '.'-LN 01E56 EB EX DE,HL 01E57 CA781D JP Z,1D78H ;Yes: execute RST 10H, done ; Decode number at (HL) into DE 01E5A 2B DEC HL ;PTP - 1 (because of RST 10H) 01E5B 110000 LD DE,0000H ;Result = 0 01E5E D7 RST 10H ;Get next character ;Digit found ? 01E5F D0 RET NC ;No: done, return 01E60 E5 PUSH HL ;Save PTP 01E61 F5 PUSH AF ;Save digit 01E62 219819 LD HL,1998H ;HL = 6552 01E65 DF RST 18H ;Result already larger than ;6552 ? 01E66 DA9719 JP C,1997H ;Yes: ?SN Error (with the ;current digit DE would become ;larger than 65529) 01E69 62 LD H,D ;HL = previous result 01E6A 6B LD L,E 01E6B 19 ADD HL,DE ;HL = HL * 10 01E6C 29 ADD HL,HL 01E6D 19 ADD HL,DE 01E6E 29 ADD HL,HL 01E6F F1 POP AF ;Restore digit 01E70 D630 SUB '0' ;Convert to numberical value 01E72 5F LD E,A ;DE = value 01E73 1600 LD D,00H 01E75 19 ADD HL,DE ;Add value 01E76 EB EX DE,HL ;DE = new result 01E77 E1 POP HL ;Restore PTP 01E78 18E4 JR 1E5EH ;Get next digit ; CLEAR statement ; --------------- ;Argument indicated ? 01E7A CA611B JP Z,1B61H ;No: continue ar 1B61H ; CLEAR with argument 01E7D CD461E CALL 1E46H ;Get INT-argument, ;if argument < 0 then ?FC Error 01E80 2B DEC HL ;PTP - 1 01E81 D7 RST 10H ;End of command reached ? 01E82 C0 RET NZ ;No: ?SN Error 01E83 E5 PUSH HL ;Save PTP 01E84 2AB140 LD HL,(40B1H) ;HL = TOPMEM 01E87 7D LD A,L ;DE -> TOPMEM - (size of new 01E88 93 SUB E ;string space) 01E89 5F LD E,A 01E8A 7C LD A,H 01E8B 9A SBC A,D 01E8C 57 LD D,A ;String space too large ? 01E8D DA7A19 JP C,197AH ;Yes: ?OM Error 01E90 2AF940 LD HL,(40F9H) ;HL -> program end 01E93 012800 LD BC,0028H ;BC = 40 01E96 09 ADD HL,BC ;HL -> program end + 40 01E97 DF RST 18H ;Compare HL and DE ;At least 40 bytes remain free? 01E98 D27A19 JP NC,197AH ;No: ?OM error 01E9B EB EX DE,HL ;HL -> new start of string ;space 01E9C 22A040 LD (40A0H),HL ;Save it in system RAM 01E9F E1 POP HL ;Restore PTP 01EA0 C3611B JP 1B61H ;Execute CLEAR, done. ; RUN statement ; ------------- ;Line number indicated ? 01EA3 CA5D1B JP Z,1B5DH ;No: continue at 1B5DH 01EA6 CDC741 CALL 41C7H ;DOS 01EA9 CD611B CALL 1B61H ;CLEAR 01EAC 011E1D LD BC,1D1EH ;BC = RET-address on program ;loop 01EAF 1810 JR 1EC1H ;Continue at GOTO ; GOSUB statement ; --------------- 01EB1 0E03 LD C,03H ;Still 2 * C bytes free ? 01EB3 CD6319 CALL 1963H ;If not: ?OM Error 01EB6 C1 POP BC ;BC = RET-address 01EB7 E5 PUSH HL ;Save PTP (for GOSUB stack) 01EB8 E5 PUSH HL ;Save PTP 01EB9 2AA240 LD HL,(40A2H) ;HL = current LN 01EBC E3 EX (SP),HL ;Save current LN, restore PTP 01EBD 3E91 LD A,91H ;A = 'GOSUB' token 01EBF F5 PUSH AF ;Save as marker on stack 01EC0 33 INC SP ;Remove LSB from stack 01EC1 C5 PUSH BC ;Put RET-address back ; GOTO statement ; -------------- 01EC2 CD5A1E CALL 1E5AH ;Decode LN, DE = LN 01EC5 CD071F CALL 1F07H ;Increment PTP to end of line 01EC8 E5 PUSH HL ;Save new PTP 01EC9 2AA240 LD HL,(40A2H) ;HL = current LN 01ECC DF RST 18H ;Compare current LN with ;required LN 01ECD E1 POP HL ;Restore new PTP 01ECE 23 INC HL ;HL = pointer on next line ;Required LN > current LN ? 01ECF DC2F1B CALL C,1B2FH ;Yes: search line DE from line ;HL onwards 01ED2 D42C1B CALL NC,1B2CH ;No: search line DE from start ;of program onwards 01ED5 60 LD H,B ;HL = pointer on required line 01ED6 69 LD L,C 01ED7 2B DEC HL ;HL - 1 ;Line found ? 01ED8 D8 RET C ;Yes: done, return ; ?UL Error 01ED9 1E0E LD E,0EH ;E = error code for ?UL Error 01EDB C3A219 JP 19A2H ;Continue at error routine ; RETURN statement ; ---------------- 01EDE C0 RET NZ ;?SN Error ? 01EDF 16FF LD D,0FFH ;Flag <> 0 01EE1 CD3619 CALL 1936H ;Search GOSUB stack 01EE4 F9 LD SP,HL ;SP = HL (delete GOSUB stack) 01EE5 22E840 LD (40E8H),HL ;Save new SP in system RAM 01EE8 FE91 CP 91H ;GOSUB stack found ? 01EEA 1E04 LD E,04H ;E = error code for ?RG Error 01EEC C2A219 JP NZ,19A2H ;No: ?RG Error 01EEF E1 POP HL ;HL = LN of gosub line 01EF0 22A240 LD (40A2H),HL ;Save as current LN 01EF3 23 INC HL ;LN = 65535 ? 01EF4 7C LD A,H ;(GOSUB came from active 01EF5 B5 OR L ;command mode ?) 01EF6 2007 JR NZ,1EFFH ;No: increment PTP to next ;command following GOSUB and ;continue program execution ;from there 01EF8 3ADD40 LD A,(40DDH) ;STOP flag = 0 ? 01EFB B7 OR A 01EFC C2181A JP NZ,1A18H ;No: back to active command ;mode 01EFF 211E1D LD HL,1D1EH ;HL = RET_address for program ;loop 01F02 E3 EX (SP),HL ;HL = PTP, RET-address = 1D1EH 01F03 3EE1 LD A,0E1H ;-- * 01F04 E1 POP HL ;Restore PTP ; DATA statement ; -------------- ; Increment PTP (HL) to next command 01F05 013A0E LD BC,0E3AH ;C = 3AH (':') ; REM statement ; ------------- ; Increment PTP (HL) to next line * 01F07 0E00 LD C,00H ;C = 00H * 01F08 00 NOP ;-- 01F09 0600 LD B,00H ;B = 00H 01F0B 79 LD A,C ;A = search character (= 00H ;when string found, PTP is then ;incremented to end of line 01F0C 48 LD C,B ;C = 00H (search character when ;string found) 01F0D 47 LD B,A ;B = search character 01F0E 7E LD A,(HL) ;A = next character 01F0F B7 OR A ;End of line ? 01F10 C8 RET Z ;Yes: done 01F11 B8 CP B ;Character found ? 01F12 C8 RET Z ;Yes: done 01F13 23 INC HL ;PTP + 1 01F14 FE22 CP 22H ;String found ? 01F16 28F3 JR Z,1F0BH ;Yes: increment PTP to end ;of line 01F18 D68F SUB 8FH ;'IF' found ? 01F1A 20F2 JR NZ,1F0EH ;No: continue search 01F1C B8 CP B ;If 3AH was searched C-flag = 1 01F1D 8A ADC A,D ;A = 00H + D + C-flag 01F1E 57 LD D,A ;D = counter for nested ;IF THEN ELSE statements 01F1F 18ED JR 1F0EH ;Continue search ; LET statement ; ------------- 01F21 CD0D26 CALL 260DH ;DE = VARPTR variable 01F24 CF RST 08H ;Next character must be 01F25 D5 DEFB 0D5H ;the token for '=' 01F26 EB EX DE,HL 01F27 22DF40 LD (40DFH),HL ;Store VARPTR 01F2A EB EX DE,HL 01F2B D5 PUSH DE ;Save VARPTR 01F2C E7 RST 20H ;TSTTYP 01F2D F5 PUSH AF ;Save type code - 3 01F2E CD3723 CALL 2337H ;Expression to X 01F31 F1 POP AF ;Restore type code - 3 01F32 E3 EX (SP),HL ;Save PTP, restore VARPTR 01F33 C603 ADD A,03H ;Adjust type code 01F35 CD1928 CALL 2819H ;Convert X into desired type 01F38 CD030A CALL 0A03H ;DE -> LSB (X) for SNG, DBL ;and INT, TSTTYP 01F3B E5 PUSH HL ;Save VARPTR ;STR type ? 01F3C 2028 JR NZ,1F66H ;No: continue at 1FF6H ; Variable assignment to string variable 01F3E 2A2141 LD HL,(4121H) ;HL -> vector of new string 01F41 E5 PUSH HL ;Save pointer 01F42 23 INC HL 01F43 5E LD E,(HL) ;DE -> new string 01F44 23 INC HL 01F45 56 LD D,(HL) 01F46 2AA440 LD HL,(40A4H) ;HL -> start of BASIC program 01F49 DF RST 18H ;String address < program start? ;(string is in line buffer, ;e.g. with INPUT) 01F4A 300E JR NC,1F5AH ;Yes: continue at 1F5AH 01F4C 2AA040 LD HL,(40A0H) ;HL -> start of string space 01F4F DF RST 18H ;String address < string space? ;(String constant in program ;text) 01F50 D1 POP DE ;Restore string pointer 01F51 300F JR NC,1F62H ;Yes: continue at 1F62H 01F53 2AF940 LD HL,(40F9H) ;HL -> start of variable space 01F56 DF RST 18H ;Vector address of new string ;variable space ? (new string ;is a variable) 01F57 3009 JR NC,1F62H ;No: continue at 1F62H 01F59 3ED1 LD A,0D1H ;-- * 01F5A D1 POP DE ;Restore string pointer 01F5B CDF529 CALL 29F5H ;BC -> last string in string ;table 01F5E EB EX DE,HL ;DE -> vector of last string in ;string table ;HL -> vector of new string 01F5F CD4328 CALL 2843H ;Put new string in string space ;and string vector in string ;table 01F62 CDF529 CALL 29F5H ;DE -> vector of new string 01F65 E3 EX (SP),HL ;HL -> vector of variables ;Save vector of new string 01F66 CDD309 CALL 09D3H ;Copy VT bytes from (DE) ;to (HL) 01F69 D1 POP DE ;Restore vector to new string 01F6A E1 POP HL ;Restore PTP 01F6B C9 RET ; ON statement ; ------------ 01F6C FE9E CP 9EH ;Next token = 'ERROR' 01F6E 2025 JR NZ,1F95H ;No: continue at 1F95H ; ON ERROR GOTO 01F70 D7 RST 10H ;Get next non-space character 01F71 CF RST 08H ;Next byte must be token 01F72 8D DEFB 8DH ;for 'GOTO' 01F73 CD5A1E CALL 1E5AH ;Decode line number 01F76 7A LD A,D ;Line number = 0 ? 01F77 B3 OR E 01F78 2809 JR Z,1F83H ;Yes: continue at 1F83H 01F7A CD2A1B CALL 1B2AH ;Save PTP and search line DE 01F7D 50 LD D,B ;DE = address of line 01F7E 59 LD E,C 01F7F E1 POP HL ;Restore PTP ;Line found ? 01F80 D2D91E JP NC,1ED9H ;No: ?UL Error 01F83 EB EX DE,HL 01F84 22F040 LD (40F0H),HL ;Save line number 01F87 EB EX DE,HL ;Line number <> 0 ? 01F88 D8 RET C ;Yes: done, return 01F89 3AF240 LD A,(40F2H) ;A = error flag 01F8C B7 OR A ;ON ERROR GOTO active ? 01F8D C8 RET Z ;No: done, return 01F8E 3A9A40 LD A,(409AH) ;A = last error code 01F91 5F LD E,A ;into E 01F92 C3AB19 JP 19ABH ;Process error ; ON GOTO / GOSUB 01F95 CD1C2B CALL 2B1CH ;DE = argument (0 - 255) 01F98 7E LD A,(HL) ;A = next character 01F99 47 LD B,A ;B = A 01F9A FE91 CP 91H ;'GOSUB' token ? 01F9C 2803 JR Z,1FA1H ;Yes: continue at 1F1AH ;No: 01F9E CF RST 08H ;It must be the 01F9F 8D DEFB 8DH ;'GOTO' token 01FA0 2B DEC HL ;PTP - 1 (because of RST 08H) 01FA1 4B LD C,E ;C = argument (counter) 01FA2 0D DEC C ;Counter - 1 01FA3 78 LD A,B ;A = token ;Counter = 0 ? 01FA4 CA601D JP Z,1D60H ;Yes: HL points to required LN ;so execute command 01FA7 CD5B1E CALL 1E5BH ;By decoding the number at (HL) ;increment PTP to the next ;character following the number 01FAA FE2C CP ',' ;Separator must be a comma 01FAC C0 RET NZ ;Otherwise execute next command 01FAD 18F3 JR 1FA2H ;Required LN reached ? ; RESUME statement ; ---------------- 01FAF 11F240 LD DE,40F2H ;DE -> ON ERROR GOT flag 01FB2 1A LD A,(DE) ;A = ON ERROR GOTO flag 01FB3 B7 OR A ;ON ERROR GOTO active ? 01FB4 CAA019 JP Z,19A0H ;No: ?RW Error 01FB7 3C INC A ;A + 1 01FB8 329A40 LD (409AH),A ;Set last error code <> 0 01FBB 12 LD (DE),A ;Set error flag <> 0 01FBC 7E LD A,(HL) ;A = next program character 01FBD FE87 CP 87H ;'NEXT' token ? 01FBF 280C JR Z,1FCDH ;Yes: continue at 1FCDH 01FC1 CD5A1E CALL 1E5AH ;Decode line number 01FC4 C0 RET NZ ;?SN Error ? 01FC5 7A LD A,D ;Line number = 0 ? 01FC6 B3 OR E 01FC7 C2C51E JP NZ,1EC5H ;No: execute GOTO ;Yes: 01FCA 3C INC A ;A = 1 (Z-flag = 0) 01FCB 1802 JR 1FCFH ;Execute RESUME NEXT ; RESUME NEXT 01FCD D7 RST 10H ;Increment PTP 01FCE C0 RET NZ ;?SN Error ? 01FCF 2AEE40 LD HL,(40EEH) ;HL = PTP on next command 01FD2 EB EX DE,HL ;DE = HL 01FD3 2AEA40 LD HL,(40EAH) ;HL = LN of error line 01FD6 22A240 LD (40A2H),HL ;Store as current LN 01FD9 EB EX DE,HL ;HL = PTP 01FDA C0 RET NZ ;Done if RESUME 0 01FDB 7E LD A,(HL) ;A = next character from ;program text 01FDC B7 OR A ;End of line ? 01FDD 2004 JR NZ,1FE3H ;No: continue at 1FE3H ;Yes: 01FDF 23 INC HL ;Increment PTP to 01FE0 23 INC HL ;next line 01FE1 23 INC HL 01FE2 23 INC HL 01FE3 23 INC HL 01FE4 7A LD A,D ;Error line = 65535 ? 01FE5 A3 AND E 01FE6 3C INC A 01FE7 C2051F JP NZ,1F05H ;No: increment PTP to next ;command and continue program ;execution 01FEA 3ADD40 LD A,(40DDH) ;A = STOP flag 01FED 3D DEC A ;A = 1 ? 01FEE CABE1D JP Z,1DBEH ;Yes: STOP ;No: 01FF1 C3051F JP 1F05H ;Continue program execution ;at next command ; ERROR statement ; --------------- 01FF4 CD1C2B CALL 2B1CH ;DE = argument (0 - 255) 01FF7 C0 RET NZ ;?SN Error ? 01FF8 B7 OR A ;ERROR 0 ? 01FF9 CA4A1E JP Z,1E4AH ;YEs: ?FC Error 01FFC 3D DEC A ;A = A - 1 01FFD 87 ADD A,A ;A = A * 2 01FFE 5F LD E,A ;E = (argument - 1 ) * 2 01FFF FE2D CP 2DH ;Errorcode > 44H (out of range) 02001 3802 JR C,2005H ;No: process error code ;Yes: 02003 1E26 LD E,26H ;E = error code for ?UE Error 02005 C3A219 JP 19A2H ;Continue at error routine ; AUTO statement ; -------------- 02008 110A00 LD DE,000AH ;DE = default first LN 0200B D5 PUSH DE ;Save first LN ;Any numbers indicated ? 0200C 2817 JR Z,2025H ;No: continue at 2025H 0200E CD4F1E CALL 1E4FH ;DE = indicated first LN 02011 EB EX DE,HL ;HL = LN, DE = PTP 02012 E3 EX (SP),HL ;Save first LN, HL = default ;first LN. Distance indicated ? 02013 2811 JR Z,2026H ;No: continue at 2026H 02015 EB EX DE,HL ;PTP back to HL 02016 CF RST 08H ;Next character must be 02017 2C DEFB ',' ;a comma 02018 EB EX DE,HL 02019 2AE440 LD HL,(40E4H) ;DE = previous distance 0201C EB EX DE,HL ;use previous distance ? ;(AUTO XX, ) 0201D 2806 JR Z,2025H ;Yes: continue at 2025H 0201F CD5A1E CALL 1E5AH ;DE = distance 02022 C29719 JP NZ,1997H ;?SN Error 02025 EB EX DE,HL ;DE = PTP, HL = distance 02026 7C LD A,H ;Distance =0 ? 02027 B5 OR L 02028 CA4A1E JP Z,1E4AH ;Yes: ?FC Error 0202B 22E440 LD (40E4H),HL ;Store distance in system RAM 0202E 32E140 LD (40E1H),A ;Set AUTO flag <> 0 02031 E1 POP HL ;Restore first LN 02032 22E240 LD (40E2H),HL ;and store it in system RAM 02035 C1 POP BC ;Delete RET-address 02036 C3331A JP 1A33H ;Input line ; IF statement ; ------------ 02039 CD3723 CALL 2337H ;X = expression ;(if condition is false then ;X = 0 else X = -1) 0203C 7E LD A,(HL) ;Get next character 0203D FE2C CP ',' ;Is it a comma ? 0203F CC781D CALL Z,1D78H ;Yes: increment PTP (like ;with 'THEN') 02042 FECA CP 0CAH ;'THEN' token ? 02044 CC781D CALL Z,1D78H ;Yes: increment PTP 02047 2B DEC HL ;PTP - 1 02048 E5 PUSH HL ;Save PTP 02049 CD9409 CALL 0994H ;TEST1 0204C E1 POP HL ;Restore PTP ;X = 0 ? (condition: false) 0204D 2807 JR Z,2056H ;Yes: continue at 2056H ; IF-condition is true 0204F D7 RST 10H ;Increment PTP ;Number indicated ? 02050 DAC21E JP C,1EC2H ;Yes: continue at GOTO ;No: 02053 C35F1D JP 1D5FH ;execute command token ; IF-condition is false 02056 1601 LD D,01H ;D = counter for nested ;IF-THEN-ELSE conditions 02058 CD051F CALL 1F05H ;Increment PTP to next command 0205B B7 OR A ;End of line reached ? 0205C C8 RET Z ;Yes: done, return 0205D D7 RST 10H ;A = next character 0205E FE95 CP 95H ;'ELSE' token found ? 02060 20F6 JR NZ,2058H ;No: continue search 02062 15 DEC D ;Nesting level counter - 1 02063 20F3 JR NZ,2058H ;Search outermost 'ELSE' 02065 18E8 JR 204FH ;Execute following command ; LPRINT statement ; ---------------- 02067 3E01 LD A,01H ;Set output flag to 02069 329C40 LD (409CH),A ;printer output 0206C C39B20 JP 209BH ;Continue at PRINT ; PRINT statement ; --------------- 0206F CDCA41 CALL 41CAH ;DOS 02072 FE40 CP 40H ;PRINT@ ? 02074 2019 JR NZ,208FH ;No: continue at 208FH 02076 CD012B CALL 2B01H ;Get argument 02079 E5 PUSH HL ;Save PTP 0207A C3D430 JP 30D4H ;Test argument and restore 0207D 00 NOP ;PTP (returns to 207EH) 0207E E5 PUSH HL ;Save PTP 0207F 210044 LD HL,4400H ;HL -> start of screen mem 02082 19 ADD HL,DE ;Add @-argument 02083 222040 LD (4020H),HL ;Store new cursor position 02086 CD2A36 CALL 362AH ;Calculate new POS 02089 32A640 LD (40A6H),A ;and save it in system RAM 0208C E1 POP HL ;Restore PTP 0208D CF RST 08H ;After @ must follow 0208E 2C DEFB ',' :a comma. 0208F FE23 CP 23H ;PRINT# ? 02091 2008 JR NZ,209BH ;No, continue at 209BH 02093 CDA935 CALL 35A9H ;Write leader and sync 02096 3E80 LD A,80H ;Set output flag to 02098 329C40 LD (409CH),A ;cassette output 0209B 2B DEC HL ;PTP - 1 0209C D7 RST 10H ;A = next non space character 0209D CCFE20 CALL Z,20FEH ;End PRINT if no argument 020A0 CA6921 JP Z,2169H ;and set next output to screen 020A3 FEBF CP 0BFH ;'USING' token ? 020A5 CABD2C JP Z,2CBDH ;Yes: continue at 2CBDH 020A8 FEBC CP 0BCH ;'TAB(' token ? 020AA CA3721 JP Z,2137H ;Yes: continue at 2137H 020AD E5 PUSH HL ;Save PTP 020AE FE2C CP ',' ;',' found ? 020B0 CA0821 JP Z,2108H ;Yes: continue at 2108H 020B3 FE3B CP ';' ;';' found ? 020B5 CA6421 JP Z,2164H ;Yes: continue at 2164H 020B8 C1 POP BC ;Correct stack 020B9 CD3723 CALL 2337H ;Put argument in X 020BC E5 PUSH HL ;Save PTP 020BD E7 RST 20H ;TSTTYP ;STR type? 020BE 2832 JR Z,20F2H ;Yes: continue at 202FH 020C0 CDBD0F CALL 0FBDH ;Convert number into string 020C3 CD6528 CALL 2865H ;Take string 020C6 CDCD41 CALL 41CDH ;DOS 020C9 2A2141 LD HL,(4121H) ;HL -> string vector 020CC 3A9C40 LD A,(409CH) ;A = output flag 020CF B7 OR A ;Test output flag ;Cassette output ? 020D0 FAE920 JP M,20E9H ;Yes: continue at 20E9H ;Screen output? 020D3 2808 JR Z,20DDH ;Yes: continue at 20DDH ; Printer output 020D5 3A9B40 LD A,(409BH) ;A = printer-POS 020D8 86 ADD A,(HL) ;A = printer-POS + string len 020D9 FE84 CP 84H ;> 132 ? 020DB 1809 JR 20E6H ;Yes: start new line ; Screen output 020DD 3A9D40 LD A,(409DH) ;A = maximum number of ;characters/line 020E0 47 LD B,A ;B = A 020E1 3AA640 LD A,(40A6H) ;A = screen-POS 020E4 86 ADD A,(HL) ;A = screen-POS + string length 020E5 B8 CP B ;> length of 1 line ? 020E6 D4FE20 CALL NC,20FEH ;Yes: start new line ; Cassette output 020E9 CDAA28 CALL 28AAH ;Output string 020EC 3E20 LD A,20H ;A = ' ' 020EE CD2A03 CALL 032AH ;Print it for separation 020F1 B7 OR A ;set Z-flag= 0: skip next CALL 020F2 CCAA28 CALL Z,28AAH ;Print string when argument ;was in STR format 020F5 E1 POP HL ;Restore PTP 020F6 C39B20 JP 209BH ;Process next argument ; Start a new line 020F9 3AA640 LD A,(40A6H) ;A = screen-POS 020FC B7 OR A ;POS = 0 ? (new line already ;started) 020FD C8 RET Z ;Yes: done 020FE 3E0D LD A,0DH ;A = Carriage Return 02100 CD2A03 CALL 032AH ;Print it 02103 CDD041 CALL 41D0H ;DOS 02106 AF XOR A ;A = 0 02107 C9 RET ; ',' with PRINT 02108 CDD341 CALL 41D3H ;DOS 0210B 3A9C40 LD A,(409CH) ;A = output flag 0210E B7 OR A ;Test output flag ;Cassette output ? 0210F F21921 JP P,2119H ;No: continue at 2119H ; Cassette output 02112 3E2C LD A,2CH ;A = ',' 02114 CD2A03 CALL 032AH ;Print it 02117 184B JR 2164H ;Process next argument ; PRINT ',' on screen or printer 02119 2808 JR Z,2123H ;continue at 2123H if screen ;output ; Printer output 0211B 3A9B40 LD A,(409BH) ;A = printer-POS 0211E FE70 CP 70H ;A > 112 ? 02120 C32B21 JP 212BH ;Yes: start new line ; Screen output 02123 3A9E40 LD A,(409EH) ;A = highest TAB position 02126 47 LD B,A ;B = A 02127 3AA640 LD A,(40A6H) ;A = screen-POS 0212A B8 CP B ;POS above highest TAB ;TAB position 0212B D4FE20 CALL NC,20FEH ;Yes: start a new line 0212E 3034 JR NC,2164H ;and process next argument 02130 D60A SUB 0AH ;A = A MOD 10 02132 30FC JR NC,2130H 02134 2F CPL 02135 1823 JR 215AH ;Print A times a space ; PRINT TAB( 02137 CD1B2B CALL 2B1BH ;DE = TAB argument 0213A CDB230 CALL 30B2H ;E = new POS value 0213D CF RST 08H ;Next character must be 0213E 29 DEFB ')' ;a ')' 0213F 2B DEC HL ;PTP - 1 02140 E5 PUSH HL ;Save PTP 02141 CDD341 CALL 41D3H ;DOS 02144 3A9C40 LD A,(409CH) ;A = output flag 02147 B7 OR A ;Test output flag ;Cassette output ? 02148 FA4A1E JP M,1E4AH ;Yes: ?FC Error ;Screen output ? 0214B CA5321 JP Z,2153H ;Yes: continue at 2153H ; Printer output 0214E 3A9B40 LD A,(409BH) ;A = printer-POS 02151 1803 JR 2156H ;Continue at 2156H ; Screen output 02153 3AA640 LD A,(40A6H) ;A = screen-POS 02156 2F CPL ;A = -A 02157 83 ADD A,E ;A = E - A ;(new POS - old POS) 02158 300A JR NC,2164H ;Done when required POS ;already reached 0215A 3C INC A ;A + 1 0215B 47 LD B,A ;into B as counter 0215C 3E20 LD A,20H ;A = ' ' ;Repeat 0215E CD2A03 CALL 032AH ;Print space 02161 05 DEC B 02162 20FA JR NZ,215EH ;Until B = 0 ; ';' with PRINT, do not generate at new line 02164 E1 POP HL ;Restore PTP 02165 D7 RST 10H ;Skip spaces/LF etc and get ;next character 02166 C3A020 JP 20A0H ;Continue at 20A0H ; Next output back to screen 02169 3A9C40 LD A,(409CH) ;-- 0216C B7 OR A ; 0216D 00 NOP 0216E 00 NOP 0216F 00 NOP 02170 AF XOR A ;Set output flag to 02171 329C40 LD (409CH),A ;screen output 02174 CDBE41 CALL 41BEH ;DOS 02177 C9 RET ; Text '?REDO' 02178 3F5245444F DEFB '?REDO' 0217D 0D DEFB 0DH ;Carriage return 0217E 00 DEFB 00H ;End of string ; Data with INPUT or READ not separated by ',' 0217F 3ADE40 LD A,(40DEH) ;A = READ/INPUT flag 02182 B7 OR A ;READ? 02183 C29119 JP NZ,1991H ;Yes: ?SN Error 02186 CDB130 CALL 30B1H ;Test E on correct TAB ;value (???) 02189 B7 OR A ;A = 0 (???) 0218A 1E2A LD E,2AH ;E = error code for ?FD Error 0218C CAA219 JP Z,19A2H ;Yes: ?FD Error 0218F C1 POP BC ;No: correct stack 02190 217821 LD HL,2178H ;HL -> '?REDO' 02193 CDA728 CALL 28A7H ;Print text 02196 2AE640 LD HL,(40E6H) ;HL = last PTP 02199 C9 RET ;Repeat last command ; INPUT statement ; --------------- 0219A CD2828 CALL 2828H ;?ID Error? 0219D 7E LD A,(HL) ;A = next character 0219E CDD641 CALL 41D6H ;DOS 021A1 D623 SUB 23H ;Character = '#' ? 021A3 32A940 LD (40A9H),A ;Flag = 0 when INPUT# 021A6 7E LD A,(HL) ;A = character 021A7 2020 JR NZ,21C9H ;No: continue at 21C9H ; INPUT# 021A9 CDAF35 CALL 35AFH ;Evaluate number and ;search for sync and leader 021AC E5 PUSH HL ;Save PTP 021AD 06FA LD B,0FAH ;B = 250 (record length) 021AF 2AA740 LD HL,(40A7H) ;HL -> line buffer 021B2 CDED01 CALL 01EDH ;Read one byte 021B5 77 LD (HL),A ;Store it in buffer 021B6 23 INC HL ;Pointer + 1 021B7 FE0D CP 0DH ;End of record ? 021B9 2802 JR Z,21BDH ;Yes: continue at 21BDH 021BB 10F5 DJNZ 21B2H ;Read next byte 021BD 2B DEC HL ;Pointer - 1 021BE 3600 LD (HL),00H ;Replace last byte with 00H 021C0 00 NOP ;-- 021C1 00 NOP ;(I guess motor off call used 021C2 00 NOP ;to be here in the TRS80) 021C3 2AA740 LD HL,(40A7H) ;HL -> line buffer 021C6 2B DEC HL ;Pointer - 1 021C7 1822 JR 21EBH ;Process data ; Normal INPUT 021C9 01DB21 LD BC,21DBH ;Set new RET address 021CC C5 PUSH BC ;to 21DBH 021CD FE22 CP 22H ;Text to be printed first? 021CF C0 RET NZ ;No: continue at 21DBH 021D0 CD6628 CALL 2866H ;Get text 021D3 CF RST 08H ;Text must be followed by 021D4 3B DEFB ';' ;a ';' 021D5 E5 PUSH HL ;Save PTP 021D6 CDAA28 CALL 28AAH ;Print text 021D9 E1 POP HL ;Restore PTP 021DA C9 RET ;Continue at 21BDH 021DB E5 PUSH HL ;Save PTP 021DC CDB31B CALL 1BB3H ;Print '?' and goto line input 021DF C1 POP BC ;BC = PTP ; pressed ? 021E0 DABE1D JP C,1DBEH ;Yes: continue at STOP 021E3 23 INC HL ;Pointer + 1 021E4 7E LD A,(HL) ;Get first character 021E5 B7 OR A ; pressed ? 021E6 2B DEC HL ;Pointer - 1 021E7 C5 PUSH BC ;Save PTP 021E8 CA041F JP Z,1F04H ;Yes: set PTP to next ;instruction and leave ;variables unchanged 021EB 362C LD (HL),2CH ;Put a comma in the buffer ;as a separator 021ED 1805 JR 21F4H ;Continue at 21F4H ; READ statement ; -------------- 021EF E5 PUSH HL ;Save PTP 021F0 2AFF40 LD HL,(40FFH) ;HL -> next data value 021F3 F6AF OR AFH ;set flag to READ * 021F4 AF XOR A ;set flag to INPUT 021F5 32DE40 LD (40DEH),A ;Store READ/INPUT flag 021F8 E3 EX (SP),HL ;Restore PTP, save DATA pointer 021F9 1802 JR 21FDH ;Continue at 21FDH ; Use next data ; DATA pointer = pointer on the data to use ; PTP = pointer on variables 021FB CF RST 08H ;Next character must be 021FC 2C DEFB ',' ;a comma (separator) 021FD CD0D26 CALL 260DH ;Get address of variable ;indicated after READ/INPUT 02200 E3 EX (SP),HL ;Save PTP, restore READ pointer 02201 D5 PUSH DE ;Save variable address 02202 7E LD A,(HL) ;A = data character 02203 FE2C CP ',' ;Separator ? 02205 2826 JR Z,222DH ;Yes: continue at 222DH ; No separator (',') found 02207 3ADE40 LD A,(40DEH) ;A = READ/INPUT flag 0220A B7 OR A ;READ ? 0220B C29622 JP NZ,2296H ;Yes: increment DATA pointer ;to next DATA line 0220E 3AA940 LD A,(40A9H) ;INPUT# ? 02211 B7 OR A 02212 1E06 LD E,06H ;E = error code for ?OD Error 02214 CAA219 JP Z,19A2H ;Yes: issue error 02217 3E3F LD A,3FH ;A = '?' 02219 CD2A03 CALL 032AH ;Print it 0221C CDB31B CALL 1BB3H ;Request missing data ('??') 0221F D1 POP DE ;Restore variable address 02220 C1 POP BC ;Restore PTP ; pressed ? 02221 DABE1D JP C,1DBEH ;Yes: continue at STOP 02224 23 INC HL ;Pointer + 1 02225 7E LD A,(HL) ;A = first character 02226 B7 OR A ; pressed ? 02227 2B DEC HL ;Pointer - 1 02228 C5 PUSH BC ;Save PTP 02229 CA041F JP Z,1F04H ;Yes: set PTP to next ;instruction and leave ;variables unchanged 0222C D5 PUSH DE ;No: Save variable address 0222D CDDC41 CALL 41DCH ;DOS 02230 E7 RST 20H ;TSTTYP 02231 F5 PUSH AF ;Save VT - 3 ;STR type ? 02232 2019 JR NZ,224DH ;No: continue at 224DH ; Put data in string variable 02234 D7 RST 10H ;First non-space/LF character ;to A 02235 57 LD D,A ;D = A 02236 47 LD B,A ;B = A 02237 FE22 CP 22H ;String delimited by '"' 02239 2805 JR Z,2240H ;Yes: B = D = string end 0223B 163A LD D,3AH ;String end can be ':' (3AH) 0223D 062C LD B,2CH ;or ',' (2CH) 0223F 2B DEC HL ;Pointer - 1 02240 CD6928 CALL 2869H ;Get string 02243 F1 POP AF ;Restore VT - 3 02244 EB EX DE,HL ;DE = DATA pointer 02245 215A22 LD HL,225AH ;Set RET address to 225AH 02248 E3 EX (SP),HL ;HL -> variable 02249 D5 PUSH DE ;Save DATA pointer 0224A C3331F JP 1F33H ;Copy new value into variable ;and continue at 225AH ; Put data in numerical variable 0224D D7 RST 10H ;Set pointer on first non-space ;character 0224E F1 POP AF ;Restore VT - 3 0224F F5 PUSH AF ;And save it again 02250 014322 LD BC,2243H ;Set new RET address to 2243H 02253 C5 PUSH BC ;(copy value into variable) ;INT or SNG value ? 02254 DA6C0E JP C,0E6CH ;Yes: get INT or SNG value ;DBL value 02257 D2650E JP NC,0E65H ;Yes: get DBL VALUE ; Continuation after getting data 0225A 2B DEC HL ;PTP - 1 0225B D7 RST 10H ;End of line reached ? 0225C 2805 JR Z,2263H ;Yes: continue at 2263H 0225E FE2C CP 2CH ;Separator found ? 02260 C27F21 JP NZ,217FH ;No: process error at 217FH 02263 E3 EX (SP),HL ;Save DATA pointer, HL = PTP 02264 2B DEC HL ;PTP - 1 02265 D7 RST 10H ;End of READ/INPUT ? 02266 C2FB21 JP NZ,21FBH ;No: process next variable 02269 D1 POP DE ;Yes: restore DATA pointer 0226A 00 NOP ;-- 0226B 00 NOP 0226C 00 NOP 0226D 00 NOP 0226E 00 NOP 0226F 3ADE40 LD A,(40DEH) ;A = READ/INPUT flag 02272 B7 OR A ;READ ? 02273 EB EX DE,HL ;DE = PTP, HL = DATA pointer 02274 C2961D JP NZ,1D96H ;Yes: continue at 1D96H 02277 D5 PUSH DE ;No: save PTP 02278 CDDF41 CALL 41DFH ;DOS 0227B B6 OR (HL) ;Still data remaining in ;the buffer ? 0227C 218622 LD HL,2286H ;HL -> '?Extra ignored' 0227F C4A728 CALL NZ,28A7H ;Yes: print text 02282 E1 POP HL ;Restore PTP 02283 C36921 JP 2169H ;Direct next output to screen ; Text '?Extra ignored' 02286 3F4578747261 DEFB '?Extra' 0228C 20 DEFB ' ' 0228D 69676E6F726564 DEFB 'ignored' 02294 0D DEFB 0DH ;Carriage Return 02295 00 DEFB 00H ;End of string ; Increment DATA pointer to next DATA line 02296 CD051F CALL 1F05H ;Increment HL to end of ;command or end of line 02299 B7 OR A ;End of line reached ? 0229A 2012 JR NZ,22AEH ;No: continue at 22AEH 0229C 23 INC HL ;Program end reached ? 0229D 7E LD A,(HL) ;(Line pointer = 0000H ?) 0229E 23 INC HL 0229F B6 OR (HL) 022A0 1E06 LD E,06H ;E = error code for ?OD Error 022A2 CAA219 JP Z,19A2H ;Yes: issue ?OD Error ;No: 022A5 23 INC HL ;DE = line number 022A6 5E LD E,(HL) 022A7 23 INC HL 022A8 56 LD D,(HL) 022A9 EB EX DE,HL ;Store line number of 022AA 22DA40 LD (40DAH),HL ;DATA line 022AD EB EX DE,HL 022AE D7 RST 10H ;DATA line found ? 022AF FE88 CP 88H ;First char. = 'DATA' token ? 022B1 20E3 JR NZ,2296H ;No: continue search ;Yes: 022B3 C32D22 JP 222DH ;HL = new DATA pointer ; NEXT statement ; -------------- 022B6 110000 LD DE,0000H ;Default address in case no ;loop variable is indicated 022B9 C40D26 CALL NZ,260DH ;Get variable address in case ;loop variable is indicated 022BC 22DF40 LD (40DFH),HL ;Save PTP 022BF CD3619 CALL 1936H ;Search FOR stack with ;VARPTR = DE (next FOR stack ;in case DE = 0) ;FOR stack found ? 022C2 C29D19 JP NZ,199DH ;No: ?NF Error ;Yes: 022C5 F9 LD SP,HL ;SP = FOR stack pointer 022C6 22E840 LD (40E8H),HL ;Save SP value 022C9 D5 PUSH DE ;Save variable address 022CA 7E LD A,(HL) ;A = step-SGN 022CB 23 INC HL ;Pointer + 1 022CC F5 PUSH AF ;Save step-SGN 022CD D5 PUSH DE ;Save variable address 022CE 7E LD A,(HL) ;Get variable type 022CF 23 INC HL ;Pointer + 1 022D0 B7 OR A ;Loop variable type INT ? 022D1 FAEA22 JP M,22EAH ;Yes: continue at 22EAH ; NEXT for SNG-variable 022D4 CDB109 CALL 09B1H ;X = BCDE + (HL) ;(Step value into X) 022D7 E3 EX (SP),HL ;Save pointer, HL = VARPTR 022D8 E5 PUSH HL ;Save address of loop var. 022D9 CD0B07 CALL 070BH ;X = X + (HL), add step value ;to loop variable 022DC E1 POP HL ;Restore address 022DD CDCB09 CALL 09CBH ;(HL) = X (copy new value ;into loop variable 022E0 E1 POP HL ;Restore pointer (now on end ;value) 022E1 CDC209 CALL 09C2H ;BCDE = (HL) = end value 022E4 E5 PUSH HL ;Save pointer 022E5 CD0C0A CALL 0A0CH ;CP X,BCDE (compare loop ;variable with end value) 022E8 1829 JR 2313H ;Continue at 2313H ; NEXT for INT-variable 022EA 23 INC HL ;The first 4 bytes of the FOR 022EB 23 INC HL ;stack are not used 022EC 23 INC HL 022ED 23 INC HL 022EE 4E LD C,(HL) ;BC = step value 022EF 23 INC HL 022F0 46 LD B,(HL) 022F1 23 INC HL 022F2 E3 EX (SP),HL ;Save pointer, HL = address 022F3 5E LD E,(HL) ;DE = loop value 022F4 23 INC HL 022F5 56 LD D,(HL) 022F6 E5 PUSH HL ;Save address + 1 022F7 69 LD L,C ;HL = step value 022F8 60 LD H,B 022F9 CDD20B CALL 0BD2H ;X = HL = HL + DE (add step ;value to loop variable) 022FC 3AAF40 LD A,(40AFH) ;Overflow ? 022FF FE04 CP 04H ;VT changed to SNG ? 02301 CAB207 JP Z,07B2H ;Yes: ?OV Error ;No: 02304 EB EX DE,HL ;DE = new loop value 02305 E1 POP HL ;Restore address + 1 02306 72 LD (HL),D ;Save new loop variable value 02307 2B DEC HL 02308 73 LD (HL),E 02309 E1 POP HL ;Restore pointer 0230A D5 PUSH DE ;Save loop value 0230B 5E LD E,(HL) ;DE = end value 0230C 23 INC HL 0230D 56 LD D,(HL) 0230E 23 INC HL 0230F E3 EX (SP),HL ;Save pointer, HL = loop value 02310 CD390A CALL 0A39H ;CP HL,DE 02313 E1 POP HL ;Restore pointer 02314 C1 POP BC ;B = step-SGN ;B = 01H: End loop if ; loop val. > end val. ;B = FFH: End loop if ; loop val. < end val. ;A = FFH: loop val. < end val. ;A = 00H: loop val. = end val. ;A = 01H: loop val. > end val. 02315 90 SUB B ;Loop ended ? 02316 CDC209 CALL 09C2H ;BCDE = (HL) ;(BC = LP on start of loop ;DE = line number) 02319 2809 JR Z,2324H ;Yes: continue at 2324H ; Loop continues 0231B EB EX DE,HL ;HL = line number 0231C 22A240 LD (40A2H),HL ;Save as current line number 0231F 69 LD L,C ;HL = line pointer 02320 60 LD H,B 02321 C31A1D JP 1D1AH ;Rebuild FOR stack and continue ;program execution at (HL) ; Loop ends 02324 F9 LD SP,HL ;SP = end of stack (current ;FOR stack deleted) 02325 22E840 LD (40E8H),HL ;Save new SP in system RAM 02328 2ADF40 LD HL,(40DFH) ;HL = PTP 0232B 7E LD A,(HL) ;A = next character 0232C FE2C CP ',' ;Is it a comma ? 0232E C21E1D JP NZ,1D1EH ;No: continue program at (HL) ;Yes: 02331 D7 RST 10H ;Increment PTP to next variable 02332 CDB922 CALL 22B9H ;and process next variable ; Process expression in parentheses and store result in X 02335 CF RST 08H ;Next character must be 02336 28 DEFB '(' ;a '(' ; Process expression and store result in X 02337 2B DEC HL ;PTP - 1 02338 1600 LD D,00H ;Priority flag = 0 0233A D5 PUSH DE ;Save flag 0233B 0E01 LD C,01H ;Memory test: still 2 bytes 0233D CD6319 CALL 1963H ;free? 02340 CD9F24 CALL 249FH ;Get 1st argument 02343 22F340 LD (40F3H),HL ;Save PTP in system RAM 02346 2AF340 LD HL,(40F3H) ;Restore PTP 02349 C1 POP BC ;Restore priority flag 0234A 7E LD A,(HL) ;A = token following argument ;(operator code) 0234B 1600 LD D,00H ;Operator flag = 0 0234D D6D4 SUB 0D4H ;Comparison operator ? ;( < , = , > ) 0234F 3813 JR C,2364H ;No: continue at 2364H 02351 FE03 CP 03H ;Token value between ;D4H and D7H ? 02353 300F JR NC,2364H ;No: continue at 2364H ; Process operators for compare ( < , = , > , =< , => , <= , >= , <> ) 02355 FE01 CP 01H ;C-flag = 1 in case of '<' 02357 17 RLA ;'<' : A = 01 (bit 0 set) ;'=' : A = 02 (bit 1 set) ;'>' : A = 04 (bit 2 set) 02358 AA XOR D ;Xor A with last operator. ;A = 00 in case the same ;operator was indicated twice 02359 BA CP D ;C-flag = 1 in case A = 00H !! 0235A 57 LD D,A ;D = new operator code ;Twice the same operator ? 0235B DA9719 JP C,1997H ;Yes: ?SN Error 0235E 22D840 LD (40D8H),HL ;Save PTP 02361 D7 RST 10H ;Get next operator 02362 18E9 JR 234DH ;Another comparison operator ? ; No operator for compare found 02364 7A LD A,D ;A = operator flag 02365 B7 OR A ;Comparison operators found ? 02366 C2EC23 JP NZ,23ECH ;Yes: continue at 23ECH ;No: 02369 7E LD A,(HL) ;A = operator code 0236A 22D840 LD (40D8H),HL ;Save PTP 0236D D6CD SUB 0CDH ;Code found ? 0236F D8 RET C ;No: done 02370 FE07 CP 07H ;Valid code ( + , - , * , / , ;arrow up , AND , OR ) ? 02372 D0 RET NC ;No: done 02373 5F LD E,A ;DE = code offset ;(0 = '+', 6 = 'OR') 02374 3AAF40 LD A,(40AFH) ;A = VT of 1st argument 02377 D603 SUB 03H ;String argument ? 02379 B3 OR E ;And code = '+' ? 0237A CA8F29 JP Z,298FH ;Yes: string addition at 298FH ; Priority test 0237D 219A18 LD HL,189AH ;HL -> priority table 02380 19 ADD HL,DE ;Add offset 02381 78 LD A,B ;A = old priority ;(at first = 0 !) 02382 56 LD D,(HL) ;D = current priority 02383 BA CP D ;Compare both priorities ;Old priority was higher ? 02384 D0 RET NC ;Yes: first calculate ;intermediate result 02385 C5 PUSH BC ;Save old priority 02386 014623 LD BC,2346H ;Set new RET-address 02389 C5 PUSH BC ;to 2346H 0238A 7A LD A,D ;A = new priority 0238B FE7F CP 7FH ;Power calculation (^) ? 0238D CAD423 JP Z,23D4H ;Yes: continue at 23D4H 02390 FE51 CP 51H ;boolean operator (AND, OR) ? 02392 DAE123 JP C,23E1H ;Yes: continue at 23E1H ; Process operators '+', '-', '*' and '/' ; Store 1st argument or intermediate result on stack 02395 212141 LD HL,4121H ;HL -> X 02398 B7 OR A ;C-flag = 0 02399 3AAF40 LD A,(40AFH) ;A = VT 0239C 3D DEC A ;- 3 0239D 3D DEC A 0239E 3D DEC A ;Type of X = STR ? 0239F CAF60A JP Z,0AF6H ;Yes: ?TM Error (for strings ;only '+' is allowed and this ;operator has already been ;checked) 023A2 4E LD C,(HL) ;BC = INT value 023A3 23 INC HL 023A4 46 LD B,(HL) 023A5 C5 PUSH BC ;INT value on stack ;Type of X = INT ? 023A6 FAC523 JP M,23C5H ;Yes: done 023A9 23 INC HL ;BC = MSBs of SNG value 023AA 4E LD C,(HL) 023AB 23 INC HL 023AC 46 LD B,(HL) 023AD C5 PUSH BC ;MSBs of SNG-value on stack 023AE F5 PUSH AF ;Save VT - 3 023AF B7 OR A ;Type of X = SNG ? 023B0 E2C423 JP PO,23C4H ;Yes: done 023B3 F1 POP AF ;Restore VT - 3 023B4 23 INC HL 023B5 3803 JR C,23BAH ;Jump is never executed 023B7 211D41 LD HL,411DH ;Save LSBs of DBL value 023BA 4E LD C,(HL) ;on stack 023BB 23 INC HL 023BC 46 LD B,(HL) 023BD 23 INC HL 023BE C5 PUSH BC 023BF 4E LD C,(HL) 023C0 23 INC HL 023C1 46 LD B,(HL) 023C2 C5 PUSH BC 023C3 06F1 LD B,0F1H ;-- * 023C4 F1 POP AF ;Restore VT - 3 (with INT- or ;SNG-value) 023C5 C603 ADD A,03H ;A = VT 023C7 4B LD C,E ;C = offset of operator code 023C8 47 LD B,A ;B = VT 023C9 C5 PUSH BC ;Save both on stack 023CA 010624 LD BC,2406H ;Set new RET-address 023CD C5 PUSH BC ;to 2406H 023CE 2AD840 LD HL,(40D8H) ;Restore PTP 023D1 C33A23 JP 233AH ;Process next argument 023D4 CDB10A CALL 0AB1H ;X = CSNG (X) 023D7 CDA409 CALL 09A4H ;(SP) = X 023DA 01F213 LD BC,13F2H ;BC -> power function 023DD 167F LD D,7FH ;D = priority code 023DF 18EC JR 23CDH ;Get 2nd argument and ;execute function ; Process logical expression 023E1 D5 PUSH DE ;Save priority code 023E2 CD7F0A CALL 0A7FH ;HL = X = CINT(X) 023E5 D1 POP DE ;Restore priority code 023E6 E5 PUSH HL ;Save 1st argument 023E7 01E925 LD BC,25E9H ;BC -> AND/OR routine 023EA 18E1 JR 23CDH ;Get 2nd argument and ;process logical expression ; Process compare operators 023EC 78 LD A,B ;A = priority code 023ED FE64 CP 64H ;Last operator of higher ;priority? 023EF D0 RET NC ;Yes: compute intermediate ;result 023F0 C5 PUSH BC ;No: save priority code 023F1 D5 PUSH DE ;Save operator code 023F2 110464 LD DE,6404H ;D = current priority ;E = offset for basic ;arithmatic (see table ;at 18ABH) 023F5 21B825 LD HL,25B8H ;Set new RET-address 023F8 E5 PUSH HL ;to 25B8H 023F9 E7 RST 20H ;TSTTYP ;STR type? 023FA C29523 JP NZ,2395H ;No: continue at 2395H ;Yes: 023FD 2A2141 LD HL,(4121H) ;HL -> string vector 02400 E5 PUSH HL ;Save pointer 02401 018C25 LD BC,258CH ;Set RET-address to 258CH ;(string compare) 02404 18C7 JR 23CDH ;Get 2nd argument and execute ;function ; Compute intermediate result ; 1st value: on stack, 2nd value: in X 02406 C1 POP BC ;Restore VT of 1st argument 02407 79 LD A,C ;A = operator code offset 02408 32B040 LD (40B0H),A ;Save in system RAM 0240B 78 LD A,B ;A = VT 0240C FE08 CP 08H ;1st argument in DBL format ? 0240E 2828 JR Z,2438H ;Yes: continue at 2438H 02410 3AAF40 LD A,(40AFH) ;A = VT of 2nd argument 02413 FE08 CP 08H ;2nd argument in DBL format ? 02415 CA6024 JP Z,2460H ;Yes: continue at 2460H 02418 57 LD D,A ;D = VT of 2nd argument 02419 78 LD A,B ;A = VT of 1st argument 0241A FE04 CP 04H ;1st argument in SNG format ? 0241C CA7224 JP Z,2472H ;Yes: continue at 2472H 0241F 7A LD A,D ;A = VT of 2nd argument 02420 FE03 CP 03H ;2nd argument in STR format ? 02422 CAF60A JP Z,0AF6H ;Yes: ?TM Error ;2nd argument in SNG format ? 02425 D27C24 JP NC,247CH ;Yes: continue at 247CH ; 1st or 2nd argument in INT format 02428 21BF18 LD HL,18BFH ;HL -> jump table for basic ;arithmatic (INT) 0242B 0600 LD B,00H ;BC = operator offset 0242D 09 ADD HL,BC ;Add offset twice 0242E 09 ADD HL,BC ;(2 bytes address) 0242F 4E LD C,(HL) ;BC = address 02430 23 INC HL 02431 46 LD B,(HL) 02432 D1 POP DE ;DE = 1st argument 02433 2A2141 LD HL,(4121H) ;HL = 2nd argument 02436 C5 PUSH BC ;Put address on stack 02437 C9 RET ;and execute routine ; 1st argument in DBL format 02438 CDDB0A CALL 0ADBH ;X = CDBL (X) (convert 2nd ;argument to DBL) 0243B CDFC09 CALL 09FCH ;Y = X 0243E E1 POP HL ;Get 1st argument from stack 0243F 221F41 LD (411FH),HL ;and load into X 02442 E1 POP HL 02443 221D41 LD (411DH),HL 02446 C1 POP BC 02447 D1 POP DE 02448 CDB409 CALL 09B4H ;X = BCDE 0244B CDDB0A CALL 0ADBH ;X = CDBL (X) (convert 1st ;argument to DBL) 0244E 21AB18 LD HL,18ABH ;HL -> jump table for basic ;arithmatic (DBL) 02451 3AB040 LD A,(40B0H) ;A = operator code offset 02454 07 RLCA ;* 2 (2 bytes offset) 02455 C5 PUSH BC ;Save BC 02456 4F LD C,A ;BC = table offset 02457 0600 LD B,00H 02459 09 ADD HL,BC ;Add offset 0245A C1 POP BC ;Restore BC 0245B 7E LD A,(HL) ;HL -> routine 0245C 23 INC HL 0245D 66 LD H,(HL) 0245E 6F LD L,A 0245F E9 JP (HL) ;Execute routine ; 2nd argument in DBL format 02460 C5 PUSH BC ;Save VT offset 02461 CDFC09 CALL 09FCH ;Y = X (2nd argument to X) 02464 F1 POP AF ;Restore VT 02465 32AF40 LD (40AFH),A ;Save VT in system RAM 02468 FE04 CP 04H ;1st argument in SNG format ? 0246A 28DA JR Z,2446H ;Yes: get 1st argument from ;stack and convert to DBL 0246C E1 POP HL ;No: 1st argument is an INT: ;Get 1st argument 0246D 222141 LD (4121H),HL ;Put it into X 02470 18D9 JR 244BH ;and convert it to DBL ; 1st argument in SNG format 02472 CDB10A CALL 0AB1H ;X = CSNG (X) (convert 2nd ;argument to SNG) 02475 C1 POP BC ;Get 1st argument from stack 02476 D1 POP DE 02477 21B518 LD HL,18B5H ;HL -> jump table 0247A 18D5 JR 2451H ;Execute function ; 2nd argument in SNG format, 1st argument in INT format 0247C E1 POP HL ;Restore 1st argument 0247D CDA409 CALL 09A4H ;(SP) = X (save 2nd argument ;on stack) 02480 CDCF0A CALL 0ACFH ;X = CSNG (HL) 02483 CDBF09 CALL 09BFH ;BCDE = X = 1st argument 02486 E1 POP HL ;1st argument from stack 02487 222341 LD (4123H),HL ;Put it in X 0248A E1 POP HL 0248B 222141 LD (4121H),HL 0248E 18E7 JR 2477H ;Continue at 2477H ; IDIV: X = DE / HL ; Divides two integer numbers with the result in SNG format ; ; I: DE = Dividend ; HL = Divisor ; O: X = Quotient 02490 E5 PUSH HL ;Save divisor 02491 EB EX DE,HL ;HL = dividend 02492 CDCF0A CALL 0ACFH ;X = CSNG (DE) (X = dividend) 02495 E1 POP HL ;Restore dividend 02496 CDA409 CALL 09A4H ;(SP) = X (dividend to stack) 02499 CDCF0A CALL 0ACFH ;X = CSNG (HL) (X = divisor) 0249C C3A008 JP 08A0H ;X = (SP) / X (execute SDIV) ; Decode argument at (PTP) and store result in X 0249F D7 RST 10H ;Operand indicated ? 024A0 1E28 LD E,28H ;E = error code for ?MO Error 024A2 CAA219 JP Z,19A2H ;No: ?MO Error ;Yes: number indicated ? 024A5 DA6C0E JP C,0E6CH ;Yes: decode number and store ;result in X ;No: 024A8 CD3D1E CALL 1E3DH ;Variable indicated ? 024AB D24025 JP NC,2540H ;Yes: continue at 2540H 024AE FECD CP 0CDH ;'+' token ? (positive sign) 024B0 28ED JR Z,249FH ;Yes: skip it, get next ;character 024B2 FE2E CP 2EH ;'.' ? (decimal point) 024B4 CA6C0E JP Z,0E6CH ;Yes: decode number 024B7 FECE CP 0CEH ;'-' token ? (negative sign) 024B9 CA3225 JP Z,2532H ;Yes: continue at 2532H 024BC FE22 CP 22H ;'"' ? (string constant) 024BE CA6628 JP Z,2866H ;Yes: continue at 2866H 024C1 FECB CP 0CBH ;'NOT' token ? 024C3 CAC425 JP Z,25C4H ;Yes: continue at 25C4H 024C6 FE26 CP 26H ;'&' ? (hexadecimal constant) 024C8 CAE334 JP Z,34E3H ;Yes: continue at 34E3H 024CB FEC3 CP 0C3H ;'ERR' token ? 024CD 200A JR NZ,24D9H ;No: continue at 24D9H ; X = ERR ; ------- 024CF D7 RST 10H ;Adjust PTP 024D0 3A9A40 LD A,(409AH) ;A = last error code 024D3 E5 PUSH HL ;Save PTP 024D4 CDF827 CALL 27F8H ;Save A to X as INT 024D7 E1 POP HL ;Restore PTP 024D8 C9 RET ; Not ERR 024D9 FEC2 CP 0C2H ;'ERL' token ? 024DB 200A JR NZ,24E7H ;No: continue at 24E7H ; X = ERL ; ------- 024DD D7 RST 10H ;Adjust PTP 024DE E5 PUSH HL ;Save PTP 024DF 2AEA40 LD HL,(40EAH) ;HL = LN of last error line 024E2 CD660C CALL 0C66H ;X = HL (SNG) (no sign) 024E5 E1 POP HL ;Restore PTP 024E6 C9 RET ; not ERL 024E7 FEC0 CP 0C0H ;'VARPTR' toekn ? 024E9 2014 JR NZ,24FFH ;No: continue at 24FFH ; X = VARPTR() ; ------------ 024EB D7 RST 10H ;Adjust PTP 024EC CF RST 08H ;Next character must be 024ED 28 DEFB '(' ;a '(' 024EE CD0D26 CALL 260DH ;DE = address of indicated ;variable. DE = 0000H in case ;variable not found 024F1 CF RST 08H ;Next character must be 024F2 29 DEFB ')' ;a ')' 024F3 E5 PUSH HL ;Save PTP 024F4 EB EX DE,HL ;HL -> variable 024F5 7C LD A,H ;Null pointer ? 024F6 B5 OR L 024F7 CA4A1E JP Z,1E4AH ;Yes: ?FC Error ;No: 024FA CD9A0A CALL 0A9AH ;X = HL (INT) 024FD E1 POP HL ;Restore PTP 024FE C9 RET ; Not VARPTR 024FF FEC1 CP 0C1H ;'USR" token ? 02501 C37A3F JP 3F7AH ;Intercept Colour BASIC token ;and continue at 27FEH in case ;'USR' token found 02504 FEC5 CP 0C5H ;'INSTR' token ? 02506 CA9D41 JP Z,419DH ;Yes: continue at 41D9H 02509 FEC8 CP 0C8H ;'MEM' token ? 0250B CAC927 JP Z,27C9H ;Yes: continue at 27C9H 0250E FEC7 CP 0C7H ;'TIME$' token ? 02510 CA7641 JP Z,4176H ;Yes: continue at 4176H 02513 FEC6 CP 0C6H ;'CHECK' token ? 02515 CA3201 JP Z,0132H ;Yes: continue at 0132H 02518 FEC9 CP 0C9H ;'INKEY$' token ? 0251A CA9D01 JP Z,019DH ;Yes: continue at 01D9H 0251D FEC4 CP 0C4H ;'STRING$' token ? 0251F CA2F2A JP Z,2A2FH ;Yes: continue at 2A2FH 02522 FEBE CP 0BEH ;'FN' token ? 02524 CA5541 JP Z,4155H ;Yes: continue at 4155H 02527 D6D7 SUB 0D7H ;Function token found ? 02529 D24E25 JP NC,254EH ;Yes: continue at 254EH ;No: 0252C CD3523 CALL 2335H ;Since all other possibilities ;have been tested, there can ;only be an expresssion ;enclosed in paranthesis ;at (PTP) 0252F CF RST 08H ;Next character must be 02530 29 DEFB ')' ;a ')' 02531 C9 RET ; Process negative sign 02532 167D LD D,7DH ;D = priority code (next ;priority after power function) 02534 CD3A23 CALL 233AH ;Argument to X 02537 2AF340 LD HL,(40F3H) ;Get PTP 0253A E5 PUSH HL ;And save it 0253B CD7B09 CALL 097BH ;Negate result (type conform) 0253E E1 POP HL ;Restore PTP 0253F C9 RET ; Process variable as operand 02540 CD0D26 CALL 260DH ;Get address of variable 02543 E5 PUSH HL ;Save PTP 02544 EB EX DE,HL ;HL = address 02545 222141 LD (4121H),HL ;Save address 02548 E7 RST 20H ;TSTTYP ;STR type ? 02549 C4F709 CALL NZ,09F7H ;No: X = (HL) (type conform) 0254C E1 POP HL ;Restore PTP 0254D C9 RET ; Function token found ; A = 00H for SNG, 01H for INT,..., 22H for RIGHT$ and 24H for MID$ ; (see keyword and address table at 1608H) 0254E 0600 LD B,00H ;MSB of offset = 00H 02550 07 RLCA ;A = A * 2 (2 bytes address) 02551 4F LD C,A ;BC = offset of address table 02552 C5 PUSH BC ;Save offset 02553 D7 RST 10H ;Adjust PTP 02554 79 LD A,C ;A = offset LSB 02555 FE41 CP 41H ;LSB > 41H ? 02557 3816 JR C,256FH ;No: continue at 256FH ; Process 1st argument of LEFT$, RIGHT$ or MID$ 02559 CD3523 CALL 2335H ;Process expression 0255C CF RST 08H ;Next character must be 0255D 2C DEFB ',' ;a ',' ;1st argument not a string ? 0255E CDF40A CALL 0AF4H ;Yes: ?TM Error 02561 EB EX DE,HL ;DE = PTP 02562 2A2141 LD HL,(4121H) ;HL -> 1st argument 02565 E3 EX (SP),HL ;Save pointer 02566 E5 PUSH HL ;Save offset to stack 02567 EB EX DE,HL ;HL = PTP 02568 CD1C2B CALL 2B1CH ;DE = 2nd argument 0256B EB EX DE,HL ;DE = PTP, HL = 2nd argument 0256C E3 EX (SP),HL ;Save 2nd argument, HL = offset 0256D 1814 JR 2583H ;Continue at 2583H ; Get function argument and execute function 0256F CD2C25 CALL 252CH ;Process expression 02572 E3 EX (SP),HL ;Save PTP, HL = offset 02573 7D LD A,L ;A = LSB of offset 02574 FE0C CP 0CH ;LSB < 0CH ? (SNG/INT/ABS/FRE/ ;INP/POS) 02576 3807 JR C,257FH ;Yes: execute function ;No: 02578 FE1B CP 1BH ;LSB < 1BH ? (SQR/RND/LOG/EXP/ ;COS/SIN/TAN/ATN) 0257A E5 PUSH HL ;Save offset 0257B DCB10A CALL C,0AB1H ;Yes: X = CSNG (X) 0257E E1 POP HL ;Restore offset 0257F 113E25 LD DE,253EH ;Set new RET-address 02582 D5 PUSH DE ;to 253EH 02583 010816 LD BC,1608H ;BC -> jump table 02586 09 ADD HL,BC ;Add offset 02587 4E LD C,(HL) ;Load jump address in HL 02588 23 INC HL 02589 66 LD H,(HL) 0258A 69 LD L,C 0258B E9 JP (HL) ;Execute function ; String compare ; ; I: (SP-2) = RET addres to 25B8H ; (SP) = Vector address of 1st string ; X = Vector address of 2nd string ; O: A = FFH : 1st string < 2nd string ; = 00H : 1st string = 2nd string ; = 01H : 1st string > 2nd string 0258C CDD729 CALL 29D7H ;Test 2nd argument if STR ;format, HL -> vector of ;2nd string 0258F 7E LD A,(HL) ;A = LEN (2nd string) 02590 23 INC HL ;BC = address (2nd string) 02591 4E LD C,(HL) 02592 23 INC HL 02593 46 LD B,(HL) 02594 D1 POP DE ;Restore vector address of ;1st string in DE 02595 C5 PUSH BC ;Save address and 02596 F5 PUSH AF ;length of 2nd string 02597 CDDE29 CALL 29DEH ;HL -> vector of 2st string 0259A D1 POP DE ;D = length of 2nd string 0259B 5E LD E,(HL) ;E = length of 1st string 0259C 23 INC HL ;BC = address of 1st string 0259D 4E LD C,(HL) 0259E 23 INC HL 0259F 46 LD B,(HL) 025A0 E1 POP HL ;HL = address of 2nd string 025A1 7B LD A,E ;Both length counters zero ? 025A2 B2 OR D 025A3 C8 RET Z ;Yes: done, return 025A4 7A LD A,D ;A = 2nd length counter 025A5 D601 SUB 01H ;Counter zero? 025A7 D8 RET C ;Yes: done, return 025A8 AF XOR A ;A = 00H 025A9 BB CP E ;1st length counter zero ? 025AA 3C INC A ;A = 01H if so. 025AB D0 RET NC ;Yes: done, return (A = 01H) 025AC 15 DEC D ;2nd length counter - 1 025AD 1D DEC E ;1st length counter - 1 025AE 0A LD A,(BC) ;Compare next character of 1st 025AF BE CP (HL) ;string with character of 2nd ;string 025B0 23 INC HL ;2nd pointer + 1 025B1 03 INC BC ;1st pointer + 1 ;Both characters identical ? 025B2 28ED JR Z,25A1H ;Yes: compare next characters 025B4 3F CCF ;Negate C-flag 025B5 C36009 JP 0960H ;A = FFH in case C-flag = 1 ;A = 00H in case C-flag = 0 ; Evaluate result of compare ; ; I: A = FFH : 1st argument < 2nd argument ; = 00H : 1st argument = 2nd argument ; = 01H : 1st argument > 2nd argument 025B8 3C INC A ;A = A + 1 (C-flag = 1 if A ;was FFH) 025B9 8F ADC A,A ;A = 01H : 1st arg. < 2nd arg. ; = 02H : 1st arg. = 2nd arg. ; = 04H : 1st arg. > 2nd arg. 025BA C1 POP BC ;Restore compare operator code ;(see 2355H) 025BB A0 AND B ;Set bits of operators done 025BC C6FF ADD A,0FFH ;A = A + FFH: C-flag = 1 if ;a condition was true (overflow ;in case A <> 0) 025BE 9F SBC A,A ;A = 00H = 0 in case false ;else A = FFH = -1 025BF CD8D09 CALL 098DH ;X = HL = A (with sign) 025C2 1812 JR 25D6H ;Back to 2346H ; NOT ; --- 025C4 165A LD D,5AH ;Priority code = 5AH (higher ;than AND and OR) 025C6 CD3A23 CALL 233AH ;Argument to X 025C9 CD7F0A CALL 0A7FH ;HL = X = CINT (X) 025CC 7D LD A,L ;Negate result 025CD 2F CPL 025CE 6F LD L,A 025CF 7C LD A,H 025D0 2F CPL 025D1 67 LD H,A 025D2 222141 LD (4121H),HL ;And write back 025D5 C1 POP BC ;Remove RET-address 025D6 C34623 JP 2346H ;and back to 2346H ; RST 20H ; ------- ; TSTTYP: Test current VT and set corresponding flags ; ; I: - ; O: A = VT - 3 ; INT: A = FFH, Z-flag = 0, C-flag = 1, S-flag = 1 ; STR: A = 00H, Z-flag = 1, C-flag = 1, S-flag = 0 ; SNG: A = 01H, Z-flag = 0, C-flag = 1, S-flag = 0 ; DBL: A = 05H, Z-flag = 0, C-flag = 0, S-flag = 0 025D9 3AAF40 LD A,(40AFH) ;A = VT 025DC FE08 CP 08H ;DBL ? 025DE 3005 JR NC,25E5H ;Yes: continue at 25E5H ;No: 025E0 D603 SUB 03H ;A = VT - 3 025E2 B7 OR A ;Set flags 025E3 37 SCF ;C-flag = 1 025E4 C9 RET 025E5 D603 SUB 03H ;A = VT - 3 025E7 B7 OR A ;Set flags 025E8 C9 RET ; Process AND / OR 025E9 C5 PUSH BC ;Save priority code 025EA CD7F0A CALL 0A7FH ;HL = X = CINT (X) = 2nd arg. 025ED F1 POP AF ;Restore priority code 025EE D1 POP DE ;DE = 1st argument 025EF 01FA27 LD BC,27FAH ;Set new RET-address 025F2 C5 PUSH BC ;to 27FAH (X = HL (INT) ) 025F3 FE46 CP 46H ;Priority code = 46H (OR) ? 025F5 2006 JR NZ,25FDH ;No: execute AND at 25FDH ; OR ; -- 025F7 7B LD A,E ;OR both arguments 025F8 B5 OR L 025F9 6F LD L,A 025FA 7C LD A,H 025FB B2 OR D 025FC C9 RET ;Back to 27FAH ; AND ; --- 025FD 7B LD A,E ;AND both arguments 025FE A5 AND L 025FF 6F LD L,A 02600 7C LD A,H 02601 A2 AND D 02602 C9 RET ;Back to 27FAH ; Return after DIM 02603 2B DEC HL ;PTP - 1 02604 D7 RST 10H ;End of command ? 02605 C8 RET Z ;Yes: done, return ;No: 02606 CF RST 08H ;Next character must be 02607 2C DEFB ',' ;a comma ; DIM statement ; ------------- 02608 010326 LD BC,2603H ;Set new return address 0260B C5 PUSH BC ;to 2603H 0260C F6AF OR 0AFH ;A <> 0 for DIM ; Find address of variable in (PTP) and create variable if it does not ; exist. ; ; I: PTP -> variable name ; O: DE -> searched variable (0000H if variable does not exist) * 0260D AF XOR A ;A = 0 for address search 0260E 32AE40 LD (40AEH),A ;Store flag 02611 46 LD B,(HL) ;B = first character of name 02612 CD3D1E CALL 1E3DH ;Is the character in (HL) a ;upper case character ? 02615 DA9719 JP C,1997H ;No: ?SN Error 02618 AF XOR A ;A = 00H 02619 4F LD C,A ;C = default second character ;of variable name 0261A D7 RST 10H ;Second character present ? 0261B 3805 JR C,2622H ;Jump when it is a number 0261D CD3D1E CALL 1E3DH ;Upper case character present ? 02620 3809 JR C,262BH ;No: keep variable name at ;one character 02622 4F LD C,A ;C = second character of name 02623 D7 RST 10H ;Get next character ;Is it a number ? 02624 38FD JR C,2623H ;Yes: get character 02626 CD3D1E CALL 1E3DH ;Is it an upper case character ? 02629 30F8 JR NC,2623H ;Yes: get character 0262B 115226 LD DE,2652H ;Set new return address 0262E D5 PUSH DE ;to 2652H 0262F 1602 LD D,02H ;D = 2 (type code for INT) 02631 FE25 CP '%' ;'%' (INT indentifier) found ? 02633 C8 RET Z ;Yes: D = type code 02634 14 INC D ;D = 3 (type code for STR) 02635 FE24 CP '$' ;'$' (STR indentifier) found ? 02637 C8 RET Z ;Yes: D = type code 02638 14 INC D ;D = 4 (type code for SNG) 02639 FE21 CP '!' ;'!' (SNG indentifier) found ? 0263B C8 RET Z ;Yes: D = type code 0263C 1608 LD D,08H ;D = 8 (type code for DBL) 0263E FE23 CP '#' ;'#' (DBL indentifier) found ? 02640 C8 RET Z ;Yes: D = type code ; No type code indicated. Get type code from DEF table 02641 78 LD A,B ;A = first character of name 02642 D641 SUB 41H ;A = offset for type code table 02644 E67F AND 7FH ;Clear highest bit 02646 5F LD E,A ;DE = offset 02647 1600 LD D,00H 02649 E5 PUSH HL ;Save PTP 0264A 210141 LD HL,4101H ;HL -> type code table 0264D 19 ADD HL,DE ;Add offset 0264E 56 LD D,(HL) ;Get type code 0264F E1 POP HL ;Restore PTP 02650 2B DEC HL ;PTP - 1 02651 C9 RET ; Search variable / create variable ; BC = 1st and 2nd character of variable name ; D = type code of variable 02652 7A LD A,D ;A = type code 02653 32AF40 LD (40AFH),A ;Save as VT 02656 D7 RST 10H ;Skip spaces/LF etc 02657 3ADC40 LD A,(40DCH) ;Array variables indicated ? 0265A B7 OR A ;(see 1CA1H) 0265B C26426 JP NZ,2664H ;No: create normal variable 0265E 7E LD A,(HL) ;A = next character following ;variable name. 0265F D628 SUB 28H ;Is it a '(' 02661 CAE926 JP Z,26E9H ;Yes: process array variable 02664 AF XOR A ;A = 00H 02665 32DC40 LD (40DCH),A ;Release array variable 02668 E5 PUSH HL ;Save PTP 02669 D5 PUSH DE ;Save type code 0266A 2AF940 LD HL,(40F9H) ;HL -> start of variables 0266D EB EX DE,HL ;DE = HL 0266E 2AFB40 LD HL,(40FBH) ;HL -> end of variables 02671 DF RST 18H ;End reached ? 02672 E1 POP HL ;Restore type code 02673 2819 JR Z,268EH ;Yes: create new variable 02675 1A LD A,(DE) ;A = type code of variable ;addressed by DE 02676 6F LD L,A ;L = type code 02677 BC CP H ;Is it the searched code ? 02678 13 INC DE ;Pointer + 1 02679 200B JR NZ,2686H ;No: continue at 2686H 0267B 1A LD A,(DE) ;A = second character of name 0267C B9 CP C ;Same as in searched name ? 0267D 2007 JR NZ,2686H ;No: continue at 2686H 0267F 13 INC DE :Pointer + 1 02680 1A LD A,(DE) ;A = first charachter of name 02681 B8 CP B ;Same as in searched name ? 02682 CACC26 JP Z,26CCH ;Yes: continue at 26CCH 02685 3E13 LD A,13H ;-- * 02685 13 INC DE ;Pointer + 1 02687 13 INC DE ;Pointer + 1 02688 E5 PUSH HL ;Save type code 02689 2600 LD H,00H ;HL = length of variable found 0268B 19 ADD HL,DE ;Put HL on next variable 0268C 18DF JR 266DH ;Repeat compare ; Variable not found 0268E 7C LD A,H ;A = type code 0268F E1 POP HL ;Restore PTP 02690 E3 EX (SP),HL ;Save PTP, HL = RET address 02691 F5 PUSH AF ;Save type code 02692 D5 PUSH DE ;Save pointer on end of ;variables 02693 11F124 LD DE,24F1H ;Was routine CALLed by VARPTR ;function ? 02696 DF RST 18H ;(RET address = 24F1H) 02697 2836 JR Z,26CFH ;Yes: continue at 26CFH 02699 114325 LD DE,2543H ;CALLed from 2540H ? 0269C DF RST 18H ;(RET address = 2543H) 0269D D1 POP DE ;Restore pointer 0269E 2835 JR Z,26D5H ;Yes: continue at 26D5H ; Create new variable 026A0 F1 POP AF ;Restore type code 026A1 E3 EX (SP),HL ;Save RET address, restore PTP 026A2 E5 PUSH HL ;Save PTP 026A3 C5 PUSH BC ;Save variable name 026A4 4F LD C,A ;C = type code 026A5 0600 LD B,00H ;B = 00H 026A7 C5 PUSH BC ;Save type code ;Calculate total length of var 026A8 03 INC BC ;BC + 1 for type code 026A9 03 INC BC ;BC + 2 for variable name 026AA 03 INC BC 026AB 2AFD40 LD HL,(40FDH) ;HL -> start of free space 026AE E5 PUSH HL ;Save pointer 026AF 09 ADD HL,BC ;+ length = new start of ;free space 026B0 C1 POP BC ;Restore old start address 026B1 E5 PUSH HL ;Save new start address 026B2 CD5519 CALL 1955H ;Test memory space and move ;memory to create space for ;new variable 026B5 E1 POP HL ;Restore new start address 026B6 22FD40 LD (40FDH),HL ;Save it in system RAM 026B9 60 LD H,B ;HL = new end address of 026BA 69 LD L,C ;memory with single variables 026BB 22FB40 LD (40FBH),HL ;Save it in system RAM 026BE 2B DEC HL ;Pointer - 1 026BF 3600 LD (HL),00H ;Clear memory space for new ;variable 026C1 DF RST 18H ;Done ? 026C2 20FA JR NZ,26BEH ;No: continue clear 026C4 D1 POP DE ;Restore type code ;HL -> new variable 026C5 73 LD (HL),E ;Store type code 026C6 23 INC HL ;Pointer + 1 026C7 D1 POP DE ;Restore variable name 026C8 73 LD (HL),E ;Store 2nd character 026C9 23 INC HL ;Pointer + 1 026CA 72 LD (HL),D ;Store 1st character 026CB EB EX DE,HL ;DE -> mantissa of new variable 026CC 13 INC DE ;DE -> new variable 026CD E1 POP HL ;Restore PTP 026CE C9 RET ; VARPTR function: variable not found 026CF 57 LD D,A ;DE = 0000H 026D0 5F LD E,A 026D1 F1 POP AF ;Correct stack 026D2 F1 POP AF 026D3 E3 EX (SP),HL ;Restore PTP, save RET address 026D4 C9 RET ;Done ; Variable at expression evaluation (2337H) not found ; Set result to 0 026D5 322441 LD (4124H),A ;Exp (X) = 0 -> X = 0 026D8 C1 POP BC ;Correct stack 026D9 67 LD H,A ;HL = 0000H 026DA 6F LD L,A 026DB 222141 LD (4121H),HL ;Set X (INT) to 0 026DE E7 RST 20H ;TSTTYP ;STR type ? 026DF 2006 JR NZ,26E7H ;No: X is ok, continue at 26E7H ;Yes: 026E1 212819 LD HL,1928H ;Vector address -> null string 026E4 222141 LD (4121H),HL ;X = HL 026E7 E1 POP HL ;Restore PTP 026E8 C9 RET ; Array variable recognized ; ; BC = variable name ; HL = PTP ; A = 00H 026E9 E5 PUSH HL ;Save PTP 026EA 2AAE40 LD HL,(40AEH) ;L = type code, H = DIM flag 026ED E3 EX (SP),HL ;Save HL, restore PTP 026EE 57 LD D,A ;D = 0 (number of dimensions) 026EF D5 PUSH DE ;Save registers 026F0 C5 PUSH BC 026F1 CD451E CALL 1E45H ;Get next dimension at (PTP) 026F4 C1 POP BC ;Restore registers 026F5 F1 POP AF 026F6 EB EX DE,HL ;DE = PTP, HL = dim. value 026F7 E3 EX (SP),HL ;Save dim. value, restore HL 026F8 E5 PUSH HL ;Save HL again 026F9 EB EX DE,HL ;HL = PTP 026FA 3C INC A ;Dimension counter + 1 026FB 57 LD D,A ;D = counter 026FC 7E LD A,(HL) ;Another dimension indicated ? 026FD FE2C CP ',' ;Separator found ? 026FF 28EE JR Z,26EFH ;Yes: get next dimension ;No: 02701 CF RST 08H ;Next character must be 02702 29 DEFB ')' ;a ')' 02703 22F340 LD (40F3H),HL ;Save PTP 02706 E1 POP HL ;Restore type code and DIM flag 02707 22AE40 LD (40AEH),HL ;and save in system RAM 0270A D5 PUSH DE ;Save dimension counter ;The stack now contains the ;dimension values and the ;number of dimensions 0270B 2AFB40 LD HL,(40FBH) ;HL -> start of array variable ;memory space 0270E 3E19 LD A,19H ;-- * 0270F 19 ADD HL,DE ;Add array size. HL now ;points on the next array 02710 EB EX DE,HL 02711 2AFD40 LD HL,(40FDH) ;DE -> end of array variable ;memory space 02714 EB EX DE,HL 02715 DF RST 18H ;End of array vars reached ? 02716 3AAF40 LD A,(40AFH) ;A = requested type code 02719 2827 JR Z,2742H ;No: array variable not found. ;HL points to free memory space ;for the new array. 0271B BE CP (HL) ;Type code found ? 0271C 23 INC HL ;Pointer + 1 0271D 2008 JR NZ,2727H ;No: continue at 2727H 0271F 7E LD A,(HL) ;2nd character of var. name 02720 B9 CP C ;and compare it 02721 23 INC HL ;Pointer + 1 ;Characters the same ? 02722 2004 JR NZ,2728H ;No: continue at 2728H 02724 7E LD A,(HL) ;Compare 1st character 02725 B8 CP B ;The same ? 02726 3E23 LD A,23H ;-- * 02726 23 INC HL ;Adjust pointer 02728 23 INC HL ;Pointer + 1 02729 5E LD E,(HL) ;DE = total length 0272A 23 INC HL 0272B 56 LD D,(HL) 0272C 23 INC HL 0272D 20E0 JR NZ,270FH ;Array not found: check next 0272F 3AAE40 LD A,(40AEH) ;New array to be created ? 02732 B7 OR A 02733 1E12 LD E,12H ;E = error code for ?DD Error 02735 C2A219 JP NZ,19A2H ;Yes: the array already exists, ;issue error. 02738 F1 POP AF ;No: A = number of dimensions 02739 96 SUB (HL) ;Does they match ? 0273A CA9527 JP Z,2795H ;Yes: compute address of the ;requested array element 0273D 1E10 LD E,10H ;E = error code for ?BS Error 0273F C3A219 JP 19A2H ;Issue error ; Array not found ; HL -> free memory space for new array 02742 77 LD (HL),A ;Save type code 02743 23 INC HL ;Pointer + 1 02744 5F LD E,A ;DE = size of array element 02745 1600 LD D,00H 02747 F1 POP AF ;A = number of dimensions 02748 71 LD (HL),C ;Save array name 02749 23 INC HL 0274A 70 LD (HL),B 0274B 23 INC HL 0274C 4F LD C,A ;C = dimension counter 0274D CD6319 CALL 1963H ;Sufficient memory available ? 02750 23 INC HL ;Pointer + 1 02751 23 INC HL ;Pointer + 1 02752 22D840 LD (40D8H),HL ;Save pointer in system RAM 02755 71 LD (HL),C ;Save number of dimensions 02756 23 INC HL ;Pointer + 1 02757 3AAE40 LD A,(40AEH) ;A = DIM flag 0275A 17 RLA ;If address search then ;C-flag = 0. ;If array create then ;C-flag = 1 0275B 79 LD A,C ;A = dimension counter 0275C 010B00 LD BC,000BH ;BC = default dimension value ;Address search ? 0275F 3002 JR NC,2763H ; Yes: continue at 2763H 02761 C1 POP BC ;Restore dimension value 02762 03 INC BC ;+ 1 for zero element 02763 71 LD (HL),C ;Save dimension value 02764 23 INC HL 02765 70 LD (HL),B 02766 23 INC HL 02767 F5 PUSH AF ;Save counter 02768 CDAA0B CALL 0BAAH ;DE = DE * BC: calculate the ;total array size. 0276B F1 POP AF ;Restore counter 0276C 3D DEC A ;Counter - 1 ;All dimensions done ? 0276D 20ED JR NZ,275CH ;No: next dimension ;Yes: 0276F F5 PUSH AF ;Save 00H on stack 02770 42 LD B,D ;BC = array size 02771 4B LD C,E 02772 EB EX DE,HL ;DE -> start of new array ;HL = array size 02773 19 ADD HL,DE ;HL -> new end of array ;variable memory space ;Memory overflow ? 02774 38C7 JR C,273DH ;Yes: ?BS Error 02776 CD6C19 CALL 196CH ;Still free memory remaining ? 02779 22FD40 LD (40FDH),HL ;Save new end address 0277C 2B DEC HL ;Pointer - 1 0277D 3600 LD (HL),00H ;Clear array byte 0277F DF RST 18H ;Start of array reached ? 02780 20FA JR NZ,277CH ;No: clear next byte 02782 03 INC BC ;BC = number of required bytes ;+ 1 02783 57 LD D,A ;D = 0 02784 2AD840 LD HL,(40D8H) ;HL -> number of dimensions 02787 5E LD E,(HL) ;DE = number of dimensions 02788 EB EX DE,HL ;HL = dimension counter ;DE = pointer 02789 29 ADD HL,HL ;HL = 2 * number of dimensions ;(Every dimension value is ;stored in 2 bytes) 0278A 09 ADD HL,BC ;+ number of bytes required ;by the array elements ;= total size (in bytes) 0278B EB EX DE,HL ;DE = total size 0278C 2B DEC HL ;Pointer - 2 0278D 2B DEC HL 0278E 73 LD (HL),E ;Save total size 0278F 23 INC HL 02790 72 LD (HL),D 02791 23 INC HL 02792 F1 POP AF ;Restore flags from stack ;Creation of new array (DIM) ? 02793 3830 JR C,27C5H ;Yes: done. ; Compute address of required variable 02795 47 LD B,A ;BC = 0000H 02796 4F LD C,A 02797 7E LD A,(HL) ;A = dimension counter 02798 23 INC HL ;Pointer + 1 02799 16E1 LD D,0E1H ;-- * 0279A E1 POP HL ;Restore pointer 0279B 5E LD E,(HL) ;DE = next dimension value 0279C 23 INC HL 0279D 56 LD D,(HL) 0279E 23 INC HL 0279F E3 EX (SP),HL ;Save pointer, HL = requested ;dimension 027A0 F5 PUSH AF ;Save counter 027A1 DF RST 18H ;Requested dimension found ? ;Requested dim. > found dim. ? 027A2 D23D27 JP NC,273DH ;Yes: ?BS Error ;No: 027A5 CDAA0B CALL 0BAAH ;DE = DE * BC = found dimension ;* last value 027A8 19 ADD HL,DE ;HL = requested dimension + ;found dimension * last value 027A9 F1 POP AF ;Restore counter 027AA 3D DEC A ;Counter - 1 027AB 44 LD B,H ;BC = array element counter 027AC 4D LD C,L 027AD 20EB JR NZ,279AH ;Process next dimension 027AF 3AAF40 LD A,(40AFH) ;A = type code 027B2 44 LD B,H ;BC = index value of array 027B3 4D LD C,L ;element 027B4 29 ADD HL,HL ;* 2 = offset for INT 027B5 D604 SUB 04H ;Typecode = INT or STR ? 027B7 3804 JR C,27BDH ;Yes: continue at 27BDH ;No: 027B9 29 ADD HL,HL ;* 2 = offset for SNG ;Type code = SNG ? 027BA 2806 JR Z,27C2H ;Yes: continue at 27C2H ;No: 027BC 29 ADD HL,HL ;* 2 = offset for DBL 027BD B7 OR A ;Type code = INT or DBL ? 027BE E2C227 JP PO,27C2H ;Yes: HL contains proper offset ;No: 027C1 09 ADD HL,BC ;Add again: offset for STR 027C2 C1 POP BC ;Start address array to BC 027C3 09 ADD HL,BC ;+ offset = requested address 027C4 EB EX DE,HL ;DE = address 027C5 2AF340 LD HL,(40F3H) ;HL = PTP 027C8 C9 RET ; MEM = FRE (numerical variable ) 027C9 AF XOR A ;A = 0 027CA E5 PUSH HL ;Save PTP 027CB 32AF40 LD (40AFH),A ;Set type code to 0 027CE CDD427 CALL 27D4H ;X = end of stack - start of ;free memory = number of ;free bytes 027D1 E1 POP HL ;Restore PTP 027D2 D7 RST 10H ;Increase PTP 027D3 C9 RET ; X = FRE ( arg ) ; --------------- 027D4 2AFD40 LD HL,(40FDH) ;HL = start of free memory 027D7 EB EX DE,HL ;DE = HL 027D8 210000 LD HL,0000H ;HL = 0000H 027DB 39 ADD HL,SP ;HL = 0 + SP = SP 027DC E7 RST 20H ;TSTTYP ;STR ? (number of free bytes ;in string space required) 027DD 200D JR NZ,27ECH ;No: continue at 27ECH ;Yes: 027DF CDDA29 CALL 29DAH ;Clear argument from string ;space 027E2 CDE628 CALL 28E6H ;Sort string space 027E5 2AA040 LD HL,(40A0H) ;HL -> start of string space 027E8 EB EX DE,HL ;DE = HL 027E9 2AD640 LD HL,(40D6H) ;HL -> last string in string ;space 027EC 7D LD A,L ;Compute the number of free 027ED 93 SUB E ;bytes; result in HL 027EE 6F LD L,A 027EF 7C LD A,H 027F0 9A SBC A,D 027F1 67 LD H,A 027F2 C3660C JP 0C66H ;X = HL ; X = POS (dummy) ; --------------- 027F5 3AA640 LD A,(40A6H) ;A = cursor position in line 027F8 6F LD L,A ;HL = A (without sign) 027F9 AF XOR A 027FA 67 LD H,A 027FB C39A0A JP 0A9AH ;X = HL (INT) ; X = USR ( X ) ; ------------- 027FE CDA941 CALL 41A9H ;DOS 02801 D7 RST 10H ;Increase PTP 02802 CD2C25 CALL 252CH ;Process expression 02805 E5 PUSH HL ;Save PTP 02806 219008 LD HL,0890H ;Set new RET address 02809 E5 PUSH HL ;to 0890H 0280A 3AAF40 LD A,(40AFH) ;A = type code 0280D F5 PUSH AF ;Save type code 0280E FE03 CP 03H ;STR argument? 02810 CCDA29 CALL Z,29DAH ;Yes: remove argument from ;string space 02813 F1 POP AF ;Restore type code 02814 EB EX DE,HL ;DE = 0890H (numerical ;argument) ;DE = vector address (string ;argument) 02815 2A8E40 LD HL,(408EH) ;HL -> USR routine 02818 E9 JP (HL) ;Execute routine ; Conversion of X into desired type ; ; I: A = desired type code ; (see 1F35H) 02819 E5 PUSH HL ;Save HL 0281A E607 AND 07H ;A = offset for jump table ;INT: A = 2, STR A = 3 ;SNG: A = 4, DBL A = 0 0281C 21A118 LD HL,18A1H ;HL -> jump table for type ;conversion 0281F 4F LD C,A ;BC = offset 02820 0600 LD B,00H 02822 09 ADD HL,BC ;Add offset to pointer 02823 CD8625 CALL 2586H ;Add offset again (2 bytes ;per address) and execute ;routine 02826 E1 POP HL ;restore HL 02827 C9 RET ; SUB for INPUT ; Test for ?ID Error ; (see 219AH) 02828 E5 PUSH HL ;Save PTP 02829 2AA240 LD HL,(40A2H) ;HL = current LN 0282C 23 INC HL ;Current LN = 65535 ? 0282D 7C LD A,H ;(HL + 1 = 0000H) 0282E B5 OR L ;(65535 = LN for command mode) 0282F E1 POP HL ;Restore PTP 02830 C0 RET NZ ;No: ok, return ; ?ID Error 02831 1E16 LD E,16H ;E = error code for ?ID Error 02833 C3A219 JP 19A2H ;Issue error ; X = STR$ ( X ) ; -------------- 02836 CDBD0F CALL 0FBDH ;Convert X into string from ;4130H onwards 02839 CD6528 CALL 2865H ;Take string constant 0283C CDDA29 CALL 29DAH ;and remove from string space ;HL -> string vector 0283F 012B2A LD BC,2A2BH ;Set new Return address 02842 C5 PUSH BC ;to 2A2BH ; Insert new string into string space ; ; I: HL -> vector to new string (somewhere in memory) ; O: DE -> vector to new string (in string space) 02843 7E LD A,(HL) ;A = string length 02844 23 INC HL ;Pointer + 1 02845 E5 PUSH HL ;Save pointer 02846 CDBF28 CALL 28BFH ;Are there still A bytes free ;in string space ? ;Yes: DE -> 1st free byte for ;the new string ;No: ?OS Error 02849 E1 POP HL ;Restore pointer 0284A 4E LD C,(HL) ;String address to BC 0284B 23 INC HL 0284C 46 LD B,(HL) 0284D CD5A28 CALL 285AH ;Store length and address of ;free memory (in string space) ;as last entry in string table 02850 E5 PUSH HL ;Save vector address of new ;string space 02851 6F LD L,A ;L = string length 02852 CDCE29 CALL 29CEH ;Copy string from (BC) to (DE): ;Copy string to string space 02855 D1 POP DE ;DE -> vector to new string 02856 C9 RET ; Search for room in string space ; ; I: A = length of new string ; O: DE = start address in string space of the new string ; HL = 40D3H = vector address of free string 02857 CDBF28 CALL 28BFH ;Still A bytes free in string ;space ? ;Yes: DE -> 1st free byte ;No: ?OS Error 0285A 21D340 LD HL,40D3H ;HL -> vector of free string 0285D E5 PUSH HL ;Save pointer 0285E 77 LD (HL),A ;A = string length 0285F 23 INC HL 02860 73 LD (HL),E ;Store address of free string 02861 23 INC HL ;space memory 02862 72 LD (HL),D 02863 E1 POP HL ;Retore vector address 02864 C9 RET ; Process string constant at (HL) and store in string table ; ; I: HL -> string constant (terminated with '"' or 00H ; O: A = last string character ; HL -> end of string ; X = vector address of new string 02865 2B DEC HL ;Pointer - 1 02866 0622 LD B,22H ;B = 1st delimiter char. ('"') 02868 50 LD D,B ;D = 2nd delimiter character 02869 E5 PUSH HL ;Save pointer 0286A 0EFF LD C,0FFH ;Set length counter to -1 0286C 23 INC HL ;Pointer + 1 0286D 7E LD A,(HL) ;Get string character 0286E 0C INC C ;Counter + 1 0286F B7 OR A ;End of string (00H) ? 02870 2806 JR Z,2878H ;Yes: continue 2878H 02872 BA CP D ;2nd delimiter reached? 02873 2803 JR Z,2878H ;Yes: end of string ;No: 02875 B8 CP B ;Start delimiter reached ? 02876 20F4 JR NZ,286CH ;No: get next character ;Yes: 02878 FE22 CP 22H ;String terminated by '"' ? 0287A CC781D CALL Z,1D78H ;Yes: increase pointer 0287D E3 EX (SP),HL ;Save end pointer, HL = start ;pointer 0287E 23 INC HL ;Pointer + 1 0287F EB EX DE,HL ;DE = start pointer 02880 79 LD A,C ;C = length 02881 CD5A28 CALL 285AH ;Store length and pointer as ;last entry in string table 02884 11D340 LD DE,40D3H ;DE = string vector 02887 3ED5 LD A,0D5H ;-- * 02887 D5 PUSH DE ;Called from FN routine in DOS 02889 2AB340 LD HL,(40B3H) ;HL = next free position in ;string table 0288C 222141 LD (4121H),HL ;Save vector address in X 0288F 3E03 LD A,03H ;Set VT to STR 02891 32AF40 LD (40AFH),A 02894 CDD309 CALL 09D3H ;Copy 3 bytes from (DE) to (HL) ;(copy length and address into ;string table) 02897 11D640 LD DE,40D6H ;End of string table reached ? 0289A DF RST 18H ;(HL = 40D6H) 0289B 22B340 LD (40B3H),HL ;Save table pointer 0289E E1 POP HL ;Restore end pointer 0289F 7E LD A,(HL) ;A = last character 028A0 C0 RET NZ ;No: done, return ;Yes: 028A1 1E1E LD E,1EH ;E = error code for ?ST Error 028A3 C3A219 JP 19A2H ;Issue error ; Process and output text constant at (HL) ; ; I: HL -> string constant 028A6 23 INC HL ;Pointer + 1 028A7 CD6528 CALL 2865H ;Copy string constant 028AA CDDA29 CALL 29DAH ;and remove it from string ;table 028AD CDC409 CALL 09C4H ;D = length, BC = start ;address of string 028B0 14 INC D ;Counter + 1 028B1 15 DEC D ;Counter - 1; counter = 0 ? 028B2 C8 RET Z ;Yes: done, return 028B3 0A LD A,(BC) ;Get character 028B4 CD2A03 CALL 032AH ;Output character 028B7 FE0D CP 0DH ;CR/LF ? 028B9 CC0321 CALL Z,2103H ;Yes: call DOS 028BC 03 INC BC ;Pointer + 1 028BD 18F2 JR 28B1H ;Next character ; Check for room in string space ; In case there are less than A bytes free in string space, the string space ; is sorted (garbage collection) and the routine is called again. ; If the string space is full a ?OS Error is generated ; ; I: A = number of required bytes ; O: DE -> A bytes free space in string space ; HL -> start of string space 028BF B7 OR A ;Z-flag = 0: 1st run 028C0 0EF1 LD C,0F1H ;-- ; Entry at 2nd call (after sorting) * 028C0 F1 POP AF ;Restore AF (Z-flag is now 1 !) 028C2 F5 PUSH AF ;Save AF 028C3 2AA040 LD HL,(40A0H) ;HL -> start of string space 028C6 EB EX DE,HL ;DE = HL 028C7 2AD640 LD HL,(40D6H) ;HL -> first free byte in ;string space (the string space ;is filled top down!) 028CA 2F CPL ;A = -A 028CB 4F LD C,A ;BC = number of required bytes 028CC 06FF LD B,0FFH 028CE 09 ADD HL,BC ;HL = HL + (-number of required ;bytes) = start address for ;the new string 028CF 23 INC HL ;+ 1 (HL already pointed to a ;free byte) 028D0 DF RST 18H ;Still inside string space ? 028D1 3807 JR C,28DAH ;No: sort string space and try ; again at 1st run ; ?OS Error at 2nd run ;Yes: 028D3 22D640 LD (40D6H),HL ;Store pointer 028D6 23 INC HL ;Pointer + 1 028D7 EB EX DE,HL ;DE -> free space 028D8 F1 POP AF ;Restore AF 028D9 C9 RET ; Sort string space (garbage collection) ; Check if there are string in the string space, that belong to already ; cleared variables. If so, remove this garbage and move the used string ; space accordingly. 028DA F1 POP AF ;Restore flag ;Already the 2nd run ? 028DB 1E1A LD E,1AH ;E = error code for ?OS Error 028DD CAA219 JP Z,19A2H ;Yes: issue error 028E0 BF CP A ;Z-flag = 1 (mark 2nd run) 028E1 F5 PUSH AF ;Save flag 028E2 01C128 LD BC,28C1H ;Set new RET address 028E5 C5 PUSH BC ;to 28C1H 028E6 2AB140 LD HL,(40B1H) ;HL -> End of string space ; Search next highest string in string space and sort ; (highest string is the string with the highest start address) ; HL = address of string last inserted and sorted in string space ; (= address of last string in string space at last run) 028E9 22D640 LD (40D6H),HL ;Store address of last string ;sorted 028EC 210000 LD HL,0000H ;HL = 0000H (default address) 028EF E5 PUSH HL ;Save it on stack 028F0 2AA040 LD HL,(40A0H) ;HL -> start of string space 028F3 E5 PUSH HL ;Save pointer on stack ; Test on highest string starts at the string space start address and ends ; on the last inserted and sorted string. ; The highest string in this range is then sorted and the routine is ; repeated until no highest string is found (all strings are sorted) ; Looks like bubblesort is used! 028F4 21B540 LD HL,40B5H ;HL -> start of string table ;= vector address of the first ;string in the string table ; Test all string variables ; First the entries in the string table, then the string (single) variables ; and finally the string array variables are tested to see if they are ; located in string space 028F7 EB EX DE,HL 028F8 2AB340 LD HL,(40B3H) ;DE -> next free location in ;string space 028FB EB EX DE,HL 028FC DF RST 18H ;End of table reached? 028FD 01F728 LD BC,28F7H ;BC = new RET address 02900 C24A29 JP NZ,294AH ;No : continue at 29A4H 02903 2AF940 LD HL,(40F9H) ;HL -> start of BASIC var space 02906 EB EX DE,HL 02907 2AFB40 LD HL,(40FBH) 0290A EB EX DE,HL ;DE -> start of array variables 0290B DF RST 18H ;End of single variables ;storage space reached? 0290C 2813 JR Z,2921H ;Yes: continue at 2921H 0290E 7E LD A,(HL) ;A = type code 0290F 23 INC HL ;Pointer + 1 (type code) 02910 23 INC HL ;Pointer + 2 (name) 02911 23 INC HL 02912 FE03 CP 03H ;String variable found ? 02914 2004 JR NZ,291AH ;No: test next variable ;Yes: 02916 CD4B29 CALL 294BH ;Test address 02919 AF XOR A ;A = 00H 0291A 5F LD E,A ;DE = offset to next variable 0291B 1600 LD D,00H 0291D 19 ADD HL,DE ;Add offset: ;HL -> vector of next variable 0291E 18E6 JR 2906H ;Test next variable ; End of single variable space reached. ; Test array variables. 02920 C1 POP BC ;Correct stack 02921 EB EX DE,HL 02922 2AFD40 LD HL,(40FDH) ;DE -> end of array variable 02925 EB EX DE,HL ;space 02926 DF RST 18H ;End reached ? 02927 CA6B29 JP Z,296BH ;Yes: insert highest string ;and sort ;No: 0292A 7E LD A,(HL) ;A = type code of array element 0292B 23 INC HL ;Pointer + 1 0292C CDC209 CALL 09C2H ;BCDE = (HL): DE = name, ;BC = length of array 0292F E5 PUSH HL ;Save pointer 02930 09 ADD HL,BC ;HL = pointer on next array 02931 FE03 CP 03H ;String array found ? 02933 20EB JR NZ,2920H ;No: test next array ;Yes: 02935 22D840 LD (40D8H),HL ;Save pointer 02938 E1 POP HL ;HL -> number of dimensions 02939 4E LD C,(HL) ;BC = number of dimensions 0293A 0600 LD B,00H 0293C 09 ADD HL,BC ;Add twice (every dimension 0293D 09 ADD HL,BC ;is stored in 2 bytes) ;HL now contains the vector ;address of the first array ;element - 1 0293E 23 INC HL ;HL + 1: vector 0293F EB EX DE,HL ;DE -> next array (= end address 02940 2AD840 LD HL,(40D8H) ;of current array, see 2935H) 02943 EB EX DE,HL 02944 DF RST 18H ;End of array reached ? 02945 28DA JR Z,2921H ;Yes: test next array ;No: 02947 013F29 LD BC,293FH ;Set new RET address 0294A C5 PUSH BC ;to 293FH ; Check string address of found string variable ; Two criteria exist: ; 1. Is the string in string space and not reused again ? ; (Is the string address smaller than the address of the last string ; sorted and inserted ?) ; 2. Is the string located at a higher position in string space than the ; string that is accepted to be the highest string in string space ? ; (Is the string address bigger than the string address of the string ; that is the highest accepted string ?) ; ; If both criteria are true, the address of the found string is stored on stack ; as the highest address. ; ; I: HL = vector address of string variable ; O: HL = vector address on the next variable 0294B AF XOR A ;A = 00H 0294C B6 OR (HL) ;A = string length 0294D 23 INC HL ;Pointer + 1 0294E 5E LD E,(HL) ;DE -> string 0294F 23 INC HL 02950 56 LD D,(HL) 02951 23 INC HL ;String length = 0 ? 02952 C8 RET Z ;Yes: done, return ;No: ; 1st criterium 02953 44 LD B,H ;BC -> vector of next variable 02954 4D LD C,L 02955 2AD640 LD HL,(40D6H) ;HL = address of last inserted ;variable 02958 DF RST 18H ;Is the found string already ;re-inserted into the string ;space ? ;(Is the string address greater ;thean de address of the last ;inserted string ?) 02959 60 LD H,B ;HL -> vector 0295A 69 LD L,C 0295B D8 RET C ;Yes: done, return ;No: ; 2nd criterium 0295C E1 POP HL ;HL = RET address 0295D E3 EX (SP),HL ;Save RET address ;HL = address of last inserted ;highest string (see 2968H) 0295E DF RST 18H ;Start address of string > HL ? 0295F E3 EX (SP),HL ;Put HL and RET adrress 02960 E5 PUSH HL ;back on the stack 02961 60 LD H,B ;HL -> vector 02962 69 LD L,C 02963 D0 RET NC ;No: done, return ;Yes: ; New highest string found ; Save string address and vector address on stack 02964 C1 POP BC ;BC = RET address 02965 F1 POP AF ;Remove start address of last ;inserted highest string 02966 F1 POP AF ;and its vector address ;from stack 02967 E5 PUSH HL ;Save current vector address 02968 D5 PUSH DE ;and start address of string ;on stack 02969 C5 PUSH BC ;Put RET address back on stack 0296A C9 RET ; All stringvariables tested ; Sort and insert new highest string behind last sorted and inserted string ; and clear all garbage in between. 0296B D1 POP DE ;Take address of highest string 0296C E1 POP HL ;and the vector address 0296D 7D LD A,L ;Address changes since 28ECH ? 0296E B4 OR H ;(new highest string found ?) 0296F C8 RET Z ;No: done, return ; A new highest string has been found 02970 2B DEC HL ;BC = address of new highest 02971 46 LD B,(HL) ;string 02972 2B DEC HL ;( = DE because the address 02973 4E LD C,(HL) ;belongs to DE ) 02974 E5 PUSH HL ;Save address + 1 02975 2B DEC HL ;HL - 1 = vector address ;of last tested string 02976 6E LD L,(HL) 02977 2600 LD H,00H ;HL = string length 02979 09 ADD HL,BC ;HL = length + string address 0297A 50 LD D,B ;DE = string address 0297B 59 LD E,C 0297C 2B DEC HL ;HL = end address of string 0297D 44 LD B,H ;BC = HL 0297E 4D LD C,L 0297F 2AD640 LD HL,(40D6H) ;HL = address of last inserted ;string 02982 CD5819 CALL 1958H ;Insert new string by attaching ;the new string to the last ;inserted string 02985 E1 POP HL ;Restore vector address + 1 02986 71 LD (HL),C ;Use new start address 02987 23 INC HL 02988 70 LD (HL),B 02989 69 LD L,C ;HL = start address of inserted 0298A 60 LD H,B ;string 0298B 2B DEC HL ;HL - 1 = address of last ;inserted string 0298C C3E928 JP 28E9H ;Search next highest string ; String addition ; ; I: HL = PTP on '+' ; BC = priority code ; X = 1st string ; O: X = new string 0298F C5 PUSH BC ;Save priority code 02990 E5 PUSH HL ;Save PTP 02991 2A2141 LD HL,(4121H) ;HL -> vector of 1st string 02994 E3 EX (SP),HL ;Save vector adrress ;and restore PTP 02995 CD9F24 CALL 249FH ;X = 2nd string 02998 E3 EX (SP),HL ;Save PTP and restore vector ;of 1st string 02999 CDF40A CALL 0AF4H ;?TM Error if X is not STR type 0299C 7E LD A,(HL) ;A = length of 1st string 0299D E5 PUSH HL ;Save vector address of ;1st string 0299E 2A2141 LD HL,(4121H) ;HL -> vector of 2nd string 029A1 E5 PUSH HL ;Save vector address of ;2nd string 029A2 86 ADD A,(HL) ;A = total length of new ;string 029A3 1E1C LD E,1CH ;E = error code for ?LS Error ;Overflow ? (new string too ;long) 029A5 DAA219 JP C,19A2H ;Yes: ?LS Error ;No: 029A8 CD5728 CALL 2857H ;Reserve A bytes of free space ;in string space. HL -> vector ;new string (space) 029AB D1 POP DE ;Restore vector address of ;2nd string 029AC CDDE29 CALL 29DEH ;Delete 2nd string from string ;table and string space ? 029AF E3 EX (SP),HL ;Save vector address of 2nd ;string and restore vector ;address of 1st string 029B0 CDDD29 CALL 29DDH ;Delete 1nd string from string ;table and string space ? 029B3 E5 PUSH HL ;Save vector address of ;1st string 029B4 2AD440 LD HL,(40D4H) ;HL = address of free space for ;new string 029B7 EB EX DE,HL ;DE = HL 029B8 CDC629 CALL 29C6H ;Copy 1st string into new space 029BB CDC629 CALL 29C6H ;Copy 2nd string behind 1st ;string 029BE 214923 LD HL,2349H ;Jump back to decoding of ;expression ar 2349H 029C1 E3 EX (SP),HL ;New RET address on stack 029C2 E5 PUSH HL ;Save old RET address on stack 029C3 C38428 JP 2884H ;Insert new string into ;string table ; Copy string to (DE) ; ; I: (SP - 2) -> string vector ; DE = new string address 029C6 E1 POP HL ;RET address to HL 029C7 E3 EX (SP),HL ;Get vector address and put ;RET address back on stack 029C8 7E LD A,(HL) ;A = length 029C9 23 INC HL 029CA 4E LD C,(HL) ;BC = string address 029CB 23 INC HL 029CC 46 LD B,(HL) 029CD 6F LD L,A ;L = counter 029CE 2C INC L ;Adjust counter 029CF 2D DEC L ;Counter - 1 ;Counter = 0 ? 029D0 C8 RET Z ;Yes: done, return ;No: 029D1 0A LD A,(BC) ;Copy byte from (BC) 029D2 12 LD (DE),A ;to (DE) 029D3 03 INC BC ;Source pointer + 1 029D4 13 INC DE ;Destination pointer + 1 029D5 18F8 JR 29CFH ;Next byte ; Remove string in X from string table and string space ? ; ; When using string-functions all string constants and intermediate results ; are basically intermediate in the string table and string space. ; Since these strings are only used by the function, they can be removed ; after completion of the function ; ; I: X = string ; O: HL -> string vector 029D7 CDF40A CALL 0AF4H ;Test if X in STR format 029DA 2A2141 LD HL,(4121H) ;HL -> string vector ; Remove from string table and string space ? 029DD EB EX DE,HL ;DE -> string vector 029DE CDF529 CALL 29F5H ;If the vector address points ;to the last entry in the ;string table, it will be ;deleted (in this case it ;is an intermediate result or ;a string constant) 029E1 EB EX DE,HL ;HL -> string vector ;Last entry deleted ? 029E2 C0 RET NZ ;No: done, return 029E3 D5 PUSH DE ;Save vector address 029E4 50 LD D,B ;BC = string address 029E5 59 LD E,C 029E6 1B DEC DE ;DE - 1 029E7 4E LD C,(HL) ;C = string lenght 029E8 2AD640 LD HL,(40D6H) ;HL = address of last string ;in string space - 1 029EB DF RST 18H ;Is the string the last one ;in string space ? (this means ;it is a string constant !) 029EC 2005 JR NZ,29F3H ;No: done ;Yes: 029EE 47 LD B,A ;B = 0, BC = string length 029EF 09 ADD HL,BC ;Add string length to HL ;HL now points on the new last ;string in string space 029F0 22D640 LD (40D6H),HL ;Store address ;(the string constant is now ;removbed from string space) 029F3 E1 POP HL ;Restore vector address 029F4 C9 RET ; Does DE point to the last entry of the string table ? ; If it does, then the last entry is deleted. ; ; I: DE -> string vector ; O: BC = string address of last entry in string table ; DE -> string vector ; HL = DE ; Z-flag = 1: the entry was deleted 029F5 2AB340 LD HL,(40B3H) ;HL -> next free entry of ;string table 029F8 2B DEC HL 029F9 46 LD B,(HL) ;BC = string address 029FA 2B DEC HL 029FB 4E LD C,(HL) 029FC 2B DEC HL 029FD DF RST 18H ;Does DE point to this entry ? 029FE C0 RET NZ ;No: done, return ;Yes: 029FF 22B340 LD (40B3H),HL ;Save new address ;(overwrite old entry) 02A02 C9 RET ; X = LEN ( X ) ; ------------- 02A03 01F827 LD BC,27F8H ;Set new return address 02A06 C5 PUSH BC ;to 27F8H 02A07 CDD729 CALL 29D7H ;Test X has STR format ;Remove string from string ;table and string space ? ;HL -> vector of string arg. 02A0A AF XOR A ;A = 00H 02A0B 57 LD D,A ;D = 00H 02A0C 7E LD A,(HL) ;A = string length 02A0D B7 OR A ;Set flags 02A0E C9 RET ;Return to 27F8H: write A to X ;as INT ; X = ASC ( ) ; ------------ 02A0F 01F827 LD BC,27F8H ;Set new return address 02A12 C5 PUSH BC ;to 27F8H 02A13 CD072A CALL 2A07H ;Get string length and vector ;address ;Length zero ? 02A16 CA4A1E JP Z,1E4AH ;Yes: ?FC Error ;HL -> string variable 02A19 23 INC HL 02A1A 5E LD E,(HL) ;DE -> string 02A1B 23 INC HL 02A1C 56 LD D,(HL) 02A1D 1A LD A,(DE) ;A = first string character 02A1E C9 RET ;Return to 27F8H: write A to X ;as INT ; X = CHR$ ( ) ; ------------- 02A1F 3E01 LD A,01H ;A = length of resulting string 02A21 CD5728 CALL 2857H ;Create room in string space 02A24 CD1F2B CALL 2B1FH ;Argument to DE 02A27 2AD440 LD HL,(40D4H) ;HL -> string 02A2A 73 LD (HL),E ;Write ASCII value into string 02A2B C1 POP BC ;Remove RET address 02A2C C38428 JP 2884H ;Put string in string space ; X = STRING$ ; ----------- 02A2F D7 RST 10H ;Adjust PTP 02A30 CF RST 08H ;Next character must be 02A31 28 DEFB '(' ;a '(' 02A32 CD1C2B CALL 2B1CH ;Get and save string length 02A35 D5 PUSH DE 02A36 CF RST 08H ;Next character must be 02A37 2C DEFB ',' ;a comma 02A38 CD3723 CALL 2337H ;Put argument into X 02A3B CF RST 08H ;Next character must be 02A3C 29 DEFB ')' ;a ')' 02A3D E3 EX (SP),HL ;Save PTP, restore length 02A3E E5 PUSH HL ;Save length 02A3F E7 RST 20H ;TSTTYP: STR argument ? 02A40 2805 JR Z,2A47H ;Yes: continue at 2A47H ;No: 02A42 CD1F2B CALL 2B1FH ;Is the number in range ;from 0 to 255 ? No: ?FC Error 02A45 1803 JR 2A4AH ;Continue at 2A4AH (A = number) 02A47 CD132A CALL 2A13H ;A = ASCII value of first ;character of string argument 02A4A D1 POP DE ;Restore length 02A4B F5 PUSH AF ;Dummy push because of jump ;to 2A2BH after ending 02A4C F5 PUSH AF ;Save character 02A4D 7B LD A,E ;A = length 02A4E CD5728 CALL 2857H ;Reserve space 02A51 5F LD E,A ;E = counter 02A52 F1 POP AF ;Restore character 02A53 1C INC E ;Counter = 0? 02A54 1D DEC E 02A55 28D4 JR Z,2A2BH ;Yes: use string ;No: 02A57 2AD440 LD HL,(40D4H) ;HL -> free space 02A5A 77 LD (HL),A ;Store character 02A5B 23 INC HL ;Pointer + 1 02A5C 1D DEC E ;Counter - 1, counter = 0 ? 02A5D 20FB JR NZ,2A5AH ;No: next character ;Yes: 02A5F 18CA JR 2A2BH ;Use string ; LEFT$ ; ----- ; ; I: (SP - 2) -> vector of the string argument ; (SP) = number 02A61 CDDF2A CALL 2ADFH ;')'? ;B = number = new string length 02A64 AF XOR A ;Set starting point on 0 ; Entry for RIGHT$ ; ; I: A = starting point of new string ; B = length of new string 02A65 E3 EX (SP),HL ;Save PTP, HL -> vector 02A66 4F LD C,A ;C = A = starting point of ;new string - 1 02A67 3EE5 LD A,0E5H ;-- ; Entry for MID$ ; ; I: B = length of new string ; C = starting point of new string inside string argument - 1 * 02A69 E5 PUSH HL ;Save vector address ; Get substring from string argument (in X) and store in X ; ; I: X = string argument ; B = length of new string ; C = starting point of new string inside string argument - 1 ; O: X = requested substring 02A69 E5 PUSH HL ;Save vector address 02A6A 7E LD A,(HL) ;A = length of argument string 02A6B B8 CP B ;Substring longer than ;argument string ? 02A6C 3802 JR C,2A70H ;Yes: set C to 0 and use the ;complete argument string ;No: 02A6E 78 LD A,B ;A = required length 02A6F 110E00 LD DE,000EH ;-- * 02A70 0E00 LD C,00H ;Starting point = 0 02A72 C5 PUSH BC ;Save BC 02A73 CDBF28 CALL 28BFH ;Free up A bytes of space ;DE -> free space 02A76 C1 POP BC ;Restore BC 02A77 E1 POP HL ;Resore vector address 02A78 E5 PUSH HL ;and save it again 02A79 23 INC HL ;Vector address + 1 02A7A 46 LD B,(HL) ;HL -> argument string 02A7B 23 INC HL 02A7C 66 LD H,(HL) 02A7D 68 LD L,B 02A7E 0600 LD B,00H ;BC = offset to new starting ;point 02A80 09 ADD HL,BC ;HL -> start of substring 02A81 44 LD B,H ;BC -> start of substring 02A82 4D LD C,L 02A83 CD5A28 CALL 285AH ;Store length and address of ;new string in string table 02A86 6F LD L,A ;L = length of substring 02A87 CDCE29 CALL 29CEH ;Copy characters of argument ;string to (DE) 02A8A D1 POP DE ;Restore vector address of ;argument string 02A8B CDDE29 CALL 29DEH ;Delete argument string from ;string space and string table? 02A8E C38428 JP 2884H ;Use new string ; RIGHT$ ; ------ ; ; I: (SP - 2) -> vector of the string argument ; (SP) = number (start of new string) 02A91 CDDF2A CALL 2ADFH ;')'? B = number 02A94 D1 POP DE ;DE = vector address 02A95 D5 PUSH DE ;Back into stack 02A96 1A LD A,(DE) ;A = argument string length 02A97 90 SUB B ;A = length - number = ;starting point of new string 02A98 18CB JR 2A65H ;Continue at 2A65H ; MID$ ; ---- ; (on the right hand side of the equal sign ; ; I: (SP - 2) -> vector of the string argument ; (SP) = number (start of new string) 02A9A EB EX DE,HL ;HL = PTP 02A9B 7E LD A,(HL) ;A = next character 02A9C CDE22A CALL 2AE2H ;B = starting point 02A9F 04 INC B ;Starting point = 0 ? 02AA0 05 DEC B 02AA1 CA4A1E JP Z,1E4AH ;Yes: ?FC Error ;No: 02AA4 C5 PUSH BC ;Save starting point 02AA5 1EFF LD E,0FFH ;E = default length (in case ;of missing length indication ;the total string length ;from starting point onwards ;is used) 02AA7 FE29 CP ')' ;Next character = ')' ? 02AA9 2805 JR Z,2AB0H ;Yes: E = length ;No: 02AAB CF RST 08H ;Next character must be 02AAC 2C DEFB ',' ;a comma 02AAD CD1C2B CALL 2B1CH ;Get length and store in E 02AB0 CF RST 08H ;Next character must be 02AB1 29 DEFB ')' ;a ')' 02AB2 F1 POP AF ;A = starting point 02AB3 E3 EX (SP),HL ;Save PTP, restore vector addr. 02AB4 01692A LD BC,2A69H ;Set new RET address 02AB7 C5 PUSH BC ;to 2A69H 02AB8 3D DEC A ;A = starting point - 1 02AB9 BE CP (HL) ;Compare with length of ;argument string 02ABA 0600 LD B,00H ;Length of new string = 0 02ABC D0 RET NC ;Create string with length = 0 ;in case starting point is ;larger than string length 02ABD 4F LD C,A ;C = starting point - 1 02ABE 7E LD A,(HL) ;A = length of arg. string 02ABF 91 SUB C ;- statring point = ;remaining string length 02AC0 BB CP E ;Requested length > ;remaining length 02AC1 47 LD B,A ;B = remaining length 02AC2 D8 RET C ;Yes: B = length ;No: 02AC3 43 LD B,E ;B = requested length 02AC4 C9 RET ;Use this ; X = VAL ( ) ; ------------ 02AC5 CD072A CALL 2A07H ;Get vector address and length ;of argument. D = 00H ;String length zero ? 02AC8 CAF827 JP Z,27F8H ;Yes: result = 0. ;No: 02ACB 5F LD E,A ;E = length 02ACC 23 INC HL ;Vector address + 1 02ACD 7E LD A,(HL) ;HL -> string 02ACE 23 INC HL 02ACF 66 LD H,(HL) 02AD0 6F LD L,A 02AD1 E5 PUSH HL ;Save pointer 02AD2 19 ADD HL,DE ;Calculate string end address 02AD3 46 LD B,(HL) ;Get next character 02AD4 72 LD (HL),D ;and replace it by 00H 02AD5 E3 EX (SP),HL ;Save end address, restore ;start address 02AD6 C5 PUSH BC ;Save character 02AD7 7E LD A,(HL) ;A = 1st character 02AD8 CD650E CALL 0E65H ;Decode string, X = number 02ADB C1 POP BC ;Restore characater 02ADC E1 POP HL ;Restore end address 02ADD 70 LD (HL),B ;Insert character 02ADE C9 RET ; SUB for LEFT$, RIGHT$ and MID$ ; Test for closing bracket and get first number from stack 02ADF EB EX DE,HL ;HL = PTP 02AE0 CF RST 08H ;Next character must be 02AE1 29 DEFB ')' ;a ')' 02AE2 C1 POP BC ;BC = RET address 02AE3 D1 POP DE ;DE = number 02AE4 C5 PUSH BC ;Put RET address on stack 02AE5 43 LD B,E ;B = number 02AE6 C9 RET ; Token found not in the range from 80H to BBH (see 1D67H) ; (not a command) 02AE7 FE7A CP 7AH ;Is it MID$ ? ;(left of '=' sign !) 02AE9 C29719 JP NZ,1997H ;No: ?SN Error 02AEC C3D941 JP 41D9H ;Yes: DOS ; IN statement ; ------------ 02AEF CD1F2B CALL 2B1FH ;A = port address 02AF2 329440 LD (4094H),A ;Save it 02AF5 CD9340 CALL 4093H ;Perform IN 02AF8 C3F827 JP 27F8H ;Write A to X as INT ; OUT statement ; ------------- 02AFB CD0E2B CALL 2B0EH ;Get port address and value 02AFE C39640 JP 4096H ;Perform OUT ; Decode argument at (HL) and store in X as an INT ; ; I: HL = PTP ; O: DE = number ; A = MSB of number ; Z-flag = 1 if number < 256 (MSB = 0) 02B01 D7 RST 10H ;Get next non-space character 02B02 CD3723 CALL 2337H ;Decode argument 02B05 E5 PUSH HL ;Save PTP 02B06 CD7F0A CALL 0A7FH ;HL = X = CINT ( X ) 02B09 EB EX DE,HL ;DE = INT number 02B0A E1 POP HL ;Restore PTP 02B0B 7A LD A,D ;A = MSB 02B0C B7 OR A ;MSB = 0 ? 02B0D C9 RET ; SUB for OUT ; Get port address and prepare RAM at 4096H 02B0E CD1C2B CALL 2B1CH ;Get port address 02B11 329440 LD (4094H),A ;Store for IN 02B14 329740 LD (4097H),A ;and OUT 02B17 CF RST 08H ;Next character must be 02B18 2C DEFB ',' ;a comma 02B19 1801 JR 2B1CH ;Get value and return ; Decode argument at (HL) and store in X as INT ; ?FC Error if the result is not in the range from 0 to 255 ; ; I: HL = PTP ; O: A = number ; DE = number 02B1B D7 RST 10H ;Get next non-space character 02B1C CD3723 CALL 2337H ;Decode argument 02B1F CD052B CALL 2B05H ;In range [0..255] ? 02B22 C24A1E JP NZ,1E4AH ;No: ?FC Error 02B25 2B DEC HL ;PTP - 1 02B26 D7 RST 10H ;And increment again 02B27 7B LD A,E ;A = number 02B28 C9 RET ; LLIST statement ; --------------- 02B29 3E01 LD A,01H ;Set output flag to 02B2B 329C40 LD (409CH),A ;printer output ; LIST statement ; -------------- 02B2E C1 POP BC ;Remove RET address 02B2F CD101B CALL 1B10H ;Get line number 02B32 C5 PUSH BC ;LP on first line 02B33 21FFFF LD HL,0FFFFH ;Set current LN to 65535 02B36 22A240 LD (40A2H),HL 02B39 E1 POP HL ;HL = LP on line 02B3A D1 POP DE ;DE = LN of last line 02B3B 4E LD C,(HL) ;BC = LP on next line 02B3C 23 INC HL 02B3D 46 LD B,(HL) 02B3E 23 INC HL 02B3F 78 LD A,B ;End of program reached ? 02B40 B1 OR C 02B41 CA191A JP Z,1A19H ;Yes: done, continue at 1A19H 02B44 CDDF41 CALL 41DFH ;DOS 02B47 CD9B1D CALL 1D9BH ;+<@> or ; pressed ? 02B4A C5 PUSH BC ;Save LP 02B4B 4E LD C,(HL) ;BC = line number 02B4C 23 INC HL ;of current line 02B4D 46 LD B,(HL) 02B4E 23 INC HL 02B4F C5 PUSH BC ;Save line number 02B50 E3 EX (SP),HL ;Save pointer, restore LN 02B51 EB EX DE,HL ;DE = current line number ;HL = last line number 02B52 DF RST 18H ;Current line number > last ;line number ? 02B53 C1 POP BC ;Pointer on current line ;back in BC 02B54 DA181A JP C,1A18H ;Yes: done, continue at 1A18H 02B57 E3 EX (SP),HL ;Save last line number ;HL = LP on next line 02B58 E5 PUSH HL ;Save LP on next line 02B59 C5 PUSH BC ;Save LP on current line 02B5A EB EX DE,HL ;HL = current line number 02B5B 22EC40 LD (40ECH),HL ;Save as '.'-line 02B5E CDAF0F CALL 0FAFH ;Print HL as decimal number 02B61 3E20 LD A,20H ;A = ' ' 02B63 E1 POP HL ;Restore pointer on current ;line 02B64 CD2A03 CALL 032AH ;Print space 02B67 CD7E2B CALL 2B7EH ;Decode line from (HL) onwards ;and store in line buffer 02B6A 2AA740 LD HL,(40A7H) ;HL -> start of line buffer 02B6D CD752B CALL 2B75H ;Print line 02B70 CDFE20 CALL 20FEH ;Start new line 02B73 18BE JR 2B33H ;Process next line ; SUB for LIST ; Print text from (HL) onwards, 00H = end of text ; ; I: HL -> text to be printed ; O: HL -> end of text (00H) 02B75 7E LD A,(HL) ;A = next character 02B76 B7 OR A ;End of text ? 02B77 C8 RET Z ;Yes: done, return 02B78 CD2A03 CALL 032AH ;Print it 02B7B 23 INC HL ;Pointer + 1 02B7C 18F7 JR 2B75H ;Next character ; SUB for LIST and EDIT ; Decode line from (HL) onwards and store result in line buffer ; ; I: HL -> program text 02B7E E5 PUSH HL ;Save pointer 02B7F 2AA740 LD HL,(40A7H) ;HL -> start of line buffer 02B82 44 LD B,H ;BC -> start of line buffer 02B83 4D LD C,L 02B84 E1 POP HL ;Restore pointer 02B85 16FF LD D,0FFH ;D = counter (maximum length = ;255 characters) 02B87 1803 JR 2B8CH ;Continue at 2B8CH ; Decode next character 02B89 03 INC BC ;Pointer + 1 02B8A 15 DEC D ;Counter - 1 ;Maximum length reached ? 02B8B C8 RET Z ;Yes: done, return ; Decode line from (HL) onwards and store at (BC) 02B8C 7E LD A,(HL) ;A = next character 02B8D B7 OR A ;End of line reached ? 02B8E 23 INC HL ;Pointer + 1 02B8F 02 LD (BC),A ;First store character 02B90 C8 RET Z ;Yes: done, return ;Token found ? 02B91 F2D23F JP P,3FD2H ;No: continue at 3FD2H 02B94 FEFB CP 0FBH ;"'" token found ? (REM) 02B96 2008 JR NZ,2BA0H ;No: continue at 2BA0H 02B98 0B DEC BC ;Yes: delete last 4 characters 02B99 0B DEC BC ;in line buffer because the 02B9A 0B DEC BC ;apostroph is stored as 02B9B 0B DEC BC ;'::REM' 02B9C 14 INC D ;Counter + 1 02B9D 14 INC D 02B9E 14 INC D 02B9F 14 INC D 02BA0 FE95 CP 95H ;'ELSE' token found ? 02BA2 CC240B CALL Z,0B24H ;Yes: buffer pointer - 1 ;('ELSE' is stored as ':ELSE') 02BA5 D67F SUB 7FH ;A = token value - 7FH 02BA7 E5 PUSH HL ;Save pointer 02BA8 5F LD E,A ;E = token value 02BA9 CDAD39 CALL 39ADH ;Colour-Token found ? ;HL -> start of corresponding ;keyword table 02BAC 7E LD A,(HL) ;A = next character 02BAD B7 OR A ;Next keyword reached ? 02BAE 23 INC HL ;Pointer + 1 02BAF F2AC2B JP P,2BACH ;No: increment HL to next ;keyword 02BB2 1D DEC E ;Token counter - 1 02BB3 20F7 JR NZ,2BACH ;Increment pointer further ;until right token is reached 02BB5 E67F AND 7FH ;Clear bit 7 02BB7 02 LD (BC),A ;Store character 02BB8 03 INC BC ;Buffer pointer + 1 02BB9 15 DEC D ;Counter - 1 ;Buffer full ? 02BBA CAD828 JP Z,28D8H ;Yes: done, continue at 28D8H 02BBD 7E LD A,(HL) ;A = next character 02BBE 23 INC HL ;Table pointer + 1 02BBF B7 OR A ;Next keyword reached ? 02BC0 F2B72B JP P,2BB7H ;No: store character in buffer 02BC3 E1 POP HL ;Yes: restore line pointer 02BC4 18C6 JR 2B8CH ;Process next character ; DELETE statement ; ---------------- 02BC6 CD101B CALL 1B10H ;Get start and end LN 02BC9 D1 POP DE ;DE = LN of end line 02BCA C5 PUSH BC ;Save pointer on start line 02BCB C5 PUSH BC ;twice 02BCC CD2C1B CALL 1B2CH ;Search end line ;Does it exist? 02BCF 3005 JR NC,2BD6H ;No: ?FC Error ;Yes: 02BD1 54 LD D,H ;DE = end line pointer 02BD2 5D LD E,L 02BD3 E3 EX (SP),HL ;Save pointer to end line ;HL = pointer to start line 02BD4 E5 PUSH HL ;Save it 02BD5 DF RST 18H ;Compare both pointer ;End >= start ? 02BD6 D24A1E JP NC,1E4AH ;No: ?FC Error ;Yes: 02BD9 212919 LD HL,1929H ;HL -> 'READY' 02BDC CDA728 CALL 28A7H ;Print text 02BDF C1 POP BC ;Restore pointer to start line 02BE0 21E81A LD HL,1AE8H ;Set new RET address to 1AE8H 02BE3 E3 EX (SP),HL ;and restore end line pointer ; Delete line(s) ; ; I: BC -> start line ; HL -> line following end line ' 02BE4 EB EX DE,HL ;DE -> line following end 02BE5 2AF940 LD HL,(40F9H) ;HL -> end of program 02BE8 1A LD A,(DE) ;Copy next line 02BE9 02 LD (BC),A ;onto line to be deleted 02BEA 03 INC BC ;Pointer + 1 02BEB 13 INC DE ;Pointer + 1 02BEC DF RST 18H ;End of program reached ? 02BED 20F9 JR NZ,2BE8H ;No: continue copying ;Yes: 02BEF 60 LD H,B ;HL = new end address 02BF0 69 LD L,C ;of program 02BF1 22F940 LD (40F9H),HL ;Save it 02BF4 C9 RET ; CSAVE statement ; --------------- 02BF5 CD3723 CALL 2337H ;Get filename 02BF8 E5 PUSH HL ;Save PTP 02BF9 CD132A CALL 2A13H ;DE -> filename 02BFC F5 PUSH AF ;Save registers 02BFD C5 PUSH BC 02BFE D5 PUSH DE 02BFF E5 PUSH HL 02C00 CD3F02 CALL 023FH ;Write leader and sync 02C03 E1 POP HL ;Restore registers 02C04 D1 POP DE 02C05 C1 POP BC 02C06 F1 POP AF 02C07 1A LD A,(DE) ;A = filename character 02C08 CD1F02 CALL 021FH ;Write to cassette 02C0B 2AA440 LD HL,(40A4H) ;HL -> start of program 02C0E EB EX DE,HL ;DE = HL 02C0F 2AF940 LD HL,(40F9H) ;HL -> end of program 02C12 1A LD A,(DE) ;A = byte from program text 02C13 13 INC DE ;Program pointer + 1 02C14 CD1F02 CALL 021FH ;Write program byte to cassette 02C17 DF RST 18H ;End of program reached ? 02C18 20F8 JR NZ,2C12H ;No, write next byte 02C1A 00 NOP ;-- 02C1B 00 NOP 02C1C 00 NOP 02C1D E1 POP HL ;Restore PTP 02C1E C9 RET ; CLOAD statement ; --------------- 02C1F 00 NOP ;-- 02C20 00 NOP 02C21 00 NOP 02C22 00 NOP 02C23 00 NOP 02C24 00 NOP 02C25 00 NOP 02C26 00 NOP 02C27 AF XOR A ;A = 00H 02C28 012F23 LD BC,232FH ;-- ; Entry for VERIFY * 02C29 2F CPL ;A <> 00H * 02C2A 23 INC HL ;PTP + 1 02C2B F5 PUSH AF ;Save flag 02C2C 2B DEC HL ;PTP - 1 02C2D D7 RST 10H ;Filename indicated ? 02C2E 3E00 LD A,00H ;A = default filename 02C30 2807 JR Z,2C39H ;No: continue at 2C39H ;Yes: 02C32 CD3723 CALL 2337H ;Put filename 02C35 CD132A CALL 2A13H ;into A 02C38 1A LD A,(DE) 02C39 6F LD L,A ;L = filename 02C3A F1 POP AF ;Restore flag 02C3B B7 OR A ;CLOAD ? 02C3C 67 LD H,A ;H = flag 02C3D 222141 LD (4121H),HL ;Save flag and filename 02C40 CC4D1B CALL Z,1B4DH ;Yes: NEW 02C43 2A2141 LD HL,(4121H) ;Restore flag and filename 02C46 EB EX DE,HL ;D = flag, E = filename 02C47 F5 PUSH AF ;Save registers 02C48 C5 PUSH BC 02C49 D5 PUSH DE 02C4A E5 PUSH HL 02C4B CD4C02 CALL 024CH ;Search for leader and sync 02C4E E1 POP HL ;Restore registers 02C4F D1 POP DE 02C50 C1 POP BC 02C51 F1 POP AF 02C52 CDED01 CALL 01EDH ;Get filename char from tape 02C55 1C INC E ;Filename indicated ? 02C56 1D DEC E 02C57 2803 JR Z,2C5CH ;No: continue at 2C5CH 02C59 BB CP E ;Specified filename found ? 02C5A 2037 JR NZ,2C93H ;No: search for next file 02C5C 2AA440 LD HL,(40A4H) ;HL = program start address 02C5F 0603 LD B,03H ;B = counter ( 3 times 00H ;indicates program end) 02C61 CDED01 CALL 01EDH ;Read 1 byte 02C64 5F LD E,A ;E = byte 02C65 96 SUB (HL) ;Does memory also contain this ;byte ? Yes: A = 00H 02C66 A2 AND D ;AND it with flag ;A = 00H if CLOAD or VERIFY ;is ok. A <> 00H if VERIFY is ;bad. ;Bad VERIFY ? 02C67 2021 JR NZ,2C8AH ;Yes: continue at 2C8AH 02C69 73 LD (HL),E ;Store byte 02C6A CD6C19 CALL 196CH ;Check free memory remaining. 02C6D 7E LD A,(HL) ;Byte read = 00H ? 02C6E B7 OR A 02C6F 23 INC HL ;Pointer + 1 02C70 20ED JR NZ,2C5FH ;No: next byte ;Yes: 02C72 CDE401 CALL 01E4H ;Blink '*' 02C75 10EA DJNZ 2C61H ;Counter - 1, read next byte 02C77 22F940 LD (40F9H),HL ;Store new end of program 02C7A 212919 LD HL,1929H ;HL -> 'READY' 02C7D CDA728 CALL 28A7H ;Print text 02C80 00 NOP ;-- 02C81 00 NOP 02C82 00 NOP 02C83 2AA440 LD HL,(40A4H) ;Reset PTP to start of BASIC ;program 02C86 E5 PUSH HL ;Save PTP 02C87 C3E81A JP 1AE8H ;Renew all pointers in program ;text, active command mode ; Error at VERIFY 02C8A 21A52C LD HL,2CA5H ;HL -> 'BAD' 02C8D CD7935 CALL 3579H ;Print text and give tone 02C90 C3181A JP 1A18H ;Back to active command mode ; Filename not found 02C93 322644 LD (4426H),A ;Print actual filename found 02C96 0603 LD B,03H ;Seach for end of program ;(3 times 00H) 02C98 CDED01 CALL 01EDH ;Read byte 02C9B B7 OR A ;00H found ? 02C9C 20F8 JR NZ,2C96H ;No: next byte 02C9E 10F8 DJNZ 2C98H ;Counter - 1: read next byte 02CA0 00 NOP ;-- 02CA1 00 NOP 02CA2 00 NOP 02CA3 18A2 JR 2C47H ;Retry CLOAD ; Text 'BAD' 02CA5 424144 DEFB 'BAD' 02CA8 0D DEFB 0DH 02CA9 00 DEFB 00H ;End of text ; X = PEEK ( X ) ; -------------- 02CAA CD7F0A CALL 0A7FH ;HL = X = CINT (X) = address 02CAD 7E LD A,(HL) ;A = memory value 02CAE C3F827 JP 27F8H ;Save A to X as INT ; POKE statement ; -------------- 02CB1 CD022B CALL 2B02H ;DE = address 02CB4 D5 PUSH DE ;Save address 02CB5 CF RST 08H ;Next byte must be 02CB6 2C DEFB ',' ;a comma 02CB7 CD1C2B CALL 2B1CH ;Get poke value 02CBA D1 POP DE ;Get address 02CBB 12 LD (DE),A ;Store value in memory 02CBC C9 RET ; PRINT USING ; ----------- 02CBD CD3823 CALL 2338H ;Get format string 02CC0 CDF40A CALL 0AF4H ;?TM Error if no string found 02CC3 CF RST 08H ;Next character must 02CC4 3B DEFB ';' ;be ';' 02CC5 EB EX DE,HL ;DE = PTP 02CC6 2A2141 LD HL,(4121H) ;HL -> string vector 02CC9 1808 JR 2CD3H ;Continue at 2CD3H ; Re-entry in case multiple nuerical values have to be printed using the same ; format string 02CCB 3ADE40 LD A,(40DEH) ;A = character following ;separator 02CCE B7 OR A ;Separator followed by a ;variable ? 02CCF 280C JR Z,2CDDH ;No: ?FC Error ;Yes: 02CD1 D1 POP DE ;Restore vector address of ;format string 02CD2 EB EX DE,HL ;HL -> vector, DE = PTP ; Execute PRINT USING ; ; I: DE = PTP on variable to be printed ; HL -> format string vector 02CD3 E5 PUSH HL ;Save vector address 02CD4 AF XOR A ;A = 0 02CD5 32DE40 LD (40DEH),A ;Clear character 02CD8 BA CP D ;C-flag = 1, Z-flag = 0 02CD9 F5 PUSH AF ;Save AF 02CDA D5 PUSH DE ;Save PTP 02CDB 46 LD B,(HL) ;B = format string length 02CDC B0 OR B ;Null string ? 02CDD CA4A1E JP Z,1E4AH ;Yes: ?FC Error ;No: 02CE0 23 INC HL ;Vector address + 1 02CE1 4E LD C,(HL) ;HL = string pointer 02CE2 23 INC HL 02CE3 66 LD H,(HL) 02CE4 69 LD L,C 02CE5 181C JR 2D03H ;Continue at 2D03H ; '%' found ; ; I: B = remaining string length ; HL = pointer on string (on next character following '%') ; O: C = number of spaces + 2 found between both '%' characters 02CE7 58 LD E,B ;Save counter 02CE8 E5 PUSH HL ;Save pointer 02CE9 0E02 LD C,02H ;C = counter for spaces ;(2 for the 2 '%' delimiters) 02CEB 7E LD A,(HL) ;Get next character 02CEC 23 INC HL ;Pointer + 1 02CED FE25 CP '%' ;2nd '%' found ? 02CEF CA172E JP Z,2E17H ;Yes: done, continue at 2E17H ;No: 02CF2 FE20 CP 20H ;Space? 02CF4 2003 JR NZ,2CF9H ;No: use '%' as text character ;(only spaces are allowed ;between '%' delimiters) 02CF6 0C INC C ;Counter + 1 02CF7 10F2 DJNZ 2CEBH ;Get next character 02CF9 E1 POP HL ;Restore string pointer in case ;no 2nd '%' was found 02CFA 43 LD B,E ;Restore previous counter value 02CFB 3E25 LD A,25H ;and use '%' as text character ; The character found is not a formatting character but a part of a text to be ; printed 02CFD CD492E CALL 2E49H ;If D <> 0 then print '+' 02D00 CD2A03 CALL 032AH ;Print character ; Process format string ; ; I: (SP - 4) -> format string vector ; (SP - 2) = AF (A = 00H, C-flag = 1, Z-flag = 0. see 2CD9H) ; (SP) = PTP ; B = string length (remaining length) ; HL = string pointer 02D03 AF XOR A ;A = 00H 02D04 5F LD E,A ;E = number of positions before ;the decimal point = 0 02D05 57 LD D,A ;Format byte = 0 ;(For composition of format ;byte see 0FBEH) 02D06 CD492E CALL 2E49H ;If D <> 0 then print '+' 02D09 57 LD D,A ;D = format byte 02D0A 7E LD A,(HL) ;Get next character 02D0B 23 INC HL ;Pointer + 1 02D0C FE21 CP '!' ;'!' found ? 02D0E CA142E JP Z,2E14H ;Yes: continue at 2E14H 02D11 FE23 CP '#' ;'#' found ? 02D13 2837 JR Z,2D4CH ;Yes: continue at 2D4CH 02D15 05 DEC B ;Counter - 1 ;String end reached ? 02D16 CAFE2D JP Z,2DFEH ;Yes: continue at 2DFEH 02D19 FE2B CP '+' ;'+' found ? 02D1B 3E08 LD A,08H ;Set bit 3 of format byte 02D1D 28E7 JR Z,2D06H ;Yes: continue at 2D06H 02D1F 2B DEC HL ;Pointer - 1 02D20 7E LD A,(HL) ;Get character again 02D21 23 INC HL ;Pointer + 1 02D22 FE2E CP '.' ;'.' found ? 02D24 2840 JR Z,2D66H ;Yes: continue at 2D66H 02D26 FE25 CP '%' ;'%' found ? 02D28 28BD JR Z,2CE7H ;Yes: continue at 2CE7H 02D2A BE CP (HL) ;Same character twice ? 02D2B 20D0 JR NZ,2CFDH ;No: character not recognized ;Yes: 02D2D FE24 CP '$' ;'$$' found ? 02D2F 2814 JR Z,2D45H ;Yes: continue at 2D45H 02D31 FE2A CP '*' ;'**' found ? 02D33 20C8 JR NZ,2CFDH ;No: character not recognized ; '**' found 02D35 78 LD A,B ;A = remaining length 02D36 FE02 CP 02H ;Less than 2 bytes remaining? 02D38 23 INC HL ;Pointer + 1 02D39 3803 JR C,2D3EH ;Yes: continue at 2D3EH 02D3B 7E LD A,(HL) ;Get next character 02D3C FE24 CP '$' ;Is it a '$' ? 02D3E 3E20 LD A,20H ;Set bit 5 (for '*' output) 02D40 2007 JR NZ,2D49H ;No: only '**' found ;Yes: 02D42 05 DEC B ;'**$' found, counter - 1 02D43 1C INC E ;Positions before decimal ;point + 1 02D44 FEAF CP AFH ;-- ; '$$' found * 02D45 AF XOR A ;A = 0 02D46 C610 ADD A,10H ;Set bit 4 ('$' in front) 02D48 23 INC HL ;Pointer + 1 02D49 1C INC E ;Positions before decimal ;point + 1 02D4A 82 ADD A,D ;update A with format byte 02D4B 57 LD D,A ;D = format byte ; '#' found 02D4C 1C INC E ;Positions before decimal ;point + 1 02D4D 0E00 LD C,00H ;Clear counter for text output 02D4F 05 DEC B ;String counter - 1 ;Last character ? 02D50 2847 JR Z,2D99H ;Yes: continue at 2D99H 02D52 7E LD A,(HL) ;Get next character 02D53 23 INC HL ;Pointer + 1 02D54 FE2E CP '.' ;Decimal point found ? 02D56 2818 JR Z,2D70H ;Yes: continue at 2D70H 02D58 FE23 CP '#' ;'#' found ? 02D5A 28F0 JR Z,2D4CH ;Yes: back to 2D4CH 02D5C FE2C CP ',' ;',' found ? 02D5E 201A JR NZ,2D7AH ;No: continue at 2D7AH ; '.' found 02D60 7A LD A,D ;Set bit 6 of format byte 02D61 F640 OR 40H 02D63 57 LD D,A ;D = format byte 02D64 18E6 JR 2D4CH ;Get next character ; '.' in front of '#' found 02D66 7E LD A,(HL) ;A = next character 02D67 FE23 CP '#' ;Next character a '#' ? 02D69 3E2E LD A,2EH ;A = '.' 02D6B 2090 JR NZ,2CFDH ;No: use '.' as text character ;Yes: 02D6D 0E01 LD C,01H ;Set counter for positions ;behind the decimal point to 1 02D6F 23 INC HL ;Pointer + 1 ; '.' behind '#' found 02D70 0C INC C ;Positions behind decimal ;point + 1 02D71 05 DEC B ;Counter - 1 ;String end ? 02D72 2825 JR Z,2D99H ;Yes: continue at 2D99H 02D74 7E LD A,(HL) ;Get next character 02D75 23 INC HL ;Pointer + 1 02D76 FE23 CP '#' ;'#' ? 02D78 28F6 JR Z,2D70H ;Yes: Positions behind decimal ;point + 1 ; Exponential format specified ? ; (4 consecutive times arrow up) 02D7A D5 PUSH DE ;Save format byte and counter 02D7B 11972D LD DE,2D97H ;Set new RET address 02D7E D5 PUSH DE ;to 2D97H 02D7F 54 LD D,H ;DE = string pointer 02D80 5D LD E,L 02D81 FE5B CP '[' ;Arrow up found ? 02D83 C0 RET NZ ;No: RET to 2D79H 02D84 BE CP (HL) ;2 times arrow up ? 02D85 C0 RET NZ ;No: RET to 2D79H 02D86 23 INC HL ;Pointer + 1 02D87 BE CP (HL) ;3 times arrow up ? 02D88 C0 RET NZ ;No: RET to 2D79H 02D89 23 INC HL ;Pointer + 1 02D8A BE CP (HL) ;4 times arrow up ? 02D8B C0 RET NZ ;No: RET to 2D79H 02D8C 23 INC HL ;Pointer + 1 02D8D 78 LD A,B ;A = string counter 02D8E D604 SUB 04H ;Subtract 4, overflow ? 02D90 D8 RET C ;Yes: the 4 arrow ups are not ;all part of the format string ; 4 consecutive arrow ups found: print number in exponential format 02D91 D1 POP DE ;Remove RET address (2D97H) 02D92 D1 POP DE ;Restore format byte and ;number of positions before ;the decimal point 02D93 47 LD B,A ;B = string counter 02D94 14 INC D ;Set bit 0 (exponential format) 02D95 23 INC HL ;Pointer + 1 02D96 CAEBD1 JP Z,0D1EBH ;Jump is never executed because ;Z-flag <> 0 (because of 2D94H) ; No exponential format output * 02D97 EB EX DE,HL ;HL = old string pointer * 02D98 D1 POP DE ;Restore format byte and number ;positions before decimal point ; Last string character was '.' or '#' 02D99 7A LD A,D ;A = format byte 02D9A 2B DEC HL ;Pointer - 1 02D9B 1C INC E ;Positions before decimal ;point + 1 02D9C E608 AND 08H ;Print positive sign ? 02D9E 2015 JR NZ,2DB5H ;Yes: continue at 2DB5H ;No: 02DA0 1D DEC E ;Positions before decimal ;point - 1 02DA1 78 LD A,B ;Any string characters left ? 02DA2 B7 OR A 02DA3 2810 JR Z,2DB5H ;No: continue at 2DB5H 02DA5 7E LD A,(HL) ;A = next character 02DA6 D62D SUB 2DH ;'-' found ? 02DA8 2806 JR Z,2DB0H ;Yes: continue at 2DB0H 02DAA FEFE CP 0FEH ;'+' found ? 02DAC 2007 JR NZ,2DB5H ;No: continue at 2DB5H 02DAE 3E08 LD A,08H ;Set bit 3 (print sign) 02DB0 C604 ADD A,04H ;Set bit 2 (behind number) 02DB2 82 ADD A,D ;Update with format byte 02DB3 57 LD D,A ;D = format byte 02DB4 05 DEC B ;String counter - 1 ; Processing of format string ready ; ; I: B = string counter ; C = number of positions behind decimal point + 1 (for decimal point) ; D = format byte ; E = number of positions in front of decimal point 02DB5 E1 POP HL ;Restore PTP 02DB6 F1 POP AF ;Restore flags (see 2CD9H) 02DB7 2850 JR Z,2E09H ;Done when Z-flag = 0 02DB9 C5 PUSH BC ;Save registers 02DBA D5 PUSH DE 02DBB CD3723 CALL 2337H ;Get value to be printed 02DBE D1 POP DE ;Restore registers 02DBF C1 POP BC 02DC0 C5 PUSH BC ;Save string counter 02DC1 E5 PUSH HL ;Save PTP 02DC2 43 LD B,E ;B = number of positions in ;front of decimal point 02DC3 78 LD A,B ;A = B 02DC4 81 ADD A,C ;Add number of positions behind ;the decimal point 02DC5 FE19 CP 19H ;More than 24 positions ? 02DC7 D24A1E JP NC,1E4AH ;Yes: ?FC Error, the maximum ;number of positions is 24 ;( 1 for sign, ; 17 for DBL format ; 1 for decimal point ; 4 for exponent ; 1 for sign following number) 02DCA 7A LD A,D ;A = format byte 02DCB F680 OR 80H ;Execute formatting ;(bit 7 set ?) 02DCD CDBE0F CALL 0FBEH ;Store number in X as formatted ;string at 4130H. HL -> string 02DD0 CDA728 CALL 28A7H ;Print string 02DD3 E1 POP HL ;Restore PTP 02DD4 2B DEC HL ;Adjust PTP 02DD5 D7 RST 10H ;Get next character 02DD6 37 SCF ;C-flag = 1 ;End of assignment reached ? 02DD7 280D JR Z,2DE6H ;Yes: continue at 2DE6H 02DD9 32DE40 LD (40DEH),A ;Store next character ;(see 2CCBH) 02DDC FE3B CP 3BH ;';' found ? 02DDE 2805 JR Z,2DE5H ;Yes: character ok 02DE0 FE2C CP 2CH ;',' found ? 02DE2 C29719 JP NZ,1997H ;No: ?SN Error 02DE5 D7 RST 10H ;Adjust PTP 02DE6 C1 POP BC ;Restore string counter 02DE7 EB EX DE,HL ;DE = PTP 02DE8 E1 POP HL ;HL -> format string vector 02DE9 E5 PUSH HL ;Save vector address 02DEA F5 PUSH AF ;Save next character 02DEB D5 PUSH DE ;Save PTP 02DEC 7E LD A,(HL) ;A = format string length 02DED 90 SUB B ;Subtract remaining length 02DEE 23 INC HL ;Vector address + 1 02DEF 4E LD C,(HL) ;HL -> format string 02DF0 23 INC HL 02DF1 66 LD H,(HL) 02DF2 69 LD L,C 02DF3 1600 LD D,00H ;DE = offset for next format 02DF5 5F LD E,A ;string (format character ;for next value to print) 02DF6 19 ADD HL,DE ;Add offset. HL now points ;to next format indication 02DF7 78 LD A,B ;A = remaining length 02DF8 B7 OR A ;Length = 0 ? 02DF9 C2032D JP NZ,2D03H ;No: process format string ;from (HL) onwards 02DFC 1806 JR 2E04H ;Yes: use old format string ;also for the next value ; End of string found 02DFE CD492E CALL 2E49H ;If D <> 0 then print '+' 02E01 CD2A03 CALL 032AH ;Print last character 02E04 E1 POP HL ;Restore PTP 02E05 F1 POP AF ;Restore flags/next character ;(see 2DEAH) 02E06 C2CB2C JP NZ,2CCBH ;Process next number with same ;format string 02E09 DCFE20 CALL C,20FEH ;End PRINT if end of assigment ;is reached (see 2DD6H) 02E0C E3 EX (SP),HL ;Save PTP, restore vector ;address 02E0D CDDD29 CALL 29DDH ;Remove format string from ;string table and string space 02E10 E1 POP HL ;Restore PTP 02E11 C36921 JP 2169H ;Output back to screen ; '!' found 02E14 0E01 LD C,01H ;Print 1 text character 02E16 3EF1 LD A,0F1H ;-- ; 2nd '%' character found ; C = number of characters to be printer * 02E17 F1 POP AF ;Remove string pointer from ;stack 02E18 05 DEC B ;Counter - 1 02E19 CD492E CALL 2E49H ;If D <> 0 then print '+' 02E1C E1 POP HL ;Restore PTP 02E1D F1 POP AF ;Restore flags: done ? 02E1E 28E9 JR Z,2E09H ;Yes: end PRINT operation ;No: 02E20 C5 PUSH BC ;Save string counter 02E21 CD3723 CALL 2337H ;Get string to be printed 02E24 CDF40A CALL 0AF4H ;?TM Error if not a string 02E27 C1 POP BC ;Restore string counter 02E28 C5 PUSH BC ;Save string counter 02E29 E5 PUSH HL ;Save PTP 02E2A 2A2141 LD HL,(4121H) ;HL -> vector of string to be ;printed 02E2D 41 LD B,C ;B = number of characters to ;be printed 02E2E 0E00 LD C,00H ;C = 0: ouput is started at ;start of string 02E30 C5 PUSH BC ;Save counters 02E31 CD682A CALL 2A68H ;Get characters to be printed ;via LEFT$ 02E34 CDAA28 CALL 28AAH ;Print characters 02E37 2A2141 LD HL,(4121H) ;HL -> vector of printed string 02E3A F1 POP AF ;A = number of printed chars 02E3B 96 SUB (HL) ;- total string length 02E3C 47 LD B,A ;B = remaining string length 02E3D 3E20 LD A,20H ;A = space 02E3F 04 INC B ;Counter + 1 02E40 05 DEC B ;Counter reached 0 ? 02E41 CAD32D JP Z,2DD3H ;Yes: process next argument ;No: 02E44 CD2A03 CALL 032AH ;Replace missing characters ;by spaces 02E47 18F7 JR 2E40H ;next character ; If D <> 0 then print '+' 02E49 F5 PUSH AF ;Save AF 02E4A 7A LD A,D ;D <> 0 ? 02E4B B7 OR A 02E4C 3E2B LD A,2BH ;A = '+' 02E4E C42A03 CALL NZ,032AH ;Yes: print '+' 02E51 F1 POP AF ;Restore AF 02E52 C9 RET ; Entry for EDIT after ?SN Error 02E53 329A40 LD (409AH),A ;Clear last error code 02E56 2AEA40 LD HL,(40EAH) ;HL = ERL 02E59 B4 OR H ;ERL = 65535 ? 02E5A A5 AND L ;(Syntax error in active 02E5B 3C INC A ;command mmode) 02E5C EB EX DE,HL ;DE = ERL 02E5D C8 RET Z ;Yes: no EDIT has to be done ;No: 02E5E 1804 JR 2E64H ;Call EDIT with LN = DE ; EDIT statement ; -------------- 02E60 CD4F1E CALL 1E4FH ;Load line number into DE 02E63 C0 RET NZ ;?SN Error ? 02E64 E1 POP HL ;Remove RET address from stack 02E65 EB EX DE,HL ;HL = line number 02E66 22EC40 LD (40ECH),HL ;Save as '.' 02E69 EB EX DE,HL ;DE = line number 02E6A CD2C1B CALL 1B2CH ;Search for line DE 02E6D D2D91E JP NC,1ED9H ;?UL Error in case the line ;does not exist 02E70 60 LD H,B ;HL = line pointer 02E71 69 LD L,C 02E72 23 INC HL ;HL + 2 02E73 23 INC HL ;BC = line number 02E74 4E LD C,(HL) 02E75 23 INC HL 02E76 46 LD B,(HL) 02E77 23 INC HL 02E78 C5 PUSH BC ;Save LN 02E79 CD7E2B CALL 2B7EH ;Decode line from (HL) onwards ;and store in line buffer 02E7C E1 POP HL ;Restore LN 02E7D E5 PUSH HL ;And save it again 02E7E CDAF0F CALL 0FAFH ;Print HL as decimal number 02E81 3E20 LD A,20H ;A = ' ' 02E83 CD2A03 CALL 032AH ;Print it 02E86 2AA740 LD HL,(40A7H) ;HL -> line buffer 02E89 3E0E LD A,0EH ;Cursor on 02E8B CD2A03 CALL 032AH 02E8E E5 PUSH HL ;Save pointer 02E8F 0EFF LD C,0FFH ;C = counter (set to -1 because ;of following INC C) 02E91 0C INC C ;Counter + 1 02E92 7E LD A,(HL) ;A = next characater 02E93 B7 OR A ;End of line reached 02E94 23 INC HL ;Pointer + 1 02E95 20FA JR NZ,2E91H ;No: continue counting ;Yes: 02E97 E1 POP HL ;Restore pointer 02E98 47 LD B,A ;B = 00H (number of already ;printed characaters) ;C = length of line 02E99 1600 LD D,00H ;D = 0 (repetition counter) 02E9B CD8403 CALL 0384H ;Get character from keyboard 02E9E D630 SUB 30H ;Can is be a digit ? 02EA0 380E JR C,2EB0H ;No: continue at 2EB0H ;Yes: 02EA2 FE0A CP 0AH ;Digit ? 02EA4 300A JR NC,2EB0H ;No: continue at 2EB0H ;Yes: 02EA6 5F LD E,A ;E = number value (00H-09H) 02EA7 7A LD A,D ;A = last value 02EA8 07 RLCA ;*2 02EA9 07 RLCA ;*2 (*4 in total) 02EAA 82 ADD A,D ;+value (*5 in total) 02EAB 07 RLCA ;*2 (*10 in total) 02EAC 83 ADD A,E ;Add next decimal position 02EAD 57 LD D,A ;D = counter 02EAE 18EB JR 2E9BH ;Get next character ; No digit entered ; D = repetition counter ; A = ASCII code of entered character - 30H (!) 02EB0 E5 PUSH HL ;Save pointer 02EB1 21992E LD HL,2E99H ;Set new RET address 02EB4 E3 EX (SP),HL ;to 2E99H and restore pointer 02EB5 15 DEC D ;Repetition required ? 02EB6 14 INC D ;Is D <> 0 ? 02EB7 C2BB2E JP NZ,2EBBH ;Yes: leave D as it is ;No: 02EBA 14 INC D ;Set D to 1 (execute required ;function at least once) 02EBB FED8 CP 0D8H ;08H = Backspace ? 02EBD CAD22F JP Z,2FD2H ;Yes: continue at 2FD2H 02EC0 FEDD CP 0DDH ;0DH = RETURN ? 02EC2 CAE02F JP Z,2FE0H ;Yes: continue at 2FE0H 02EC5 FEF0 CP 0F0H ;20H = space ? 02EC7 2841 JR Z,2F0AH ;Yes: continue at 2F0AH 02EC9 FE31 CP 31H ;Lower case (char > 60H) ? 02ECB 3802 JR C,2ECFH ;No: character ok. ;Yes: 02ECD D620 SUB 20H ;Convert to upper case 02ECF FE21 CP 21H ;51H = 'Q' ? 02ED1 CAF62F JP Z,2FF6H ;Yes: continue at 2FF6H 02ED4 FE1C CP 1CH ;4CH = 'L' ? 02ED6 CA402F JP Z,2F40H ;Yes: continue at 2F40H 02ED9 FE23 CP 23H ;53H = 'S' ? 02EDB 283F JR Z,2F1CH ;Yes: continue at 2F1CH 02EDD FE19 CP 19H ;49H = 'I' ? 02EDF CA7D2F JP Z,2F7DH ;Yes: continue at 2F7DH 02EE2 FE14 CP 14H ;44H = 'D' ? 02EE4 CA4A2F JP Z,2F4AH ;Yes: continue at 2F4AH 02EE7 FE13 CP 13H ;43H = 'C' ? 02EE9 CA652F JP Z,2F65H ;Yes: continue at 2F65H 02EEC FE15 CP 15H ;45H = 'E' ? 02EEE CAE32F JP Z,2FE3H ;Yes: continue at 2FE3H 02EF1 FE28 CP 28H ;58H = 'X' ? 02EF3 CA782F JP Z,2F78H ;Yes: continue at 2F78H 02EF6 FE1B CP 1BH ;4BH = 'K' ? 02EF8 281C JR Z,2F16H ;Yes: continue at 2F16H 02EFA FE18 CP 18H ;48H = 'H' ? 02EFC CA752F JP Z,2F75H ;Yes: continue at 2F75H 02EFF FE11 CP 11H ;41H = 'A' ? 02F01 C0 RET NZ ;No: back to 2E99H ; 'A': start again 02F02 C1 POP BC ;Remove RET address 02F03 D1 POP DE ;Restore LN 02F04 CDFE20 CALL 20FEH ;Start new line on screen 02F07 C3652E JP 2E65H ;Restart EDIT ; Space bar: print next character 02F0A 7E LD A,(HL) ;Get next character 02F0B B7 OR A ;End of line reached ? 02F0C C8 RET Z ;Yes: done, return 02F0D 04 INC B ;Counter + 1 02F0E CD2A03 CALL 032AH ;Print character 02F11 23 INC HL ;Pointer + 1 02F12 15 DEC D ;Repeat ? 02F13 20F5 JR NZ,2F0AH ;Yes: next character 02F15 C9 RET ; 'K': delete line up to character entered 02F16 E5 PUSH HL ;Save pointer 02F17 215F2F LD HL,2F5FH ;Set new RET address to 2F5FH ;(to print '!' at the end) 02F1A E3 EX (SP),HL ;Restore pointer 02F1B 37 SCF ;C-flag = 0 (indicator for ;delete character) ; 'S': search for character entered 02F1C F5 PUSH AF ;Save flags 02F1D CD8403 CALL 0384H ;Get character 02F20 5F LD E,A ;E = character 02F21 F1 POP AF ;Restore flags 02F22 F5 PUSH AF ;And save them again 02F23 DC5F2F CALL C,2F5FH ;Print '!' for 'K' operation 02F26 7E LD A,(HL) ;A = next character 02F27 B7 OR A ;End of line reached ? 02F28 CA3E2F JP Z,2F3EH ;Yes: done. ;No: 02F2B CD2A03 CALL 032AH ;Print character 02F2E F1 POP AF ;Restore flags 02F2F F5 PUSH AF ;And save them again ;'K' operation ? 02F30 DCA12F CALL C,2FA1H ;Yes: Delete character 02F33 3802 JR C,2F37H ;Yes: Skip next operation ;(counter and pointer are ;adjusted at 2FA1H) 02F35 23 INC HL ;Pointer + 1 02F36 04 INC B ;Counter + 1 02F37 7E LD A,(HL) ;A = next character 02F38 BB CP E ;= searched character ? 02F39 20EB JR NZ,2F26H ;No: next character ;Yes: 02F3B 15 DEC D ;Repeat done ? 02F3C 20E8 JR NZ,2F26H ;No: next character ;Yes: 02F3E F1 POP AF ;Restore flags 02F3F C9 RET ; 'L': list line and start again 02F40 CD752B CALL 2B75H ;Print line 02F43 CDFE20 CALL 20FEH ;Start new line on screen 02F46 C1 POP BC ;Remove RET address 02F47 C37C2E JP 2E7CH ;Restart EDIT ; 'D': Delete character 02F4A 7E LD A,(HL) ;A = character 02F4B B7 OR A ;End of line reached? 02F4C C8 RET Z ;Yes: done, return. ;No: 02F4D 3E21 LD A,21H ;A = '!' 02F4F CD2A03 CALL 032AH ;Print it 02F52 7E LD A,(HL) ;A = character 02F53 B7 OR A ;End of line ? 02F54 2809 JR Z,2F5FH ;Yes: done. ;No: 02F56 CD2A03 CALL 032AH ;Print character 02F59 CDA12F CALL 2FA1H ;and delete 02F5C 15 DEC D ;Repeat ? 02F5D 20F3 JR NZ,2F52H ;Yes: next character ; Print '!' 02F5F 3E21 LD A,21H ;A = '!' 02F61 CD2A03 CALL 032AH ;Print it 02F64 C9 RET ; 'C': change character 02F65 7E LD A,(HL) ;A = character 02F66 B7 OR A ;End of line reached ? 02F67 C8 RET Z ;Yes : done, return. 02F68 CD8403 CALL 0384H ;Get new character 02F6B 77 LD (HL),A ;Use it 02F6C CD2A03 CALL 032AH ;And print it 02F6F 23 INC HL ;Pointer + 1 02F70 04 INC B ;Counter + 1 02F71 15 DEC D ;Repeat ? 02F72 20F1 JR NZ,2F65H ;Yes: next character ;No: 02F74 C9 RET ;Done. ; 'H': Hack off rest of the line and jump to 'I' 02F75 3600 LD (HL),00H ;Set end of line at current ;position 02F77 48 LD C,B ;C = number of already printed ;characters = new line length ; 'X': print rest of the line and jump to 'I' 02F78 16FF LD D,0FFH ;Execute 255 times the space 02F7A CD0A2F CALL 2F0AH ;bar function to print the ;remaining part of the line ; 'I': insert new characters 02F7D CD8403 CALL 0384H ;Get new character 02F80 B7 OR A ;(why ?) 02F81 CA7D2F JP Z,2F7DH ;(see 0384H) 02F84 FE08 CP 08H ;Arrow left ? 02F86 280A JR Z,2F92H ;Yes: delete character 02F88 FE0D CP 0DH ;RETURN ? 02F8A CAE02F JP Z,2FE0H ;Yes: execute RETURN function 02F8D FE1B CP 1BH ;SHIFT+arrow up ? (End I-func) 02F8F C8 RET Z ;Yes: done, return ;No: 02F90 201E JR NZ,2FB0H ;Insert character ; Arrow left: Delete character in I-function 02F92 3E08 LD A,08H ;A = ASCII code of delete ;character = backspace 02F94 05 DEC B ;Any character already printed? 02F95 04 INC B ;(is there anything to delete) 02F96 281F JR Z,2FB7H ;No: done ;Yes: 02F98 CD2A03 CALL 032AH ;Delete character from screen 02F9B 2B DEC HL ;Pointer - 1 02F9C 05 DEC B ;Counter - 1 02F9D 117D2F LD DE,2F7DH ;Set new RET address 02FA0 D5 PUSH DE ;to 2F7DH ; Delete character at (HL) 02FA1 E5 PUSH HL ;Save pointer 02FA2 0D DEC C ;Length of line - 1 02FA3 7E LD A,(HL) ;Get character 02FA4 B7 OR A ;End of line reached ? 02FA5 37 SCF ;C-flag = 1 02FA6 CA9008 JP Z,0890H ;Yes: restore pointer and done ;No: 02FA9 23 INC HL ;Pointer + 1 02FAA 7E LD A,(HL) ;Get next character 02FAB 2B DEC HL ;pointer - 1 02FAC 77 LD (HL),A ;And store at current position 02FAD 23 INC HL ;Pointer + 1 02FAE 18F3 JR 2FA3H ;Shift line until end of line ;is reached ; Insert character at (HL) 02FB0 F5 PUSH AF ;Save character 02FB1 79 LD A,C ;A = length of line 02FB2 FEFF CP 0FFH ;Maximum length reached ? 02FB4 3803 JR C,2FB9H ;No: insert character ;Yes: 02FB6 F1 POP AF ;restore character 02FB7 18C4 JR 2F7DH ;Back to the 'I'-function ; Insert character 02FB9 90 SUB B ;A = length of line - number ;of characters already printed ;= remaining length 02FBA 0C INC C ;Length of line + 1 02FBB 04 INC B ;Printed characters + 1 02FBC C5 PUSH BC ;Save counter 02FBD EB EX DE,HL ;DE = pointer 02FBE 6F LD L,A ;HL = remaining length 02FBF 2600 LD H,00H 02FC1 19 ADD HL,DE ;HL = current length + ;remaining length = pointer to ;the end of line 02FC2 44 LD B,H ;BC = end pointer 02FC3 4D LD C,L 02FC4 23 INC HL ;HL = end pointer + 1 02FC5 CD5819 CALL 1958H ;Shift line 02FC8 C1 POP BC ;Restore counter 02FC9 F1 POP AF ;Restore character 02FCA 77 LD (HL),A ;Insert character 02FCB CD2A03 CALL 032AH ;Print character 02FCE 23 INC HL ;ointer + 1 02FCF C37D2F JP 2F7DH ;Back to the 'I'-function ; Arrow left: delete character left from cursor 02FD2 78 LD A,B ;A = number of printed ;characters (+ number of ;characters left from cursor) 02FD3 B7 OR A ;Anything printed ? 02FD4 C8 RET Z ;No: done, return ;Yes: 02FD5 05 DEC B ;Counter - 1 02FD6 2B DEC HL ;Pointer - 1 02FD7 3E08 LD A,08H ;Delete character 02FD9 CD2A03 CALL 032AH ;on screen 02FDC 15 DEC D ;Repeat ? 02FDD 20F3 JR NZ,2FD2H ;Yes: next character 02FDF C9 RET ; RETURN: Print remaining part of line and end EDIT 02FE0 CD752B CALL 2B75H ;Print remaining line ; 'E': end EDIT 02FE3 CDFE20 CALL 20FEH ;Start new line on screen 02FE6 C1 POP BC ;Remove RET address 02FE7 D1 POP DE ;Restore LN 02FE8 7A LD A,D ;LN = 65535 ? 02FE9 A3 AND E ;(set Z-flag for 2FEFH, 02FEA 3C INC A ;see 1A71H) 02FEB 2AA740 LD HL,(40A7H) ;HL = line buffer address 02FEE 2B DEC HL ;Pointer - 1 ;LN = 65535 ? 02FEF C8 RET Z ;Yes: done, return 02FF0 37 SCF ;C-flag = 1 02FF1 23 INC HL ;Pointer + 1 02FF2 F5 PUSH AF ;Save flags 02FF3 C3981A JP 1A98H ;Insert line at HL into ;program text ; 'Q': terminate edit, ignore changes 02FF6 C1 POP BC ;Restore RET address 02FF7 D1 POP DE ;Restore LN 02FF8 C3191A JP 1A19H ;Back to active command mode 02FFB DEC3 SBC A,0C3H ;-- 02FFD C344B2 JP 0B244H ; Keyboard input with FKEY evaluation ; (Is only used by line input (at 05D9H) and has ; therefor 05E3H as return address!! 03000 C31534 JP 3415H ;Continue at 3415H ; No Function Key pressed (start of 3458H) ; CTRL + number 1 to 8 pressed for colour change ? 03003 E5 PUSH HL ;Save pointer 03004 211840 LD HL,4018H ;HL = CTRL byte 03007 CB7E BIT 7,(HL) ;CTRL pressed ? 03009 2812 JR Z,301DH ;No: done ;Yes: 0300B CBBE RES 7,(HL) ;Clear bit 0300D FE31 CP 31H ;A number pressed ? 0300F 380C JR C,301DH ;No: put character in A 03011 FE39 CP 39H ;Valid number ? 03013 3008 JR NC,301DH ;No: done ;Yes: 03015 D631 SUB 31H ;A = Colour code 0 to 7 03017 CD2136 CALL 3621H ;Store new colour code and ;cursor on 0301A E1 POP HL ;Restore pointer 0301B 18E3 JR 3000H ;Get new character ; Give character in A to input routine 0301D E1 POP HL ;Restore pointer 0301E C3E305 JP 05E3H ;Return to line input routine 03021 FF RST 38H ;-- ; Graphic character (> 7FH) recognized 03022 FEC0 CP 0C0H ;This comparison was used in ;a previous version to output ;the characters 192-255 ;(C0H-FFH) as tab-function. ;(output of 0 to 63 spaces) ;In the current version all ;values > 7FH are printed as ;graphic characters. 03024 C30531 JP 3105H ;Print character ; Previously used Tab-function (not used) 03027 D6C0 SUB 0C0H ;A = value - 192 (= number of ;spaces to print) 03029 CA0831 JP Z,3108H ;A = 0: done 0302C 47 LD B,A ;B = counter 0302D 3E20 LD A,' ' ;A = space 0302F C5 PUSH BC ;Save counter 03030 CD8431 CALL 3184H ;Print character 03033 C1 POP BC ;Restore counter 03034 10F7 DJNZ 302DH ;Next character 03036 C30831 JP 3108H ; Move cursor one position to the right (= CHR$(25) ) 03039 23 INC HL ;Cursor address + 1 0303A E5 PUSH HL ;Save cursor address 0303B CD6531 CALL 3165H ;HL -> actual line 0303E EB EX DE,HL ;DE = HL 0303F E1 POP HL ;Restore cursor address 03040 DF RST 18H ;Next line reached ? 03041 C0 RET NZ ;No: done ;Yes: 03042 11D8FF LD DE,0FFD8H ;DE = -40 03045 19 ADD HL,DE ;Subtract 40 (length of 1 ;line) from new address. ;The cursor is located at the ;start of line again 03046 C9 RET ; This routine loads the CRTC register pair A and A + 1 with HL: ; 16 bit load for CRTC register ; ; I: A = register number of lower register of register pair ; HL = value to be written into CRTC 03047 C5 PUSH BC ;Save BC 03048 E5 PUSH HL ;Save HL 03049 0602 LD B,02H ;Counter = 2 0304B 0EFA LD C,0FAH ;C = CRTC select register 0304D ED79 OUT (C),A ;Select register A 0304F 0C INC C ;C = CRTC data register 03050 ED61 OUT (C),H ;Write data to CRTC register 03052 3C INC A ;Next register 03053 65 LD H,L ;H = L 03054 10F5 DJNZ 304BH ;Loop 03056 E1 POP HL ;Restore HL 03057 C1 POP BC ;Restore BC 03058 C9 RET ; Cursor off (= CHR$(15) ) 03059 E5 PUSH HL ;Save address 0305A 210720 LD HL,2007H ;Set H and L for CRTC ;programming 0305D 1804 JR 3063H ;Continue at 3063H ; Cursor on (= CHR$(14) ) 0305F E5 PUSH HL ;Save address 03060 2A1940 LD HL,(4019H) ;H and L = value for CRTC ;programming 03063 3E0A LD A,0AH ;Select CRTC registers 10+11 03065 CD4730 CALL 3047H ;Write HL into CRTC 03068 7C LD A,H ;A = cursor start scan line 03069 E1 POP HL ;Restore address 0306A E5 PUSH HL ;Save registers 0306B D5 PUSH DE 0306C FE20 CP 20H ;Cursor off ? 0306E C41436 CALL NZ,3614H ;No: set colour of new cursor 03071 00 NOP ;-- 03072 3E0E LD A,0EH ;Select CRTC registers 14+15 ;(Cursor position) 03074 CD4730 CALL 3047H ;Write address into CRTC 03077 D1 POP DE ;Restore registers 03078 E1 POP HL 03079 C9 RET ; Save registers and set colour ; ; I: A = character at (HL) ; HL -> screen location in LGR screen memory 0307A E5 PUSH HL ;Save registers 0307B D5 PUSH DE 0307C F5 PUSH AF 0307D C3F835 JP 35F8H ;Continue at 35F8H ; This routine updates the colour memory at position HL + DE with the current ; text colour set (see 35F8H) ; ; I: HL + DE -> Colour memory byte to be updated ; O: - 03080 19 ADD HL,DE ;Set pointer into colour mem. 03081 E5 PUSH HL ;Save colour memory pointer 03082 219043 LD HL,4390H ;HL -> colour codes table 03085 110000 LD DE,0000H ;DE = offset = 0; 03088 3A2340 LD A,(4023H) ;Take current colour value 0308B 5F LD E,A ;Use it as offset in table 0308C 19 ADD HL,DE ;Set pointer into table 0308D 7E LD A,(HL) ;A = colour code 0308E E1 POP HL ;Restore colour memory pointer 0308F 77 LD (HL),A ;Write value into colour mem. 03090 F1 POP AF ;Restore registers 03091 D1 POP DE 03092 E1 POP HL 03093 C9 RET 03094 03 DEFB 03 ;-- 03095 01 DEFB 01 03096 02 DEFB 02 03097 04 DEFB 04 03098 06 DEFB 06 03099 08 DEFB 08 0309A 09 DEFB 09 0309B 0A DEFB 0A 0309C 05 DEFB 05 ; Calculate new POS value (AF) ; ; I: -- ; O: A = new POS value 0309D E5 PUSH HL ;Save registers 0309E D5 PUSH DE 0309F C5 PUSH BC 030A0 2A2040 LD HL,(4020H) ;HL = new cursor address 030A3 E5 PUSH HL ;Save address 030A4 CD6531 CALL 3165H ;Calculate start of line 030A7 EB EX DE,HL ;DE -> start of line 030A8 E1 POP HL ;HL = cursor address 030A9 B7 OR A ;C-flag = 0 030AA ED52 SBC HL,DE ;HL = cursor address - start ;of line = cursor position ;inside line 030AC 7D LD A,L ;A = POS value 030AD C1 POP BC ;Restore registers 030AE D1 POP DE 030AF E1 POP HL 030B0 C9 RET ; Test TAB value 030B1 7B LD A,E ;A = TAB value 030B2 5F LD E,A ;E = TAB value 030B3 3A9C40 LD A,(409CH) ;A = output flag 030B6 B7 OR A ;Test output flag ;Cassette output ? 030B7 FA4A1E JP M,1E4AH ;Yes: ?FC Error ;Screen output ? 030BA 2805 JR Z,30C1H ;Yes: continue at 30C1H ;Printer output: 030BC 3A9E40 LD A,(409EH) ;A = highest possible TAB ;value. 030BF 1803 JR 30C4H ;Continue at 30C4H ; Screen output 030C1 3A9D40 LD A,(409DH) ;A = number of characters per ;line 030C4 BB CP E ;Desired TAB value bigger as ;length of line ? 030C5 300B JR NC,30D2H ;No: value ok ;Yes: 030C7 C5 PUSH BC ;Save BC 030C8 43 LD B,E ;Exchange A and E 030C9 5F LD E,A 030CA 78 LD A,B 030CB C1 POP BC ;Restore BC 030CC 93 SUB E ;Subtract line length 030CD 30FD JR NC,30CCH ;Continue when > 0 030CF 83 ADD A,E ;Undo last subtract 030D0 5F LD E,A ;E = new TAB value (never ;bigger then length of line) 030D1 C9 RET ; TAB value is ok. 030D2 7B LD A,E ;Put value in A 030D3 C9 RET ; SUB for PRINT@ (see 207AH) ; ; I: DE = @ argument 030D4 21E703 LD HL,03E7H ;HL = 999 030D7 DF RST 18H ;@ value > 999 ? 030D8 E1 POP HL ;Restore PTP 030D9 DA4A1E JP C,1E4AH ;Yes: ?FC Error ;No: 030DC C37E20 JP 207EH ;Done ; Calculate new POS value (as 309DH but with value in E and A) 030DF CD9D30 CALL 309DH ;Calculate POS 030E2 5F LD E,A ;Put result also in E 030E3 C9 RET ; Screen routine (called via DCB call) ; ; I: IX -> Screen DCB (= 401DH) ; C = character to be written 030E4 DD6E03 LD L,(IX+03H) ;HL = actual cursor address 030E7 DD6604 LD H,(IX+04H) ;(from DCB) ;False DCB type ? 030EA DA7D31 JP C,317DH ;Yes: continue at 317DH ;No: 030ED DD7E05 LD A,(IX+05H) ;Cursor is on ? 030F0 B7 OR A 030F1 2005 JR NZ,30F8H ;Yes: continue at 30F8H ;No: 030F3 CD5930 CALL 3059H ;Cursor off 030F6 1803 JR 30FBH ;Continue at 30F8H 030F8 CD5F30 CALL 305FH ;Cursor on 030FB 79 LD A,C ;A = character to be output 030FC FE20 CP 20H ;Control character 030FE 3822 JR C,3122H ;Yes: continue at 3122H ;No: 03100 FE80 CP 80H ;Graphic character ? 03102 D22230 JP NC,3022H ;Yes: continue at 3022H ;No: 03105 CD8431 CALL 3184H ;Output character 03108 7E LD A,(HL) ;A = character at new cursor ;position 03109 57 LD D,A ;D = character 0310A DD7E05 LD A,(IX+05H) ;Cursor is on ? 0310D B7 OR A 0310E 2808 JR Z,3118H ;No: continue at 3118H ;Yes: 03110 DD7205 LD (IX+05H),D ;Store character 03113 CD5F30 CALL 305FH ;Cursor on 03116 1803 JR 311BH ;Continue at 311BH 03118 CD5930 CALL 3059H ;Cursor off 0311B DD7503 LD (IX+03H),L ;Save new cursor address 0311E DD7404 LD (IX+04H),H 03121 C9 RET ; Control character ( value < 32 ) recognized. ; ; I: A = control character ; HL = cursor address 03122 110831 LD DE,3108H ;Set return address 03125 D5 PUSH DE ;to 3108H 03126 FE08 CP 08H ;Backspace ? 03128 CADF31 JP Z,31DFH ;Yes: continue at 31DFH ;No: 0312B FE0A CP 0AH ;Code < 10 ? 0312D D8 RET C ;Yes: done 0312E FE0E CP 0EH ;Cursor on ? 03130 DAC931 JP C,31C9H ;Jump when character < 0EH 03133 CAF831 JP Z,31F8H ;Yes: continue at 31F8H ;No: 03136 FE0F CP 0FH ;Cursor off ? 03138 CAFD31 JP Z,31FDH ;Yes: continue at 31FDH .No: 0313B FE18 CP 18H ;Character < 24 0313D D8 RET C ;Yes: done ,No: 0313E FE18 CP 18H ;Cursor left ? 03140 CAE531 JP Z,31E5H ;Yes: continue at 31E5H ;No: 03143 FE19 CP 19H ;Cursor right ? 03145 CA3930 JP Z,3039H ;Yes: continue at 3039H ;No: 03148 FE1A CP 1AH ;Cursor down ? 0314A CA0032 JP Z,3200H ;Yes: continue at 3200H ;No: 0314D FE1B CP 1BH ;Cursor up ? 0314F CA1232 JP Z,3212H ;Yes: continue at 3212H ;No: 03152 FE1C CP 1CH ;Cursor home ? 03154 CAD431 JP Z,31D4H ;Yes: continue at 31D4H ;No: 03157 FE1D CP 1DH ;Cursor to start of line ? 03159 CAD931 JP Z,31D9H ;Yes: continue at 31D9H ;No: 0315C FE1E CP 1EH ;CLear until end of line ? 0315E 285F JR Z,31BFH ;Yes: continue at 31BFH ;No: 03160 FE1F CP 1FH ;Clear until end of screen ? 03162 2845 JR Z,31A9H ;Yes: continue at 31A9H 03164 C9 RET ; Calculate start of line address of current line ; ; I: HL = current cursor address ; O: HL = address of start of line 03165 1100BC LD DE,0BC00H ;DE = -4400H 03168 0601 LD B,01H ;Counter = 1 0316A 19 ADD HL,DE ;HL = current @ value ;(= address - 4400H) 0316B 112800 LD DE,0028H ;DE = 40 (length of line) 0316E B7 OR A ;C-flag = 0 0316F ED52 SBC HL,DE ;Subtract 40 03171 3803 JR C,3176H ;Jump when < 0 03173 04 INC B ;Counter + 1 03174 18F5 JR 316BH ;Again 03176 21D843 LD HL,43D8H ;HL = 4400H - 28H 03179 19 ADD HL,DE ;Add length of 1 line 0317A 10FD DJNZ 3179H ;Loop B times 0317C C9 RET ; False DCB type detected 0317D DD7E05 LD A,(IX+05H) ;Cursor is on ? 03180 B7 OR A 03181 C0 RET NZ ;Yes: ok. ;No: 03182 7E LD A,(HL) ;A = character at next ;screen location 03183 C9 RET ; Print character on screen ; ; I: HL -> screen location ; A = character 03184 CD7A30 CALL 307AH ;Update character colour 03187 77 LD (HL),A ;Put character in screen memory 03188 23 INC HL ;Next screen location 03189 11E847 LD DE,47E8H ;DE -> last screen location ;on LGR screen + 1 0318C DF RST 18H ;End of screen reached ? 0318D D8 RET C ;No: done 0318E 21E847 LD HL,47E8H ;HL = address of screen end 03191 11D8FF LD DE,0FFD8H ;DE = -40 03194 19 ADD HL,DE ;HL = HL - 40 = start of last ;line 03195 E5 PUSH HL ;Save address 03196 CD3936 CALL 3639H ;Prepare registers 03199 EDA0 LDI ;Move character memory 0319B D9 EXX ;Switch registers 0319C EDA0 LDI ;Move colour memory 0319E D9 EXX ;Switch registers 0319F 78 LD A,B ;Done ? 031A0 B1 OR C 031A1 20F6 JR NZ,3199H ;No: move again 031A3 D9 EXX ;Switch registers 031A4 E1 POP HL ;Restore second registerset 031A5 D1 POP DE 031A6 C1 POP BC 031A7 D9 EXX ;Switch registers 031A8 E1 POP HL ;Restore start of last line ; Clear until end of screen (= CHR$(31) ) 031A9 11E847 LD DE,47E8H ;DE = highest LGR screen ;address + 1 031AC E5 PUSH HL ;Save cursor address 031AD CDE031 CALL 31E0H ;Clear character at cursor ;address and set colour 031B0 23 INC HL ;Next address 031B1 DF RST 18H ;End reached ? 031B2 20F9 JR NZ,31ADH ;No: clear next 031B4 E1 POP HL ;Restore cursor address 031B5 C9 RET ; RENUM statement ; --------------- 031B6 FDE5 PUSH IY ;Save IY 031B8 1868 JR 3222H ;Continue at 3222H ; Return from RENUM 031BA FDE1 POP IY ;Restore IY 031BC C3832C JP 2C83H ;Renew all pointers in BASIC ;program ; Clear until end of line (= CHR$(30) ) 031BF E5 PUSH HL ;Save cursor address 031C0 CD6531 CALL 3165H ;Calculate start address of ;current line 031C3 EB EX DE,HL ;result in DE, HL = 40 031C4 19 ADD HL,DE ;HL = start address of next ;line 031C5 EB EX DE,HL ;Result in DE 031C6 E1 POP HL ;Restore cursor address 031C7 18E3 JR 31ACH ;Continue at 31ACH ; Start new line (= CHR$(13) ) 031C9 CD1B36 CALL 361BH ;Clear current line 031CC 19 ADD HL,DE ;HL = start address next line 031CD 11E847 LD DE,47E8H ;DE -> end of LGR screen + 1 031D0 DF RST 18H ;End reached ? 031D1 28BE JR Z,3191H ;Yes: scroll ;No: 031D3 C9 RET ;done ; Move cursor home (= CHR$(28) ) 031D4 210044 LD HL,4400H ;HL -> start of screen memory = ;new cursor address 031D7 1803 JR 31DCH ;Set as new address ; Move cursor to start of line (= CHR$(29) ) 031D9 CD6531 CALL 3165H ;Calculate start of line ;address 031DC C35F30 JP 305FH ;Program CRTC with new values ; Backspace (= CHR$(8) ) 031DF 2B DEC HL ;Cursor address - 1 031E0 3E20 LD A,20H ;A = space character 031E2 C3EE35 JP 35EEH ;Continue at 35EEH ; Move cursor one position to the left (= CHR$(24) ) 031E5 E5 PUSH HL ;Save cursor address 031E6 CD6531 CALL 3165H ;Calculate start of line ;address 031E9 EB EX DE,HL ;Put result in DE 031EA E1 POP HL ;Restore cursor address 031EB DF RST 18H ;Are we at start of line ? 031EC 2803 JR Z,31F1H ;Yes: add one line of ;characters for wrap around 031EE 2B DEC HL ;Cursor address - 1 031EF 18EB JR 31DCH ;Set as new address ; Cursor to end of line 031F1 2B DEC HL ;HL - 1 031F2 112800 LD DE,0028H ;DE = characters per line 031F5 19 ADD HL,DE ;HL + 40 031F6 18E4 JR 31DCH ;Continue at 31DCH ; Cursor on 031F8 7E LD A,(HL) ;A = character at cursor pos. 031F9 DD7705 LD (IX+05H),A ;Store it in DCB 031FC C9 RET ; Cursor off 031FD AF XOR A ;A = 0 031FE 18F9 JR 31F9H ;Continue at 31F9H ; Move cursor one line down (= CHR$(26) ) 03200 CD0736 CALL 3607H ;Set screen colour and DE = 40 03203 19 ADD HL,DE ;Set cursor address into next ;line 03204 B7 OR A ;Clear C-flag 03205 3F CCF ;C-flag = 1 03206 11E847 LD DE,47E8H ;DE = highest LGR screen ;address + 1 03209 DF RST 18H ;Cursor now beyound LGR screen ? 0320A 3804 JR C,3210H ;No: continue at 3210H ;Yes: 0320C 1140FC LD DE,0FC40H ;DE = -960 0320F 19 ADD HL,DE ;Add to cursor location to ;create wrap around to top line 03210 18CA JR 31DCH ;Continue at 31DCH ; Move cursor one line up (= CHR$(27) ) 03212 CD0F36 CALL 360FH ;Set screen colour and DE = -40 03215 19 ADD HL,DE ;Set cursor address into ;previous line 03216 110044 LD DE,4400H ;DE = lowest LGR screen address 03219 DF RST 18H ;Cursor now before LGR screen ? 0321A 3004 JR NC,3220H ;No: continue at 3220H ;Yes: 0321C 11E803 LD DE,03E8H ;DE = 1000 (size of LGR screen) 0321F 19 ADD HL,DE ;Add to cursor location to ;create a wrap around to bottom ;line 03220 18BA JR 31DCH ;Continue at 31DCH ; RENUM entry from 31B8H ; ; I: HL = PTP 03222 2B DEC HL ;PTP - 1 03223 D7 RST 10H ;Character indicated 03224 2006 JR NZ,322CH ;Yes: continue at 323FH 03226 110A00 LD DE,000AH ;Starting LN = 10 03229 D5 PUSH DE ;Save it 0322A 1813 JR 323FH ;Continue at 323FH ; Indicate starting line number and increment 0322C D24A1E JP NC,1E4AH ;?FC Error when not a number 0322F CD5A1E CALL 1E5AH ;DE = starting LN 03232 CF RST 08H ;Next character must be 03233 2C DEFB ',' ;a comma 03234 30F6 JR NC,322CH ;?FC Error when comma is not ;followed by a number 03236 D5 PUSH DE ;Save starting LN 03237 CD5A1E CALL 1E5AH ;DE = increment 0323A 7A LD A,D ;Increment = 0 ? 0323B B3 OR E 0323C CA4A1E JP Z,1E4AH ;Yes: ?FC Error 0323F ED53E440 LD (40E4H),DE ;Store increment in system RAM 03243 D1 POP DE 03244 ED53E240 LD (40E2H),DE ;Store starting LN in ;system RAM 03248 FD2AF940 LD IY,(40F9H) ;IY -> End of program 0324C 110001 LD DE,0100H ;DE = 256 0324F FD19 ADD IY,DE ;IY = IY + 256 03251 FDE5 PUSH IY ;Save end of program address ;+ 256 03253 2AA440 LD HL,(40A4H) ;HL -> start of program 03256 E5 PUSH HL ;Save it ; Build RENUM table 03257 7E LD A,(HL) ;End of program reached ? 03258 23 INC HL ;Pointer + 1 03259 B6 OR (HL) ;Next line pointer = 0 ? 0325A 284A JR Z,32A6H ;Yes: continue at 32A6H 0325C 23 INC HL ;Pointer + 2 0325D 23 INC HL 0325E CDBA33 CALL 33BAH ;Search line for GOTO, GOSUB ;etc. 03261 23 INC HL ;Pointer + 1 03262 28F3 JR Z,3257H ;Process next line when no ;keyword was found 03264 CDD833 CALL 33D8H ;LN indicated? (in case of THEN ;or ELSE there can be either a ;command of a line number!) 03267 2B DEC HL ;Pointer - 1 03268 28F4 JR Z,325EH ;No: continue search 0326A 23 INC HL ;Pointer + 1 0326B E5 PUSH HL ;Save program pointer 0326C D5 PUSH DE ;Save table pointer 0326D FDE5 PUSH IY ;Save end of program address 0326F D1 POP DE ;and put it in DE 03270 2AB140 LD HL,(40B1H) ;HL = TOPMEM 03273 ED52 SBC HL,DE ;Subtract program end address ;Free memory space available ? 03275 DA7A19 JP C,197AH ;No: ?OM Error ;Yes: 03278 110400 LD DE,0004H ;Additional 4 bytes free ? 0327B ED52 SBC HL,DE 0327D DA7A19 JP C,197AH ;No: ?OM Error ;Yes: 03280 FD7000 LD (IY+00H),B ;Store number of digits of ;LN found 03283 E1 POP HL ;Restore table pointer in HL 03284 CD5A1E CALL 1E5AH ;DE = LN found 03287 FD7301 LD (IY+01H),E ;Store LN 0328A FD7202 LD (IY+02H),D 0328D FD360300 LD (IY+03H),00H ;And mark with 00H 03291 CDB133 CALL 33B1H ;Increase IY by 4 03294 E1 POP HL ;Restore program pointer 03295 2B DEC HL ;Program pointer - 1 03296 23 INC HL ;Program pointer + 1 03297 7E LD A,(HL) ;A = next character 03298 FE20 CP 20H ;Space found ? 0329A 28FA JR Z,3296H ;Yes: get next character 0329C FE2C CP 2CH ;Comma found ? (with ON GOTO or ;ON GOSUB) 0329E 2803 JR Z,32A3H ;Yes: continue ar 32A3H 032A0 2B DEC HL ;Program pointer - 1 032A1 18BB JR 325EH ;Continue searching line 032A3 23 INC HL ;Program pointer + 1 032A4 18BE JR 3264H ;Serach next LN ; RENUM table completed ; Now use the new line numbers from the table 032A6 FD3600FF LD (IY+00H),0FFH ;Table end 032AA E1 POP HL ;Restore program start 032AB FDE1 POP IY ;Restore table start 032AD ED5BE240 LD DE,(40E2H) ;DE = starting LN 032B1 D5 PUSH DE ;Save new LN 032B2 FDE5 PUSH IY ;Save table start 032B4 E5 PUSH HL ;Save program start 032B5 D5 PUSH DE ;Save starting LN 032B6 CDC209 CALL 09C2H ;BCDE = (HL): DE = pointer to ;next line, BC = line number 032B9 7A LD A,D ;Program end reached ? 032BA B3 OR E 032BB 2841 JR Z,32FEH ;Yes: continue at 32FEH 032BD EB EX DE,HL ;HL -> next line 032BE D1 POP DE ;Restore new LN 032BF FDE5 PUSH IY ;Save table pointer 032C1 FD7E00 LD A,(IY+00H) ;Table end reached ? 032C4 3C INC A ;(FFH + 1 = 00H) 032C5 2821 JR Z,32E8H ;Yes: continue at 32E8H 032C7 FD7E03 LD A,(IY+03H) ;A = table marker 032CA B7 OR A ;Marker <> 0 ? 032CB 2016 JR NZ,32E3H ;Yes: this entry has already ;the new line number 032CD FD7E01 LD A,(IY+01H) ;No: Is the current line number 032D0 B9 CP C ;already in the table ? 032D1 2010 JR NZ,32E3H 032D3 FD7E02 LD A,(IY+02H) 032D6 B8 CP B 032D7 200A JR NZ,32E3H ;No: check next entry ;Yes: 032D9 FD7301 LD (IY+01H),E ;Insert new line number in 032DC FD7202 LD (IY+02H),D ;the table 032DF FD360301 LD (IY+03H),01H ;Mark entry 032E3 CDB133 CALL 33B1H ;Increase table pointer by 4 032E6 18D9 JR 32C1H ;Check next entry ; Table end reached, insert next line number 032E8 FDE1 POP IY ;Restore table start 032EA E5 PUSH HL ;Save program pointer 032EB 2AE440 LD HL,(40E4H) ;HL = increment 032EE 19 ADD HL,DE ;HL = new LN + increment = ;next new LN ;Next LN > 65535 ? 032EF DA7A19 JP C,197AH ;Yes: ?OM Error (wrong error ;code !!) 032F2 EB EX DE,HL ;DE = new LN 032F3 21F8FF LD HL,0FFF8H ;New LN > 65529 ? 032F6 ED52 SBC HL,DE 032F8 DA7A19 JP C,197AH ;Yes: ?OM Error (?!?) 032FB E1 POP HL ;Restore program pointer 032FC 18B7 JR 32B5H ;Search for next line number in ;table ; Use new line numbers in program 032FE D1 POP DE ;Correct stack 032FF E1 POP HL ;Restore program start 03300 FDE1 POP IY ;Restore table start 03302 D1 POP DE ;Restore starting LN 03303 7E LD A,(HL) ;Program end reached ? 03304 23 INC HL 03305 B6 OR (HL) 03306 CABA31 JP Z,31BAH ;Yes: RENUM done 03309 23 INC HL ;Put new line number 0330A 73 LD (HL),E ;into program 0330B 23 INC HL 0330C 72 LD (HL),D 0330D CDBA33 CALL 33BAH ;Search for GOTO, GOSUB etc. 03310 23 INC HL ;Pointer + 1 03311 2009 JR NZ,331CH ;Token found: continue at 33C1H 03313 E5 PUSH HL ;Save pointer 03314 2AE440 LD HL,(40E4H) ;HL = increment 03317 19 ADD HL,DE ;Calculate next LN 03318 EB EX DE,HL ;DE = new LN 03319 E1 POP HL ;Restore pointer 0331A 18E7 JR 3303H ;Put new LN into program ; GOTO, GOSUB etc. found 0331C E5 PUSH HL ;Save pointer 0331D D5 PUSH DE ;Save new LN 0331E CDD833 CALL 33D8H ;Transfer LN found into line ;buffer and determine the ;number of digits 03321 D1 POP DE ;Restore new LN 03322 E1 POP HL ;Restore pointer 03323 2B DEC HL ;Pointer - 1 03324 28E7 JR Z,330DH ;Search for next token if no LN ;was found (e.g. after THEN ;or ELSE) 03326 23 INC HL ;Pointer + 1 03327 7E LD A,(HL) ;A = next character 03328 FE20 CP 20H ;Space ? 0332A 28FA JR Z,3326H ;Yes: update pointer and take ;next character 0332C D5 PUSH DE ;Save new LN 0332D E5 PUSH HL ;Save pointer 0332E FD6E01 LD L,(IY+01H) ;HL = new LN for this spot 03331 FD6602 LD H,(IY+02H) 03334 CD9433 CALL 3394H ;Put new LN in line buffer ;(in ASCII format!) 03337 FD4E00 LD C,(IY+00H) ;C = number of digits (=length) ;of old LN 0333A CDB133 CALL 33B1H ;Increment IY to next entry 0333D EB EX DE,HL ;DE -> new LN in line buffer 0333E E1 POP HL ;HL = program pointer ;(points to old LN) 0333F CDF833 CALL 33F8H ;Replace old LN at this spot 03342 D1 POP DE ;Restore new LN 03343 2B DEC HL ;Pointer - 1 03344 23 INC HL ;Pointer + 1 03345 7E LD A,(HL) ;Increment pointer until 03346 FE20 CP 20H ;the next non-space 03348 28FA JR Z,3344H ;character is found 0334A FE2C CP 2CH ;Comma found ? 0334C 2803 JR Z,3351H ;Yes: check for following LN ;No: 0334E 2B DEC HL ;Pointer - 1 0334F 18BC JR 330DH ;Search for next token ; ',' found (with ON GOTO or ON GOSUB) 03351 23 INC HL ;Pointer + 1 03352 18C8 JR 331CH ;Replace next LN ; Delete B characters from program ; ; I: B = number of characters to be deleted ; HL -> program text ; (from (HL) onwards, B bytes are removed from the program text) 03354 D5 PUSH DE ;Save registers 03355 C5 PUSH BC 03356 E5 PUSH HL 03357 E5 PUSH HL 03358 D1 POP DE ;DE -> program text 03359 D5 PUSH DE ;Save DE twice 0335A D5 PUSH DE 0335B 2AF940 LD HL,(40F9H) ;HL -> end of program 0335E E5 PUSH HL ;Save it 0335F 2B DEC HL ;End address - 1 03360 13 INC DE ;Program pointer + 1 03361 10FC DJNZ 335FH ;Repeat until B = 0 03363 22F940 LD (40F9H),HL ;Save new end address 03366 E1 POP HL ;Restore old end address 03367 C1 POP BC ;Restore program pointer 03368 ED42 SBC HL,BC ;Calcute the number of bytes 0336A 23 INC HL ;that have to be moved 0336B E5 PUSH HL ;Put the resulting blocksize 0336C C1 POP BC ;into BC 0336D E1 POP HL ;Restore program pointer 0336E EB EX DE,HL ;DE -> characters to be deleted ;HL -> remaining program text ;(following the characters to ;be deleted) 0336F EDB0 LDIR ;Move program text 03371 E1 POP HL ;Restore registers 03372 C1 POP BC 03373 D1 POP DE 03374 C9 RET ; Insert B characters into program ; ; I: B = number of characters to be inserted ; HL -> program text ; (from (HL) onwards, B bytes are inserted in the program text) 03375 D5 PUSH DE ;Save registers 03376 C5 PUSH BC 03377 E5 PUSH HL 03378 2AF940 LD HL,(40F9H) ;HL -> end of program 0337B E5 PUSH HL ;Copy pointer 0337C D1 POP DE ;into DE 0337D 23 INC HL ;End address + 1 0337E 10FD DJNZ 337DH ;Repeat until B = 0 03380 22F940 LD (40F9H),HL ;Save new end address 03383 C1 POP BC ;Restore program text pointer 03384 C5 PUSH BC ;and save it again 03385 E5 PUSH HL ;Save end address 03386 B7 OR A ;C-flag = 0 03387 ED42 SBC HL,BC ;Calculate the number of ;remaining characters upto ;program end 03389 E5 PUSH HL ;Put the resulting blocksize 0338A C1 POP BC ;into BC 0338B 03 INC BC ;Adjust blocksize + 1 0338C E1 POP HL ;Restore new end address 0338D EB EX DE,HL ;Put it in DE 0338E EDB8 LDDR ;Move program text 03390 E1 POP HL 03391 C1 POP BC 03392 D1 POP DE 03393 C9 RET ; Convert line number to ASCII format and put it in line buffer ; ; I: HL = line number ; O: B = number of digits (line number length) ; HL -> line number in ASCII format 03394 D5 PUSH DE ;Save DE 03395 222141 LD (4121H),HL ;X = HL 03398 010000 LD BC,0000H ;No formatting 0339B 2AA740 LD HL,(40A7H) ;HL -> line buffer 0339E E5 PUSH HL ;Save line buffer pointer 0339F CD2F13 CALL 132FH ;Decode number 033A2 E1 POP HL ;Restore line buffer pointer 033A3 0605 LD B,05H ;B = maximum length 033A5 7E LD A,(HL) ;A = character from line buffer 033A6 D630 SUB 30H ;Leading zero ? 033A8 2005 JR NZ,33AFH ;No: done ;Yes: 033AA 23 INC HL ;Line buffer pointer + 1 033AB 10F8 DJNZ 33A5H ;Get next character 033AD 2B DEC HL ;All digits = '0': pointer - 1 033AE 04 INC B ;Counter + 1 (1 digit) 033AF D1 POP DE ;Restore DE 033B0 C9 RET ; Increment table pointer to next entry 033B1 FD23 INC IY 033B3 FD23 INC IY 033B5 FD23 INC IY 033B7 FD23 INC IY 033B9 C9 RET ; Search line from (HL) for GOTO, GOSUB etc. ; ; I: HL -> line text ; O: A = token found ; Z-flag = 1 if no token found ; HL -> token found or end of line 033BA 23 INC HL ;pointer + 1 033BB 7E LD A,(HL) ;A = char from program text 033BC B7 OR A ;End of line ? 033BD C8 RET Z ;Yes: return 033BE FE8D CP 8DH ;Token for GOTO ? 033C0 280C JR Z,33CEH ;Yes: continue at 33CEH 033C2 FE91 CP 91H ;Token for GOSUB ? 033C4 2808 JR Z,33CEH 033C6 FECA CP 0CAH ;Token for THEN ? 033C8 2804 JR Z,33CEH 033CA FE95 CP 95H ;Token for ELSE 033CC 20EC JR NZ,33BAH ;No: next character ; Token found 033CE 2B DEC HL ;Was it a Colour BASIC token ? 033CF 7E LD A,(HL) ;Does the previous byte 033D0 FEFF CP 0FFH ;equal FFH ? 033D2 23 INC HL ;Put pointer back 033D3 7E LD A,(HL) ;And character back 033D4 28E4 JR Z,33BAH ;Yes: continue search 033D6 A7 AND A ;No: Z-flag = 0 033D7 C9 RET ; Determine length of line number found and put line number in line buffer ; ; I: HL -> line number (= token found + 1) ; O: B = number of digits (line number length) ; DE -> line buffer (line number is in line buffer from (DE) onwards) ; HL -> next character after the line number ; Z-flag = 0 in case of digits found 033D8 ED5BA740 LD DE,(40A7H) ;DE -> line buffer 033DC D5 PUSH DE ;Save DE 033DD 0600 LD B,00H ;Counter = 0 033DF 7E LD A,(HL) ;Get next character 033E0 FE20 CP 20H ;Space ? 033E2 280B JR Z,33EFH ;Yes: get next character 033E4 FE30 CP 30H ;Possible digit ? 033E6 380A JR C,33F2H ;No: done. 033E8 FE3A CP 3AH ;Digit ? 033EA 3006 JR NC,33F2H ;No: done. 033EC 04 INC B ;Counter + 1 033ED 12 LD (DE),A ;Store digit 033EE 13 INC DE ;Buffer pointer + 1 033EF 23 INC HL ;Line pointer + 1 033F0 18ED JR 33DFH ;Loop 033F2 AF XOR A ;A = 00H 033F3 12 LD (DE),A ;Mark line number end in line ;buffer 033F4 D1 POP DE ;Restore buffer address 033F5 04 INC B ;Set Z-flag 033F6 05 DEC B ;Z-flag = 0 when digits found 033F7 C9 RET ; Shift program text in such a way, that a new line number can be inserted ; and then insert the new line number ; ; I: B = new line number length ; C = old line number length ; HL -> program text ; (new line number is inserted from (HL) onwards) ; DE -> new line number in ASCII format 033F8 C5 PUSH BC ;Save lengths 033F9 78 LD A,B ;A = new length 033FA 99 SBC A,C ;- old length 033FB 2810 JR Z,340DH ;Insert new line number when ;both lengths are identical 033FD 05 DEC B ;New length - 1 033FE 2808 JR Z,3408H ;Old length > new length: ;continue at 3408H 03400 0D DEC C ;Old length - 1 03401 20F6 JR NZ,33F9H ;New length > old length: ;continue at 33F9H 03403 CD7533 CALL 3375H ;Insert character 03406 1805 JR 340DH ;And transfer line number ; Old length is bigger than new length 03408 41 LD B,C ;B = remaining length 03409 05 DEC B ;B - 1 0340A CD5433 CALL 3354H ;Delete B characters 0340D C1 POP BC ;Restore lengths 0340E 1A LD A,(DE) ;Transfer digit from line 0340F 77 LD (HL),A ;buffer to program text 03410 13 INC DE ;Line buffer pointer + 1 03411 23 INC HL ;Program text pointer + 1 03412 10FA DJNZ 340EH ;Repeat until B = 0 03414 C9 RET ; Get key from keyboard and check for FKEY (see 3000H) 03415 CD4900 CALL 0049H ;Wait for key pressed 03418 FE5C CP 5CH ;Possible FKEY ? 0341A 383C JR C,3458H ;No: continue at 3458H ;Yes: 0341C FE60 CP 60H ;Is an FKEY ? 0341E 3038 JR NC,3458H ;No: continue at 3458H 03420 D65B SUB 5BH ;A = FKEY number 1..4 ; Transfer FKEY text into line buffer ; A = FKEY code (01 to 08 for FKEY1 to FKEY8) 03422 57 LD D,A ;D = FKEY code 03423 78 LD A,B ;A = maximum number of ;characters (see 05D9H) 03424 FE07 CP 07H ;Are 7 characters still ;allowed ? 03426 38ED JR C,3415H ;No: ignore FKEY and get next ;key input 03428 7A LD A,D ;FKEY code back into A 03429 C5 PUSH BC ;Save counter 0342A E5 PUSH HL ;Save buffer pointer ; Set HL as pointer to FKEY definition string belonging to FKEY pressed 0342B 214943 LD HL,4349H ;HL -> FKEY definition strings ;in system RAM - length of ;one string 0342E 110700 LD DE,0007H ;DE = length of FKEY string 03431 19 ADD HL,DE ;HL -> next string 03432 3D DEC A ;Proper definition string ? 03433 20FC JR NZ,3431H ;No: next 03435 D1 POP DE ;Restore buffer pointer 03436 0607 LD B,07H ;B = length of FKEY string 03438 7E LD A,(HL) ;A = character of FKEY string 03439 FE00 CP 00H ;Is it a 00H (= execute a CR) ? 0343B 2812 JR Z,344FH ;Yes, execute FKEY command 0343D 12 LD (DE),A ;Store character 0343E D5 PUSH DE ;Save buffer pointer 0343F CD3300 CALL 0033H ;Output byte 03442 D1 POP DE ;Restore buffer pointer 03443 23 INC HL ;Next position in FKEY string 03444 13 INC DE ;Buffer pointer + 1 03445 10F1 DJNZ 3438H ;Process next 03447 EB EX DE,HL ;HL = buffer pointer 03448 C1 POP BC ;Restore counter 03449 78 LD A,B ;A = counter 0344A D607 SUB 07H ;Subtract 7 characters 0344C 47 LD B,A ;Counter back in B 0344D 18C6 JR 3415H ;Wait for next key press ; Insert a 'RETURN' to execute FKEY command 0344F EB EX DE,HL ;HL = buffer pointer 03450 78 LD A,B ;A = remaining length of FKEY ;text 03451 C1 POP BC ;Restore counter 03452 80 ADD A,B ;A = maximum number of ;characters + remaining length 03453 D607 SUB 07H ;Subtract 7 characters 03455 47 LD B,A ;New counter back in B 03456 3E0D LD A,0DH ;A = 'RETURN' ; + pressed ? (FKEY5 to FKEY8) 03458 FE7C CP 7CH ;Possible FKEY pressed ? 0345A DA0330 JP C,3003H ;No: continue at 3003H 0345D FE80 CP 80H ;FKEY pressed ? 0345F D20330 JP NC,3003H ;No: continue at 3003H 03462 D677 SUB 77H ;A = FKEY code (05H to 08H) 03464 18BC JR 3422H ;Continue at 3422H ; FKEY statement ; -------------- 03466 2B DEC HL ;PTP - 1 03467 D7 RST 10H ;Get FKEY number ;Digit ? 03468 D24A1E JP NC,1E4AH ;No: ?FC Error 0346B D630 SUB 30H ;Convert character to number 0346D F5 PUSH AF ;Save FKEY number 0346E 23 INC HL ;PTP + 1 0346F CF RST 08H ;Next character must be 03470 D5 DEFB 0D5H ;the token for '=' 03471 CF RST 08H ;Next character must be 03472 22 DEFB 22H ;double quotes 03473 F1 POP AF ;A = FKEY number 03474 FE01 CP 01 ;FKEY number < 1 03476 DA4A1E JP C,1E4AH ;Yes: ?FC Error 03479 FE09 CP 09H ;FKEY number > 8 0347B 30EB JR NC,3468H ;Yes: ?FC Error 0347D E5 PUSH HL ;Save PTP 0347E 214943 LD HL,4349H ;HL -> FKEY definitions - 7 03481 110700 LD DE,0007H ;DE = 7 characters length 03484 19 ADD HL,DE ;HL -> FKEY definition 03485 3D DEC A ;FKEY number - 1 ;Down to 0 ? 03486 20FC JR NZ,3484H ;No: next FKEY text 03488 EB EX DE,HL ;DE -> proper FKEY definition 03489 E1 POP HL ;HL = PTP 0348A 2B DEC HL ;PTP - 1 0348B 0607 LD B,07H ;7 characters definition length 0348D D7 RST 10H ;Get next character 0348E FE22 CP 22H ;Is it double quotes ? 03490 280C JR Z,349EH ;Yes: end of new definition 03492 FE00 CP 00H ;Insert 'RETURN' 03494 280A JR Z,34A0H ;Yes: copy 00H and finish 03496 12 LD (DE),A ;Copy into FKEY definition 03497 13 INC DE ;Pointer + 1 03498 10F3 DJNZ 348DH ;Next character 0349A 23 INC HL ;PTP + 1 0349B CF RST 08H ;Next character must be 0349C 22 DEFB 22H ;double quotes 0349D C9 RET ; End of text reached: fill remaining characters with spaces 0349E 3E20 LD A,' ' ;A = space 034A0 12 LD (DE),A ;Copy into FKEY definition 034A1 05 DEC B ;Next position in definition ;All done ? 034A2 2803 JR Z,34A7H ;Yes: continue ar 34A7H 034A4 13 INC DE ;Pointer + 1 034A5 18F9 JR 34A0H ;Loop 034A7 B7 OR A ;A = 00H ? 034A8 C8 RET Z ;Yes: done 034A9 18F0 JR 349BH ;Test on double quotes ; Default definition for FKEY 1 to 8. (This table is copied into system RAM ; from 4350H onwards) 034AB 4C495354202020 DEFB 'LIST ' ;FKEY 1 = "LIST " 034B2 52554E20202020 DEFB 'RUN ' ;FKEY 2 = "RUN " 034B9 4155544F202020 DEFB 'AUTO ' ;FKEY 3 = "AUTO " 034C0 45444954202020 DEFB 'EDIT ' ;FKEY 4 = "EDIT " 034C7 52454E554D2020 DEFB 'RENUM ' ;FKEY 5 = "RENUM " 034CE 53595354454D00 DEFB 'SYSTEM',00H ;FKEY 6 = "SYSTEM 034D5 434C4F41442020 DEFB 'CLOAD ' ;FKEY 7 = "CLOAD " 034DC 43534156452022 DEFB 'CSAVE "' ;FKEY 8 = "CSAVE "" ; &H 034E3 D7 RST 10H ;Get character following & 034E4 FE48 CP 48H ;Is it 'H' (hexadecimal) 034E6 203D JR NZ,3528H ;No: test for &O ; Decode hexadecimal constant 034E8 23 INC HL ;PTP + 1 034E9 CD1635 CALL 34F3H ;DE = constant 034EC E5 PUSH HL ;Save PTP 034ED EB EX DE,HL ;HL = constant 034EE CD9A0A CALL 0A9AH ;Write HL to X as INT 034F1 E1 POP HL ;Restore PTP 034F2 C9 RET ; DE = &H (HL) 034F3 110000 LD DE,0000H ;Result = 0 034F6 CD0135 CALL 3501H ;Decode MSB 034F9 57 LD D,A ;D = MSB 034FB CD0135 CALL 3501H ;Decode LSB 034FE 5F LD E,A ;E = LSB 034FF 23 INC HL ;PTP + 1 03500 C9 RET ; A = &H (HL) 03501 CD0F35 CALL 350FH ;Decode nibble 03504 07 RLCA ;Shift bits 4-7 03505 07 RLCA 03506 07 RLCA 03507 07 RLCA 03508 23 INC HL ;PTP + 1 03509 47 LD B,A ;Temporary result in B 0350A CD0F35 CALL 350FH ;Decode second nibble 0350D 80 ADD A,B ;And add previous result 0350E C9 RET ; Decode a hexadecimal digit 0350F 7E LD A,(HL) ;A = character 03510 D630 SUB '0' ;Character < '0' 03512 DA4A1E JP C,1E4AH ;Yes: ?FC Error 03515 FE0A CP 10H ;Character > '9' 03517 D8 RET C ;No: value ok, done 03518 D607 SUB 07H ;Character < 'A' 0351A DA4A1E JP C,1E4AH ;Yes: ?FC Error 0351D FE10 CP 10H ;Character > 'F' 0351F D24A1E JP NC,1E4AH ;Yes: ?FC Error 03522 C9 RET ; &O 03523 FE4F CP 4FH ;Is it 'O' (octal) 03525 C29719 JP NZ,1997H ;No: ?SN Error ; Decode octal constant 03528 110000 LD DE,0000H ;Result = 0 0352B 23 INC HL ;PTP + 1 0352C CD4535 CALL 3545H ;Decode highest octal digit 0352F 07 RLCA ;Shift free bits 0-2 03530 07 RLCA 03531 07 RLCA 03532 23 INC HL ;PTP + 1 03533 47 LD B,A ;Temporary result in B 03534 CD4535 CALL 3545H ;Decode next octal digit 03537 80 ADD A,B ;Add previous result 03538 07 RLCA ;Shift free bits 0-2 03539 07 RLCA 0353A 07 RLCA 0353B 23 INC HL ;PTP + 1 0353C 47 LD B,A ;Temporary result in B 0353D CD4535 CALL 3545H ;Decode last octal digit 03540 80 ADD A,B ;Add previous result 03541 5F LD E,A ;LSB value into E 03542 23 INC HL ;PTP + 1 03543 18A7 JR 34ECH ;Write HL to X as INT ; Decode highest octal digit ('0' - '3') 03545 7E LD A,(HL) ;A = character 03546 D630 SUB '0' ;Character < '0' 03548 380D JR C,3557H ;Yes: ?FC Error 0354A FE04 CP 04H ;Character < '4' 0354C D8 RET C ;Yes: value ok, done 0354D 1808 JR 3557H ;No: ?FC Error ; Decode lower octal digit ('0' - '7') 0354F 7E LD A,(HL) ;A = character 03550 D630 SUB '0' ;Character < '0' 03552 3803 JR C,3557H ;Yes: ?FC Error 03554 FE08 CP 08H ;Character < '8' 03556 D8 RET C ;Yes: value ok, done 03557 C34A1E JP 1E4AH ;No: ?FC Error ; CALL statement ; -------------- 0355A CDFE34 CALL 34F3H ;DE = address following CALL 0355D E5 PUSH HL ;Save PTP 0355E EB EX DE,HL ;HL = address of routine 0355F 116735 LD DE,3567H ;Set return address for routine 03562 D5 PUSH DE ;that is called to 3567H 03563 E9 JP (HL) ;activate routine 03564 FF RST 38H ;-- 03565 FF RST 38H 03566 FF RST 38H ; Return from CALL-routine 03567 E1 POP HL ;Restore PTP 03568 C9 RET ; Translation table for colour codes (is copied into system RAM from 4390H ; onwards). With the first Colour Genies, the COLOUR value was directly ; written into the colour-RAM (from F000H onwards). ; Due to hardware changes in later models, colour codes changed. In order to ; keep it compatible this table is used to regain the original colour settings. ; This table indicates for every COLOUR value, which value has to be ; written into the colour-RAM in order to regain the old order. ; ; Value in colour-RAM COLOUR value 03569 03 DEFB 03H ; 1 0356A 05 DEFB 05H ; 2 0356B 02 DEFB 02H ; 3 0356C 04 DEFB 04H ; 4 0356D 06 DEFB 06H ; 5 0356E 08 DEFB 08H ; 6 0356F 01 DEFB 01H ; 7 03560 0E DEFB 0EH ; 8 03561 09 DEFB 09H ; 9 03572 10 DEFB 10H ; 10 03573 07 DEFB 07H ; 11 03574 0B DEFB 0BH ; 12 03575 0C DEFB 0CH ; 13 03576 0D DEFB 0DH ; 14 03577 0A DEFB 0AH ; 15 03578 0F DEFB 0FH ; 16 ; Print text from (HL) onwards and generate sound (with error message) 03579 CDA728 CALL 28A7H ;Print text 0357C 110900 LD DE,0009H ;Set various values to write 0357F D5 PUSH DE ;into the PSG 03580 110008 LD DE,0800H 03583 D5 PUSH DE 03584 113E10 LD DE,103EH 03587 D5 PUSH DE 03588 117800 LD DE,0078H ;DE = PSG value 0358B 3E01 LD A,01H ;Write 0078H in frequency reg 0358D CD2A3E CALL 3E2AH ;of channel A 03590 D1 POP DE 03591 3E08 LD A,08H :Set amplitude of channel A to ;envelope shape use and 03593 CD2A3E CALL 3E2AH ;switch on channel A 03596 D1 POP DE 03597 3E0C LD A,0CH ;Amplitude channel B = 8 03599 CD2A3E CALL 3E2AH ;Amplitude channel C = 0 0359C D1 POP DE 0359D 3E0D LD A,0DH 0359F C3323E JP 3E32H ;Set envelope and return ; SUB for SHAPE (see 3CF2H). ; Load HL with the start address of the SHAPE table ; ; I: ; O: HL -> start of SHAPE table 035A2 2AB140 LD HL,(40B1H) ;HL = TOPMEM 035A5 23 INC HL ;HL -> start of SHAPE table 035A6 C3F53C JP 3CF5H ;Continue at 3CF5H ; SUB for PRINT# 035A9 CDB535 CALL 35B5H ;Decode number 035AC C33F02 JP 023FH ;Write leader and sync ; SUB for INPUT# 035AF CDB535 CALL 35B5H ;Decode number 035B2 C34C02 JP 024CH ;Search for leader and sync ; Decode number at PRINT# and INPUT# 035B5 AF XOR A ;A = 0 035B6 CD012B CALL 2B01H ;DE = number 035B9 CF RST 08H ;Next character must be 035BA 2C DEFB ',' ;a comma 035BB 7B LD A,E ;A = LSB 035BC A2 AND D ;AND with MSB. MSB must be ;FFH because a negative number ;is required. 035BD C602 ADD A,02H ;Number was -1 or -2 ? 035BF D24A1E JP NC,1E4AH ;No: ?FC Error 035C2 C9 RET ; Set volume of indicated channel to 0 (not used) ; Is the value of the argument between 1 and 3, then the corresponding PSG ; channel volume will be set to 0. If no argument is given, the volume of ; all PSG channels will be set to 0. ; This routine can be used by redirecting e.g. the KILL command ; (so the command will be KILL n or KILL). ; POKE, &H4192,195 : POKE &H4193,53 ; ; I: HL = PTP on argument or command/line end 035C3 2B DEC HL ;PTP -1 035C4 D7 RST 10H ;Channel number provided ? 035C5 281A JR Z,35E1H ;No: continue at 35E1H 035C7 CD1C2B CALL 2B1CH ;A = Channel number 035CA 0608 LD B,08H ;Register = 8 035CC FE01 CP 01H ;Channel 1 ? 035CE 280B JR Z,35DBH ;Yes: register number is ok 035D0 04 INC B ;Register = 9 035D1 FE02 CP 02H ;Channel 2 ? 035D3 2806 JR Z,35DBH ;Yes: register number is ok 035D5 04 INC B ;Register = 10 035D6 FE03 CP 03H ;Channel 3 ? 035D8 C24A1E JP NZ,1E4AH ;No: ?FC Error 035DB 78 LD A,B ;A = register number 035DC 1E00 LD E,00H ;E = 00H 035DE C3323E JP 3E32H ;Write to PSG (SOUND A,E) ; No channel number provided: set volume of all channels to 0. 035E1 3E0A LD A,0AH ;Switch off channel 2 and 3 035E3 110000 LD DE,0000H 035E6 CD2A3E CALL 3E2AH 035E9 3E08 LD A,08H ;Switch off channel 1 035EB C3323E JP 3E32H ; SUB for screen output ; Write character in A at (HL) and update screen colour ; ; I: A = character ; HL -> screen position 035EE 77 LD (HL),A ;Write character 035EF CD7A30 CALL 307AH ;Update character colour 035F2 23 INC HL ;Next position 035F3 CD7A30 CALL 307AH ;Update character colour 035F6 2B DEC HL ;Back to original position 035F7 C9 RET ; SUB for screen output ; Update the colour of a screen location addressed by HL ; ; I: HL -> screen location of character in LGR screen memory 035F8 1100AC LD DE,0AC00H ;DE = difference between ;LGR screen memory (4400H) ;and corresponding colour ;memory (0F000H) 035FB FE20 CP ' ' ;Space character ? 035FD C28030 JP NZ,3080H ;No: set colour according ;to current colour setting ; Spaces get the first colour in the colour code table 03600 3A9043 LD A,(4390H) ;A = first entry in colour code ;table 03603 19 ADD HL,DE ;Set pointer into colour mem 03604 C38F30 JP 308FH ;Set colour ; SUB for 'cursor one line down' 03607 112800 LD DE,0028H ;DE = 40 (characters per line) 0360A 3E20 LD A,20H ;Character = ' ' 0360C C37A30 JP 307AH ;Output space (delete cursor) ; SUB for 'cursor one line up' 0360F 11D8FF LD DE,0FFD8H ;DE = -40 03612 18F6 JR 360AH ;Continue at 360AH ; SUB for 'cursor on/off' 03614 2002 JR NZ,3618H ;Continue at 3618H (see 306EH) 03616 3E20 LD A,20H ;-- 03618 C37A30 JP 307AH ;Output character in A ; SUB for 'Carriage Return' 0361B CD0A36 CALL 360AH ;Delete cursor character 0361E C36531 JP 3165H ;Continue at 3165H ; SUB for COLOUR change (see 3017H) 03621 322340 LD (4023H),A ;Save new COLOUR value 03624 2A2040 LD HL,(4020H) ;HL = actual cursor address 03627 C35F30 JP 305FH ;Switch on cursor ; SUB for PRINT@ (see 2086H) ; Calculate new screen-POS ; ; I: DE = @ argument ; O: A = POS value 0362A E5 PUSH HL ;Save HL 0362B EB EX DE,HL ;HL = @ argument 0362C 112800 LD DE,0028H ;DE = 40 (length of 1 line) 0362F 19 ADD HL,DE ;Add line length 03630 B7 OR A ;C-flag = 0 03631 ED52 SBC HL,DE ;Subtract line length until 03633 30FC JR NC,3631H ;result becomes negative 03635 19 ADD HL,DE ;Compensate last subtract 03636 7D LD A,L ;A = L = actual POS 03637 E1 POP HL ;Restore HL 03638 C9 RET ; SUB for scroll (see 3196H) 03639 D9 EXX ;Switch registers 0363A F1 POP AF ;RET-address to AF 0363B C5 PUSH BC ;Save registers 0363C D5 PUSH DE 0363D E5 PUSH HL 0363E 1100F0 LD DE,0F000H ;Prepare second register set 03641 2128F0 LD HL,0F028H ;for scroll of colour memory 03644 01C003 LD BC,03C0H 03647 C5 PUSH BC ;Save BC as counter 03648 D9 EXX ;Switch back registers 03649 110044 LD DE,4400H ;Prepare first register set 0364C 212844 LD HL,4428H ;for scroll of LGR screen mem. 0364F C1 POP BC ;Restore counter 03650 F5 PUSH AF ;RET address back on stack 03651 C9 RET ; JOY statement ; ------------- 03652 7E LD A,(HL) ;A = char. from program text 03653 23 INC HL ;PTP + 1 03654 FEDB CP 0DBH ;Token for INP ? 03656 CAC536 JP Z,36C5H ;Yes: continue at 36C5H 03659 FEA0 CP 0A0H ;Token for OUT ? 0365B CAB336 JP Z,36B3H ;Yes: continue at 36B3H 0365E C39719 JP 1997H ;?SN Error ; COLOUR function (right of = sign) : ; *** WARNING: NEVER USE THIS! *** ; It can lead to a system crash or total program destruction ; If you want to perform this function do a PEEK(&H4023) + 1. Much safer.... 03661 3A2340 LD A,(4023H) ;A = colour value 03664 3C INC A ;Adjust to get proper value ;as with COLOUR n (1-16) ;Colour value zero ? 03665 CA0D37 JP Z,370DH ;Yes: continue at 370DH ;Note: It would have been ok ;if the jump would have been ;unconditional! :-( 03668 B8 CP B ;Compare with what ? 03669 77 LD (HL),A ;Write A using PTP! Yikes!!! ; Read a BASIC program from I/O port (JOYINP) 0366A 2AA440 LD HL,(40A4H) ;HL -> start of user BASIC RAM 0366D 2B DEC HL ;Pointer - 1 0366E 0603 LD B,03H ;B = counter 03670 E5 PUSH HL ;Save pointer 03671 260F LD H,0FH ;Select register 15 (port B) 03673 CDBB3A CALL 3ABBH ;A = PSG port B 03676 CB57 BIT 2,A ;Strobe signal high ? 03678 28F9 JR Z,3673H ;No, wait for strobe pulse 0367A CDBB3A CALL 3ABBH ;A = contents of PSG register 0367D CB57 BIT 2,A ;Stobe signal low again ? 0367F 20F9 JR NZ,367AH ;No, wait for strobe pulse end 03681 260E LD H,0EH ;Select register 14 (port A) 03683 CDBB3A CALL 3ABBH ;A = PSG port A 03686 E1 POP HL ;Restore pointer 03687 77 LD (HL),A ;Save in memory 03688 B7 OR A ;Set flags 03689 23 INC HL ;Update memory pointer ;A = zero ? 0368A 20E2 JR NZ,366EH ;No: next character of program ;3 consecutive zeros ? 0368C 10E2 DJNZ 3670H ;No: continue read 0368E C9 RET ; Write a BASIC program to I/O port (JOYOUT) 0368F 2AA440 LD HL,(40A4H) ;HL -> start of user BASIC RAM 03692 2B DEC HL ;Pointer - 1 03693 ED5BF940 LD DE,(40F9H) ;DE -> end of program text + 2 03697 7E LD A,(HL) ;Get byte from program text 03698 E5 PUSH HL ;Save pointer 03699 6F LD L,A ;Data in L 0369A 260E LD H,0EH ;Use PSG port A register 0369C CDB23A CALL 3AB2H ;Output data by port A 0369F 24 INC H ;Use PSG port B register 036A0 3E04 LD A,04H ;Start strobe pulse 036A2 CDB23A CALL 3AB2H 036A5 060A LD B,0AH ;B = delay time 036A7 10FE DJNZ 36A7H ;Wait 036A9 AF XOR A ;End strobe pulse 036AA CDB23A CALL 3AB2H ;Output A 036AD E1 POP HL ;Restore pointer 036AE 23 INC HL ;Pointer + 1 036AF DF RST 18H ;End of program reached ? 036B0 20E5 JR NZ,3697H ;No, send next byte of program 036B2 C9 RET ; JOYOUT ; ------ 036B3 E5 PUSH HL ;Save PTP 036B4 2607 LD H,07H ;Select PSG enable register 036B6 CDBB3A CALL 3ABBH ;A = contents of PSG register 036B9 E63F AND 3FH ;Set port A and B to output 036BB F6C0 OR 0C0H 036BD CDB23A CALL 3AB2H ;Write to PSG enable register 036C0 CD8F36 CALL 368FH ;Write BASIC program 036C3 E1 POP HL ;Restore PTP 036C4 C9 RET ; JOYINP ; ------ 036C5 3E07 LD A,07H ;Select PSG enable register 036C7 D3F8 OUT (0F8H),A 036C9 3E3F LD A,3FH ;Set Port A and B to input 036CB D3F9 OUT (0F9H),A 036CD CD6A36 CALL 366AH ;Read BASIC program 036D0 C3772C JP 2C77H ;Renew all pointers in program ; SWAP statement ; -------------- 036D3 CD0D26 CALL 260DH ;Find or create 1st variable 036D6 D5 PUSH DE ;Save pointer on 1st variable 036D7 3AAF40 LD A,(40AFH) ;A = variable type of X 036DA F5 PUSH AF ;Save it 036DB CF RST 08H ;Next character must be 036DC 2C DEFB ',' ;a comma 036DD CD0D26 CALL 260DH ;Find or create 2nd variable 036E0 C1 POP BC ;Restore 1st variable type 036E1 3AAF40 LD A,(40AFH) ;Take variable type of X 036E4 B8 CP B ;Both variables same type ? 036E5 C24A1E JP NZ,1E4AH ;No: ?FC Error ; Now swap all bytes from both variables. The number of bytes to swap is ; indicated by the VT in B 036E8 E3 EX (SP),HL ;HL -> 1st variable 036E9 4E LD C,(HL) ;C = byte from 1st var 036EA 1A LD A,(DE) ;A = byte from 2nd var 036EB 77 LD (HL),A ;Byte from 2nd var in 1st var 036EC 79 LD A,C ;A = byte from 1st var 036ED 12 LD (DE),A ;Byte from 1st var in 2nd var 036EE 23 INC HL ;Pointer on 1st var + 1 036EF 13 INC DE ;Pointer on 2nd var + 1 036F0 10F7 DJNZ 36E9H ;Until all var bytes swapped 036F2 E1 POP HL ;Restore PTP 036F3 C9 RET ; X = SOUND(register) 036F4 CF RST 08H ;Next character must be 036F5 28 DEFB '(' ;a '(' 036F6 CD1C2B CALL 2B1CH ;A = register parameter value 036F9 F5 PUSH AF ;Save it 036FA CF RST 08H ;Next character must be 036FB 29 DEFB ')' ;a ')' 036FC F1 POP AF ;Restore parameter value 036FD FE10 CP 10H ;In range (0 to 15) 036FF D24A1E JP NC,1E4AH ;No: ?FC Error 03702 E5 PUSH HL ;Save PTP 03703 67 LD H,A ;H = PSG register number 03704 CDBB3A CALL 3ABBH ;A = contents PSG register H 03707 C3723F JP 3F72H ;Put A in X and return ; X = SCALE 0370A 3A1443 LD A,(4314H) ;A = current scale value 0370D E5 PUSH HL ;Save PTP 0370E C3723F JP 3F72H ;Put A in X as INT and return ; Table with colour codes (not used) 03711 10 DEFB 10H 03712 0D DEFB 0DH 03713 0E DEFB 0EH 03714 04 DEFB 04H 03715 06 DEFB 06H 03716 03 DEFB 03H 03717 01 DEFB 01H 03718 02 DEFB 02H 03719 05 DEFB 05H 0371A 07 DEFB 07H 0371B 08 DEFB 08H 0371C 09 DEFB 09H 0371D 0A DEFB 0AH 0371E 0B DEFB 0BH 0371F 0C DEFB 0CH 03720 0F DEFB 0FH ; Table with colour codes (not used) 03721 10 DEFB 10H 03722 0D DEFB 0DH 03723 06 DEFB 06H 03724 04 DEFB 04H 03725 0F DEFB 0FH 03726 03 DEFB 03H 03727 09 DEFB 09H 03728 02 DEFB 02H 03729 01 DEFB 01H 0372A 05 DEFB 05H 0372B 07 DEFB 07H 0372C 08 DEFB 08H 0372D 0A DEFB 0AH 0372E 0B DEFB 0BH 0372F 0C DEFB 0CH 03730 0E DEFB 0EH : Table with colour codes (not used) 03731 10 DEFB 10H 03732 05 DEFB 05H 03733 02 DEFB 02H 03734 04 DEFB 04H 03735 0E DEFB 0EH 03736 09 DEFB 09H 03737 01 DEFB 01H 03738 0A DEFB 0AH 03739 07 DEFB 07H 0373A 06 DEFB 06H 0373B 0D DEFB 0DH 0373C 03 DEFB 03H 0373D 08 DEFB 08H 0373E 0B DEFB 0BH 0373F 0C DEFB 0CH 03740 0F DEFB 0FH ; Unused ROM space 03741 FF RST 38H ;-- 03742 FF RST 38H 03743 FF RST 38H 03744 FF RST 38H 03745 FF RST 38H 03746 FF RST 38H 03747 FF RST 38H 03748 FF RST 38H 03749 FF RST 38H 0374A FF RST 38H 0374B FF RST 38H 0374C FF RST 38H 0374D FF RST 38H 0374E FF RST 38H 0374F FF RST 38H 03750 FF RST 38H 03751 FF RST 38H 03752 FF RST 38H 03753 FF RST 38H 03754 FF RST 38H 03755 FF RST 38H 03756 FF RST 38H 03757 FF RST 38H 03758 FF RST 38H 03759 FF RST 38H 0375A FF RST 38H 0375B FF RST 38H 0375C FF RST 38H 0375D FF RST 38H 0375E FF RST 38H 0375F FF RST 38H 03760 FF RST 38H 03761 FF RST 38H 03762 FF RST 38H 03763 FF RST 38H 03764 FF RST 38H 03765 FF RST 38H 03766 FF RST 38H 03767 FF RST 38H 03768 FF RST 38H 03769 FF RST 38H 0376A FF RST 38H 0376B FF RST 38H 0376C FF RST 38H 0376D FF RST 38H 0376E FF RST 38H 0376F FF RST 38H 03770 FF RST 38H 03771 FF RST 38H 03772 FF RST 38H 03773 FF RST 38H 03774 FF RST 38H 03775 FF RST 38H 03776 FF RST 38H 03777 FF RST 38H 03778 FF RST 38H 03779 FF RST 38H 0377A FF RST 38H 0377B FF RST 38H 0377C FF RST 38H 0377D FF RST 38H 0377E FF RST 38H 0377F FF RST 38H 03780 FF RST 38H 03781 FF RST 38H 03782 FF RST 38H 03783 FF RST 38H 03784 FF RST 38H 03785 FF RST 38H 03786 FF RST 38H 03787 FF RST 38H 03788 FF RST 38H 03789 FF RST 38H 0378A FF RST 38H 0378B FF RST 38H 0378C FF RST 38H 0378D FF RST 38H 0378E FF RST 38H 0378F FF RST 38H 03790 FF RST 38H 03791 FF RST 38H 03792 FF RST 38H 03793 FF RST 38H 03794 FF RST 38H 03795 FF RST 38H 03796 FF RST 38H 03797 FF RST 38H 03798 FF RST 38H 03799 FF RST 38H 0379A FF RST 38H 0379B FF RST 38H 0379C FF RST 38H 0379D FF RST 38H 0379E FF RST 38H 0379F FF RST 38H 037A0 FF RST 38H 037A1 FF RST 38H 037A2 FF RST 38H 037A3 FF RST 38H 037A4 FF RST 38H 037A5 FF RST 38H 037A6 FF RST 38H 037A7 FF RST 38H 037A8 FF RST 38H 037A9 FF RST 38H 037AA FF RST 38H 037AB FF RST 38H 037AC FF RST 38H 037AD FF RST 38H 037AE FF RST 38H 037AF FF RST 38H 037B0 FF RST 38H 037B1 FF RST 38H 037B2 FF RST 38H 037B3 FF RST 38H 037B4 FF RST 38H 037B5 FF RST 38H 037B6 FF RST 38H 037B7 FF RST 38H 037B8 FF RST 38H 037B9 FF RST 38H 037BA FF RST 38H 037BB FF RST 38H 037BC FF RST 38H 037BD FF RST 38H 037BE FF RST 38H 037BF FF RST 38H 037C0 FF RST 38H 037C1 FF RST 38H 037C2 FF RST 38H 037C3 FF RST 38H 037C4 FF RST 38H 037C5 FF RST 38H 037C6 FF RST 38H 037C7 FF RST 38H 037C8 FF RST 38H 037C9 FF RST 38H 037CA FF RST 38H ; Print text on screen (not used) ; ; I: HL -> text 037CB D5 PUSH DE ;Save DE 037CC 111D40 LD DE,401DH ;DE -> screen DCB 037CF 1804 JR 37D5H ;Continue at 36D5H ; Print text on printer (not used) ; The end of text must be indicated with 03H or 0DH. ; The 0DH is printed, the 03H not. ; ; I: HL -> text 037D1 D5 PUSH DE ;Save DE 037D2 112540 LD DE,4025H ;DE -> printer DCB 037D5 E5 PUSH HL ;Save text pointer 037D6 7E LD A,(HL) ;A = character from text 037D7 FE03 CP 03H ;End of text ? 037D9 2809 JR Z,37E4H ;Yes: continue at 37E4H 037DB CD1B00 CALL 001BH ;Print character (using DCB) 037DE 7E LD A,(HL) ;A = character from text 037DF FE0D CP 0DH ;End of text ? 037E1 23 INC HL ;Pointer + 1 037E2 20F2 JR NZ,37D6H ;No: next character 037E4 E1 POP HL ;Restore original text pointer 037E5 D1 POP DE ;Restore DE 037E6 C9 RET ; Conversion of the binary value in DE to 4 hex digits ; Used by DOS system call $HEXDE ; (reverse of the &H command) ; ; I: DE = binary value ; HL -> memory space for storage of the 4 hex characters 037E7 7A LD A,D ;A = D 037E8 CDEC37 CALL 37ECH ;Convert A into 2 hex chars 037EB 7B LD A,E ;A = E 037EC F5 PUSH AF ;Save binary value 037ED 0F RRCA ;Isolate upper nibble 037EE 0F RRCA 037EF 0F RRCA 037F0 0F RRCA 037F1 CDF537 CALL 37F5H 037F4 F1 POP AF ;Restore binary value 037F5 E60F AND 0FH ;Isolate lower nibble 037F7 C690 ADD A,90H ;Make hex character out of 037F9 27 DAA ;the binary value 0-15 037FA CE40 ADC A,40H 037FC 27 DAA 037FD 77 LD (HL),A ;Save hex character 037FE 23 INC HL ;Update pointer 037FF C9 RET ; CTRC programming table for PAL standard ; The table entries are written into the CTRC register 15 downwards to ; register 0 ; The table is copied into system RAM from 42F0H onwards ; LGR mode 03800 01 DEFB 01H ;Cursor position LSB 03801 00 DEFB 00H ; MSB 03802 00 DEFB 00H ;Start address of page LSB 03803 04 DEFB 04H ;Start address of page MSB 03804 07 DEFB 07H ;Cursor stop scan line 03805 C4 DEFB C4H ;Cursor start scan line 03806 07 DEFB 07H ;Scan lines/row 03807 A0 DEFB A0H ;Interlace mode 03808 1F DEFB 1FH ;VSYNC position 03809 19 DEFB 19H ;Character rows/frame 0380A 00 DEFB 00H ;VSYNC adjust 0380B 26 DEFB 26H ;Vertical total 0380C 96 DEFB 96H ;HSYNC width 0380D 34 DEFB 34H ;HSYNC position 0380E 28 DEFB 28H ;Characters/row 0380F 46 DEFB 46H ;Horizontal total ; FGR mode 03810 00 DEFB 00H 03811 00 DEFB 00H 03812 00 DEFB 00H 03813 08 DEFB 08H 03814 00 DEFB 00H 03815 20 DEFB 20H 03816 01 DEFB 01H 03817 20 DEFB 20H 03818 74 DEFB 74H 03819 66 DEFB 66H 0381A 1F DEFB 1FH 0381B 7E DEFB 7EH 0381C 96 DEFB 96H 0381D 34 DEFB 34H 0381E 28 DEFB 28H 0381F 46 DEFB 46H ; The next 3 bytes determine the baudrate at which characters are read/written ; from/to cassette tape. These values are copies into system RAM at ; 4310H, 4311H and 4312H. See also routines at 01FAH and 021FH. 03820 46 DEFB 46H 03821 4B DEFB 4BH 03822 69 DEFB 69H ; CTRC programming table for NTSC standard (not used) ; Using NTSC requires also hardware alterations on the video ; hardware. Therefor, this table is useless for non-NTSC ; computers ; LGR mode 03823 01 DEFB 01H 03824 00 DEFB 00H 03825 00 DEFB 00H 03826 04 DEFB 04H 03827 07 DEFB 07H 03828 C4 DEFB C4H 03829 07 DEFB 07H 0382A A0 DEFB A0H 0382B 1B DEFB 1BH 0382C 19 DEFB 19H 0382D 06 DEFB 06H 0382E 1F DEFB 1FH 0382F 34 DEFB 34H 03830 2E DEFB 2EH 03831 28 DEFB 28H 03832 38 DEFB 38H ; FGR mode, NTSC standard 03833 00 DEFB 00H 03834 00 DEFB 00H 03835 00 DEFB 00H 03836 08 DEFB 08H 03837 00 DEFB 00H 03838 20 DEFB 20H 03839 01 DEFB 01H 0383A 20 DEFB 20H 0383B 6E DEFB 6EH 0383C 66 DEFB 66H 0383D 08 DEFB 08H 0383E 7F DEFB 7FH 0383F 34 DEFB 34H 03840 2E DEFB 2EH 03841 28 DEFB 28H 03842 38 DEFB 38H ; Default values for timing of cassette I/O (not used) ; These values are used for the American version of the ; Colour Genie 03843 4C DEFB 4CH 03844 51 DEFB 51H 03845 71 DEFB 71H ; FCLS (without parameter) 03846 3E00 LD A,00H ;A = FCOLOUR code (0) 03848 1808 JR 3852H ;Execute FCLS ; Continuation of FCLS routine of 3C87H (with parameter) 0384A C4C23F CALL NZ,3FC2H ;If there is a parameter: ;get parameter 0384D FE04 CP 04H ;Value in range (1 to 4) 0384F D24A1E JP NC,1E4AH ;No: ?FC Error ; SUB for FCLS (AF,BC,DE,HL) ; Perform an FCLS A ; ; I: A = FCOLOUR value 03852 4F LD C,A ;Value in C ;Build byte value for FGR ;memory to FCLS with the proper ;colour 03853 0603 LD B,03H ;4 pixels per byte 03855 07 RLCA ;Shift 2 positions 03856 07 RLCA 03857 B1 OR C ;or with C 03858 10FB DJNZ 3855H 0385A 4F LD C,A ;FCLS byte value in C 0385B E5 PUSH HL ;Save PTP 0385C 2AA440 LD HL,(40A4H) ;HL -> start of user BASIC RAM 0385F 110148 LD DE,4801H ;DE -> start of FGR memory + 1 03862 DF RST 18H ;FGR mode disabled at startup ;with ? 03863 2809 JR Z,386EH ;Yes, nothing to do so return 03865 210048 LD HL,4800H ;HL -> start of FGR memory 03868 71 LD (HL),C ;Put FCLS value in first byte 03869 01FF0F LD BC,0FFFH ;BC = bytes to fill 0386C EDB0 LDIR ;Fill all bytes in FGR memory 0386E E1 POP HL ;Restore PTP 0386F C9 RET ; This routine initializes the CRTC. The screen mode (LGR or FGR) is taken ; from the port 255 status byte 03870 3A1C43 LD A,(431CH) ;Take port 255 status byte ; Entry with port 255 status byte already in A 03873 E5 PUSH HL ;Save HL 03874 21F042 LD HL,42F0H ;HL -> CRTC table for LGR mode 03877 CB6F BIT 5,A ;LGR mode ? 03879 2803 JR Z,387EH ;Yes: continue at 387EH 0387B 210043 LD HL,4300H ;HL -> CRTC table for FGR mode 0387E D3FF OUT (0FFH),A ;Set CRTC mode 03880 321C43 LD (431CH),A :Save port 255 output status 03883 0610 LD B,10H ;B = CRTC registers 16 03885 0EFA LD C,0FAH ;C = CTRC register select port 03887 05 DEC B ;register counter - 1 03888 ED41 OUT (C),B ;Select register 0388A 04 INC B ;Adjust B for OUTI 0388B 0C INC C ;C = CTRC data register port 0388C EDA3 OUTI ;Write value from CRTC table ;to register. ;All registers done ? 0388E 20F5 JR NZ,3885H ;No: update next register 03890 E1 POP HL ;Restore HL 03891 C9 RET ; This routine sets the screen to LGR and NBGRD. Then it prints the text : addressed by HL ; ; I: HL -> text ; O: - 03892 D9 EXX ;Save registers 03893 3A1C43 LD A,(431CH) ;Take port 255 ouput status 03896 E6DB AND 0DBH ;Set LGR and NBGRD. Leave other ;bits as they are 03898 CD7338 CALL 3873H ;Initialize CRTC 0389B D9 EXX ;Restore registers 0389C CDA728 CALL 28A7H ;Print text 0389F C9 RET ; SUB for CONT (see 1DF2H) ; Program CRTC on last value and store last LN as actual LN 038A0 D9 EXX ;Save registers 038A1 CD7038 CALL 3870H ;Initialize CRTC 038A4 D9 EXX ;Restore registers 038A5 22A240 LD (40A2H),HL ;Renew actual LN 038A8 C9 RET ; FGR statement ; ------------- 038A9 3A1C43 LD A,(431CH) ;A = port 255 output status 038AC CBEF SET 5,A ;FGR/LGR bit to FGR 038AE 18C3 JR 3873H ;Initialize CTRC ; LGR statement ; ------------- 038B0 3A1C43 LD A,(431CH) ;A = port 255 output status 038B3 CBAF RES 5,A ;FGR/LGR bit to LGR 038B5 18BC JR 3873H ;Initialize CRTC ; Old BRGD routine. Replaced by BGRD n at 3FE4H. 038B7 0604 LD B,04H ;-- 038B9 1802 JR 38BDH ; NBGRD statement ; --------------- 038BB 0600 LD B,00H ;BGRD value = 0 038BD 3A1C43 LD A,(431CH) ;A = port 255 output status 038C0 E6FB AND 0FBH ;Clear old BGRD bits 038C2 B0 OR B ;Set new BGRD bits 038C3 321C43 LD (431CH),A ;Store status in system RAM 038C6 D3FF OUT (0FFH),A ;Set new BGRD 038C8 C9 RET ; COLOUR statement ; ---------------- 038C9 CDC23F CALL 3FC2H ;A = colour value - 1 038CC FE10 CP 10H ;Value in range (1 to 16) ? 038CE D24A1E JP NC,1E4AH ;No: ?FC Error 038D1 322340 LD (4023H),A ;Store new value in system RAM 038D4 C9 RET ; FCOLOUR statement ; ----------------- ; The FCOLOUR token is stored in 3 bytes! (FFH, 81H, 52H) ; Because of an error in the old ROM, only the keyword FCOLOU was recognized. ; The missing 'R' had to be stored seperately. 038D5 CF RST 08H ;Next character must be a 'R' 038D6 52 DEFB 'R' ;becuase token is only FCOLOU 038D7 CDC23F CALL 3FC2H ;A = fcolour value - 1 038DA FE04 CP 04H ;Value in range (1 to 4) ? 038DC 30F0 JR NC,38CEH ;No: ?FC Error 038DE 321343 LD (4313H),A ;Store new FCOLOUR value 038E1 C9 RET ; SUB for tokenizing (see 1C15H) ; Scan Colour-keywords table when the end of the normal keyword table ; has been reached. ; ; I: A = current table character ; B = token counter ; C = current text character ; DE = text pointer ; HL = table pointer 038E2 E67F AND 7FH ;Table end reached ? 038E4 C0 RET NZ ;No: return 038E5 EB EX DE,HL ;HL = text pointer 038E6 112F39 LD DE,392FH ;DE -> Colour keyword table 038E9 C5 PUSH BC ;Save token counter 038EA 067F LD B,7FH ;Set new token counter 038EC 7E LD A,(HL) ;A = current text character 038ED FE61 CP 61H ;Possible lower case ? 038EF 3806 JR C,38F7H ;No: ok, continue at 38F7H 038F1 FE7B CP 7BH ;Lower case ? 038F3 3002 JR NC,38F7H ;No: ok, continue at 38F7H 038F5 E65F AND 5FH ;Convert to upper case 038F7 4E LD C,(HL) ;C = current text character 038F8 EB EX DE,HL ;HL = table pointer 038F9 23 INC HL ;Table pointer + 1 038FA B6 OR (HL) ;Next keyword reached ? 038FB F2F938 JP P,38F9H ;No: increment pointer until ;next keyword reached 038FE 04 INC B ;Token counter + 1 038FF 7E LD A,(HL) ;A = keyword table character 03900 E67F AND 7FH ;End of keyword table reached ? 03902 2829 JR Z,392DH ;Yes: return 03904 B9 CP C ;Compare with text character ;The same ? 03905 20F2 JR NZ,38F9H ;No: try next keyword 03907 EB EX DE,HL ;DE = keyword table pointer 03908 E5 PUSH HL ;Save text pointer 03909 13 INC DE ;Table pointer + 1 0390A 1A LD A,(DE) ;A = next table character 0390B B7 OR A ;Next keyword reached ? 0390C FA1E39 JP M,391EH ;Yes: all characters match! ;continue ar 391EH 0390F 4F LD C,A ;No: C = table character 03910 23 INC HL ;Text pointer + 1 03911 7E LD A,(HL) ;A = next text character 03912 FE61 CP 61H ;Convert to upper case 03914 3802 JR C,3918H 03916 E65F AND 5FH 03918 B9 CP C ;Compare to table character 03919 28EE JR Z,3909H ;Next character when indentical 0391B E1 POP HL ;Restore old text pointer 0391C 18D9 JR 38F7H ;And compare next keyword ; Keyword found 0391E F1 POP AF ;Text pointer 0391F F1 POP AF ;Old token counter 03920 F1 POP AF ;Remove RET address to 1C18H 03921 D1 POP DE ;and to 1C3DH 03922 D1 POP DE ;Restore counter of characters ;per line 03923 E3 EX (SP),HL ;Save text pointer, restore ;buffer pointer 03924 36FF LD (HL),0FFH ;Store FFH in buffer as ;Colour-keyword identifier 03926 78 LD A,B ;A = token value of keyword ;that has been found 03927 42 LD B,D ;BC = DE 03928 4B LD C,E 03929 D1 POP DE ;Restore text pointer in DE 0392A C3573D JP 3D57H ;Store token ; End of keyword table reached, no keyword matched 0392D C1 POP BC ;Restore old counters 0392E F1 POP AF ;Remove RET address to 1C18H 0392F C9 RET ;Return to 1C3DH ; Keyword table for Colour BASIC statements 03930 C34F4C4F5552 DEFB 80H+'C','OLOUR' ;COLOUR 03936 C6434F4C4F55 DEFB 80H+'F','COLOU' ;FCOLOUR 0393C CB4559504144 DEFB 80H+'K','EYPAD' ;KEYPAD 03942 CA4F59 DEFB 80H+'J','OY' ;JOY 03945 D04C4F54 DEFB 80H+'P','LOT' ;PLOT 03949 C64752 DEFB 80H+'F','GR' ;FGR 0394C CC4752 DEFB 80H+'L','GR' ;LGR 0394F C6434C53 DEFB 80H+'F','CLS' ;FCLS 03953 D04C4159 DEFB 80H+'P','LAY' ;PLAY 03957 C34952434C45 DEFB 80H+'C','IRCLE' ;CIRCLE 0395D D343414C45 DEFB 80H+'S ,'CALE' ;SCALE 03962 D348415045 DEFB 80H+'S','HAPE' ;SHAPE 03967 CE5348415045 DEFB 80H+'N','SHAPE' ;NSHAPE 0396D D85348415045 DEFB 80H+'X','SHAPE' ;XSHAPE 03973 D041494E54 DEFB 80H+'P','AINT' ;PAINT 03978 C3504F494E54 DEFB 80H+'C','POINT' ;CPOINT 0397E CE504C4F54 DEFB 80H+'N','PLOT' ;NPLOT 03983 D34F554E44 DEFB 80H+'S','OUND' ;SOUND 03988 C3484152 DEFB 80H+'C','HAR' ;CHAR 0398C D2454E554D DEFB 80H+'R','ENUM' ;RENUM 03991 D3574150 DEFB 80H+'S','WAP' ;SWAP 03995 C64B4559 DEFB 80H+'F','KEY' ;FKEY 03999 C3414C4C DEFB 80H+'C','ALL' ;CALL 0399D D64552494659 DEFB 80H+'V','ERIFY' ;VERIFY 039A3 C2475244 DEFB 80H+'B','GRD' ;BGRD 039A7 CE42475244 DEFB 80H+'N','BGRD' ;NBGRD 039AC 80 DEFB 80H ;End of table marker ; SUB for LIST (see 2BA9H) ; Establish start of keyword table. ; ; O: HL -> keyword table 039AD FE80 CP 80H ;Token value = FFH? (FFH - 7FH) 039AF 215016 LD HL,1650H ;HL -> BASIC keyword table 039B2 C0 RET NZ ;No: HL is set properly: return 039B3 E1 POP HL ;RET address to HL 039B4 E3 EX (SP),HL ;RET address back, ;Line pointer to HL 039B5 7E LD A,(HL) ;A = next character 039B6 D67F SUB 7FH ;Is it a token ? 039B8 5F LD E,A ;E = character - 7FH 039B9 23 INC HL ;Pointer + 1 039BA E3 EX (SP),HL ;Save pointer, ;RET address in HL 039BB E5 PUSH HL ;Save RET address 039BC 2A8C43 LD HL,(438CH) ;HL -> Colour keyword table 039BF C9 RET ; SUB for program loop (see 1D67H) ; Establish start address of jump address table 039C0 FE7F CP 7FH ;Colour token found ? 039C2 2808 JR Z,39CCH ;Yes: continue at 39CCH 039C4 FE3C CP 3CH ;Command found ? 039C6 D2E72A JP NC,2AE7H ;No: continue at 2AE7H 039C9 C36A1D JP 1D6AH ;Execute command ; Colour token found 039CC 23 INC HL ;PTP + 1 039CD 7E LD A,(HL) ;Get real token value 039CE D680 SUB 80H ;Subtract 80H 039D0 07 RLCA ;*2 = table offset 039D1 4F LD C,A ;BC = table offset 039D2 0600 LD B,00H 039D4 EB EX DE,HL ;DE = PTP 039D5 2A8E43 LD HL,(438EH) ;HL -> Colour jump table 039D8 C3721D JP 1D72H ;Get jump address as execute ;routine ; Address table for Colour BASIC statements 039DB C938 DEFW 38C9H ;COLOUR 039DD D538 DEFW 38D5H ;FCOLOUR 039DF 9719 DEFW 1997H ;KEYPAD (= ?SN Error!) 039E1 5236 DEFW 3652H ;JOY 039E3 C13B DEFW 3BC1H ;PLOT 039E5 A938 DEFW 38A9H ;FGR 039E7 B038 DEFW 38B0H ;LGR 039E9 833C DEFW 3C83H ;FCLS 039EB 613D DEFW 3D61H ;PLAY 039ED F83A DEFW 3AF8H ;CIRCLE 039EF F13A DEFW 3AF1H ;SCALE 039F1 DD3C DEFW 3CDDH ;SHAPE 039F3 D83C DEFW 3CD8H ;NSHAPE 039F5 D33C DEFW 3CD3H ;XSHAPE 039F7 383E DEFW 3E38H ;PAINT 039F9 9719 DEFW 1997H ;CPOINT (= ?SN Error!) 039FB BE3B DEFW 3BBEH ;NPLOT 039FD 953F DEFW 3F95H ;SOUND 039FF A83F DEFW 3FA8H ;CHAR 03A01 B631 DEFW 31B6H ;RENUM 03A03 D336 DEFW 36D3H ;SWAP 03A05 6634 DEFW 3466H ;FKEY 03A07 5A35 DEFW 355AH ;CALL 03A09 4935 DEFW 3F33H ;VERIFY 03A0B E43F DEFW 3FE4H ;BGRD 03A0D BB38 DEFW 38BBH ;NBGRD ; X = KEYPAD1, KEYPAD2, or KEYPAD(n) 03A0F 7E LD A,(HL) ;A = char from program text 03A10 23 INC HL ;PTP + 1 03A11 E5 PUSH HL ;Save PTP 03A12 FE31 CP '1' ;Is it a '1' ? (KEYPAD1) 03A14 CAD83A JP Z,3AD8H ;Yes: continue at 3AD8H 03A17 FE32 CP '2' ;Is it a '2' ? (KEYPAD2) 03A19 CADC3A JP Z,3ADCH ;Yes: continue at 3ADCH 03A1C C3C33A JP 3AC3H ;Check if (n) set ; X = JOY1X, JOY1Y, JOY2X, JOY2Y or JOY(n) 03A1F 7E LD A,(HL) ;A = character at PTP 03A20 FE28 CP '(' ;Is it a '(' 03A22 2826 JR Z,3A4AH ;Yes: continue at 3A4AH 03A24 1604 LD D,04H 03A26 FE32 CP '2' ;Is it a '2' ? (JOY2) 03A28 2807 JR Z,3A31H ;Yes: continue at 3A31H 03A2A CB3A SRL D ;D = D / 2 03A2C FE31 CP '1' ;Is it a '1' ? (JOY1) 03A2E C29719 JP NZ,1997H ;No: ?SN Error 03A31 D7 RST 10H ;Get next non-space character 03A32 FE59 CP 'Y' ;Char = 'Y' ? (JOY1Y,JOY2Y) 03A34 2805 JR Z,3A3BH ;Yes: continue at 3A3BH 03A36 15 DEC D ;D = D - 1 03A37 FE58 CP 'X' ;Char = 'X' ? (JOY1X,JOY2X) 03A39 20F3 JR NZ,3A2EH ;No: ?SN Error ;JOY1X: D = 1 JOY1Y: D = 2 ;JOY2X: D = 3 JOY2Y: D = 4 03A3B 23 INC HL ;PTP + 1 03A3C E5 PUSH HL ;Save PTP 03A3D CD5E3A CALL 3A5EH ;Get joystick value 03A40 E63F AND 3FH ;Set to value between 0-63 03A42 3C INC A ;Adjust to 1 to 64 03A43 1816 JR 3A5BH ;Put A in X as INT and return ; Not used 03A45 18F4 JR 3A3BH ;Get joystick value 03A47 00 NOP ;-- 03A48 00 NOP 03A49 00 NOP ; JOY (n) 03A4A 23 INC HL ;PTP + 1 03A4B CD1C2B CALL 2B1CH ;Get parameter 03A4E FE08 CP 08H ;In range (0-7) 03A50 D24A1E JP NC,1E4AH ;No: ?FC Error 03A53 57 LD D,A ;Parameter in D 03A54 CF RST 08H ;Next character must be 03A55 29 DEFB ')' ;a ')' 03A56 14 INC D ;D + 1 03A57 E5 PUSH HL ;Save PTP 03A58 CD5E3A CALL 3A5EH ;Get joystick value 03A5B C3723F JP 3F72H ;Put A in X as INT and return ; Get joystick value ; I: D = parameter with joystick ID (range: 1 to 8) ; D = 1: JOY1X / D = 2: JOY1Y / D = 3: JOY2X / D = 4: JOY2Y ; The remaining values (5 to 8) can be used for a second pair ; of joysticks (or 4 other analogue inputs) ; O: Value return by joystick 03A5E CDA93A CALL 3AA9H ;Set port A to output, ;port B to input 03A61 AF XOR A ;A = 0; 03A62 1E80 LD E,80H ;E,7 = 1 03A64 B3 OR E ;Set bit in A 03A65 6F LD L,A ;L = A 03A66 260E LD H,0EH ;Select PSG port A 03A68 CDB33A CALL 3AB3H ;Write A to port A 03A6B 24 INC H ;Select PSG Port B 03A6C CDBB3A CALL 3ABBH ;A = contents of port B 03A6F D5 PUSH DE ;Save counter D 03A70 17 RLA ;Shift required bit into C-flag 03A71 15 DEC D ;Required bit in C-flag ? 03A72 20FC JR NZ,3A70H ;No: shift again 03A74 D1 POP DE ;Restore counter 03A75 7D LD A,L ;Last output value in A ;Required bit = '1' ? 03A76 3803 JR C,3A7BH ;Yes: continue at 3A7BH 03A78 7B LD A,E ;A = bitmask 03A79 2F CPL ;Invert it 03A7A A5 AND L ;And with L 03A7B CB3B SRL E ;Shift E 1 bit to the right ;All 8 bits done ? 03A7D 30E5 JR NC,3A64H ;No: loop 03A7F C9 RET ; Old KEYPAD routine (now at 3A0FH) 03A80 C3143F JP 3F14H ;Was: KEYPAD1 03A83 00 NOP ;-- 03A84 C3183F JP 3F18H ;Was: KEYPAD2 ; KEYPAD routine ; Read value from keypad and store in A ; ; I: D = keypad bit mask (FEH for KEYPAD1, F7H for KEYPAD2) ; O: A = value from keypad 03A87 CDA93A CALL 3AA9H ;Set port A to output, ;port B to input 03A8A 1EE4 LD E,0E4H ;E = LSB of start address ;of KEYPAD table 03A8C 0603 LD B,03H ;Test 2 columns 03A8E 6A LD L,D ;L = keypad address 03A8F 260E LD H,0EH ;Select port A 03A91 CDB33A CALL 3AB3H ;Select keypad 03A94 24 INC H ;Next PSG register 03A95 CDBB3A CALL 3ABBH ;Get keypad value 03A98 0E04 LD C,04H ;Test 4 rows 03A9A 1F RRA ;Shift next bit into C-flag ;Key pressed ? 03A9B 3008 JR NC,3AA5H ;Yes: continue at 3AA5H 03A9D 1C INC E ;Table offset + 1 03A9E 0D DEC C ;Row counter - 1 03A9F 20F9 JR NZ,3A9AH ;Check next row 03AA1 CB02 RLC D ;Address next column 03AA3 10E9 DJNZ 3A8EH ;Read next column 03AA5 163A LD D,3AH ;DE -> keypad table at proper ;offset 03AA7 1A LD A,(DE) ;A = keypad value 03AA8 C9 RET ; Prepare port A for output and port B for input 03AA9 2607 LD H,07H ;Select PSG enable register 03AAB CDBB3A CALL 3ABBH ;A = contents of PSG register 03AAE E63F AND 3FH ;Set port A to output (bit 7) 03AB0 F640 OR 40H ;and port B to input (bit 6) ; Write A into PSG register addressed by H ; ; I: H = PSG register number ; A = data to write into register 03AB2 6F LD L,A ;L = A 03AB3 0EF8 LD C,0F8H 03AB5 ED61 OUT (C),H ;Select PSG register 03AB7 0C INC C 03AB8 ED69 OUT (C),L ;Write new contents in PSG 03ABA C9 RET ; Read PSG register addressed by H ; ; I: H = PSG register number ; O: A = contents of data register 03ABB 0EF8 LD C,0F8H ;C = PSG select register 03ABD ED61 OUT (C),H ;Select register H 03ABF 0C INC C ;C = PSG data register 03AC0 ED78 IN A,(C) ;A = data from data register 03AC2 C9 RET ; KEYPAD(n) 03AC3 E1 POP HL ;Restore PTP 03AC4 2B DEC HL ;Adjust PTP 03AC5 CF RST 08H ;Next character must be 03AC6 28 DEFB '(' ;a '(' 03AC7 CDC23F CALL 3FC2H ;Get n - 1 03ACA FE02 CP 02H ;In range (1 or 2) 03ACC D24A1E JP NC,1E4AH ;No: ?FC Error 03ACF F5 PUSH AF ;save n 03AD0 CF RST 08H ;Next character must be 03AD1 29 DEFB ')' ;a ')' 03AD2 F1 POP AF ;Restore parameter 03AD3 E5 PUSH HL ;Save PTP 03AD4 FE01 CP 01H ;n = 1 ? 03AD6 2804 JR Z,3ADCH ;Yes: continue at 3ADCH ; KEYPAD1 03AD8 16FE LD D,0FEH ;Set bitmask for keypad 1 03ADA 1802 JR 3ADEH ;Continue at 3ADEH ; KEYPAD2 03ADC 16F7 LD D,0F7H ;Set bitmask for keypad 2 03ADE CD873A CALL 3A87H ;A = value from keypad 03AE1 C3723F JP 3F72H ;Put A in X and return ; Keypad table with the return values for the 12 keys on the keypad 03AE4 03 DEFB 03H ;'3' 03AE5 06 DEFB 06H ;'6' 03AE6 09 DEFB 09H ;'9' 03AE7 0C DEFB 0CH ;Fire button (right) 03AE8 02 DEFB 02H ;'2' 03AE9 05 DEFB 05H ;'5' 03AEA 08 DEFB 08H ;'8' 03AEB 0A DEFB 0AH ;'0' 03AEC 01 DEFB 01H ;'1' 03AED 04 DEFB 04H ;'4' 03AEE 07 DEFB 07H ;'7' 03AEF 0B DEFB 0BH ;Fire button (left) 03AF0 00 DEFB 00H ;No key pressed ; SCALE statement ; --------------- 03AF1 CD1C2B CALL 2B1CH ;Get new scale value 03AF4 321443 LD (4314H),A ;and save it in system RAM 03AF7 C9 RET ; CIRCLE statement ; ---------------- 03AF8 CD1C2B CALL 2B1CH ;Get X-coordinate 03AFB F5 PUSH AF ;Save X-coordinate 03AFC CF RST 08H ;Next character must be 03AFD 2C DEFB ',' ;a comma 03AFE CD1C2B CALL 2B1CH ;Get Y-coordinate 03B01 F5 PUSH AF ;Save Y-coordinate 03B02 CF RST 08H ;Next character must be 03B03 2C DEFB ',' ;a comma 03B04 CD1C2B CALL 2B1CH ;Get radius 03B07 D1 POP DE ;D = Y-coordinate 03B08 C1 POP BC ;B = X-coordinate 03B09 4A LD C,D ;C = Y-coordinate ; B = X-coordinate, C = Y-coordinate, A = radius 03B0A E5 PUSH HL ;Save PTP 03B0B 57 LD D,A ;Radius in D = Y-distance 03B0C 1E00 LD E,00H ;X-distance = 0 03B0E 2680 LD H,80H ;H = step value ; Plot next 8 points ;Y-distance < X-distance ;(circle is closed) ? 03B10 FA523B JP M,3B52H ;Yes: restore PTP and return 03B13 CD7A3B CALL 3B7AH ;Plot 4 points and swap X- ;and Y-distance 03B16 CD7A3B CALL 3B7AH ;Plot 4 points and swap back 03B19 CD5E3B CALL 3B5EH ;Negate distances 03B1C C5 PUSH BC ;Save registers 03B1D D5 PUSH DE 03B1E E5 PUSH HL 03B1F 2E80 LD L,80H ;Bit 7 of L = 1: This causes ;an overflow with the first ;ADD HL,HL to bit 0 of H 03B21 63 LD H,E ;H = X-distance 03B22 0608 LD B,08H ;Process 8 bits 03B24 1E00 LD E,00H ;E = 0, D = Y-distance ; Calculate next step for Y distance 03B26 29 ADD HL,HL ;Shift next bit from H ;to C-flag 03B27 ED52 SBC HL,DE ;HL = HL - DE - C-flag 03B29 3803 JR C,3B2EH ;Jump when underflow. Because ;E = 0, this can only happen ;when H < D. 03B2B 23 INC HL ;HL + 1 (= L + 1) 03B2C 1801 JR 3B2FH ;Loop 03B2E 19 ADD HL,DE ;Reverse subtract 03B2F 10F5 DJNZ 3B26H ;Loop 03B31 7D LD A,L ;A = L 03B32 E1 POP HL ;Restore registers 03B33 D1 POP DE 03B34 C1 POP BC 03B35 84 ADD A,H ;A = A + step value ;C-flag = 1 if A + H > 255 03B36 67 LD H,A ;H = new step value 03B37 7A LD A,D ;A = Y-distance 03B38 2E00 LD L,00H ;L = 0; 03B3A 9D SBC A,L ;A = Y-distance - C-flag 03B3B 57 LD D,A ;D = new Y-distance 03B3C 1C INC E ;X-distance + 1 03B3D 7A LD A,D ;A = Y-distance 03B3E BB CP E ;X-distance > Y-distance ? 03B3F C3103B JP 3B10H ;Continue at 3B10H ; PLOT B + E , C + D 03B42 C5 PUSH BC ;Save registers 03B43 D5 PUSH DE 03B44 E5 PUSH HL 03B45 7B LD A,E ;A = X-distance 03B46 80 ADD A,B ;+ centre-coordinates 03B47 6F LD L,A ;Results in X-coordinate 03B48 7A LD A,D ;A = Y-distance 03B49 81 ADD A,C ;+ centre-coordinates 03B4A 67 LD H,A ;Results in Y-coordinate 03B4B CD8A3B CALL 3B8AH ;PLOT L , H 03B4E E1 POP HL ;Restore registers 03B4F D1 POP DE 03B50 C1 POP BC 03B51 C9 RET ; End CIRCLE 03B52 E1 POP HL ;Restore PTP 03B53 C9 RET ; Negate X-distance (E = -E) 03B54 7B LD A,E ;A = E 03B55 ED44 NEG ;A = -A 03B57 5F LD E,A ;new value back in E 03B58 C9 RET ; Negate Y-distance (D = -D) 03B59 7A LD A,D ;A = D 03B5A ED44 NEG ;A = -A 03B5C 57 LD D,A ;new value back in D 03B5D C9 RET ; Negate X- and Y-distance 03B5E CD543B CALL 3B54H ;Negate X-distance 03B61 CD593B CALL 3B59H ;Negate Y-distance 03B64 C9 RET ; PLOT B - E , C + D 03B65 CD543B CALL 3B54H ;Negate X-distance 03B68 CD423B CALL 3B42H ;PLOT B + E , C + D 03B6B C9 RET ; PLOT B + E , C - D 03B6C CD593B CALL 3B59H ;Negate Y-distance 03B6F CD423B CALL 3B42H ;PLOT B + E , C + D 03B72 C9 RET ; Swap X- and Y-distance 03B73 7B LD A,E ;L = E 03B74 6F LD L,A 03B75 7A LD A,D ;E = D 03B76 5F LD E,A 03B77 7D LD A,L ;D = L 03B78 57 LD D,A 03B79 C9 RET ; Plot 4 points and exchange X- and Y-distance 03B7A CD423B CALL 3B42H ;PLOT B + E, C + D ;(bottom right) 03B7D CD653B CALL 3B65H ;PLOT B - E, C + D ;(bottom left) 03B80 CD6C3B CALL 3B6CH ;PLOT B - E, C - D ;(top left) 03B83 CD653B CALL 3B65H ;PLOT B + E, C - D ;(top right) 03B86 CD733B CALL 3B73H ;Exchange distances ;for second call, see 3B13H) 03B89 C9 RET ; SUB for PLOT, PAINT, SHAPE and CIRCLE ; PLOT L , H (AF,BC,DE,HL) ; ; I: L = X-coordinate ; H = Y-coordinate ; (4313H) = FCOLOUR value 03B8A 3A1343 LD A,(4313H) ;A = FCOLOUR value 03B8D E603 AND 03H ;Clear unused bits ; PLOT L , H ; as 3B8AH but A = FCOLOUR value 03B8F 4F LD C,A ;C = FCOLOUR value 03B90 3E9F LD A,9FH ;A = X-max. (159) 03B92 BD CP L ;Beyond X-max ? 03B93 D8 RET C ;Yes: done 03B94 3E65 LD A,65H ;A = Y-max (101) 03B96 BC CP H ;Beyond Y-max ? 03B97 D8 RET C ;Yes: done 03B98 7D LD A,L ;A = X-coordinate 03B99 6C LD L,H ;L = Y-coordinate 03B9A 2600 LD H,00H ;HL = Y-coordinate 03B9C 54 LD D,H ;DE = HL 03B9D 5D LD E,L 03B9E 29 ADD HL,HL ;HL = HL * 40 03B9F 29 ADD HL,HL ;(one row in FGR mode 03BA0 19 ADD HL,DE ;corresponds with 40 bytes 03BA1 29 ADD HL,HL ;in FGR screen memory) 03BA2 29 ADD HL,HL 03BA3 29 ADD HL,HL 03BA4 5F LD E,A ;E = X-coordinate 03BA5 CB3B SRL E ;E = E * 4 03BA7 CB3B SRL E ;(one byte in FGR memory ;contains 4 pixels) 03BA9 1648 LD D,48H ;DE = start of FGR memory + ;X-coordinate * 4 03BAB 19 ADD HL,DE ;Add Y-coordinate * 40 to get ;the byte in FGR screen memory ;that has to be used 03BAC E603 AND 03H ;Compute position of pixel 03BAE 3C INC A ;inside byte 03BAF 47 LD B,A ;B = X-coordinate MOD 4 03BB0 3EFC LD A,0FCH ;A = 11111100 (2 bits/pixel) 03BB2 0F RRCA ;Shift the 2 zero bits to the 03BB3 0F RRCA ;required position 03BB4 CB09 RRC C ;Shift FCOLOUR code along 03BB6 CB09 RRC C 03BB8 10F8 DJNZ 3BB2H ;Repeat until counter = 0 03BBA A6 AND (HL) ;Get byte of required pixel 03BBB B1 OR C ;and set new colour 03BBC 77 LD (HL),A ;Save new byte value 03BBD C9 RET ; NPLOT statement ; --------------- 03BBE 0600 LD B,00H ;Set NPLOT 03BC0 3A0603 LD A,(0306H) ;-- ; PLOT statement ; -------------- * 03BC1 0603 LD B,03H ;Set PLOT 03BC3 3A1343 LD A,(4313H) ;A = FCOLOUR value 03BC6 F5 PUSH AF ;Save it on stack 03BC7 A0 AND B ;And it with B to get either ;black (NPLOT) or the current ;value (PLOT) 03BC8 321343 LD (4313H),A ;Save new FCOLOUR to use 03BCB CD7B3C CALL 3C7BH ;'TO' token indicated ? 03BCE 382F JR C,3BFFH ;No: continue at 3BFFH 03BD0 3A1543 LD A,(4315H) ;Get last X-value and 03BD3 F5 PUSH AF ;save it on stack 03BD4 3A1643 LD A,(4316H) ;Get last Y-value and 03BD7 F5 PUSH AF ;save it on stack 03BD8 CD1C2B CALL 2B1CH ;Get next X-value and 03BDB 321543 LD (4315H),A ;save it in system RAM 03BDE F5 PUSH AF ;and on stack 03BDF CF RST 08H ;Next character must be 03BE0 2C DEFB ',' ;a comma 03BE1 CD1C2B CALL 2B1CH ;Get next Y-value and 03BE4 321643 LD (4316H),A ;save it in system RAM 03BE7 D9 EXX ;switch register set 03BE8 6F LD L,A ;L' = Y2 03BE9 D1 POP DE ;Restore X-value 03BEA 62 LD H,D ;H' = X2 03BEB C1 POP BC ;Restore last Y-value 03BEC D1 POP DE ;Restore last X-value 03BED 58 LD E,B ;E' = Y1, D' = X1 03BEE D9 EXX ;Switch register set 03BEF E5 PUSH HL ;Save PTP 03BF0 D9 EXX ;Switch register set 03BF1 CD1F3C CALL 3C1FH ;PLOT D , E TO H , L 03BF4 E1 POP HL ;Restore PTP 03BF5 CD7B3C CALL 3C7BH ;'TO' indicated ? 03BF8 28D6 JR Z,3BD0H ;Yes, get next X,Y-coordinates 03BFA F1 POP AF ;Restore old FCOLOUR value 03BFB 321343 LD (4313H),A ;and store it in system RAM 03BFE C9 RET ; Get new X,Y-coordinates ('TO' not at the start) 03BFF CD1C2B CALL 2B1CH ;Get X-coordinate 03C02 F5 PUSH AF ;Save X-coordinate 03C03 CF RST 08H ;Next character must be 03C04 2C DEFB ',' ;a comma 03C05 CD1C2B CALL 2B1CH ;Get Y-coordinate 03C08 F5 PUSH AF ;Save Y-coordinate 03C09 CD7B3C CALL 3C7BH ;'TO' indicated ? 03C0C 30CA JR NC,3BD8H ;Yes: get second pair of ;X,Y-coordinates 03C0E F1 POP AF ;No: Restore Y-coordinate 03C0F 321643 LD (4316H),A ;Save it in system RAM 03C12 57 LD D,A ;D = Y-coordinate 03C13 F1 POP AF ;Restore X-coordinate 03C14 321543 LD (4315H),A ;Save it in system RAM 03C17 5F LD E,A ;E = X-coordinate 03C18 EB EX DE,HL ;DE = PTP, H = Y-, L = X-coor. 03C19 D5 PUSH DE ;Save PTP 03C1A CD8A3B CALL 3B8AH ;PLOT L , H 03C1D 18D5 JR 3BF4H ;Restore PTP and previous ;FCOLOUR value ; SUB for PLOT ; PLOT D , E TO H , L (AF,BC,DE,HL) ; I: D = X-Coordinate of starting point ; E = Y-Coordinate of starting point ; H = X-Coordinate of ending point ; L = Y-Coordinate of ending point 03C1F CDC63C CALL 3CC6H ;PLOT H , L (plot end point) 03C22 DF RST 18H ;HL = DE ? (start and end are ;identical) 03C23 C8 RET Z ;Yes: done. 03C24 00 NOP ;-- 03C25 00 NOP 03C26 D5 PUSH DE ;Save X1,Y1 03C27 7B LD A,E ;A = Y1 03C28 95 SUB L ;A = Y1 - Y2 ;Negative result ? 03C29 DC8B3C CALL C,3C8BH ;Yes: negate result and set ;C-flag = 1 03C2C CB19 RR C ;Put C-flag in bit 7 of C 03C2E CB39 SRL C ;Shift C to the right 03C30 47 LD B,A ;B = Y-diff (always positive!) 03C31 CB39 SRL C ;Shift C to the right 03C33 CB39 SRL C ;Shift C to the right 03C35 7A LD A,D ;A = X1 03C36 94 SUB H ;A = X1 - X2 ;Negative result ? 03C37 DC8B3C CALL C,3C8BH ;Yes: negate result and set ;C-flag = 1 03C3A CB19 RR C ;Put C-flag in bit 7 of C 03C3C 37 SCF ;C-flag = 1 03C3D CB19 RR C ;Shift C to the right, bit 7=1 03C3F B8 CP B ;X-diff < Y-diff ? 03C40 384D JR C,3C8FH ;Yes: swap lower and upper ;nibble of C, E = X-diff, ;D = Y-diff 03C42 57 LD D,A ;No: D = X-diff 03C43 78 LD A,B 03C44 5F LD E,A ;E = Y-diff ; D now contains the bigger difference and E contains the smaller difference. ; Both nibbles of C indicate the angle; the upper nibble for D ; and the lower nibble for E 03C45 C5 PUSH BC ;Save angle 03C46 E5 PUSH HL ;Save X2,Y2 03C47 7A LD A,D ;A = bigger difference 03C48 4F LD C,A ;C = A 03C49 3E00 LD A,00H ;A = 0 03C4B 57 LD D,A ;D = 0 03C4C 47 LD B,A ;B = 0, so BC = bigger diff. 03C4D 67 LD H,A ;H = 0 03C4E 7B LD A,E ;A = smaller difference 03C4F 6F LD L,A ;L = A, so HL = smaller diff 03C50 CB25 SLA L ;HL = HL * 2 03C52 CB14 RL H 03C54 ED42 SBC HL,BC ;HL = smaller difference * 2 - ;bigger difference 03C56 CB21 SLA C ;BC = BC * 2 03C58 CB10 RL B 03C5A CB23 SLA E ;E = smaller difference * 2 03C5C CB12 RL D ;D = bigger difference * 2 03C5E 7C LD A,H ;A = H 03C5F D9 EXX ;Switch register sets 03C60 E1 POP HL ;Restore X2,Y2 03C61 C1 POP BC ;Restore angle 03C62 D1 POP DE ;Restore X1,Y1 ; Calculate and plot next point 03C63 CB27 SLA A ;A,7 into C-flag ;C-flag = 1 ? 03C65 D4A03C CALL NC,3CA0H ;No: change X2 and Y2 ;according to the angle of ;the smaller difference 03C68 CDAF3C CALL 3CAFH ;Change X2 and Y2 according to ;the angle of the bigger diff. 03C6B CDC63C CALL 3CC6H ;PLOT H , L 03C6E 7A LD A,D ;A = X1 03C6F BC CP H ;X1 = X2 ? 03C70 2003 JR NZ,3C75H ;No: set next point 03C72 7B LD A,E ;A = Y1 03C73 BD CP L ;Y1 = Y2 ? 03C74 C8 RET Z ;Yes: done. 03C75 D9 EXX ;Switch register sets 03C76 19 ADD HL,DE ;HL' = HL' + DE' 03C77 7C LD A,H ;A = H' 03C78 D9 EXX ;Switch register sets 03C79 18E8 JR 3C63H ;Set next point ; 'TO' indicated ? 03C7B 7E LD A,(HL) ;A = next character 03C7C FEBD CP 0BDH ;'TO' token ? 03C7E 200D JR NZ,3C8DH ;No: C-flag = 1 03C80 23 INC HL ;PTP + 1 03C81 AF XOR A ;C-flag = 0 03C82 C9 RET ; FCLS statement ; -------------- 03C83 2B DEC HL ;Adjust PTP 03C84 D7 RST 10H ;Get next non-space character 03C85 3E00 LD A,00H ;A = 00H 03C87 C34A38 JP 384AH ;Continue ar 384AH 03C8A 00 NOP ;-- ; A = -A, C-flag = 1 03C8B ED44 NEG ;A = -A 03C8D 37 SCF ;C-flag = 1 03C8E C9 RET ; Swap upper and lower nibble of C, E = X-diff, D = Y-diff (see 3C40H) 03C8F CD973C CALL 3C97H ;Swap nibbles of C 03C92 5F LD E,A ;E = X-diff 03C93 78 LD A,B ;A = Y-diff 03C94 57 LD D,A ;D = A 03C95 18AE JR 3C45H ;Back to 3C45H ; Swap upper and lower nibble of C 03C97 CB09 RRC C ;Rotate C left 4 times 03C99 CB09 RRC C 03C9B CB09 RRC C 03C9D CB09 RRC C 03C9F C9 RET ; Change X2 and Y2 according to the angle of the smaller difference 03CA0 CD973C CALL 3C97H ;Swap nibbles of C 03CA3 CDAF3C CALL 3CAFH ;Change X2 and Y2 03CA6 CD973C CALL 3C97H ;Swap nibbles of C 03CA9 D9 EXX ;Switch register sets 03CAA B7 OR A ;C-flag = 0 03CAB ED42 SBC HL,BC ;HL' = HL' - BC' 03CAD D9 EXX ;Switch register sets 03CAE C9 RET ; Change X2 and Y2 according to the angle of the bigger difference 03CAF CB79 BIT 7,C ;Change Y2 ? 03CB1 CABD3C JP Z,3CBDH ;Yes: continue at 3CBDH 03CB4 CB71 BIT 6,C ;Increase X2 ? 03CB6 C2BB3C JP NZ,3CBBH ;No: continue at 3CBBH 03CB9 24 INC H ;X2 + 1 03CBA C9 RET 03CBB 25 DEC H ;X2 - 1 03CBC C9 RET 03CBD CB71 BIT 6,C ;Increment Y2 ? 03CBF C2C43C JP NZ,3CC4H ;No: continue at 3CC4H 03CC2 2C INC L ;Y2 + 1 03CC3 C9 RET 03CC4 2D DEC L ;Y2 - 1 03CC5 C9 RET ; SUB for PLOT ; PLOT H , L (AF) ; ; I: H = X-coordinate ; L = Y-coordinate 03CC6 C5 PUSH BC ;Save registers 03CC7 D5 PUSH DE 03CC8 E5 PUSH HL 03CC9 7C LD A,H ;Swap H and L 03CCA 65 LD H,L 03CCB 6F LD L,A 03CCC CD8A3B CALL 3B8AH ;PLOT H , L 03CCF E1 POP HL ;Restore registers 03CD0 D1 POP DE 03CD1 C1 POP BC 03CD2 C9 RET ; XSHAPE statement ; ---------------- 03CD3 110303 LD DE,0303H ;Set bit mask for XSHAPE 03CD6 1808 JR 3CE0H ;Continue at 3CE0H ; NSHAPE statement ; ---------------- 03CD8 110000 LD DE,0000H ;Set bit mask for NSHAPE 03CDB 1803 JR 3CE0H ;Continue at 3CE0H ; SHAPE statement ; --------------- 03CDD 110003 LD DE,0300H ;Set bit mask for SHAPE 03CE0 ED531743 LD (4317H),DE ;Save bit mask 03CE4 2B DEC HL ;Adjust PTP 03CE5 D7 RST 10H ;Get next non-space character 03CE6 CD1C2B CALL 2B1CH ;Get X coordinate 03CE9 F5 PUSH AF ;Save X coordinate 03CEA CF RST 08H ;Next character must be 03CEB 2C DEFB ',' ;a comma 03CEC CD1C2B CALL 2B1CH ;Get Y coordinate 03CEF D1 POP DE ;D = X coordinate 03CF0 5F LD E,A ;E = Y coordinate 03CF1 E5 PUSH HL ;Save PTP 03CF2 C3A235 JP 35A2H ;Continue at 35A2H 03CF5 46 LD B,(HL) ;B = length of SHAPE table 03CF6 23 INC HL ;Update SHAPE table pointer 03CF7 3A1443 LD A,(4314H) ;A = SCALE factor 03CFA B7 OR A ;SCALE = 0 ? 03CFB 284B JR Z,3D48H ;Yes: done. 03CFD 4F LD C,A ;C = SCALE factor 03CFE 7E LD A,(HL) ;A = entry from SHAPE table 03CFF CB2F SRA A ;Take upper nibble 03D01 CB2F SRA A 03D03 CB2F SRA A 03D05 CB2F SRA A 03D07 08 EX AF,AF' 03D08 3E01 LD A,01H ;A' = 1 = flag for processing ;of first segment (every table ;entry contains 2 segments) 03D0A 08 EX AF,AF' 03D0B F5 PUSH AF ;Save table value 03D0C CB2F SRA A ;Direction: vertical ? (bit0=1) 03D0E 383D JR C,3D4DH ;Yes: continue at 3D4DH 03D10 CB2F SRA A ;Direction: left ? (bit1=1) 03D12 3836 JR C,3D4AH ;Yes: continue at 3D4AH 03D14 14 INC D ;X + 1 (direction: right) 03D15 C5 PUSH BC ;Save registers 03D16 D5 PUSH DE 03D17 E5 PUSH HL 03D18 6F LD L,A ;L = table value 03D19 3A1343 LD A,(4313H) ;A = FCOLOUR value 03D1C F5 PUSH AF ;Save it 03D1D 7D LD A,L ;Table value bacl to A 03D1E 2A1743 LD HL,(4317H) ;Take bit mask for operation 03D21 A4 AND H ;Mask colour value 03D22 AD XOR L 03D23 321343 LD (4313H),A ;Store as new FCOLOUR value 03D26 6A LD L,D ;Coordinates in HL 03D27 63 LD H,E 03D28 CD8A3B CALL 3B8AH ;PLOT L , H 03D2B F1 POP AF ;Restore original FCOLOUR value 03D2C 321343 LD (4313H),A ;Store it in system RAM 03D2F E1 POP HL ;Restore registers 03D30 D1 POP DE 03D31 C1 POP BC 03D32 F1 POP AF ;Restore table value 03D33 0D DEC C ;SCALE factor > 1 ? 03D34 20D5 JR NZ,3D0BH ;Yes: process same table value ;again (C times) 03D36 C5 PUSH BC ;Save table counter 03D37 08 EX AF,AF' 03D38 3D DEC A ;Flag = 1 ? 03D39 47 LD B,A ;B = flag - 1 03D3A 08 EX AF,AF' 03D3B 04 INC B ;B = 0 ? 03D3C 05 DEC B ;(then flag was 1) 03D3D C1 POP BC ;Restore table counter 03D3E 3A1443 LD A,(4314H) ;A = SCALE factor 03D41 4F LD C,A ;C = SCALE factor 03D42 7E LD A,(HL) ;A = table value ;Flag was 1 ? 03D43 28C6 JR Z,3D0BH ;Yes: process second segment 03D45 23 INC HL ;Table pointer + 1 03D46 10AF DJNZ 3CF7H ;Next entry in SHAPE table 03D48 E1 POP HL ;Restore PTP 03D49 C9 RET ; Direction: left 03D4A 15 DEC D ;X-coordinate - 1 03D4B 18C8 JR 3D15H ;Back to SCALE routine ; Direction: vertical 03D4D CB2F SRA A ;Direction: up ? (Bit1=1) 03D4F 3803 JR C,3D54H ;Yes: continue at 3D45H 03D51 1C INC E ;Y-coordinate + 1 (down) 03D52 18C1 JR 3D15H ;Back to SCALE routine ; Direction: up 03D54 1D DEC E ;Y-coordinate - 1 03D55 18BE JR 3D15H ;Back to SCALE routine ; SUB for tokenizing (see 392AH) ; Store Colour-Token into coded line. 03D57 0C INC C ;Character counter + 1 03D58 23 INC HL ;Buffer pointer + 1 03D59 EB EX DE,HL ;DE = buffer pointer (on coded ;text) ;HL = text pointer (on uncoded ;text) 03D5A 23 INC HL ;Text pointer + 1 03D5B 12 LD (DE),A ;Store token in buffer 03D5C 13 INC DE ;Buffer pointer + 1 03D5D 0C INC C ;Character counter + 1 03D5E C3CC1B JP 1BCCH ;Continue at 1BCCH ; PLAY statement ; -------------- 03D61 CF RST 08H ;Next character must be 03D62 28 DEFB '(' ;a '(' 03D63 CDC23F CALL 3FC2H ;Get channel number - 1 03D66 FE03 CP 03H ;In range (1 to 3) ? 03D68 D24A1E JP NC,1E4AH ;No: ?FC Error 03D6B F5 PUSH AF ;Save channel number 03D6C CF RST 08H ;Next character must be 03D6D 2C DEFB ',' ;a comma. 03D6E CDC43F CALL 3FC4H ;Get octave number - 1 03D71 FE08 CP 08H ;In range (1 to 8) ? 03D73 30F3 JR NC,3D68H ;No: ?FC Error 03D75 3C INC A ;Adjust octave number 03D76 F5 PUSH AF ;Save octave number 03D77 CF RST 08H ;Next character must be 03D78 2C DEFB ',' ;a comma 03D79 CD1C2B CALL 2B1CH ;Get note number 03D7C B7 OR A ;Note number zero ? 03D7D 283F JR Z,3DBEH ;Yes: continue at 3DBEH 03D7F FE1E CP 1EH ;In range (1 to 29) 03D81 30E5 JR NC,3D68H ;No: ?FC Error 03D83 CB27 SLA A ;A * 2 to get offset 03D85 5F LD E,A ;DE = note table offset 03D86 1600 LD D,00H 03D88 CF RST 08H ;Next character must be 03D89 2C DEFB ',' ;a comma 03D8A E5 PUSH HL ;Save PTP 03D8B 21CF3D LD HL,3DCFH ;HL -> note table 03D8E 19 ADD HL,DE ;Add offset 03D8F 5E LD E,(HL) ;DE = note frequency 03D90 23 INC HL 03D91 56 LD D,(HL) 03D92 E1 POP HL ;Restore PTP 03D93 C1 POP BC ;B = octave number 03D94 05 DEC B ;Adjust to use as counter ;Counter zero ? 03D95 2806 JR Z,3D9DH ;Yes: continue at 3D9DH 03D97 CB3A SRL D ;Do DE = DE / 2 for every 03D99 CB1B RR E ;octave: double frequency 03D9B 10FA DJNZ 3D97H ;Loop 03D9D F1 POP AF ;A = channel number 03D9E F5 PUSH AF ;Save it again 03D9F CB27 SLA A ;Calculate register address 03DA1 3C INC A ;A = A * 2 + 1 03DA2 CD2A3E CALL 3E2AH ;Write note freq. into PSG 03DA5 CD1C2B CALL 2B1CH ;Get volume value 03DA8 FE11 CP 11H ;In range (0 to 16) ? 03DAA 30BC JR NC,3D68H ;No: ?FC Error 03DAC D5 PUSH DE ;Save frequency setting 03DAD 1E38 LD E,38H ;Select: 03DAF 3E07 LD A,07H ;A = PSG register 7 03DB1 CD323E CALL 3E32H ;Write to PSG 03DB4 D1 POP DE ;Restore frequency setting 03DB5 F1 POP AF ;Restore channel number 03DB6 C608 ADD A,08H ;Calculate register address 03DB8 CD323E CALL 3E32H ;Write to PSG 03DBB CF RST 08H ;Next character must be 03DBC 29 DEFB ')' ;a ')' 03DBD C9 RET 03DBE CF RST 08H ;Next character must be 03DBF 2C DEFB ',' ;a comma 03DC0 CD1C2B CALL 2B1CH ;Get amplitude value 03DC3 FE11 CP 11H ;In range (0 to 16) ? 03DC5 D24A1E JP NC,1E4AH ;No: ?FC Error 03DC8 F1 POP AF ;Correct stack 03DC9 F1 POP AF ;Get channel number 03DCA 1E00 LD E,00H ;Amplitude = 0 03DCC C3B63D JP 3DB6H ;Continue at 3DB6H ; Note table containing the frequency register values for the PSG 03DCF 0000 DEFW 0000H 03DD1 5D0D DEFW 0D5DH 03DD3 E70B DEFW 0BE7H 03DD5 9B0A DEFW 0A9BH 03DD7 020A DEFW 0A02H 03DD9 EB08 DEFW 08EBH 03DDB F207 DEFW 07F2H 03DDD 1407 DEFW 0714H 03DDF 9C0C DEFW 0C9CH 03DE1 3C0B DEFW 0B3CH 03DE3 7309 DEFW 0973H 03DE5 6B08 DEFW 086BH 03DE7 8007 DEFW 0780H 03DE9 5D0D DEFW 0D5DH 03DEB 5D0D DEFW 0D5DH 03DED 5D0D DEFW 0D5DH 03DEF 4A09 DEFW 094AH 03DF1 9010 DEFW 1090H 03DF3 C00E DEFW 0EC0H 03DF5 240D DEFW 0D24H 03DF7 680C DEFW 0C68H 03DF9 0C0B DEFW 0B0CH 03DFB D809 DEFW 09D8H 03DFD C808 DEFW 08C8H 03DFF A00F DEFW 0FA0H 03E01 EB0D DEFW 0DEBH 03E03 B40B DEFW 0BB4H 03E05 700A DEFW 0A70H 03E07 4A09 DEFW 094AH 03E09 4808 DEFW 0848H 03E0B F6B7 OR 0B7H ;-- 03E0D C9 RET ; SUB for ? (not used) ; Write DE in X. If DE > 0 then VT = INT else VT = SNG 03E0E CB7A BIT 7,D ;D negative ? 03E10 2813 JR Z,3E25H ;No: Write DE in X as INT 03E12 CDEF0A CALL 0AEFH ;VT = SNG 03E15 7A LD A,D ;A <- D <- E <- 00H 03E16 53 LD D,E ;(Shift DE 8 bits to the left, 03E17 1E00 LD E,00H ;overflow in A) 03E19 B7 OR A ;C-flag = 0 03E1A 1F RRA ;ADE back 1 bit to the right 03E1B CB1A RR D 03E1D CB1B RR E 03E1F 0691 LD B,91H ;B = Exp for 2 ^ 17 03E21 CD6909 CALL 0969H ;SFLOAT (X) 03E24 C9 RET 03E25 EB EX DE,HL ;HL = DE 03E26 CD9A0A CALL 0A9AH ;Write HL to X as INT 03E29 C9 RET ; SUB for PSG programming ; Wwrites the 16 bit value in DE into PSG registers addressed by A ; ; I: A = register number of MSB data register ; DE = register data 03E2A 47 LD B,A ;Save register number in B 03E2B D3F8 OUT (0F8H),A ;Select PSG register 03E2D 7A LD A,D ;Register data from D to A 03E2E D3F9 OUT (0F9H),A ;Write data in PSG register 03E30 05 DEC B ;register number - 1 03E31 78 LD A,B ;Put it in A ; Now write LSB register with value in E 03E32 D3F8 OUT (0F8H),A ;Select PSG register 03E34 7B LD A,E ;Register data from E to A 03E35 D3F9 OUT (0F9H),A ;Write data in PSG register 03E37 C9 RET ; PAINT statement ; --------------- 03E38 AF XOR A ;Number of parameters = 0 03E39 2B DEC HL ;Adjust PTP 03E3A 3C INC A ;Number of parameters + 1 03E3B 08 EX AF,AF' ;A' = counter 03E3C D7 RST 10H ;Get next non-space character 03E3D CD1C2B CALL 2B1CH ;Get next parameter 03E40 F5 PUSH AF ;Save parameter on stack 03E41 2B DEC HL ;Adjust PTP 03E42 D7 RST 10H ;Get next non-space character ;End reached ? 03E43 280C JR Z,3E51H ;Yes: continue at 3E51H 03E45 FE2C CP 2CH ;Comma ? 03E47 2005 JR NZ,3E4EH ;No: ?SN Error 03E49 08 EX AF,AF' ;A = counter 03E4A FE05 CP 05H ;Maximum number of parameters ;(4) exceeded ? 03E4C 38EC JR C,3E3AH ;No: continue at 3E3AH 03E4E C39719 JP 1997H ;?SN Error ; Evaluate the parameters on stack 03E51 08 EX AF,AF' ;A = counter 03E52 FE03 CP 03H ;At least 2 parameters ? 03E54 38F8 JR C,3E4EH ;No: ?SN error 03E56 3D DEC A ;Correct A to get the number 03E57 3D DEC A ;border colours 03E58 321D43 LD (431DH),A ;Store this in A 03E5B 111843 LD DE,4318H ;DE -> system RAM area ;for PAINT statement 03E5E 47 LD B,A ;Number of border colours 03E5F 83 ADD A,E ;DE -> last byte in 03E60 5F LD E,A ;system RAM area for PAINT 03E61 F1 POP AF ;Get value from stack 03E62 3D DEC A ;-1 03E63 FE04 CP 04H ;Colour value in range ? 03E65 D24A1E JP NC,1E4AH ;No: ?FC Error 03E68 12 LD (DE),A ;Store in system RAM 03E69 1B DEC DE ;pointer - 1 03E6A 10F5 DJNZ 3E61H ;Next parameter 03E6C F1 POP AF ;A = Y coordinate 03E6D FE66 CP 66H ;Y coordinate in range ? 03E6F 30F4 JR NC,3E65H ;No: ?FC Error 03E71 57 LD D,A ;D = Y coordinate 03E72 F1 POP AF ;A = X coordinate 03E73 FEA0 CP 0A0H ;X coordinate in range ? 03E75 30EE JR NC,3E65H ;No: ?FC Error 03E77 5F LD E,A ;E = X coordinate 03E78 E5 PUSH HL ;Save PTP 03E79 21FFFF LD HL,0FFFFH ;HL = -1 (flag for routine end) 03E7C E5 PUSH HL ;Save flag 03E7D EB EX DE,HL ;HL = Y,X ; Set next point 03E7E 221E43 LD (431EH),HL ;Save coordinates in system RAM 03E81 CD043F CALL 3F04H ;Set FCOLOUR if border not ;reached 03E84 2806 JR Z,3E8CH ;Continue at 3E8CH when border ;has been reached 03E86 2D DEC L ;X - 1 03E87 3EFF LD A,0FFH ;A = -1 03E89 BD CP L ;X = -1 ? 03E8A 20F5 JR NZ,3E81H ;No: next point 03E8C 2C INC L ;X + 1 03E8D 7D LD A,L ;A = X-coordinate 03E8E 322043 LD (4320H),A ;Save it (left edge) 03E91 2A1E43 LD HL,(431EH) ;Last coordinates to HL 03E94 2C INC L ;X + 1 03E95 3EA0 LD A,0A0H ;A = 160 03E97 BD CP L ;X = 160 ? 03E98 2805 JR Z,3E9FH ;Yes: continue at 3E9FH 03E9A CD043F CALL 3F04H ;Set FCOLOUR if border not ;reached 03E9D 20F5 JR NZ,3E94H ;If border not reached: ;next point 03E9F 2D DEC L ;X - 1 03EA0 7D LD A,L ;A = X-coordinate 03EA1 322143 LD (4321H),A ;Save it (right edge) 03EA4 3A1F43 LD A,(431FH) ;A = Y-coordinate 03EA7 A7 AND A ;Y = 0 ? 03EA8 280C JR Z,3EB6H ;Yes: continue at 3EB6H 03EAA 3D DEC A ;Y - 1 03EAB 67 LD H,A ;H = Y-coordinate 03EAC CDC33E CALL 3EC3H ;Check Y-coordinate 03EAF 3A1F43 LD A,(431FH) ;A = Y-coordinate 03EB2 FE65 CP 65H ;Y = 102 ? 03EB4 2805 JR Z,3EBBH ;Yes: continue at 3EBBH 03EB6 3C INC A ;Y + 1 03EB7 67 LD H,A ;H = Y-coordinate 03EB8 CDC33E CALL 3EC3H ;Check Y-coordinate 03EBB 3EFF LD A,0FFH ;A = -1 03EBD E1 POP HL ;Restore Y-coordinate 03EBE BC CP H ;Flag reached ? 03EBF 20BD JR NZ,3E7EH ;No: next point 03EC1 E1 POP HL ;Restore PTP 03EC2 C9 RET ; Check Y-coordinate ; ; I: H = Y-coordinate 03EC3 0EFF LD C,0FFH ;C = 255 (flag) 03EC5 3A2043 LD A,(4320H) ;A = X-coordinate of left edge 03EC8 6F LD L,A ;L = left edge 03EC9 3A2143 LD A,(4321H) ;A = X-coordinate right edge 03ECC 95 SUB L ;A = distance between left ;and right edge 03ECD 47 LD B,A ;B = distance 03ECE 04 INC B ;B + 1 03ECF C8 RET Z ;Done when both edges are ;identical ; Check complete line of new Y-coordinate 03ED0 C5 PUSH BC ;Save register 03ED1 E5 PUSH HL 03ED2 CDF13E CALL 3EF1H ;Border colour at L,H reached ? 03ED5 E1 POP HL ;Restore registers 03ED6 C1 POP BC 03ED7 2006 JR NZ,3EDFH ;No: continue at 3EDFH 03ED9 0EFF LD C,0FFH ;Yes: flag = 255 03EDB 2C INC L ;X + 1 03EDC 10F2 DJNZ 3ED0H ;Check next X-coordinate 03EDE C9 RET ; Border colour not reaches at new Y-coordinate 03EDF AF XOR A ;A = 0 03EE0 B9 CP C ;Flag = 0 ? ;(This area already recognized) 03EE1 28F8 JR Z,3EDBH ;Yes: continue at 3EDBH 03EE3 0E02 LD C,02H ;C = 2 (for 1963H) 03EE5 C5 PUSH BC ;Save BC 03EE6 CD6319 CALL 1963H ;Stack has still room enough ? 03EE9 C1 POP BC ;Restore BC 03EEA D1 POP DE ;RET address to DE 03EEB E5 PUSH HL ;Save X,Y coordinates 03EEC D5 PUSH DE ;Put RET address back on stack 03EED 0E00 LD C,00H ;Flag = 0 03EEF 18EA JR 3EDBH ;Continue at 3EDBH ; Border colour reached at point L,H ? ; Z-flag = 0: No ; Z-flag = 1: Yes 03EF1 CD3A3F CALL 3F3AH ;A = CPOINT( L,H ) 03EF4 E5 PUSH HL ;Save coordinated 03EF5 211D43 LD HL,431DH ;HL -> number of border colours 03EF8 46 LD B,(HL) ;B = number of border colours 03EF9 211943 LD HL,4319H ;HL -> border colour table 03EFC BE CP (HL) ;Border colour reached ? 03EFD 2803 JR Z,3F02H ;Yes: done. 03EFF 23 INC HL ;Pointer + 1 03F00 10FA DJNZ 3EFCH ;Check next colour 03F02 E1 POP HL ;Restore coordinates 03F03 C9 RET ; Set new colour for point L,H in case border colour is not reached yet. 03F04 E5 PUSH HL ;Save coordinates 03F05 CDF13E CALL 3EF1H ;Border colour reached ? 03F08 F5 PUSH AF ;Save flags 03F09 41 LD B,C ;B = X MOD 4 (from CPOINT) 03F0A 3A1943 LD A,(4319H) ;A = new FCOLOUR 03F0D 4F LD C,A ;C = A 03F0E C4B03B CALL NZ,3BB0H ;If border colour not reached: ;set new colour 03F11 F1 POP AF ;Restore flags 03F12 E1 POP HL ;Restore coordinates 03F13 C9 RET ; Old KEYPAD1 routine (no longer used) 03F14 16FE LD D,0FEH 03F16 1802 JR 3F1AH ; Old KEYPAD2 routine (no longer used) 03F18 16F7 LD D,0F7H 03F1A CD873A CALL 3A87H 03F1D 6F LD L,A 03F1E 2600 LD H,00H 03F20 C9 RET ; SUB for processing expressions (at 2337H) ; Continuation of 3F7AH: interception of Colour-BASIC functions 03F21 FE91 CP 91H ;Token for SOUND ? 03F23 CAF436 JP Z,36F4H ;Yes: continue at 36F4H 03F26 FE8A CP 8AH ;Token for SCALE ? 03F28 CA0A37 JP Z,370AH ;Yes: continue at 370AH 03F2B FE80 CP 80H ;Token for COLOUR ? 03F2D CA6136 JP Z,3661H ;Yes: continue at 3661H 03F30 C30525 JP 2505H ;Continue at 2505H ; VERIFY statement ; ---------------- 03F33 23 INC HL ;PTP + 1 03F34 C3292C JP 2C29H ;Continue at 2C29H 03F37 6E LD L,(HL) ;-- 03F38 63 LD H,E 03F39 77 LD (HL),A ; SUB for CPOINT and PAINT ; This routine takes the colour value for pixel at (X,Y) ; ; I: L = X coordinate ; H = Y coordinate ; O: A = colour value (1 to 4) - 1 03F3A 7D LD A,L ;A = X coordinate 03F3B 6C LD L,H ;HL = Y coordinate 03F3C 2600 LD H,00H 03F3E 54 LD D,H ;DE = Y coordinate 03F3F 5D LD E,L 03F40 29 ADD HL,HL ;Multiply Y coordinate by 40 03F41 29 ADD HL,HL ;(40 bytes/ line) 03F42 19 ADD HL,DE ;Result in HL 03F43 29 ADD HL,HL ;HL = offset from start of FGR 03F44 29 ADD HL,HL ;page to start of line (Y) 03F45 29 ADD HL,HL 03F46 5F LD E,A ;Multiply X coordinate by 4 03F47 CB3B SRL E ;(4 pixels/byte) 03F49 CB3B SRL E ;E = offset from start of line ;to X 03F4B 1648 LD D,48H ;DE = start of FGR page + E 03F4D 19 ADD HL,DE ;HL -> FGR memory location ;that contains (X,Y) 03F4E E603 AND 03H ;Now make counter for 03F50 3C INC A ;getting the proper 2 bits for 03F51 4F LD C,A ;X coordinate within the byte 03F52 47 LD B,A ;Result in B as counter 03F53 7E LD A,(HL) ;Load byte from FGR memory 03F54 07 RLCA ;Rotate until the proper 2 03F55 07 RLCA ;bits are in bit 1 and 0 03F56 10FC DJNZ 3F54H 03F58 E603 AND 03H ;Clear bits 7 to 2 03F5A C9 RET 03F5B 00 NOP ;-- ; X = CPOINT(x-coordinate,y-coordinate) 03F5C CF RST 08H ;Next character must be 03F5D 28CD DEFB ')' ;a '(' 03F5E CD1C2B CALL 2B1CH ;Get X coordinate 03F61 F5 PUSH AF ;and put it on stack 03F62 CF RST 08H ;Next character must be 03F63 2C DEFB ',' ;a comma 03F64 CD1C2B CALL 2B1CH ;Get Y coordinate 03F67 F5 PUSH AF ;and put it on stack 03F68 CF RST 08H ;Next character must be 03F69 29 DEFB ')' ;a ')' 03F6A D1 POP DE ;D = Y coordinate 03F6B F1 POP AF ;A = X coordinate 03F6C EB EX DE,HL ;H = Y coordinate, DE = PTP 03F6D D5 PUSH DE ;Save PTP 03F6E 6F LD L,A ;L = X coordinate 03F6F CD3A3F CALL 3F3AH ;Get FGR memory contents for ;specified coordinate 03F72 6F LD L,A ;HL = A 03F73 2600 LD H,00H 03F75 CD9A0A CALL 0A9AH ;Write HL to X as INT 03F78 E1 POP HL ;Restore PTP 03F79 C9 RET ; SUB for processing of expressions ; Interception of Colour-BASIC functions 03F7A CAFE27 JP Z,27FEH ;USR token found: ;Continue at 27FEH 03F7D FEFF CP 0FFH ;Colour-BASIC token ? 03F7F C20425 JP NZ,2504H ;No: continue at 2504H 03F82 D7 RST 10H ;Increase PTP, next token in A 03F83 23 INC HL ;PTP + 1 03F84 FE82 CP 82H ;Token for KEYPAD ? 03F86 CA0F3A JP Z,3A0FH ;Yes: continue at 3A0FH 03F89 FE8F CP 8FH ;Token for CPOINT ? 03F8B 28CF JR Z,3F5CH ;Yes: continue at 3F5CH 03F8D FE83 CP 83H ;Token for JOY ? 03F8F CA1F3A JP Z,3A1FH ;Yes: continue at 3A1FH 03F92 C3213F JP 3F21H ;Continue at 3F21H ; SOUND statement ; --------------- 03F95 CD1C2B CALL 2B1CH ;Get PSG register number 03F98 FE10 CP 10H ;In range (0 to 15) ? 03F9A D24A1E JP NC,1E4AH ;No: ?FC Error 03F9D F5 PUSH AF ;Save PSG register number 03F9E CF RST 08H ;Next character must be 03F9F 2C DEFB ',' ;a comma 03FA0 CD1C2B CALL 2B1CH ;Get register data 03FA3 5F LD E,A ;E = register data 03FA4 F1 POP AF ;A = PSG register number 03FA5 C3323E JP 3E32H :Write to PSG ; CHAR statement ; -------------- 03FA8 CDC23F CALL 3FC2H ;A = char value - 1 03FAB FE04 CP 04H ;Value in range (1 to 4) ? 03FAD D24A1E JP NC,1E4AH ;No: ?FC Error 03FB0 E603 AND 03H ;Mask bits 03FB2 07 RLCA ;Rotate to proper position 03FB3 07 RLCA 03FB4 07 RLCA 03FB5 47 LD B,A ;Put it in B 03FB6 3A1C43 LD A,(431CH) ;A = port 255 output status 03FB9 E6E7 AND 0E7H ;Clear the old bits for CHAR 03FBB B0 OR B ;Set the new bits 03FBC D3FF OUT (0FFH),A ;Activate new CHAR 03FBE 321C43 LD (431CH),A ;and store status in system RAM 03FC1 C9 RET ; Process expression at (HL) and return result - 1 in A ; ; I: HL = PTP on BASIC expression ; O: A = result - 1 03FC2 2B DEC HL ;PTP - 1 03FC3 D7 RST 10H ;Get next non-space character 03FC4 CD1C2B CALL 2B1CH ;Get result 03FC7 3D DEC A ;A - 1 03FC8 C9 RET ; Set character and cursor colour (not used) 03FC9 CD7A30 CALL 307AH 03FCC 23 INC HL 03FCD CD7A30 CALL 307AH 03FD0 2B DEC HL 03FD1 C9 RET ; SUB for LIST (see 2B91H) ; No token found. Output a text-constant ? 03FD2 FE22 CP 22H ;Text-constant ? 03FD4 C2892B JP NZ,2B89H ;No: return to LIST 03FD7 03 INC BC ;Buffer pointer + 1 03FD8 15 DEC D ;Counter - 1 03FD9 C8 RET Z ;Return when line buffer full 03FDA 7E LD A,(HL) ;Get character 03FDB FE22 CP 22H ;End of text reached ? 03FDD 23 INC HL ;Text pointer + 1 03FDE 02 LD (BC),A ;Put character in buffer 03FDF CA892B JP Z,2B89H ;Yes: return to LIST 03FE2 18F3 JR 3FD7H ;Next character ; BGRD statement ; -------------- 03FE4 2B DEC HL ;Adjust PTP 03FE5 D7 RST 10H ;Get next non-space character 03FE6 0604 LD B,04H ;Set BGRD value to 4 ;parameter present after BGRD ? 03FE8 CABD38 JP Z,38BDH ;No: continue at 38BDH 03FEB CDC23F CALL 3FC2H ;A = bgrd value - 1 03FEE FE04 CP 04H ;Value in range (1 to 4) ? 03FF0 D24A1E JP NC,1E4AH ;No: ?FC Error 03FF3 E603 AND 03H ;Mask bits 03FF5 0F RRCA ;Rotate to proper position 03FF6 0F RRCA 03FF7 47 LD B,A ;Put result in B 03FF8 3A1C43 LD A,(431CH) ;A = port 255 output status 03FFB E63F AND 3FH ;Clear old bits for BGRD n 03FFD C3C238 JP 38C2H ;Continue at 38C2H ; End of BASIC interpreter