M100 TS-DOS ROM RST 7 Handlers: Difference between revisions
From Bitchin100 DocGarden
Jump to navigationJump to search
(icuEhlHjnrzOdNG) |
No edit summary |
||
(2 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
== TS-DOS Model 100/102 ROM RST 7 Handlers == | |||
This is the code for the DOS-ON RST 7 Hooks, along with the TPDD1 Rename functionality. | |||
<pre> | |||
; ========================================================================================= | |||
; Load default RST 7 vector table values | |||
; ========================================================================================= | |||
3FFAH LXI 7FF3H ; Address of a RET opcode in ROM | |||
3FFDH SHLD FAE6H ; Save as hook for RST 7,0Ch?? We didn't modify this one | |||
4000H SHLD FB08H ; Save as hook for RST 7,2Eh - DSKI$ function | |||
4003H SHLD FB0AH ; Save as hook for RST 7,30h - OPEN/CLOSE/PRINT/LINE INPUT | |||
4006H SHLD FAF0H ; Save as hook for RST 7,16h - SAVE | |||
4009H SHLD FAF4H ; Save as hook for RST 7,1Ah - RUN | |||
400CH LXI H,08DBH ; Load address of "Generate FC Error" in Main ROM | |||
400FH SHLD FB2CH ; Save as hook for RST 7,52h - LFILES | |||
4012H SHLD FB32H ; Save as hook for RST 7,58h - KILL | |||
4015H SHLD FB34H ; Save as hook for RST 7,5Ah - NAME | |||
4018H SHLD FB36H ; Save as hook for RST 7,5Ch - SAVEM | |||
401BH SHLD FB38H ; Save as hook for RST 7,5Eh - LOADM and RUNM | |||
401EH RET | |||
; ========================================================================================= | |||
; Install our RST 7 hook for all RST 7 calls we are interested in. This uses the "ON TIME" | |||
; time storage location to copy a 6-byte routine to switch to OptROM and call our | |||
; RST 7 "switch" statement in our ROM. This means ON TIME can't be used when using | |||
; the DOS-ON feature. | |||
; ========================================================================================= | |||
401FH CALL 3FFAH ; Load default RST 7 vector table values | |||
4022H LXI H,4084H ; Point to RST 7 RAM hook routine | |||
4025H LXI D,F93DH ; Point Time for ON TIME interrupt to use as our hook routine | |||
4028H LXI B,0006H ; Copy our RST 7 hood to the "ON TIME" time location | |||
402BH CALL 4A05H ; Move BC bytes from HL to DE - copy our hook to RAM | |||
402EH LXI H,F93DH ; Load address of "ON TIM" time where our hook was copied | |||
4031H SHLD FAF4H ; Use our RAM RST 7 Hook for RST 7,1Ah - RUN | |||
4034H SHLD FAF0H ; Use our RAM RST 7 Hook for RST 7,16h - SAVE | |||
4037H SHLD FB38H ; Use our RAM RST 7 Hook for RST 7,5Eh - LOADM and RUNM | |||
403AH SHLD FB36H ; Use our RAM RST 7 Hook for RST 7,5Ch - SAVEM | |||
403DH SHLD FB08H ; Use our RAM RST 7 Hook for RST 7,2Eh - DSKI$ | |||
4040H SHLD FB0AH ; Use our RAM RST 7 Hook for RST 7,30h - OPEN/CLOSE/PRINT/INPUT | |||
4043H SHLD FB2CH ; Use our RAM RST 7 Hook for RST 7,52h - LFILES | |||
4046H SHLD FB32H ; Use our RAM RST 7 Hook for RST 7,58h - KILL | |||
4049H SHLD FB34H ; Use our RAM RST 7 Hook for RST 7,5Ah - NAME | |||
404CH RET | |||
; ========================================================================================= | |||
; Process jump to custom RST 7 Hook routine from Main ROM | |||
; ========================================================================================= | |||
404DH PUSH PSW ; Preserve PSW | |||
404EH LDA FAC9H ; Get address of last RST 38H call argument | |||
4051H CPI 1AH ; RST 7,1Ah Hook - RUN statement | |||
4053H JZ 4451H | |||
4056H CPI 16H ; RST 7,16h Hook - SAVE statement | |||
4058H JZ 44E7H | |||
405BH CPI 5EH ; RST 7,5Eh Hook - LOADM and RUNM statement | |||
405DH JZ 43C1H | |||
4060H CPI 5CH ; RST 7,5Ch Hook - SAVEM statement | |||
4062H JZ 440DH | |||
4065H CPI 2EH ; RST 7,2Eh Hook - DSKI$ function | |||
4067H JZ 4324H | |||
406AH CPI 30H ; RST 7,30h Hook - OPEN/CLOSE/PRINT/LINE INPUT satement | |||
406CH JZ 451DH | |||
406FH CPI 52H ; RST 7,52h Hook - LFILES | |||
4071H JZ 4346H | |||
4074H CPI 58H ; RST 7,58h Hook - KILL | |||
4076H JZ 4377H | |||
4079H CPI 5AH ; RST 7,5Ah Hook - NAME statement | |||
407BH JZ 4396H | |||
407EH POP PSW ; Restore stack frame | |||
407FH MVI E,02H ; Prepare to generate "SN" error | |||
4081H JMP 4C37H ; Generate error in E | |||
; ========================================================================================= | |||
; RST 7 Handler copied to RAM for DOS-ON | |||
; ========================================================================================= | |||
4084H CALL FAA4H ; Call RAM hook to switch to OptROM | |||
4087H JMP 404DH ; Jump to TS-DOS RST 7 handler in OptROM | |||
; ========================================================================================= | |||
; Open TPDD file for Read Mode. File already stored in TX buffer. | |||
; ========================================================================================= | |||
408AH LXI H,0101H ; Load "Open file" opcode | |||
408DH MVI A,03H ; Load OPEN_READ mode into A | |||
408FH STA FCE8H ; Save A in TX data storage (mode location) | |||
4092H JMP 409BH ; Send Request in HL and await response - Open File | |||
; ========================================================================================= | |||
; Send TPDD Write File opcode using RX buffer with length in A | |||
; ========================================================================================= | |||
4095H MOV H,A ; Move length to H | |||
4096H MVI L,04H ; Load TPDD_WRITE opcode to L | |||
4098H JMP 40A7H ; Send TX packet using RX buffer | |||
; ========================================================================================= | |||
; Send Request in HL and await response | |||
; ========================================================================================= | |||
409BH CALL 4822H ; Send TPDD Command/Len in HL | |||
409EH CALL 49F0H ; Wait for data to be ready | |||
40A1H CALL 47CCH ; Copy Receive RX packet routine to RAM and execute it | |||
40A4H JMP 47F8H ; Check RX packet for Normal Response & report errors | |||
; ========================================================================================= | |||
; Use RX buffer to send a TX packet (used to send data). Opcode/len in HL | |||
; ========================================================================================= | |||
40A7H SHLD FD02H ; Save Opcode/len to RX buffer | |||
40AAH LXI H,FD02H ; Storage for RX packet | |||
40ADH CALL 4828H ; Send TPDD pointed to by HL | |||
40B0H CALL 47CCH ; Receive a packet | |||
40B3H JMP 47F8H ; Check RX packet for Normal Response & report errors | |||
; ========================================================================================= | |||
; Send TPDD_READ data opcode and recieve response | |||
; ========================================================================================= | |||
40B6H LXI H,0003H ; Load TPDD_READ opcode | |||
40B9H CALL 4822H ; Send TPDD Command/Len in HL | |||
40BCH CALL 47CCH ; Receive a packet | |||
40BFH LDA FD03H ; Get length byte from RX buffer | |||
40C2H LXI H,FD04H ; Point to return data addres in RX buffer | |||
40C5H CPI 80H ; Test for maximum read length | |||
40C7H RET | |||
; ========================================================================================= | |||
; Write HL bytes of data from (DE) to TPDD | |||
; ========================================================================================= | |||
40C8H PUSH D ; Push address of write-data to stack | |||
40C9H PUSH H ; Push length of data to the stack | |||
40CAH CALL 4101H ; Test free Disk space and issue TPDD_OPEN request | |||
40CDH POP H ; Get address of data from stack | |||
40CEH SHLD FCD5H ; Save length as remaining length to write | |||
40D1H POP H ; Get address of data to write to TPDD from stack | |||
40D2H LXI D,FD04H ; Point to RX buffer to copy write data | |||
40D5H LXI B,0080H ; Prepare to copy 128 bytes of data to the RX buffer | |||
; ========================================================================================= | |||
; Write BC bytes of data from (HL) to (DE) and write to TPDD, DE=RX buffer data pointer | |||
; ========================================================================================= | |||
40D8H CALL 4A05H ; Move BC bytes from M to (DE) with increment | |||
40DBH PUSH H ; Push the updated address to the stack | |||
40DCH LHLD FCD5H ; Get the remaining lenth left to write | |||
40DFH LXI B,0080H ; Prepare to subtract 128 from the length | |||
40E2H DSUB ; Subtract 128 bytes from remaining length to write | |||
40E3H JC 40F4H ; Jump out of loop if less than 128 bytes remaining | |||
40E6H JZ 40F4H ; Jump out of loop if exactly 128 bytes remaining | |||
40E9H SHLD FCD5H ; Save updated length left to write for next pass | |||
40ECH MVI A,80H ; Prepare to write 128 bytes to TPDD | |||
40EEH CALL 4095H ; Send TPDD Write File opcode using RX buffer with length in A | |||
40F1H JMP 40D1H ; Jump to send next packet of 128 bytes | |||
; ========================================================================================= | |||
; Write remaining bytes (128 or less from above) to TPDD | |||
; ========================================================================================= | |||
40F4H POP H ; Clear stack of unneeded updated source address | |||
40F5H LDA FCD5H ; Load A with remainder of bytes to be sent | |||
40F8H CALL 4095H ; Send TPDD Write File opcode using RX buffer with length in A | |||
40FBH LXI H,0002H ; Load TPDD_CLOSE opcode in HL | |||
40FEH JMP 409BH ; Send Request in HL and await response | |||
; ========================================================================================= | |||
; Test if enough space on disk for HL bytes and issue Open request, error if disk full | |||
; ========================================================================================= | |||
4101H LXI D,0500H ; Load decimal 1280 to calculate sector number | |||
4104H XCHG ; Swap HL/DE to perform size/bytes_per_sector | |||
4105H CALL 4C1BH ; Signed integer divide (FAC1=DE/HL) | |||
4108H LDA FD1FH ; Get number of free sectors on disk | |||
410BH SUB L ; Compare required sectors with free space to see if enough room | |||
410CH JC 4881H ; Disk Full Error | |||
410FH JZ 4881H ; Disk Full Error | |||
4112H LDA FCD6H ; Load open mode (new, append, etc.) | |||
4115H STA FCE8H ; Save file open mode to TX buffer | |||
4118H LXI H,0101H ; Load TPDD_OPEN opcode | |||
411BH JMP 409BH ; Send Request in HL and await response | |||
; ========================================================================================= | |||
; Insert BC spaces at address of RAM file being loaded/run | |||
; ========================================================================================= | |||
411EH LHLD FCE2H ; Load address of file being processed | |||
4121H CALL 4C0BH ; Insert BC spaces at M | |||
4124H JC 488AH ; RAM full error | |||
; ========================================================================================= | |||
; Open TPDD file and read data to file address being processed | |||
; ========================================================================================= | |||
4127H LHLD FCE2H ; Get address of file being processed | |||
412AH PUSH H ; Save address on stack | |||
412BH CALL 408AH ; Open TPDD file for Read Mode | |||
412EH CALL 40B6H ; Send TPDD_READ data opcode and recieve response | |||
4131H MOV C,A ; Move read length to C | |||
4132H MVI B,00H ; Clear MSB of copy length | |||
4134H POP D ; Restore address to write data | |||
; ========================================================================================= | |||
; Write BC bytes from M to DE and subtract BC from total file size | |||
; ========================================================================================= | |||
4135H CALL 4A05H ; Move BC bytes from M to (DE) with increment | |||
4138H PUSH D ; Save updated address to stack | |||
4139H LDA FD03H ; Get length byte from RX buffer | |||
413CH LHLD FCDDH ; Get total file size from storage | |||
413FH MOV C,A ; Load count of bytes transfered this block | |||
4140H MVI B,00H ; Clear MSB of count | |||
4142H DSUB ; Subtract this block from total file length | |||
4143H SHLD FCDDH ; Save remaining bytes to be read back to temp storage | |||
4146H JC 414EH ; Branch if too many bytes read | |||
4149H MOV A,L ; Load LSB to A to test for zero | |||
414AH ORA H ; OR MSB to test for zero | |||
414BH JNZ 412EH ; Branch to read more data if not zero | |||
414EH POP D ; Pop address from stack - cleanup | |||
414FH RET | |||
; ========================================================================================= | |||
; Write data to FDC Emulation mode physical/logical sector | |||
; ========================================================================================= | |||
4150H LDA FCDDH ; Get physical sector number | |||
4153H CPI 01H ; Test if physical sector is #1 | |||
4155H RZ ; Return if trying to write to sector 1 - reserved!!! | |||
4156H CALL 4998H ; Flush RX queue and discard | |||
4159H MVI A,57H ; Load FDC opcode for "W"rite sector | |||
415BH STA FCD3H ; Save the FDC emulation mode opcode | |||
415EH CALL 42CEH ; Send FDC emulation mode opcode | |||
4161H CALL 4998H ; Flush RX queue and discard | |||
4164H CALL 4176H ; Increment to next logical/physical sector | |||
4167H LHLD FCE4H ; FDC Emulation data pointer address | |||
416AH CALL 48D9H ; Send BC bytes to RS-232 from (HL) using XON/XOFF | |||
416DH SHLD FCE4H ; LCD Buffer address of current file selection | |||
4170H CALL 42EEH ; Read FDC Emulation mode response | |||
4173H JMP 4150H ; Jump to write next sector ??? | |||
; ========================================================================================= | |||
; Increment to next logical/physical sector | |||
; ========================================================================================= | |||
4176H LDA FD09H ; Get byte 7 from the RX buffer (logical sector length) | |||
4179H CALL 4191H ; Get FDC Emulation RAM buffer sector length based on response | |||
417CH CPI 35H ; Test if RAM Buffer logical sector length is "500" (1280) | |||
417EH JZ 4189H ; Just update physical sector if RAM length = physical sector len | |||
4181H LXI H,FCDEH ; Load pointer to logical sector value | |||
4184H INR M ; Increment to next logical sector | |||
4185H MOV A,M ; Get the next logical sector value | |||
4186H CPI 14H ; Test if logical sector = 20 (There are 20 64-byte logical sectors) | |||
4188H RNZ ; Return if not paat end of physical sector | |||
4189H LXI H,FCDDH ; Point to physical sector storage | |||
418CH INR M ; Increment to next physical sector - we "rolled over" | |||
418DH INX H ; Point to logical sector | |||
418EH MVI M,01H ; Start with logical sector #1 in new physical sector | |||
4190H RET | |||
; ========================================================================================= | |||
; Get FDC Emulation RAM buffer sector length based on response code in A | |||
; ========================================================================================= | |||
4191H LXI B,0500H ; Initialize to 1280 byte sector length | |||
4194H CPI 35H ; Compare response to test for "500" | |||
4196H RZ ; Return if match | |||
4197H LXI B,0040H ; Sector lenth not 1280, must be 64 bytes | |||
419AH RET | |||
; ========================================================================================= | |||
; Send TPDD opcode 0x08 - Go to FDC emulation mode | |||
; ========================================================================================= | |||
419BH LXI H,0008H ; Prepare to send Opcode 0x08 (FDC Emulation Mode) | |||
419EH CALL 4822H ; Send TPDD Command/Len in HL | |||
41A1H CALL 49D3H ; Send 0x0D to RS-232 and Delay 3ms | |||
41A4H JMP 4998H ; Flush RX queue and discard | |||
; ========================================================================================= | |||
; Rename the TPDD file whose name is in "current BASIC program" | |||
; ========================================================================================= | |||
41A7H LXI H,FC93H ; Filename of current BASIC program | |||
41AAH LXI D,FCE8H ; Point to data area in TX buffer | |||
41ADH LXI B,0006H ; Move 6 bytes of filename data | |||
; ========================================================================================= | |||
; Rename the TPDD file whose name is in (HL) | |||
; ========================================================================================= | |||
41B0H CALL 4A05H ; Move BC bytes from M to (DE) with increment | |||
41B3H LDA FCCBH ; NADSBox / Desklink / TPDD2 flag | |||
41B6H ANA A ; Test for TPDD server | |||
41B7H JNZ 4258H ; Send TPDD_RENAME opcode and check response | |||
; ========================================================================================= | |||
; Rename on a TPDD. I'm guessing the drive will allow changing a name to something | |||
; that already exists, or there is no "rename", so TS-DOS is reading sector 1 and doing | |||
; the rename opertaion manually, then writing sector 1 back to the disk. | |||
; ========================================================================================= | |||
41BAH CALL 4A72H ; Send Dir Reference opcode | |||
41BDH JNZ 487EH ; File Exists Error | |||
41C0H LXI D,0500H ; Prepare to test for 1280 bytes of free ram (1 sector) | |||
41C3H CALL 4308H ; Test if at least DE bytes of RAM free | |||
41C6H LXI H,0100H ; Load HL with physical sector 1, logical sector 0 | |||
41C9H SHLD FCDDH ; Save in FDC Emulation sector storage | |||
41CCH CALL 419BH ; Send opcode 0x08 - go to FDC emulation mode | |||
41CFH CALL 427EH ; Load Physical sector 1 to (HL) (HL=Unused memory pointer) | |||
41D2H LHLD FBB6H ; Get pointer to data - Unused memory pointer | |||
41D5H PUSH H ; Push data pointer to the stack | |||
41D6H MVI B,28H ; Prepare to test up to 40 filenames (max for TPDD) | |||
41D8H LXI D,FC9CH ; Filename of last program loaded from tape | |||
41DBH CALL 4269H ; Compare "Last program loaded" filename with all files on TPDD | |||
41DEH JC 487BH ; Printer not ready / FF error | |||
41E1H MOV A,B ; Get index in TPDD Sector 1 of filename that matches the old filename | |||
41E2H ANA A ; Test if old filename exists | |||
41E3H JZ 487BH ; Jump to error if filename not found in sector 1 - FF error | |||
41E6H PUSH H ; Save address within Sector 1 of matching filename to stack | |||
41E7H LXI D,FCE8H ; Point to TX buffer data area (payload) | |||
41EAH XCHG ; HL <--> DE Prepare to copy new filename to Sector 1 data | |||
41EBH LXI B,0009H ; Prepare to copy 9 bytes of filename | |||
41EEH CALL 4A05H ; Move BC bytes from M to (DE) with increment - copy new filename to sector 1 | |||
41F1H POP H ; Restore pointer to filename address within sector 1 | |||
41F2H PUSH H ; Save it to the stack again | |||
41F3H LXI D,FD20H ; Load address of data byte 28 in RX buffer | |||
41F6H LXI B,001FH ; Prepare to copy 31 bytes to RX buffer from Sector 1 data | |||
41F9H CALL 4A05H ; Move BC bytes from M to (DE) with increment - Save File data in RX buffer | |||
; ========================================================================================== | |||
; Now we will "remove" the renamed file from sector 1 by copying over it with the remaining | |||
; files in the sector. Filenames in sector 1 must be in alphabetical order, so we have to | |||
; remove it and reinsert it at the new location based on the new name. | |||
; ========================================================================================== | |||
41FCH POP D ; Restore pointer to filename address within sector 1 | |||
41FDH PUSH D ; Save it to the stack again | |||
41FEH LXI H,001FH ; Prepare to add 31 bytes to the sector 1 pointer (go to next file) | |||
4201H DAD D ; Point to next file after rename file within sector 1 | |||
4202H PUSH H ; Save address of next file after rename file to stack | |||
4203H LHLD FBB6H ; Unused memory pointer | |||
4206H LXI B,0500H ; Load size of 1 TPDD sector (1280 bytes) | |||
4209H DAD B ; Point to end of sector 1 data in free memory region | |||
420AH POP B ; Restore address of next file after rename file from stack | |||
420BH PUSH B ; Save it back to the stack | |||
420CH DSUB ; Calculate number of bytes from next file after rename to end of sector 1 | |||
420DH XTHL ; HL <--> (SP) Prepare to move HL to BC, HL now has address of next file | |||
420EH POP B ; Get byte count to end of sector 1 | |||
420FH CALL 4A05H ; Move BC bytes from M to (DE) with increment - shift bytes "left" in buffer | |||
4212H LHLD FBB6H ; Unused memory pointer - point to beginning of Sector 1 data | |||
4215H MVI B,27H ; Prepare to search throuh 39 files (we just deleted one) | |||
4217H LXI D,FD20H ; Load address of data byte 28 in RX buffer (our saved file) | |||
421AH CALL 4269H ; Search Sector-1 files at (HL) for filename at (DE) | |||
421DH PUSH H ; Save address of location where file should be inserted in Sector 1 | |||
421EH LHLD FBB6H ; Unused memory pointer - point to beginning of Sector 1 | |||
4221H LXI B,04FFH ; Prepare to move bytes "right" to end of sector (1280 bytes - 1) | |||
4224H DAD B ; Point to end of sector 1 data | |||
4225H PUSH H ; Save end of sector 1 address to stack | |||
4226H LXI B,001FH ; Prepare to subtract 1 file entry length from end of sector 1 address | |||
4229H DSUB ; Shorten the copy operation by 1 file entry so we don't overflow memory | |||
422AH POP D ; Get end of sector 1 address from stack as our "copy to" address | |||
422BH POP B ; Get address where file needs to be inserted from the stack | |||
422CH PUSH B ; Save it back to the stack for later | |||
422DH PUSH H ; Save address of end of Sector 1 minus one file entry length to stack | |||
422EH DSUB ; Calculate the copy lenght of data from insertion point to end of sector-1 file | |||
422FH PUSH H ; Save copy length to the stack to copy it to BC | |||
4230H POP B ; Get copy length into BC | |||
4231H INX B ; Increment length by 1 so the last byte is inclusive | |||
4232H POP H ; Get address of file insertion point from stack | |||
4233H CALL 4C4EH ; Move BC bytes from M to (DE) with decrement - shift files "right" in sector 1 | |||
4236H LXI H,FD20H ; Get address of our saved file info in the RX buffer | |||
4239H POP D ; Get address in Sector 1 of file insertion point | |||
423AH LXI B,001FH ; Prepare to copy 1 file entry size (31 bytes) | |||
423DH CALL 4A05H ; Move BC bytes from M to (DE) with increment | |||
; =============================================================================== | |||
; Seems like the next two lines don't do anything. The value being loaded in HL | |||
; *appears* to mean "Logical sector 20, physical sector 1", but only if the SHLD | |||
; target address is FCCDH. Then 5 instructions further down, the value in | |||
; ED80h is overwritten with logical sector 0. | |||
; =============================================================================== | |||
4240H LXI H,1401H ; Set L = logical sector 1, H=File type 0x14? | |||
4243H SHLD FCDEH ; Save logical sector & filetype | |||
4246H POP H ; POP stale address within Sector 1 of matching filename from stack | |||
4247H POP H ; Get address of unused memory (Sector 1 data storage) from stack | |||
4248H SHLD FCE4H ; Save in FDC Emulation data pointer address | |||
424BH LXI H,0100H ; Load HL= logical sector 1, physical sector 0 | |||
424EH SHLD FCDDH ; Save in FDC Emulation physical/logical sector storage | |||
4251H CALL 4150H ; Write data to FDC Emulation mode physical/logical sector | |||
4254H CALL 49CDH ; Send "M1",0x0D to RS-232 and delay about 3ms - go to Standard mode | |||
4257H RET | |||
; ========================================================================================= | |||
; Send TPDD_RENAME opcode and check response for errors | |||
; ========================================================================================= | |||
4258H LXI H,190DH ; Load TPDD_RENAME opcode | |||
425BH CALL 4822H ; Send TPDD Command/Len in HL | |||
425EH CALL 47CCH ; Receive a packet | |||
4261H LDA FD04H ; Get response error code | |||
4264H ANA A ; Check for errors | |||
4265H JNZ 487EH ; Report File Exists Error if not zero | |||
4268H RET | |||
; ========================================================================================= | |||
; Search Sector-1 files at (HL) for filename at (DE), maximum of "B" entries searched | |||
; ========================================================================================= | |||
4269H MVI C,09H ; Prepare to compare 9 bytes | |||
426BH CALL 4A1CH ; Compare (HL) with (DE), C bytes long (HL & DE preserved) | |||
426EH RZ ; Return if they are the same | |||
426FH RC ; Return if filename is less (files are sorted on TPDD) | |||
4270H MOV A,M ; Get 1st byte of filename to test for NULL | |||
4271H ORA A ; Test if A is 0 | |||
4272H RZ ; Return if string is NULL | |||
4273H PUSH B ; Save BC on stack | |||
4274H LXI B,001FH ; Prepare to add 31 to HL | |||
4277H DAD B ; Add 31 to HL | |||
4278H POP B ; Restore original BC | |||
4279H DCR B ; Decrement loop counter | |||
427AH RZ ; Return if no more items to compare | |||
427BH JMP 4269H ; Jump to compare next entry | |||
; ========================================================================================= | |||
; Read FDC sectors to New File Address (Free memory) | |||
; ========================================================================================= | |||
427EH LHLD FCE2H ; Get pointer for TPDD read data | |||
4281H CALL 4298H ; Read sector A into (HL) | |||
4284H LDA FCDDH ; Load current FDC Emulation physical sector number | |||
4287H DCR A ; Decrement to previous sector | |||
4288H RZ ; Return if sector number is zero | |||
4289H JMP 4281H ; Jump to read another sector (what breaks the loop? - A not saved) | |||
; ========================================================================================= | |||
; Receive RX bytes to (HL) routine copied to RAM | |||
; ========================================================================================= | |||
428CH CALL 6D7EH ; Get a character from RS232 receive queue | |||
428FH MOV M,A ; Save next byte to (HL) | |||
4290H INX H ; Increment pointer | |||
4291H DCX B ; Decrement counter | |||
4292H MOV A,C ; Prepare to test or zero | |||
4293H ORA B ; OR in MSB of coutner | |||
4294H JNZ FD89H ; Jump back to receive next character (RAM address) | |||
4297H RET | |||
; ========================================================================================= | |||
; Read FDC sector A to (HL), BC has length | |||
; ========================================================================================= | |||
4298H PUSH H ; Save target address for RX data stack | |||
4299H MVI A,52H ; Load FDC Emulation opcode for "R"ead | |||
429BH STA FCD3H ; Save as FDC Emulation opcode to send | |||
429EH CALL 42CEH ; Send FDC emulation mode opcode | |||
42A1H CALL 4176H ; Increment to next logical/physical sector | |||
42A4H CALL 4862H ; Test if DSR is set - drive ready, error otherwise | |||
42A7H PUSH B ; Save length of RX to the stack | |||
42A8H LXI H,428CH ; Load address of RX routine to copy to RAM | |||
42ABH LXI B,000CH ; Size of the RX routine to be copied to RAM | |||
42AEH LXI D,FD89H ; Target address of RX routine (in ALTLCD buffer) | |||
42B1H CALL 4A05H ; Move BC bytes from M to (DE) with increment | |||
42B4H MVI A,0DH ; Prepare to send CR to RS-232 | |||
42B6H CALL 485FH ; Send A to RS-232 using XON/XOFF | |||
42B9H CALL 4BDBH ; Call Main ROM's Set interrupt to 1DH routine. | |||
42BCH POP B ; Restore count of bytes to receive | |||
42BDH POP H ; Restore target address for RX data | |||
42BEH RST 1 ; Call main ROM at address in following 2 bytes | |||
42BFH DW FD89H ; Switch to Main ROM and call our RAM based RX routine | |||
42C1H RET | |||
; ========================================================================================= | |||
; Convert decimal value in A to base 10 ASCII value in BC | |||
; ========================================================================================= | |||
42C2H MVI B,2FH ; Start with '0' - 1 | |||
42C4H SUI 0AH ; Subtract 10 from A | |||
42C6H INR B ; Increment B (10's position) | |||
42C7H JNC 42C4H ; Keep looping until A negative | |||
42CAH ADI 3AH ; Convert negative remainder to positive ASCII '0'-'9' | |||
42CCH MOV C,A ; Store LSB ASCII value in C | |||
42CDH RET | |||
; ========================================================================================= | |||
; Send FDC emulation mode opcode | |||
; ========================================================================================= | |||
42CEH LDA FCDDH ; Get physical sector number | |||
42D1H CALL 42C2H ; Convert A to 10-based ASCII | |||
42D4H LDA FCD3H ; Load the FDC emulation mode opcode to send | |||
42D7H CALL 485FH ; Send A to RS-232 using XON/XOFF | |||
42DAH CALL 49DBH ; Send BC to RS-232 using XON/XOFF - send physical sector # | |||
42DDH LDA FCDEH ; Get logical sector number | |||
42E0H CALL 42C2H ; Convert A to 10-based ASCII | |||
42E3H MVI A,2CH ; Load code for ',' | |||
42E5H CALL 485FH ; Send A to RS-232 using XON/XOFF | |||
42E8H CALL 49DBH ; Send BC to RS-232 using XON/XOFF - send logical sector # | |||
42EBH CALL 49D3H ; Send 0x0D to RS-232 and Delay 3ms | |||
; ========================================================================================= | |||
; Read FDC Emulation mode response | |||
; ========================================================================================= | |||
42EEH LXI H,FD04H ; Point to RX buffer data area | |||
42F1H PUSH H ; Save RX buffer address on stack | |||
42F2H MVI C,08H ; Prepare to read 8 bytes from RX - standard FDC response length | |||
42F4H CALL 47E5H ; Get next byte from RX into HL | |||
42F7H DCR C ; Decrement loop counter | |||
42F8H JNZ 42F4H ; Keep looping until 8 bytes read | |||
42FBH POP H ; Get start of RX buffer address from stack | |||
42FCH MOV A,M ; Get first response byte | |||
42FDH CPI 30H ; Test if response error code is '0' - no error | |||
42FFH RZ ; Return if no error | |||
4300H CPI 42H ; Test for FDC Emulation mode "write protect" error code | |||
4302H JZ 486DH ; Write Protect Error | |||
4305H JMP 4867H ; Drive Not Ready Error | |||
; ========================================================================================= | |||
; Test if at least DE bytes of RAM left | |||
; ========================================================================================= | |||
4308H LHLD FBB6H ; Unused memory pointer | |||
430BH PUSH H ; Push unused memory location on stack | |||
430CH SHLD FCE2H ; Save unused memory location locally | |||
430FH LXI H,FFC0H ; Prepare to subtract 64 from stack pointer | |||
4312H DAD SP ; Add SP to HL (-64) (need some call space to run program) | |||
4313H POP B ; Restore unused memory location in BC | |||
4314H DSUB ; Subtract stack from unused memory pointer | |||
4315H RST 3 ; Compare DE and HL - check if enough free RAM | |||
4316H JC 488AH ; RAM full error | |||
4319H RET | |||
; ========================================================================================= | |||
; Issue TPDD Delete file Opcode | |||
; ========================================================================================= | |||
431AH XRA A ; Prepare to indicate we can't use Next Dir feature | |||
431BH STA FD01H ; Save in dir reference location in TX buffer | |||
431EH LXI H,0005H ; Load Delete File opcode into HL | |||
4321H JMP 409BH ; Send Request in HL and await response | |||
; ========================================================================================= | |||
; RST 7,2Eh Hook - DSKI$ function | |||
; ========================================================================================= | |||
4324H POP PSW ; Pop return address - we will return manually to Main ROM | |||
4325H CPI 30H ; Test A against '0' to check for bounds (only allow '0' and '1') | |||
4327H JC 00A6H ; Return to Main ROM if less than '0' - not our's | |||
432AH CPI 32H ; Test A against '2' to check for bounds | |||
432CH JNC 00A6H ; Return to Main ROM if >= '2' | |||
432FH SUI 30H ; Convert ASCII bank number to binary | |||
4331H STA FCCAH ; Save the target bank number in TPDD2 Bank number space | |||
4334H INX H ; Point to next byte to ensure it is ':' | |||
4335H DCR E ; ? Maybe length | |||
4336H MOV A,M ; Get next byte of filename | |||
4337H CPI 3AH ; Test if it is ':' | |||
4339H JNZ 00A6H ; Return if not ':' | |||
433CH INX H ; Increment to filename portion | |||
433DH DCR E ; ? Maybe length | |||
433EH XTHL ; Put pointer to filename on stack so we don't lose it when we pop | |||
433FH POP H ; Pop so we return to our caller's return address | |||
4340H MVI A,09H ; Load A with a value we will test for later to see if it's our file | |||
4342H ORA A ; Set return flags | |||
4343H JMP 00A6H ; Return to Main ROM | |||
; ========================================================================================= | |||
; RST 7,52h Hook - LFILES function | |||
; ========================================================================================= | |||
4346H POP PSW ; POP return address from stack...we will return manually | |||
4347H PUSH D ; Preserve DE on STACK | |||
4348H PUSH H ; Preserve HL on STACK | |||
4349H PUSH PSW ; Preserve A on STACK | |||
434AH XRA A ; Flag to generate system errors vs. printing | |||
434BH CALL 4A85H ; Save OS's baud rate string to storage area | |||
434EH LDES 02H ; DE = SP + 2 | |||
4350H LHLX ; Get value of HL pushed to stack above - LFILES argument pointer | |||
4351H MOV A,M ; Get 1st byte of argument | |||
4352H ANA A ; Test if arguement is zero | |||
4353H JZ 436AH ; Jump to display files from current TPDD bank number if zero | |||
4356H CPI 3AH ; Test if 1st byte is ':' | |||
4358H JZ 436AH ; Jump to display files from current TPDD bank number if ':" | |||
435BH CALL 4BCFH ; Evaluate expression at M-1 - Convert "0:" or "1:" to decimal | |||
435EH MOV A,E ; Get result of evaluation | |||
435FH CPI 02H ; Compare result for bounds | |||
4361H JNC 4370H ; Jump to exit routine if not 0 or 1 | |||
4364H STA FCCAH ; Save as TPDD2 Bank number | |||
4367H LDES 02H ; DE = SP + 2 | |||
4369H SHLX ; Save updated expression pointer to stack location prior to RST 7 | |||
436AH CALL 4704H ; Display / print all files and free space | |||
436DH CALL 4AC4H ; Restore original baud settings | |||
; ========================================================================================= | |||
; RST 7 Hook exit routine | |||
; ========================================================================================= | |||
4370H POP PSW ; Get preserved A from stack | |||
4371H POP H ; Get preserved HL from stack | |||
4372H POP D ; Get preserved DE from stack | |||
4373H POP B ; B isn't PUSHed in the Hook routines, POP the return address | |||
4374H JMP 00A6 ; Return to the Main ROM | |||
; ========================================================================================= | |||
; RST 7,58h Hook - KILL statement | |||
; ========================================================================================= | |||
4377H POP PSW ; POP the return address - we will return manually | |||
4378H CPI 09H ; Test if we found "0:" or "1:" in the DSKI$ function | |||
437AH JNZ 4516H ; Generate FC error | |||
437DH PUSH D ; Preserve DE on the stack | |||
437EH PUSH H ; Preserve HL on the stack | |||
437FH PUSH PSW ; Preserve A on the stack | |||
4380H XRA A ; Flag to generate system errors vs. printing | |||
4381H CALL 4A85H ; Save OS's baud rate string to storage area | |||
4384H LXI H,FC93H ; Filename of current BASIC program | |||
4387H CALL 4A57H ; Send Dir Reference for filename at (HL) | |||
438AH JZ 487BH ; "FF" error if attribute byte is zero | |||
438DH CALL 431AH ; Issue TPDD Delete file Opcode | |||
4390H CALL 4AC4H ; Restore original baud settings | |||
4393H JMP 4370H ; RST 7 Hook exit routine | |||
; ========================================================================================= | |||
; RST 7,5Ah Hook - NAME statement | |||
; ========================================================================================= | |||
4396H POP PSW ; POP the return address - we will return manually | |||
4397H CPI 09H ; Test if we found "0:" or "1:" in the DSKI$ function | |||
4399H JNZ 4516H ; Generate FC error | |||
439CH PUSH D ; Preserve DE on the stack | |||
439DH PUSH H ; Preserve HL on the stack | |||
439EH PUSH PSW ; Preserve A on the stack | |||
439FH XRA A ; Flag to generate system errors vs. printing | |||
43A0H CALL 4A85H ; Save OS's baud rate string to storage area | |||
43A3H LXI H,FC9CH ; Filename of last program loaded from tape | |||
43A6H CALL 4A57H ; Send Dir Reference for filename at (HL) | |||
43A9H JZ 487BH ; "FF" error if attribut byte is zero | |||
43ACH LXI H,FCE8H ; Point to TX buffer data area (payload) | |||
43AFH LXI D,FC9CH ; Filename of last program loaded from tape | |||
43B2H LXI B,0009H ; Prepare to copy 9 bytes of filename | |||
43B5H CALL 4A05H ; Move BC bytes from M to (DE) with increment | |||
43B8H CALL 41A7H ; Rename the TPDD file whose name is in "current BASIC program" | |||
43BBH CALL 4AC4H ; Restore original baud settings | |||
43BEH JMP 4370H ; RST 7 Hook exit routine | |||
; ========================================================================================= | |||
; RST 7,5Eh Hook - LOADM and RUNM statement | |||
; ========================================================================================= | |||
43C1H POP PSW | |||
43C2H CPI 09H ; Test if we found "0:" or "1:" in the DSKI$ function | |||
43C4H JNZ 00A6H ; Return if not a TPDD file | |||
43C7H POP B ; Pop return address from stack - we will jump manually to exit | |||
43C8H PUSH H ; Preserve HL on the stack | |||
43C9H LXI B,4F43H ; Load code for "CO" filename extension | |||
43CCH CALL 44BAH ; Compare extension in current BASIC program filename with value in BC | |||
43CFH JZ 487BH ; "FF" Printer not ready error | |||
43D2H CALL 408AH ; Open TPDD file for Read Mode | |||
43D5H LHLD FD1DH ; Get file size parameter from RX buffer | |||
43D8H MOV A,L ; Swap endianness of file size | |||
43D9H MOV L,H ; Move MSB to LSB | |||
43DAH MOV H,A ; Move LSB to MSB | |||
43DBH SHLD FCDDH ; Save endian modified length back to storage | |||
43DEH CALL 40B6H ; Send TPDD_READ data opcode and recieve response, HL=RX buf upon return | |||
43E1H CALL 4C6AH ; Copy CO header bytes (6) from (HL) to "active" CO Header storage area | |||
43E4H PUSH H ; Push updated (+6) RX data pointer to stack | |||
43E5H CALL 4C6EH ; Go print CO address, length and invocation address to LCD | |||
43E8H LHLD FACEH ; Address of CO Header - get CO load address | |||
43EBH PUSH H ; Push CO load address to stack | |||
43ECH PUSH H ; Push another copy to the stack to preserve value during XTHL/POP | |||
43EDH LHLD F5F4H ; RST 5.5 RAM Vector | |||
43F0H XTHL ; HL <--> (SP) Load RST 5.5 RAM vector as return address | |||
43F1H POP B ; BC now has RST 5.5 RAM Vector, HL= CO load address | |||
43F2H DSUB ; Test if CO load address is less that RST 5.5 RAM address | |||
43F3H JC 488AH ; Trying to clober RST5.5 RAM vectors - generate RAM full error | |||
43F6H POP D ; Get CO load address saved on stack | |||
43F7H POP H ; Get Updated (+6) RX data pointer from stack | |||
43F8H LDA FD03H ; Load RX Length byte from RX data buffer | |||
43FBH SUI 06H ; Subtract CO header length from packet data length | |||
43FDH MOV C,A ; Save packet data length in BC | |||
43FEH MVI B,00H ; Make MSB of BC zero | |||
4400H CALL 4135H ; Write BC bytes from M to DE and subtract BC from total file size | |||
4403H CALL 4AC4H ; Restore original baud settings | |||
4406H LXI H,251AH ; Load new return address in Main ROM | |||
4409H PUSH H ; Push new return address to stack | |||
440AH JMP 00A6H ; Jump to Main ROM | |||
; ========================================================================================= | |||
; RST 7,5Ch Hook - SAVEM statement | |||
; ========================================================================================= | |||
440DH POP PSW ; POP the return address - we will return elsewhere | |||
440EH CPI 09H ; Test if we found "0:" or "1:" in the DSKI$ function | |||
4410H JNZ 00A6H ; Return if not a TPDD file | |||
4413H CALL 4C72H ; Process SAVEM arguments for address, length and entry point | |||
4416H LXI B,4F43H ; Load code for "CO" file extension | |||
4419H CALL 44BAH ; Compare ext. in current BASIC program with BC, send dir ref. if match | |||
441CH JNZ 487EH ; Jump to generate File Exists Error if found | |||
441FH MVI A,01H ; Set open mode for new file | |||
4421H STA FCD6H ; Save open mode to input variable | |||
4424H LHLD FAD0H ; Length of last program loaded/saved to tape | |||
4427H LXI B,0006H ; Prepare to add CO header size (6 bytes) to required length | |||
442AH PUSH B ; Push CO header length to stack | |||
442BH DAD B ; Add CO header size to required length | |||
442CH PUSH H ; Push updated file length to stack | |||
442DH CALL 4101H ; Test free Disk space and issue TPDD_OPEN request | |||
4430H POP H ; Get updated file length from stack | |||
4431H SHLD FCD5H ; Save as lenght of file being saved / loaded | |||
4434H POP B ; Get CO header length from stack | |||
4435H LXI H,FACEH ; Load address of "active" CO header block | |||
4438H LXI D,FD04H ; DE points to the data area in RX buffer | |||
443BH CALL 4A05H ; Move BC bytes from M to (DE) with increment | |||
443EH LHLD FD04H ; DE points to the data area in RX buffer | |||
4441H LXI B,007AH ; Prepare to write 122 bytes of data to next location in RX buffer | |||
4444H CALL 40D8H ; Write 122 bytes from (HL) and send TPDD_WRITE to TPDD | |||
4447H CALL 4AC4H ; Restore original baud settings | |||
444AH LXI H,0501H ; Load return address in Main ROM - vector to BASIC ready | |||
444DH PUSH H ; Push return address to stack | |||
444EH JMP 00A6H ; Return to Main ROM | |||
; ========================================================================================= | |||
; RST 7,1Ah Hook - RUN statement | |||
; ========================================================================================= | |||
4451H POP PSW | |||
4452H CPI 09H ; Test if we found "0:" or "1:" in the DSKI$ function | |||
4454H JNZ 00A6H ; Return if not TPDD file | |||
4457H POP B ; Get return address from stack | |||
4458H POP PSW ; Get 1st byte of RUN statement argument | |||
4459H PUSH PSW ; Put back the data we stole | |||
445AH PUSH B ; Put back the return address | |||
445BH JZ 00A6H ; Return if there were no arguments to the RUN statement | |||
445EH SBB A ; Clear zero flag (C is set and A=0xFF) | |||
445FH STA FC92H ; Save in flag to execute BASIC program (non-zero = execute) | |||
4462H LXI B,4142H ; Load code for "BA" BASIC file extension | |||
4465H CALL 44BAH ; Compare ext. in current BASIC program with BC, send dir ref. if match | |||
4468H JZ 487BH ; Jump to error if not "BA" or " " - generate "FF" error | |||
446BH LHLD FD1DH ; Get file size parameter from RX buffer | |||
446EH MOV C,H ; Swap endianness of file size | |||
446FH MOV B,L ; Swap LSB to MSB | |||
4470H MOV H,B ; Copy file size parameter back to HL | |||
4471H MOV L,C ; Copy LSB of file size to HL | |||
4472H SHLD FCDDH ; Store length of file | |||
4475H CALL 44ABH ; Call NEW statement, upon return HL=address of last variable assigned | |||
4478H INX H ; Increment to free memory space | |||
4479H SHLD FCE2H ; Save as address of file being loaded/saved/etc. | |||
447CH LHLD FCDDH ; Get disk file length | |||
447FH PUSH H ; Save file length on stack | |||
4480H PUSH H ; Push file length to stack to copy to BC | |||
4481H POP B ; Pop file length to BC | |||
4482H CALL 411EH ; Insert BC spaces at address of RAM file being loaded/run | |||
4485H POP D ; Get length of disk file from stack | |||
4486H LHLD FBAEH ; Load Start of DO files pointer | |||
4489H DAD D ; Increment Start of DO files pointer by disk file length | |||
448AH SHLD FBAEH ; Save updated Start of DO files pointer | |||
448DH LHLD FAD8H ; Load pointer to address used for RAM Input processing | |||
4490H DAD D ; Increment pointer by disk file length | |||
4491H SHLD FAD8H ; Save updated RAM Input processing pointer | |||
4494H CALL 4AC4H ; Restore original baud settings | |||
4497H XRA A ; Clear zero flag and A | |||
4498H LXI H,23F5 ; Load address in Main ROM to configure and execute current BASIC programH | |||
449BH PUSH H ; Push return address to stack | |||
449CH JMP 00A6H ; Return to Main ROM | |||
; ========================================================================================= | |||
; Call "BASIC NEW" helper routine. This get's copied to RAM below. | |||
; ========================================================================================= | |||
449FH XRA A ; Prepare to switch to Main ROM | |||
44A0H OUT E0H ; Switch to Main ROM | |||
44A2H CALL 20FFH ; Call BASIC NEW statement | |||
44A5H CALL FAA4H ; Switch back to OptROM | |||
44A8H JMP 4478H ; Jump back into RST 7,1Ch Hook - RUN statement | |||
; ========================================================================================= | |||
; Copy "BASIC NEW" helper routine to RAM and Jump to it --- Call Main ROM's NEW statement | |||
; ========================================================================================= | |||
44ABH LXI H,449FH ; Point to helper function to copy to RAM | |||
44AEH LXI D,FD89H ; RAM destination | |||
44B1H LXI B,000CH ; Length of helper funciton | |||
44B4H CALL 4A05H ; Copy helper to RAM | |||
44B7H JMP FD89H ; Branch to helper function | |||
; ========================================================================================= | |||
; Compare current BASIC program file extension with value in BC or " " | |||
; ========================================================================================= | |||
44BAH PUSH PSW ; Preserve A on Stack | |||
44BBH PUSH H ; Preserve HL on Stack | |||
44BCH PUSH D ; Preserve DE on Stack | |||
44BDH PUSH B ; Preserve comparison file extension on Stack | |||
44BEH LHLD FC99H ; Load 2 extension field bytes of current BASIC program name | |||
44C1H LXI D,2020H ; Load 2 spaces (0x20) into DE | |||
44C4H RST 3 ; Test if filename extension in current BASIC program is " " | |||
44C5H JZ 44D6H ; Jump if current BASIC program filename extension is " " | |||
44C8H POP D ; Get comparison file extension from stack into DE | |||
44C9H PUSH D ; Push file extension back to stack for storage | |||
44CAH RST 3 ; Test if current BASIC program filename extension matches BC | |||
44CBH JZ 44D6H ; Jump if current BASIC program filename extension matches BC | |||
44CEH POP B ; Get BC back off stack | |||
44CFH POP D ; Recover DE from stack | |||
44D0H POP H ; Recover HL from stack | |||
44D1H POP PSW ; Recover A & flags from stack | |||
44D2H POP B ; Pop return address - File extension doesn't match so don't run | |||
44D3H JMP 00A6H ; Return to Main ROM | |||
; ========================================================================================= | |||
; Store expected extension (on stack) to current BASIC program and send dir reference for | |||
; the disk file | |||
; ========================================================================================= | |||
44D6H POP H ; Get expected file extension "BA" or "CO" from stack | |||
44D7H SHLD FC99H ; Save to 2 extension field bytes of current BASIC program name | |||
44DAH POP D ; Restore DE from stack | |||
44DBH POP H ; Restore HL from stack | |||
44DCH POP PSW ; Restore A from stack | |||
44DDH XRA A ; Flag to generate system errors vs. printing | |||
44DEH CALL 4A85H ; Save OS's baud rate string to storage area | |||
44E1H LXI H,FC93H ; Filename of current BASIC program | |||
44E4H JMP 4A57H ; Send Dir Reference for filename at (HL) | |||
; ========================================================================================= | |||
; RST 7,16h Hook - SAVE statement | |||
; ========================================================================================= | |||
44E7H POP PSW ; POP return address, we will return manually | |||
44E8H CPI 09H ; Test if we found "0:" or "1:" in the DSKI$ function | |||
44EAH JNZ 00A6H ; Return if not a TPDD file | |||
44EDH LXI B,4142H ; Load code for "BA" basic extension | |||
44F0H CALL 44BAH ; Compare extension in current BASIC program filename with value in BC | |||
44F3H JNZ 487EH ; File Exists Error | |||
44F6H CALL 4C66H ; Update line addresses for current BASIC program | |||
44F9H LHLD F67CH ; Start of BASIC program pointer | |||
44FCH XCHG ; HL <--> DE DE=BASIC program strt, HL=BASIC program end | |||
44FDH RST 3 ; Compare DE and HL | |||
44FEH JZ 450FH ; Vector to BASIC ready - print Ok if BASIC start=BASIC end | |||
4501H PUSH D ; Save start of BASIC program to stack | |||
4502H POP B ; POP start of BASIC program from stack | |||
4503H DSUB ; Subtract BASIC start address from BASIC end address | |||
4504H MVI A,01H ; Set file open mode for new file | |||
4506H STA FCD6H ; Save open mode to pass to function | |||
4509H CALL 40C8H ; Write HL bytes of data from (DE) to TPDD | |||
450CH CALL 4AC4H ; Restore original baud settings | |||
450FH LXI H,0502H ; Load address in Main ROM of Vector to BASIC ready - print Ok | |||
4512H PUSH H ; Push new return address to stack | |||
4513H JMP 00A6H ; Return to Main ROM | |||
; ========================================================================================= | |||
; Return to Main ROM's Generate FC Error routine | |||
; ========================================================================================= | |||
4516H LXI H,08DBH ; Load address of Generate FC error routine | |||
4519H PUSH H ; Push return address to the stack | |||
451AH JMP 00A6H ; Return to Main ROM | |||
; ========================================================================================= | |||
; RST 7,30h Hook - OPEN/CLOSE/READ/WRITE/LINE INPUT statement | |||
; ========================================================================================= | |||
451DH XRA A ; Clear A to set print error flag | |||
451EH STA FCD2H ; Set flag to generate system errors vs. print | |||
4521H POP PSW ; POP return address ... returning manually | |||
4522H SHLD FCCEH ; Save HL in Stack pointer upon entry location | |||
4525H PUSH D ; Preserve DE on stack | |||
4526H PUSH H ; Preserve HL on stack | |||
4527H PUSH PSW ; Preserve A on stack | |||
4528H LXI D,0004H ; Offset of the file descriptor address MSB | |||
452BH DAD D ; Point to the file descriptor address MSB | |||
452CH MOV A,M ; Get MSB address of FD | |||
452DH CPI 09H ; Test if we found "0:" or "1:" in the DSKI$ function | |||
452FH JZ 4538H ; Jump to process the sub-operation code if it's a TPDD file | |||
; ========================================================================================= | |||
; RST 7,30h Hook exit routine | |||
; ========================================================================================= | |||
4532H POP PSW ; Restore A from stack | |||
4533H POP H ; Restore HL from stack | |||
4534H POP D ; Restore DE from stack | |||
4535H JMP 00A6H ; Return to Main ROM | |||
; ========================================================================================= | |||
; Test the RST 7,30h sub-operation code and vector to the proper handler function | |||
; ========================================================================================= | |||
4538H POP PSW ; Retrieve A from the stack - contains sub-operation code | |||
4539H PUSH PSW ; Restore to stack | |||
453AH CPI 00H ; Test for OPEN sub-operation | |||
453CH JZ 455CH | |||
453FH CPI 02H ; Test for CLOSE sub-operation | |||
4541H JZ 45E8H | |||
4544H CPI 04H ; Test for PRINT # sub-operation | |||
4546H JZ 46B0H | |||
4549H CPI 06H ; Test for EOF sub-operation | |||
454BH JZ 4607H | |||
454EH CPI 08H ; Test for LINE INPUT sub-operation | |||
4550H JNZ 4532H | |||
4553H LDES 06H ; Get stack location upon entry (we pushed 3 times = 6 bytes) in DE | |||
4555H LXI H,161BH ; Not an operation we care about, load address for "Special RAM IO" routine | |||
4558H SHLX ; Replace our return address so we return to "Special RAM IO" routine instead | |||
4559H JMP 4532H ; Jump to RST 7,32h exit routine | |||
; ========================================================================================= | |||
; RST 7,30h OPEN sub-operation | |||
; ========================================================================================= | |||
455CH XRA A ; Generate system errors vs. printing | |||
455DH CALL 4A85H ; Save OS's baud rate string to storage area | |||
4560H LXI H,FC99H ; Load address of 1st extension byte of current BASIC program filename | |||
4563H MOV A,M ; Get 1st byte of file extension from current BASIC program | |||
4564H CPI 20H ; Test if opening a file with no extension | |||
4566H JZ 456EH ; Branch to proivde "DO" default extension if non provided | |||
4569H CPI 44H ; Test if A is 'D' - opening a "DO" file | |||
456BH JNZ 488DH ; Generate system error 0x0C - ID Error | |||
456EH MVI M,44H ; Change 1st extension byte to 'D' | |||
4570H INX H ; Increment to 2nd extension byte | |||
4571H MVI M,4FH ; Change 2nd extension byte to 'O' | |||
4573H LXI H,FC93H ; Filename of current BASIC program | |||
4576H CALL 4A57H ; Send Dir Reference for filename at (HL) | |||
4579H MOV C,A ; Move attribute byte to C | |||
457AH CALL 465BH ; Calculate offset of BASIC instruction file # EOF marker | |||
457DH MVI M,00H ; Set EOF marker to zero - not EOF | |||
457FH POP H ; POP PSW and discard | |||
4580H POP H ; Restore address of FD control | |||
4581H POP D ; Restore DE | |||
4582H PUSH D ; Save DE back to stack | |||
4583H PUSH H ; Save FD control address back to stack | |||
4584H MOV D,C ; Save TPDD file attribute byte to D | |||
4585H MOV A,E ; Move open mode to A (8=Append,1=Read,2=Write) | |||
4586H ANI 07H ; Mask all but lower 3 bits so we get 0, 1, or 2 | |||
4588H LXI H,4AE4H ; Get address of RST 7,32h open mode to TPDD Open mode mapping | |||
458BH MOV C,A ; Save mapping mode table offset to C | |||
458CH MVI B,00H ; Clear MSB of offset for 16-bit add | |||
458EH DAD B ; Calculate index address into mapping table | |||
458FH MOV A,M ; Load TPDD open mode from mapping | |||
4590H DCR A ; Test if TPDD open mode is Write | |||
4591H JZ 45CDH ; Jump if opening for write mode | |||
4594H DCR A ; Test if TPDD open mode is Append | |||
4595H JNZ 45E0H ; Jump to open TPDD for Read mode if not zero | |||
4598H LDA FD1CH ; Load attribute byte from RX buffer | |||
459BH ANA A ; Opening for Append, test if file already exists | |||
459CH JNZ 45A1H ; Jump to perform open for append if file already exists | |||
459FH INX H ; Opening for append but file doesn't exist, increment mapping to Write | |||
45A0H INX H ; Increment again to skip "read" mapping in table | |||
; ========================================================================================= | |||
; Open TPDD file with open mode as specified by RST 7,32h mapping table | |||
; ========================================================================================= | |||
45A1H MOV A,M ; Reload the TPDD open mode from the mapping table | |||
45A2H STA FCE8H ; Point to TX buffer data area (payload) | |||
45A5H LXI H,0101H ; Load TPDD_OPEN opcode in HL | |||
45A8H CALL 409BH ; Send Request in HL and await response | |||
45ABH LHLD FCCEH ; Get address of FD control | |||
45AEH LXI D,0007H ; Load offset of write buffer length within FD control | |||
45B1H DAD D ; Point to write buffer length within FD control | |||
45B2H XRA A ; Clear A | |||
45B3H MOV M,A ; Set the write buffer length to zero - just opened the file | |||
45B4H INX H ; Increment to write buffer output pointer address | |||
45B5H MOV D,H ; Save HL to DE to update write buffer output pointer | |||
45B6H MOV E,L ; Save LSB of HL to DE | |||
45B7H INX H ; Increment to MSB of write buffer output pointer | |||
45B8H INX H ; Increment to write buffer location | |||
45B9H SHLX ; Reset write buffer output poiner to beginning of buffer | |||
45BAH POP H ; Restore address of FD control | |||
45BBH POP D ; Restore DE from stack | |||
45BCH MOV A,E ; Load RST 7,32h open mode into A | |||
45BDH CPI 08H ; Test if open mode is Append | |||
45BFH JNZ 45C4H ; Jump to retain open mode if not append | |||
45C2H MVI E,02H ; Change Append open mode value to "Write" | |||
45C4H MOV M,E ; Save open status to FD control | |||
45C5H XTHL ; HL <--> (SP) Prepare to change our return address, saving HL | |||
45C6H LXI H,14DEH ; Load new return address in ROM "LCD and PRT file open" routine | |||
45C9H XTHL ; Put return address back to stack, restoring HL | |||
45CAH JMP 00A6H ; Return to the new address in LCD and PRT file open routine in Main ROM | |||
; ========================================================================================= | |||
; RST 7,30h open file for write mode. The Attribute byte from the Dir Ref opcode is in D | |||
; ========================================================================================= | |||
45CDH MOV A,D ; Get the File attribute byte from the Dir Reference operation | |||
45CEH ORA A ; Test if the file exists (will be 'F' if the file exists) | |||
45CFH JZ 45A1H ; Jump to create the file if it doesn't already exist | |||
45D2H PUSH H ; Save HL to the stack for restoration | |||
45D3H CALL 431AH ; Issue TPDD Delete file Opcode - Overwriting existing file | |||
45D6H LXI H,FC93H ; Filename of current BASIC program | |||
45D9H CALL 4A57H ; Send Dir Reference for filename at (HL) - Need new Dir Ref | |||
45DCH POP H ; Restore HL from stack | |||
45DDH JMP 45A1H ; Open TPDD file with open mode as specified by RST 7,32h mapping table | |||
; ========================================================================================= | |||
; RST 7,30h open file for read mode. Ensure the file exists via the attribute byte in D | |||
; ========================================================================================= | |||
45E0H MOV A,D ; Load the file attribute byte from the Dir Ref opcode | |||
45E1H ORA A ; Test if attribute byte is zero | |||
45E2H JZ 487BH ; Generate "FF" error if file doesn't exist | |||
45E5H JMP 45A1H ; Jump to open the file | |||
; ========================================================================================= | |||
; RST 7,30h Sub command - CLOSE FILE | |||
; ========================================================================================= | |||
45E8H POP PSW ; Retrieve A PUSHed by RST 7,32a entry | |||
45E9H POP H ; Retrieve HL | |||
45EAH POP D ; Retrieve DE | |||
45EBH PUSH H ; Save FD control pointer to stack | |||
45ECH MOV A,M ; Get FD control status byte | |||
45EDH MVI M,00H ; Change FD control status to "closed" | |||
45EFH CPI 02H ; Test if status | |||
45F1H CZ 46DDH ; Call flush output buffer routine if opened for write mode | |||
45F4H LXI H,0002H ; Load TPDD_CLOSE opcode into HL | |||
45F7H CALL 409BH ; Send Request in HL and await response | |||
45FAH CALL 4AC4H ; Restore original baud settings | |||
45FDH POP H ; Restore FD control pointer | |||
45FEH XTHL ; HL <--> (SP) so we can preserve HL through POP | |||
45FFH POP H ; Pop return address (actually FD control address) from stack | |||
4600H LXI H,4D59H ; Load new reuturn address - LCD, CRT, and LPT file close routine | |||
4603H PUSH H ; Push new return address to stack - not returning to caller | |||
4604H JMP 00A6H ; Return to Main ROM | |||
; ========================================================================================= | |||
; RST 7,30h Sub command - EOF | |||
; ========================================================================================= | |||
4607H CALL 465BH ; Calculate offset of BASIC instruction file # EOF marker | |||
460AH MOV A,M ; Get the current EOF marker | |||
460BH MVI M,00H ; Set the EOF marker to zero to reset it | |||
460DH ANA A ; Test if at EOF for this file | |||
460EH JNZ 4627H ; Jump if EOF marker for this file not zero | |||
4611H LHLD FCCEH ; Get address of FD control | |||
4614H LXI B,0007H ; Offset of write buffer length within FD control | |||
4617H DAD B ; Point to write buffer length | |||
4618H MOV A,M ; Get current write buffer length | |||
4619H INX H ; Point to LSB of read/write buffer output pointer within FD control | |||
461AH PUSH H ; Save address of read/write buffer output pointer to stack | |||
461BH ANA A ; Test if data left in the buffer | |||
461CH CZ 4663H ; Call to read more data from TPDD if buffer empty | |||
461FH POP D ; Restore address of read/write output buffer within FD control | |||
4620H LHLX ; Get current read/write pointer location from FD control | |||
4621H MOV A,M ; Read the next byte from the buffer | |||
4622H INX H ; Increment buffer pointer to the next byte | |||
4623H SHLX ; Save read/write buffer pointer back to FD control | |||
4624H DCX D ; Decrement back to read/write buffer length within FD control | |||
4625H XCHG ; HL <--> DE Prepare to update buffer length | |||
4626H DCR M ; Decrement length since we just read a byte | |||
; ========================================================================================= | |||
; Test if EOF for BASIC file # | |||
; ========================================================================================= | |||
4627H CPI 1AH ; Test if byte is EOF marker | |||
4629H STC ; Ensure the Carry flag is set | |||
462AH CMC ; And now clear it to indicate not EOF | |||
462BH JNZ 4633H ; Jump if not at end of file | |||
462EH CALL 465BH ; Calculate offset of BASIC instruction file # EOF marker | |||
4631H MOV M,A ; Save EOF marker for this file # | |||
4632H STC ; Set Carry to indicate EOF | |||
; ========================================================================================= | |||
; Save EOF status | |||
; ========================================================================================= | |||
4633H PUSH PSW ; Save EOF indication in Carry flag and marker value to stack | |||
4634H LDES 10H ; Load offset to our return address (we PUSHed a bunch to the stack) | |||
4636H LHLX ; Load HL with our return address from the stack | |||
4637H LXI B,189AH ; Load address of return within EOF function | |||
463AH DSUB ; Test if we were called from the EOF function | |||
463BH JNZ 464FH ; Jump if not called from ROM EOF function - don't to EOF logical testing | |||
463EH CALL 465BH ; Calculate offset of BASIC instruction file # EOF marker | |||
4641H POP PSW ; Retreive EOF and marker value from stack | |||
4642H MOV M,A ; Save the marker value to the file # marker storage location | |||
4643H MOV C,A ; Save marker value in C | |||
4644H SBB A ; Subtract with borrow (C was set if EOF) | |||
4645H CALL 4BCBH ; Call into SGN function to set FAC1 with sign of A (EOF test) | |||
4648H LDES 12H ; Prepare to "POP" 6 register pairs from the stack all at once | |||
464AH XCHG ; HL <--> DE HL now has new stack value | |||
464BH SPHL ; HL <--> SP "POP" 6 values from the stack | |||
464CH JMP 00A6H ; Return to Main ROM | |||
; ========================================================================================= | |||
; Non-EOF function call return | |||
; ========================================================================================= | |||
464FH POP PSW ; Restore PSW with EOF indication (C flag) | |||
4650H POP H ; Pop old PSW - we don't want it | |||
4651H POP H ; Resore HL from stack | |||
4652H POP D ; Restore DE from stack | |||
4653H XTHL ; Push HL to stack to set new return address | |||
4654H LXI H,4E8AH ; Load address of a "Stack frame retrun" routine | |||
4657H XTHL ; Stack gets new return address, restore HL | |||
4658H JMP 00A6H ; Return to the new address (not returning to parent) | |||
; ========================================================================================= | |||
; Calculate offset of BASIC instruction file # EOF marker | |||
; ========================================================================================= | |||
465BH LHLD FAA2H ; Get file # of active BASIC instruction (EOF, LINE INPUT, etc.) | |||
465EH LXI D,FA91H ; Load base address of file status array | |||
4661H DAD D ; Add offset to base of file status byte array | |||
4662H RET | |||
; ========================================================================================= | |||
; RST 7,30A Read data from server (TPDD) into FD file buffer | |||
; ========================================================================================= | |||
4663H LXI H,0003H ; Load TPDD_READ opcode in HL | |||
4666H CALL 4822H ; Send TPDD Command/Len in HL | |||
4669H CALL 47CCH ; Receive a packet | |||
466CH LDA FD02H ; Get response byte from storage for RX packet | |||
466FH CPI 10H ; Test for valid read file response | |||
4671H JNZ 469EH ; Branch if not valid read from file response | |||
4674H LDA FD03H ; Get length of read from RX buffer | |||
4677H LHLD FCCEH ; Get pointer to FD control | |||
467AH LXI D,0008H ; Offset of address of read/write buffer relative to FD control | |||
467DH DAD D ; Point to address of read/write buffer within FD control | |||
467EH PUSH H ; Save address of read/write buffer to stack | |||
467FH MOV D,H ; Move address of read/write buffer to DE for update | |||
4680H MOV E,L ; Move LSB | |||
4681H INX H ; Increment to MSB of read/write buffer address in FD control | |||
4682H INX H ; Increment to read/write buffer | |||
4683H SHLX ; Reset pointer to read/write buffer - we just read more data | |||
4684H LXI D,FD04H ; DE points to the RX data in the buffer | |||
4687H XCHG ; HL <--> DE Prepare to move data from RX buffer to FD buffer | |||
4688H MOV C,A ; Move the RX data length to C | |||
4689H MVI B,00H ; Clear MSB of BC count | |||
468BH CALL 4A05H ; Move BC bytes from M to (DE) with increment - copy to FD buffer | |||
468EH LDA FD03H ; Get length of RX read data again | |||
4691H CPI 80H ; Test for maximum read length | |||
4693H JZ 469AH ; If maximum read, skip writing EOF marker to read/write buffer | |||
4696H XCHG ; HL = destination address in FD buffer | |||
4697H MVI M,1AH ; Terminate .DO file in FD read/write buffer with EOF marker | |||
4699H INR A ; Increment length to reflect EOF marker | |||
; ========================================================================================= | |||
; RST 7,32A Read - not max read size | |||
; ========================================================================================= | |||
469AH POP H ; Get address of read/write buffer in FD control from stack | |||
469BH DCX H ; Decrement to FD control read/write buffer length location | |||
469CH MOV M,A ; Save length of data in read/write buffer to FD control | |||
469DH RET | |||
; ========================================================================================= | |||
; RST 7,32A Read - unsuccessful TPDD read | |||
; ========================================================================================= | |||
469EH LHLD FCCEH ; Get address of FD control | |||
46A1H LXI D,0007H ; Load offset of output buffer count in FD control | |||
46A4H DAD D ; Point to output buffer length in FD control | |||
46A5H MVI M,01H ; Set read/write buffer length to 1 to indicate EOF marker | |||
46A7H INX H ; Increment to LSB of read/write buffer output address in FD control | |||
46A8H MOV D,H ; Save HL in DE for update of read/write buffer output in FD control | |||
46A9H MOV E,L ; Save LSB of HL to DE | |||
46AAH INX H ; Increment to MSB of read/write buffer in FD control | |||
46ABH INX H ; Increment to the FD read/write buffer | |||
46ACH SHLX ; Reset the FD control read/write buffer pointer to begining of buffer | |||
46ADH MVI M,1AH ; Write an EOF marker to the buffer | |||
46AFH RET | |||
; ========================================================================================= | |||
; RST 7,32h PRINT # sub-operation | |||
; ========================================================================================= | |||
46B0H LHLD FCCEH ; Pointer to FD control | |||
46B3H LXI D,0007H ; ?Offset to output byte count | |||
46B6H DAD D ; Get pointer to file's output byte count | |||
46B7H MOV A,M ; Load byte count of pending bytes to write | |||
46B8H CPI 80H ; Test if 128 bytes to write | |||
46BAH CZ 46DDH ; Call routine to flush output buffer to file | |||
46BDH POP PSW ; Restore A from stack (from RST 7,32h entry) | |||
46BEH POP H ; Restore HL from stack | |||
46BFH POP D ; Restore DE from stack | |||
46C0H POP H ; Pop the return address - we will return via JMP | |||
46C1H POP PSW ; Get the caller's A so we know what byte is being written | |||
46C2H PUSH PSW ; Put it back on the stack...it isn't ours | |||
46C3H CPI 1AH ; Test if writing an EOF marker to the file | |||
46C5H JZ 46D6H ; Jump if writing EOF marder to the file - don't actually write it | |||
46C8H LHLD FCCEH ; Get address of FD control | |||
46CBH LXI D,0007H ; Get offset of output buffer length within FD control | |||
46CEH DAD D ; Point to output buffer length address | |||
46CFH INR M ; Increment the output buffer length - writing 1 byte | |||
46D0H INX H ; Point to current file location pointer in FD control | |||
46D1H XCHG ; HL <--> DE Move address of file location pointer to DE | |||
46D2H LHLX ; Load current file location address to HL | |||
46D3H MOV M,A ; Save the byte in the buffer (RX buffer for subsequent write) | |||
46D4H INX H ; Increment the curent file location pointer (we will flush later) | |||
46D5H SHLX ; Save the update current file location pointer to FD control | |||
46D6H LXI H,14EAH ; Load address to update automatic timer and POP regs from the stack | |||
46D9H PUSH H ; Push new return address. We will return to the parent's caller | |||
46DAH JMP 00A6H ; Return to Main ROM | |||
</pre> | |||
Navigate to: | |||
<DPL> | |||
category=M100 TS-DOS ROM Disassembly | |||
</DPL> | |||
[[Category:M100 TS-DOS ROM Disassembly]] |
Latest revision as of 19:55, 8 July 2011
TS-DOS Model 100/102 ROM RST 7 Handlers
This is the code for the DOS-ON RST 7 Hooks, along with the TPDD1 Rename functionality.
; ========================================================================================= ; Load default RST 7 vector table values ; ========================================================================================= 3FFAH LXI 7FF3H ; Address of a RET opcode in ROM 3FFDH SHLD FAE6H ; Save as hook for RST 7,0Ch?? We didn't modify this one 4000H SHLD FB08H ; Save as hook for RST 7,2Eh - DSKI$ function 4003H SHLD FB0AH ; Save as hook for RST 7,30h - OPEN/CLOSE/PRINT/LINE INPUT 4006H SHLD FAF0H ; Save as hook for RST 7,16h - SAVE 4009H SHLD FAF4H ; Save as hook for RST 7,1Ah - RUN 400CH LXI H,08DBH ; Load address of "Generate FC Error" in Main ROM 400FH SHLD FB2CH ; Save as hook for RST 7,52h - LFILES 4012H SHLD FB32H ; Save as hook for RST 7,58h - KILL 4015H SHLD FB34H ; Save as hook for RST 7,5Ah - NAME 4018H SHLD FB36H ; Save as hook for RST 7,5Ch - SAVEM 401BH SHLD FB38H ; Save as hook for RST 7,5Eh - LOADM and RUNM 401EH RET ; ========================================================================================= ; Install our RST 7 hook for all RST 7 calls we are interested in. This uses the "ON TIME" ; time storage location to copy a 6-byte routine to switch to OptROM and call our ; RST 7 "switch" statement in our ROM. This means ON TIME can't be used when using ; the DOS-ON feature. ; ========================================================================================= 401FH CALL 3FFAH ; Load default RST 7 vector table values 4022H LXI H,4084H ; Point to RST 7 RAM hook routine 4025H LXI D,F93DH ; Point Time for ON TIME interrupt to use as our hook routine 4028H LXI B,0006H ; Copy our RST 7 hood to the "ON TIME" time location 402BH CALL 4A05H ; Move BC bytes from HL to DE - copy our hook to RAM 402EH LXI H,F93DH ; Load address of "ON TIM" time where our hook was copied 4031H SHLD FAF4H ; Use our RAM RST 7 Hook for RST 7,1Ah - RUN 4034H SHLD FAF0H ; Use our RAM RST 7 Hook for RST 7,16h - SAVE 4037H SHLD FB38H ; Use our RAM RST 7 Hook for RST 7,5Eh - LOADM and RUNM 403AH SHLD FB36H ; Use our RAM RST 7 Hook for RST 7,5Ch - SAVEM 403DH SHLD FB08H ; Use our RAM RST 7 Hook for RST 7,2Eh - DSKI$ 4040H SHLD FB0AH ; Use our RAM RST 7 Hook for RST 7,30h - OPEN/CLOSE/PRINT/INPUT 4043H SHLD FB2CH ; Use our RAM RST 7 Hook for RST 7,52h - LFILES 4046H SHLD FB32H ; Use our RAM RST 7 Hook for RST 7,58h - KILL 4049H SHLD FB34H ; Use our RAM RST 7 Hook for RST 7,5Ah - NAME 404CH RET ; ========================================================================================= ; Process jump to custom RST 7 Hook routine from Main ROM ; ========================================================================================= 404DH PUSH PSW ; Preserve PSW 404EH LDA FAC9H ; Get address of last RST 38H call argument 4051H CPI 1AH ; RST 7,1Ah Hook - RUN statement 4053H JZ 4451H 4056H CPI 16H ; RST 7,16h Hook - SAVE statement 4058H JZ 44E7H 405BH CPI 5EH ; RST 7,5Eh Hook - LOADM and RUNM statement 405DH JZ 43C1H 4060H CPI 5CH ; RST 7,5Ch Hook - SAVEM statement 4062H JZ 440DH 4065H CPI 2EH ; RST 7,2Eh Hook - DSKI$ function 4067H JZ 4324H 406AH CPI 30H ; RST 7,30h Hook - OPEN/CLOSE/PRINT/LINE INPUT satement 406CH JZ 451DH 406FH CPI 52H ; RST 7,52h Hook - LFILES 4071H JZ 4346H 4074H CPI 58H ; RST 7,58h Hook - KILL 4076H JZ 4377H 4079H CPI 5AH ; RST 7,5Ah Hook - NAME statement 407BH JZ 4396H 407EH POP PSW ; Restore stack frame 407FH MVI E,02H ; Prepare to generate "SN" error 4081H JMP 4C37H ; Generate error in E ; ========================================================================================= ; RST 7 Handler copied to RAM for DOS-ON ; ========================================================================================= 4084H CALL FAA4H ; Call RAM hook to switch to OptROM 4087H JMP 404DH ; Jump to TS-DOS RST 7 handler in OptROM ; ========================================================================================= ; Open TPDD file for Read Mode. File already stored in TX buffer. ; ========================================================================================= 408AH LXI H,0101H ; Load "Open file" opcode 408DH MVI A,03H ; Load OPEN_READ mode into A 408FH STA FCE8H ; Save A in TX data storage (mode location) 4092H JMP 409BH ; Send Request in HL and await response - Open File ; ========================================================================================= ; Send TPDD Write File opcode using RX buffer with length in A ; ========================================================================================= 4095H MOV H,A ; Move length to H 4096H MVI L,04H ; Load TPDD_WRITE opcode to L 4098H JMP 40A7H ; Send TX packet using RX buffer ; ========================================================================================= ; Send Request in HL and await response ; ========================================================================================= 409BH CALL 4822H ; Send TPDD Command/Len in HL 409EH CALL 49F0H ; Wait for data to be ready 40A1H CALL 47CCH ; Copy Receive RX packet routine to RAM and execute it 40A4H JMP 47F8H ; Check RX packet for Normal Response & report errors ; ========================================================================================= ; Use RX buffer to send a TX packet (used to send data). Opcode/len in HL ; ========================================================================================= 40A7H SHLD FD02H ; Save Opcode/len to RX buffer 40AAH LXI H,FD02H ; Storage for RX packet 40ADH CALL 4828H ; Send TPDD pointed to by HL 40B0H CALL 47CCH ; Receive a packet 40B3H JMP 47F8H ; Check RX packet for Normal Response & report errors ; ========================================================================================= ; Send TPDD_READ data opcode and recieve response ; ========================================================================================= 40B6H LXI H,0003H ; Load TPDD_READ opcode 40B9H CALL 4822H ; Send TPDD Command/Len in HL 40BCH CALL 47CCH ; Receive a packet 40BFH LDA FD03H ; Get length byte from RX buffer 40C2H LXI H,FD04H ; Point to return data addres in RX buffer 40C5H CPI 80H ; Test for maximum read length 40C7H RET ; ========================================================================================= ; Write HL bytes of data from (DE) to TPDD ; ========================================================================================= 40C8H PUSH D ; Push address of write-data to stack 40C9H PUSH H ; Push length of data to the stack 40CAH CALL 4101H ; Test free Disk space and issue TPDD_OPEN request 40CDH POP H ; Get address of data from stack 40CEH SHLD FCD5H ; Save length as remaining length to write 40D1H POP H ; Get address of data to write to TPDD from stack 40D2H LXI D,FD04H ; Point to RX buffer to copy write data 40D5H LXI B,0080H ; Prepare to copy 128 bytes of data to the RX buffer ; ========================================================================================= ; Write BC bytes of data from (HL) to (DE) and write to TPDD, DE=RX buffer data pointer ; ========================================================================================= 40D8H CALL 4A05H ; Move BC bytes from M to (DE) with increment 40DBH PUSH H ; Push the updated address to the stack 40DCH LHLD FCD5H ; Get the remaining lenth left to write 40DFH LXI B,0080H ; Prepare to subtract 128 from the length 40E2H DSUB ; Subtract 128 bytes from remaining length to write 40E3H JC 40F4H ; Jump out of loop if less than 128 bytes remaining 40E6H JZ 40F4H ; Jump out of loop if exactly 128 bytes remaining 40E9H SHLD FCD5H ; Save updated length left to write for next pass 40ECH MVI A,80H ; Prepare to write 128 bytes to TPDD 40EEH CALL 4095H ; Send TPDD Write File opcode using RX buffer with length in A 40F1H JMP 40D1H ; Jump to send next packet of 128 bytes ; ========================================================================================= ; Write remaining bytes (128 or less from above) to TPDD ; ========================================================================================= 40F4H POP H ; Clear stack of unneeded updated source address 40F5H LDA FCD5H ; Load A with remainder of bytes to be sent 40F8H CALL 4095H ; Send TPDD Write File opcode using RX buffer with length in A 40FBH LXI H,0002H ; Load TPDD_CLOSE opcode in HL 40FEH JMP 409BH ; Send Request in HL and await response ; ========================================================================================= ; Test if enough space on disk for HL bytes and issue Open request, error if disk full ; ========================================================================================= 4101H LXI D,0500H ; Load decimal 1280 to calculate sector number 4104H XCHG ; Swap HL/DE to perform size/bytes_per_sector 4105H CALL 4C1BH ; Signed integer divide (FAC1=DE/HL) 4108H LDA FD1FH ; Get number of free sectors on disk 410BH SUB L ; Compare required sectors with free space to see if enough room 410CH JC 4881H ; Disk Full Error 410FH JZ 4881H ; Disk Full Error 4112H LDA FCD6H ; Load open mode (new, append, etc.) 4115H STA FCE8H ; Save file open mode to TX buffer 4118H LXI H,0101H ; Load TPDD_OPEN opcode 411BH JMP 409BH ; Send Request in HL and await response ; ========================================================================================= ; Insert BC spaces at address of RAM file being loaded/run ; ========================================================================================= 411EH LHLD FCE2H ; Load address of file being processed 4121H CALL 4C0BH ; Insert BC spaces at M 4124H JC 488AH ; RAM full error ; ========================================================================================= ; Open TPDD file and read data to file address being processed ; ========================================================================================= 4127H LHLD FCE2H ; Get address of file being processed 412AH PUSH H ; Save address on stack 412BH CALL 408AH ; Open TPDD file for Read Mode 412EH CALL 40B6H ; Send TPDD_READ data opcode and recieve response 4131H MOV C,A ; Move read length to C 4132H MVI B,00H ; Clear MSB of copy length 4134H POP D ; Restore address to write data ; ========================================================================================= ; Write BC bytes from M to DE and subtract BC from total file size ; ========================================================================================= 4135H CALL 4A05H ; Move BC bytes from M to (DE) with increment 4138H PUSH D ; Save updated address to stack 4139H LDA FD03H ; Get length byte from RX buffer 413CH LHLD FCDDH ; Get total file size from storage 413FH MOV C,A ; Load count of bytes transfered this block 4140H MVI B,00H ; Clear MSB of count 4142H DSUB ; Subtract this block from total file length 4143H SHLD FCDDH ; Save remaining bytes to be read back to temp storage 4146H JC 414EH ; Branch if too many bytes read 4149H MOV A,L ; Load LSB to A to test for zero 414AH ORA H ; OR MSB to test for zero 414BH JNZ 412EH ; Branch to read more data if not zero 414EH POP D ; Pop address from stack - cleanup 414FH RET ; ========================================================================================= ; Write data to FDC Emulation mode physical/logical sector ; ========================================================================================= 4150H LDA FCDDH ; Get physical sector number 4153H CPI 01H ; Test if physical sector is #1 4155H RZ ; Return if trying to write to sector 1 - reserved!!! 4156H CALL 4998H ; Flush RX queue and discard 4159H MVI A,57H ; Load FDC opcode for "W"rite sector 415BH STA FCD3H ; Save the FDC emulation mode opcode 415EH CALL 42CEH ; Send FDC emulation mode opcode 4161H CALL 4998H ; Flush RX queue and discard 4164H CALL 4176H ; Increment to next logical/physical sector 4167H LHLD FCE4H ; FDC Emulation data pointer address 416AH CALL 48D9H ; Send BC bytes to RS-232 from (HL) using XON/XOFF 416DH SHLD FCE4H ; LCD Buffer address of current file selection 4170H CALL 42EEH ; Read FDC Emulation mode response 4173H JMP 4150H ; Jump to write next sector ??? ; ========================================================================================= ; Increment to next logical/physical sector ; ========================================================================================= 4176H LDA FD09H ; Get byte 7 from the RX buffer (logical sector length) 4179H CALL 4191H ; Get FDC Emulation RAM buffer sector length based on response 417CH CPI 35H ; Test if RAM Buffer logical sector length is "500" (1280) 417EH JZ 4189H ; Just update physical sector if RAM length = physical sector len 4181H LXI H,FCDEH ; Load pointer to logical sector value 4184H INR M ; Increment to next logical sector 4185H MOV A,M ; Get the next logical sector value 4186H CPI 14H ; Test if logical sector = 20 (There are 20 64-byte logical sectors) 4188H RNZ ; Return if not paat end of physical sector 4189H LXI H,FCDDH ; Point to physical sector storage 418CH INR M ; Increment to next physical sector - we "rolled over" 418DH INX H ; Point to logical sector 418EH MVI M,01H ; Start with logical sector #1 in new physical sector 4190H RET ; ========================================================================================= ; Get FDC Emulation RAM buffer sector length based on response code in A ; ========================================================================================= 4191H LXI B,0500H ; Initialize to 1280 byte sector length 4194H CPI 35H ; Compare response to test for "500" 4196H RZ ; Return if match 4197H LXI B,0040H ; Sector lenth not 1280, must be 64 bytes 419AH RET ; ========================================================================================= ; Send TPDD opcode 0x08 - Go to FDC emulation mode ; ========================================================================================= 419BH LXI H,0008H ; Prepare to send Opcode 0x08 (FDC Emulation Mode) 419EH CALL 4822H ; Send TPDD Command/Len in HL 41A1H CALL 49D3H ; Send 0x0D to RS-232 and Delay 3ms 41A4H JMP 4998H ; Flush RX queue and discard ; ========================================================================================= ; Rename the TPDD file whose name is in "current BASIC program" ; ========================================================================================= 41A7H LXI H,FC93H ; Filename of current BASIC program 41AAH LXI D,FCE8H ; Point to data area in TX buffer 41ADH LXI B,0006H ; Move 6 bytes of filename data ; ========================================================================================= ; Rename the TPDD file whose name is in (HL) ; ========================================================================================= 41B0H CALL 4A05H ; Move BC bytes from M to (DE) with increment 41B3H LDA FCCBH ; NADSBox / Desklink / TPDD2 flag 41B6H ANA A ; Test for TPDD server 41B7H JNZ 4258H ; Send TPDD_RENAME opcode and check response ; ========================================================================================= ; Rename on a TPDD. I'm guessing the drive will allow changing a name to something ; that already exists, or there is no "rename", so TS-DOS is reading sector 1 and doing ; the rename opertaion manually, then writing sector 1 back to the disk. ; ========================================================================================= 41BAH CALL 4A72H ; Send Dir Reference opcode 41BDH JNZ 487EH ; File Exists Error 41C0H LXI D,0500H ; Prepare to test for 1280 bytes of free ram (1 sector) 41C3H CALL 4308H ; Test if at least DE bytes of RAM free 41C6H LXI H,0100H ; Load HL with physical sector 1, logical sector 0 41C9H SHLD FCDDH ; Save in FDC Emulation sector storage 41CCH CALL 419BH ; Send opcode 0x08 - go to FDC emulation mode 41CFH CALL 427EH ; Load Physical sector 1 to (HL) (HL=Unused memory pointer) 41D2H LHLD FBB6H ; Get pointer to data - Unused memory pointer 41D5H PUSH H ; Push data pointer to the stack 41D6H MVI B,28H ; Prepare to test up to 40 filenames (max for TPDD) 41D8H LXI D,FC9CH ; Filename of last program loaded from tape 41DBH CALL 4269H ; Compare "Last program loaded" filename with all files on TPDD 41DEH JC 487BH ; Printer not ready / FF error 41E1H MOV A,B ; Get index in TPDD Sector 1 of filename that matches the old filename 41E2H ANA A ; Test if old filename exists 41E3H JZ 487BH ; Jump to error if filename not found in sector 1 - FF error 41E6H PUSH H ; Save address within Sector 1 of matching filename to stack 41E7H LXI D,FCE8H ; Point to TX buffer data area (payload) 41EAH XCHG ; HL <--> DE Prepare to copy new filename to Sector 1 data 41EBH LXI B,0009H ; Prepare to copy 9 bytes of filename 41EEH CALL 4A05H ; Move BC bytes from M to (DE) with increment - copy new filename to sector 1 41F1H POP H ; Restore pointer to filename address within sector 1 41F2H PUSH H ; Save it to the stack again 41F3H LXI D,FD20H ; Load address of data byte 28 in RX buffer 41F6H LXI B,001FH ; Prepare to copy 31 bytes to RX buffer from Sector 1 data 41F9H CALL 4A05H ; Move BC bytes from M to (DE) with increment - Save File data in RX buffer ; ========================================================================================== ; Now we will "remove" the renamed file from sector 1 by copying over it with the remaining ; files in the sector. Filenames in sector 1 must be in alphabetical order, so we have to ; remove it and reinsert it at the new location based on the new name. ; ========================================================================================== 41FCH POP D ; Restore pointer to filename address within sector 1 41FDH PUSH D ; Save it to the stack again 41FEH LXI H,001FH ; Prepare to add 31 bytes to the sector 1 pointer (go to next file) 4201H DAD D ; Point to next file after rename file within sector 1 4202H PUSH H ; Save address of next file after rename file to stack 4203H LHLD FBB6H ; Unused memory pointer 4206H LXI B,0500H ; Load size of 1 TPDD sector (1280 bytes) 4209H DAD B ; Point to end of sector 1 data in free memory region 420AH POP B ; Restore address of next file after rename file from stack 420BH PUSH B ; Save it back to the stack 420CH DSUB ; Calculate number of bytes from next file after rename to end of sector 1 420DH XTHL ; HL <--> (SP) Prepare to move HL to BC, HL now has address of next file 420EH POP B ; Get byte count to end of sector 1 420FH CALL 4A05H ; Move BC bytes from M to (DE) with increment - shift bytes "left" in buffer 4212H LHLD FBB6H ; Unused memory pointer - point to beginning of Sector 1 data 4215H MVI B,27H ; Prepare to search throuh 39 files (we just deleted one) 4217H LXI D,FD20H ; Load address of data byte 28 in RX buffer (our saved file) 421AH CALL 4269H ; Search Sector-1 files at (HL) for filename at (DE) 421DH PUSH H ; Save address of location where file should be inserted in Sector 1 421EH LHLD FBB6H ; Unused memory pointer - point to beginning of Sector 1 4221H LXI B,04FFH ; Prepare to move bytes "right" to end of sector (1280 bytes - 1) 4224H DAD B ; Point to end of sector 1 data 4225H PUSH H ; Save end of sector 1 address to stack 4226H LXI B,001FH ; Prepare to subtract 1 file entry length from end of sector 1 address 4229H DSUB ; Shorten the copy operation by 1 file entry so we don't overflow memory 422AH POP D ; Get end of sector 1 address from stack as our "copy to" address 422BH POP B ; Get address where file needs to be inserted from the stack 422CH PUSH B ; Save it back to the stack for later 422DH PUSH H ; Save address of end of Sector 1 minus one file entry length to stack 422EH DSUB ; Calculate the copy lenght of data from insertion point to end of sector-1 file 422FH PUSH H ; Save copy length to the stack to copy it to BC 4230H POP B ; Get copy length into BC 4231H INX B ; Increment length by 1 so the last byte is inclusive 4232H POP H ; Get address of file insertion point from stack 4233H CALL 4C4EH ; Move BC bytes from M to (DE) with decrement - shift files "right" in sector 1 4236H LXI H,FD20H ; Get address of our saved file info in the RX buffer 4239H POP D ; Get address in Sector 1 of file insertion point 423AH LXI B,001FH ; Prepare to copy 1 file entry size (31 bytes) 423DH CALL 4A05H ; Move BC bytes from M to (DE) with increment ; =============================================================================== ; Seems like the next two lines don't do anything. The value being loaded in HL ; *appears* to mean "Logical sector 20, physical sector 1", but only if the SHLD ; target address is FCCDH. Then 5 instructions further down, the value in ; ED80h is overwritten with logical sector 0. ; =============================================================================== 4240H LXI H,1401H ; Set L = logical sector 1, H=File type 0x14? 4243H SHLD FCDEH ; Save logical sector & filetype 4246H POP H ; POP stale address within Sector 1 of matching filename from stack 4247H POP H ; Get address of unused memory (Sector 1 data storage) from stack 4248H SHLD FCE4H ; Save in FDC Emulation data pointer address 424BH LXI H,0100H ; Load HL= logical sector 1, physical sector 0 424EH SHLD FCDDH ; Save in FDC Emulation physical/logical sector storage 4251H CALL 4150H ; Write data to FDC Emulation mode physical/logical sector 4254H CALL 49CDH ; Send "M1",0x0D to RS-232 and delay about 3ms - go to Standard mode 4257H RET ; ========================================================================================= ; Send TPDD_RENAME opcode and check response for errors ; ========================================================================================= 4258H LXI H,190DH ; Load TPDD_RENAME opcode 425BH CALL 4822H ; Send TPDD Command/Len in HL 425EH CALL 47CCH ; Receive a packet 4261H LDA FD04H ; Get response error code 4264H ANA A ; Check for errors 4265H JNZ 487EH ; Report File Exists Error if not zero 4268H RET ; ========================================================================================= ; Search Sector-1 files at (HL) for filename at (DE), maximum of "B" entries searched ; ========================================================================================= 4269H MVI C,09H ; Prepare to compare 9 bytes 426BH CALL 4A1CH ; Compare (HL) with (DE), C bytes long (HL & DE preserved) 426EH RZ ; Return if they are the same 426FH RC ; Return if filename is less (files are sorted on TPDD) 4270H MOV A,M ; Get 1st byte of filename to test for NULL 4271H ORA A ; Test if A is 0 4272H RZ ; Return if string is NULL 4273H PUSH B ; Save BC on stack 4274H LXI B,001FH ; Prepare to add 31 to HL 4277H DAD B ; Add 31 to HL 4278H POP B ; Restore original BC 4279H DCR B ; Decrement loop counter 427AH RZ ; Return if no more items to compare 427BH JMP 4269H ; Jump to compare next entry ; ========================================================================================= ; Read FDC sectors to New File Address (Free memory) ; ========================================================================================= 427EH LHLD FCE2H ; Get pointer for TPDD read data 4281H CALL 4298H ; Read sector A into (HL) 4284H LDA FCDDH ; Load current FDC Emulation physical sector number 4287H DCR A ; Decrement to previous sector 4288H RZ ; Return if sector number is zero 4289H JMP 4281H ; Jump to read another sector (what breaks the loop? - A not saved) ; ========================================================================================= ; Receive RX bytes to (HL) routine copied to RAM ; ========================================================================================= 428CH CALL 6D7EH ; Get a character from RS232 receive queue 428FH MOV M,A ; Save next byte to (HL) 4290H INX H ; Increment pointer 4291H DCX B ; Decrement counter 4292H MOV A,C ; Prepare to test or zero 4293H ORA B ; OR in MSB of coutner 4294H JNZ FD89H ; Jump back to receive next character (RAM address) 4297H RET ; ========================================================================================= ; Read FDC sector A to (HL), BC has length ; ========================================================================================= 4298H PUSH H ; Save target address for RX data stack 4299H MVI A,52H ; Load FDC Emulation opcode for "R"ead 429BH STA FCD3H ; Save as FDC Emulation opcode to send 429EH CALL 42CEH ; Send FDC emulation mode opcode 42A1H CALL 4176H ; Increment to next logical/physical sector 42A4H CALL 4862H ; Test if DSR is set - drive ready, error otherwise 42A7H PUSH B ; Save length of RX to the stack 42A8H LXI H,428CH ; Load address of RX routine to copy to RAM 42ABH LXI B,000CH ; Size of the RX routine to be copied to RAM 42AEH LXI D,FD89H ; Target address of RX routine (in ALTLCD buffer) 42B1H CALL 4A05H ; Move BC bytes from M to (DE) with increment 42B4H MVI A,0DH ; Prepare to send CR to RS-232 42B6H CALL 485FH ; Send A to RS-232 using XON/XOFF 42B9H CALL 4BDBH ; Call Main ROM's Set interrupt to 1DH routine. 42BCH POP B ; Restore count of bytes to receive 42BDH POP H ; Restore target address for RX data 42BEH RST 1 ; Call main ROM at address in following 2 bytes 42BFH DW FD89H ; Switch to Main ROM and call our RAM based RX routine 42C1H RET ; ========================================================================================= ; Convert decimal value in A to base 10 ASCII value in BC ; ========================================================================================= 42C2H MVI B,2FH ; Start with '0' - 1 42C4H SUI 0AH ; Subtract 10 from A 42C6H INR B ; Increment B (10's position) 42C7H JNC 42C4H ; Keep looping until A negative 42CAH ADI 3AH ; Convert negative remainder to positive ASCII '0'-'9' 42CCH MOV C,A ; Store LSB ASCII value in C 42CDH RET ; ========================================================================================= ; Send FDC emulation mode opcode ; ========================================================================================= 42CEH LDA FCDDH ; Get physical sector number 42D1H CALL 42C2H ; Convert A to 10-based ASCII 42D4H LDA FCD3H ; Load the FDC emulation mode opcode to send 42D7H CALL 485FH ; Send A to RS-232 using XON/XOFF 42DAH CALL 49DBH ; Send BC to RS-232 using XON/XOFF - send physical sector # 42DDH LDA FCDEH ; Get logical sector number 42E0H CALL 42C2H ; Convert A to 10-based ASCII 42E3H MVI A,2CH ; Load code for ',' 42E5H CALL 485FH ; Send A to RS-232 using XON/XOFF 42E8H CALL 49DBH ; Send BC to RS-232 using XON/XOFF - send logical sector # 42EBH CALL 49D3H ; Send 0x0D to RS-232 and Delay 3ms ; ========================================================================================= ; Read FDC Emulation mode response ; ========================================================================================= 42EEH LXI H,FD04H ; Point to RX buffer data area 42F1H PUSH H ; Save RX buffer address on stack 42F2H MVI C,08H ; Prepare to read 8 bytes from RX - standard FDC response length 42F4H CALL 47E5H ; Get next byte from RX into HL 42F7H DCR C ; Decrement loop counter 42F8H JNZ 42F4H ; Keep looping until 8 bytes read 42FBH POP H ; Get start of RX buffer address from stack 42FCH MOV A,M ; Get first response byte 42FDH CPI 30H ; Test if response error code is '0' - no error 42FFH RZ ; Return if no error 4300H CPI 42H ; Test for FDC Emulation mode "write protect" error code 4302H JZ 486DH ; Write Protect Error 4305H JMP 4867H ; Drive Not Ready Error ; ========================================================================================= ; Test if at least DE bytes of RAM left ; ========================================================================================= 4308H LHLD FBB6H ; Unused memory pointer 430BH PUSH H ; Push unused memory location on stack 430CH SHLD FCE2H ; Save unused memory location locally 430FH LXI H,FFC0H ; Prepare to subtract 64 from stack pointer 4312H DAD SP ; Add SP to HL (-64) (need some call space to run program) 4313H POP B ; Restore unused memory location in BC 4314H DSUB ; Subtract stack from unused memory pointer 4315H RST 3 ; Compare DE and HL - check if enough free RAM 4316H JC 488AH ; RAM full error 4319H RET ; ========================================================================================= ; Issue TPDD Delete file Opcode ; ========================================================================================= 431AH XRA A ; Prepare to indicate we can't use Next Dir feature 431BH STA FD01H ; Save in dir reference location in TX buffer 431EH LXI H,0005H ; Load Delete File opcode into HL 4321H JMP 409BH ; Send Request in HL and await response ; ========================================================================================= ; RST 7,2Eh Hook - DSKI$ function ; ========================================================================================= 4324H POP PSW ; Pop return address - we will return manually to Main ROM 4325H CPI 30H ; Test A against '0' to check for bounds (only allow '0' and '1') 4327H JC 00A6H ; Return to Main ROM if less than '0' - not our's 432AH CPI 32H ; Test A against '2' to check for bounds 432CH JNC 00A6H ; Return to Main ROM if >= '2' 432FH SUI 30H ; Convert ASCII bank number to binary 4331H STA FCCAH ; Save the target bank number in TPDD2 Bank number space 4334H INX H ; Point to next byte to ensure it is ':' 4335H DCR E ; ? Maybe length 4336H MOV A,M ; Get next byte of filename 4337H CPI 3AH ; Test if it is ':' 4339H JNZ 00A6H ; Return if not ':' 433CH INX H ; Increment to filename portion 433DH DCR E ; ? Maybe length 433EH XTHL ; Put pointer to filename on stack so we don't lose it when we pop 433FH POP H ; Pop so we return to our caller's return address 4340H MVI A,09H ; Load A with a value we will test for later to see if it's our file 4342H ORA A ; Set return flags 4343H JMP 00A6H ; Return to Main ROM ; ========================================================================================= ; RST 7,52h Hook - LFILES function ; ========================================================================================= 4346H POP PSW ; POP return address from stack...we will return manually 4347H PUSH D ; Preserve DE on STACK 4348H PUSH H ; Preserve HL on STACK 4349H PUSH PSW ; Preserve A on STACK 434AH XRA A ; Flag to generate system errors vs. printing 434BH CALL 4A85H ; Save OS's baud rate string to storage area 434EH LDES 02H ; DE = SP + 2 4350H LHLX ; Get value of HL pushed to stack above - LFILES argument pointer 4351H MOV A,M ; Get 1st byte of argument 4352H ANA A ; Test if arguement is zero 4353H JZ 436AH ; Jump to display files from current TPDD bank number if zero 4356H CPI 3AH ; Test if 1st byte is ':' 4358H JZ 436AH ; Jump to display files from current TPDD bank number if ':" 435BH CALL 4BCFH ; Evaluate expression at M-1 - Convert "0:" or "1:" to decimal 435EH MOV A,E ; Get result of evaluation 435FH CPI 02H ; Compare result for bounds 4361H JNC 4370H ; Jump to exit routine if not 0 or 1 4364H STA FCCAH ; Save as TPDD2 Bank number 4367H LDES 02H ; DE = SP + 2 4369H SHLX ; Save updated expression pointer to stack location prior to RST 7 436AH CALL 4704H ; Display / print all files and free space 436DH CALL 4AC4H ; Restore original baud settings ; ========================================================================================= ; RST 7 Hook exit routine ; ========================================================================================= 4370H POP PSW ; Get preserved A from stack 4371H POP H ; Get preserved HL from stack 4372H POP D ; Get preserved DE from stack 4373H POP B ; B isn't PUSHed in the Hook routines, POP the return address 4374H JMP 00A6 ; Return to the Main ROM ; ========================================================================================= ; RST 7,58h Hook - KILL statement ; ========================================================================================= 4377H POP PSW ; POP the return address - we will return manually 4378H CPI 09H ; Test if we found "0:" or "1:" in the DSKI$ function 437AH JNZ 4516H ; Generate FC error 437DH PUSH D ; Preserve DE on the stack 437EH PUSH H ; Preserve HL on the stack 437FH PUSH PSW ; Preserve A on the stack 4380H XRA A ; Flag to generate system errors vs. printing 4381H CALL 4A85H ; Save OS's baud rate string to storage area 4384H LXI H,FC93H ; Filename of current BASIC program 4387H CALL 4A57H ; Send Dir Reference for filename at (HL) 438AH JZ 487BH ; "FF" error if attribute byte is zero 438DH CALL 431AH ; Issue TPDD Delete file Opcode 4390H CALL 4AC4H ; Restore original baud settings 4393H JMP 4370H ; RST 7 Hook exit routine ; ========================================================================================= ; RST 7,5Ah Hook - NAME statement ; ========================================================================================= 4396H POP PSW ; POP the return address - we will return manually 4397H CPI 09H ; Test if we found "0:" or "1:" in the DSKI$ function 4399H JNZ 4516H ; Generate FC error 439CH PUSH D ; Preserve DE on the stack 439DH PUSH H ; Preserve HL on the stack 439EH PUSH PSW ; Preserve A on the stack 439FH XRA A ; Flag to generate system errors vs. printing 43A0H CALL 4A85H ; Save OS's baud rate string to storage area 43A3H LXI H,FC9CH ; Filename of last program loaded from tape 43A6H CALL 4A57H ; Send Dir Reference for filename at (HL) 43A9H JZ 487BH ; "FF" error if attribut byte is zero 43ACH LXI H,FCE8H ; Point to TX buffer data area (payload) 43AFH LXI D,FC9CH ; Filename of last program loaded from tape 43B2H LXI B,0009H ; Prepare to copy 9 bytes of filename 43B5H CALL 4A05H ; Move BC bytes from M to (DE) with increment 43B8H CALL 41A7H ; Rename the TPDD file whose name is in "current BASIC program" 43BBH CALL 4AC4H ; Restore original baud settings 43BEH JMP 4370H ; RST 7 Hook exit routine ; ========================================================================================= ; RST 7,5Eh Hook - LOADM and RUNM statement ; ========================================================================================= 43C1H POP PSW 43C2H CPI 09H ; Test if we found "0:" or "1:" in the DSKI$ function 43C4H JNZ 00A6H ; Return if not a TPDD file 43C7H POP B ; Pop return address from stack - we will jump manually to exit 43C8H PUSH H ; Preserve HL on the stack 43C9H LXI B,4F43H ; Load code for "CO" filename extension 43CCH CALL 44BAH ; Compare extension in current BASIC program filename with value in BC 43CFH JZ 487BH ; "FF" Printer not ready error 43D2H CALL 408AH ; Open TPDD file for Read Mode 43D5H LHLD FD1DH ; Get file size parameter from RX buffer 43D8H MOV A,L ; Swap endianness of file size 43D9H MOV L,H ; Move MSB to LSB 43DAH MOV H,A ; Move LSB to MSB 43DBH SHLD FCDDH ; Save endian modified length back to storage 43DEH CALL 40B6H ; Send TPDD_READ data opcode and recieve response, HL=RX buf upon return 43E1H CALL 4C6AH ; Copy CO header bytes (6) from (HL) to "active" CO Header storage area 43E4H PUSH H ; Push updated (+6) RX data pointer to stack 43E5H CALL 4C6EH ; Go print CO address, length and invocation address to LCD 43E8H LHLD FACEH ; Address of CO Header - get CO load address 43EBH PUSH H ; Push CO load address to stack 43ECH PUSH H ; Push another copy to the stack to preserve value during XTHL/POP 43EDH LHLD F5F4H ; RST 5.5 RAM Vector 43F0H XTHL ; HL <--> (SP) Load RST 5.5 RAM vector as return address 43F1H POP B ; BC now has RST 5.5 RAM Vector, HL= CO load address 43F2H DSUB ; Test if CO load address is less that RST 5.5 RAM address 43F3H JC 488AH ; Trying to clober RST5.5 RAM vectors - generate RAM full error 43F6H POP D ; Get CO load address saved on stack 43F7H POP H ; Get Updated (+6) RX data pointer from stack 43F8H LDA FD03H ; Load RX Length byte from RX data buffer 43FBH SUI 06H ; Subtract CO header length from packet data length 43FDH MOV C,A ; Save packet data length in BC 43FEH MVI B,00H ; Make MSB of BC zero 4400H CALL 4135H ; Write BC bytes from M to DE and subtract BC from total file size 4403H CALL 4AC4H ; Restore original baud settings 4406H LXI H,251AH ; Load new return address in Main ROM 4409H PUSH H ; Push new return address to stack 440AH JMP 00A6H ; Jump to Main ROM ; ========================================================================================= ; RST 7,5Ch Hook - SAVEM statement ; ========================================================================================= 440DH POP PSW ; POP the return address - we will return elsewhere 440EH CPI 09H ; Test if we found "0:" or "1:" in the DSKI$ function 4410H JNZ 00A6H ; Return if not a TPDD file 4413H CALL 4C72H ; Process SAVEM arguments for address, length and entry point 4416H LXI B,4F43H ; Load code for "CO" file extension 4419H CALL 44BAH ; Compare ext. in current BASIC program with BC, send dir ref. if match 441CH JNZ 487EH ; Jump to generate File Exists Error if found 441FH MVI A,01H ; Set open mode for new file 4421H STA FCD6H ; Save open mode to input variable 4424H LHLD FAD0H ; Length of last program loaded/saved to tape 4427H LXI B,0006H ; Prepare to add CO header size (6 bytes) to required length 442AH PUSH B ; Push CO header length to stack 442BH DAD B ; Add CO header size to required length 442CH PUSH H ; Push updated file length to stack 442DH CALL 4101H ; Test free Disk space and issue TPDD_OPEN request 4430H POP H ; Get updated file length from stack 4431H SHLD FCD5H ; Save as lenght of file being saved / loaded 4434H POP B ; Get CO header length from stack 4435H LXI H,FACEH ; Load address of "active" CO header block 4438H LXI D,FD04H ; DE points to the data area in RX buffer 443BH CALL 4A05H ; Move BC bytes from M to (DE) with increment 443EH LHLD FD04H ; DE points to the data area in RX buffer 4441H LXI B,007AH ; Prepare to write 122 bytes of data to next location in RX buffer 4444H CALL 40D8H ; Write 122 bytes from (HL) and send TPDD_WRITE to TPDD 4447H CALL 4AC4H ; Restore original baud settings 444AH LXI H,0501H ; Load return address in Main ROM - vector to BASIC ready 444DH PUSH H ; Push return address to stack 444EH JMP 00A6H ; Return to Main ROM ; ========================================================================================= ; RST 7,1Ah Hook - RUN statement ; ========================================================================================= 4451H POP PSW 4452H CPI 09H ; Test if we found "0:" or "1:" in the DSKI$ function 4454H JNZ 00A6H ; Return if not TPDD file 4457H POP B ; Get return address from stack 4458H POP PSW ; Get 1st byte of RUN statement argument 4459H PUSH PSW ; Put back the data we stole 445AH PUSH B ; Put back the return address 445BH JZ 00A6H ; Return if there were no arguments to the RUN statement 445EH SBB A ; Clear zero flag (C is set and A=0xFF) 445FH STA FC92H ; Save in flag to execute BASIC program (non-zero = execute) 4462H LXI B,4142H ; Load code for "BA" BASIC file extension 4465H CALL 44BAH ; Compare ext. in current BASIC program with BC, send dir ref. if match 4468H JZ 487BH ; Jump to error if not "BA" or " " - generate "FF" error 446BH LHLD FD1DH ; Get file size parameter from RX buffer 446EH MOV C,H ; Swap endianness of file size 446FH MOV B,L ; Swap LSB to MSB 4470H MOV H,B ; Copy file size parameter back to HL 4471H MOV L,C ; Copy LSB of file size to HL 4472H SHLD FCDDH ; Store length of file 4475H CALL 44ABH ; Call NEW statement, upon return HL=address of last variable assigned 4478H INX H ; Increment to free memory space 4479H SHLD FCE2H ; Save as address of file being loaded/saved/etc. 447CH LHLD FCDDH ; Get disk file length 447FH PUSH H ; Save file length on stack 4480H PUSH H ; Push file length to stack to copy to BC 4481H POP B ; Pop file length to BC 4482H CALL 411EH ; Insert BC spaces at address of RAM file being loaded/run 4485H POP D ; Get length of disk file from stack 4486H LHLD FBAEH ; Load Start of DO files pointer 4489H DAD D ; Increment Start of DO files pointer by disk file length 448AH SHLD FBAEH ; Save updated Start of DO files pointer 448DH LHLD FAD8H ; Load pointer to address used for RAM Input processing 4490H DAD D ; Increment pointer by disk file length 4491H SHLD FAD8H ; Save updated RAM Input processing pointer 4494H CALL 4AC4H ; Restore original baud settings 4497H XRA A ; Clear zero flag and A 4498H LXI H,23F5 ; Load address in Main ROM to configure and execute current BASIC programH 449BH PUSH H ; Push return address to stack 449CH JMP 00A6H ; Return to Main ROM ; ========================================================================================= ; Call "BASIC NEW" helper routine. This get's copied to RAM below. ; ========================================================================================= 449FH XRA A ; Prepare to switch to Main ROM 44A0H OUT E0H ; Switch to Main ROM 44A2H CALL 20FFH ; Call BASIC NEW statement 44A5H CALL FAA4H ; Switch back to OptROM 44A8H JMP 4478H ; Jump back into RST 7,1Ch Hook - RUN statement ; ========================================================================================= ; Copy "BASIC NEW" helper routine to RAM and Jump to it --- Call Main ROM's NEW statement ; ========================================================================================= 44ABH LXI H,449FH ; Point to helper function to copy to RAM 44AEH LXI D,FD89H ; RAM destination 44B1H LXI B,000CH ; Length of helper funciton 44B4H CALL 4A05H ; Copy helper to RAM 44B7H JMP FD89H ; Branch to helper function ; ========================================================================================= ; Compare current BASIC program file extension with value in BC or " " ; ========================================================================================= 44BAH PUSH PSW ; Preserve A on Stack 44BBH PUSH H ; Preserve HL on Stack 44BCH PUSH D ; Preserve DE on Stack 44BDH PUSH B ; Preserve comparison file extension on Stack 44BEH LHLD FC99H ; Load 2 extension field bytes of current BASIC program name 44C1H LXI D,2020H ; Load 2 spaces (0x20) into DE 44C4H RST 3 ; Test if filename extension in current BASIC program is " " 44C5H JZ 44D6H ; Jump if current BASIC program filename extension is " " 44C8H POP D ; Get comparison file extension from stack into DE 44C9H PUSH D ; Push file extension back to stack for storage 44CAH RST 3 ; Test if current BASIC program filename extension matches BC 44CBH JZ 44D6H ; Jump if current BASIC program filename extension matches BC 44CEH POP B ; Get BC back off stack 44CFH POP D ; Recover DE from stack 44D0H POP H ; Recover HL from stack 44D1H POP PSW ; Recover A & flags from stack 44D2H POP B ; Pop return address - File extension doesn't match so don't run 44D3H JMP 00A6H ; Return to Main ROM ; ========================================================================================= ; Store expected extension (on stack) to current BASIC program and send dir reference for ; the disk file ; ========================================================================================= 44D6H POP H ; Get expected file extension "BA" or "CO" from stack 44D7H SHLD FC99H ; Save to 2 extension field bytes of current BASIC program name 44DAH POP D ; Restore DE from stack 44DBH POP H ; Restore HL from stack 44DCH POP PSW ; Restore A from stack 44DDH XRA A ; Flag to generate system errors vs. printing 44DEH CALL 4A85H ; Save OS's baud rate string to storage area 44E1H LXI H,FC93H ; Filename of current BASIC program 44E4H JMP 4A57H ; Send Dir Reference for filename at (HL) ; ========================================================================================= ; RST 7,16h Hook - SAVE statement ; ========================================================================================= 44E7H POP PSW ; POP return address, we will return manually 44E8H CPI 09H ; Test if we found "0:" or "1:" in the DSKI$ function 44EAH JNZ 00A6H ; Return if not a TPDD file 44EDH LXI B,4142H ; Load code for "BA" basic extension 44F0H CALL 44BAH ; Compare extension in current BASIC program filename with value in BC 44F3H JNZ 487EH ; File Exists Error 44F6H CALL 4C66H ; Update line addresses for current BASIC program 44F9H LHLD F67CH ; Start of BASIC program pointer 44FCH XCHG ; HL <--> DE DE=BASIC program strt, HL=BASIC program end 44FDH RST 3 ; Compare DE and HL 44FEH JZ 450FH ; Vector to BASIC ready - print Ok if BASIC start=BASIC end 4501H PUSH D ; Save start of BASIC program to stack 4502H POP B ; POP start of BASIC program from stack 4503H DSUB ; Subtract BASIC start address from BASIC end address 4504H MVI A,01H ; Set file open mode for new file 4506H STA FCD6H ; Save open mode to pass to function 4509H CALL 40C8H ; Write HL bytes of data from (DE) to TPDD 450CH CALL 4AC4H ; Restore original baud settings 450FH LXI H,0502H ; Load address in Main ROM of Vector to BASIC ready - print Ok 4512H PUSH H ; Push new return address to stack 4513H JMP 00A6H ; Return to Main ROM ; ========================================================================================= ; Return to Main ROM's Generate FC Error routine ; ========================================================================================= 4516H LXI H,08DBH ; Load address of Generate FC error routine 4519H PUSH H ; Push return address to the stack 451AH JMP 00A6H ; Return to Main ROM ; ========================================================================================= ; RST 7,30h Hook - OPEN/CLOSE/READ/WRITE/LINE INPUT statement ; ========================================================================================= 451DH XRA A ; Clear A to set print error flag 451EH STA FCD2H ; Set flag to generate system errors vs. print 4521H POP PSW ; POP return address ... returning manually 4522H SHLD FCCEH ; Save HL in Stack pointer upon entry location 4525H PUSH D ; Preserve DE on stack 4526H PUSH H ; Preserve HL on stack 4527H PUSH PSW ; Preserve A on stack 4528H LXI D,0004H ; Offset of the file descriptor address MSB 452BH DAD D ; Point to the file descriptor address MSB 452CH MOV A,M ; Get MSB address of FD 452DH CPI 09H ; Test if we found "0:" or "1:" in the DSKI$ function 452FH JZ 4538H ; Jump to process the sub-operation code if it's a TPDD file ; ========================================================================================= ; RST 7,30h Hook exit routine ; ========================================================================================= 4532H POP PSW ; Restore A from stack 4533H POP H ; Restore HL from stack 4534H POP D ; Restore DE from stack 4535H JMP 00A6H ; Return to Main ROM ; ========================================================================================= ; Test the RST 7,30h sub-operation code and vector to the proper handler function ; ========================================================================================= 4538H POP PSW ; Retrieve A from the stack - contains sub-operation code 4539H PUSH PSW ; Restore to stack 453AH CPI 00H ; Test for OPEN sub-operation 453CH JZ 455CH 453FH CPI 02H ; Test for CLOSE sub-operation 4541H JZ 45E8H 4544H CPI 04H ; Test for PRINT # sub-operation 4546H JZ 46B0H 4549H CPI 06H ; Test for EOF sub-operation 454BH JZ 4607H 454EH CPI 08H ; Test for LINE INPUT sub-operation 4550H JNZ 4532H 4553H LDES 06H ; Get stack location upon entry (we pushed 3 times = 6 bytes) in DE 4555H LXI H,161BH ; Not an operation we care about, load address for "Special RAM IO" routine 4558H SHLX ; Replace our return address so we return to "Special RAM IO" routine instead 4559H JMP 4532H ; Jump to RST 7,32h exit routine ; ========================================================================================= ; RST 7,30h OPEN sub-operation ; ========================================================================================= 455CH XRA A ; Generate system errors vs. printing 455DH CALL 4A85H ; Save OS's baud rate string to storage area 4560H LXI H,FC99H ; Load address of 1st extension byte of current BASIC program filename 4563H MOV A,M ; Get 1st byte of file extension from current BASIC program 4564H CPI 20H ; Test if opening a file with no extension 4566H JZ 456EH ; Branch to proivde "DO" default extension if non provided 4569H CPI 44H ; Test if A is 'D' - opening a "DO" file 456BH JNZ 488DH ; Generate system error 0x0C - ID Error 456EH MVI M,44H ; Change 1st extension byte to 'D' 4570H INX H ; Increment to 2nd extension byte 4571H MVI M,4FH ; Change 2nd extension byte to 'O' 4573H LXI H,FC93H ; Filename of current BASIC program 4576H CALL 4A57H ; Send Dir Reference for filename at (HL) 4579H MOV C,A ; Move attribute byte to C 457AH CALL 465BH ; Calculate offset of BASIC instruction file # EOF marker 457DH MVI M,00H ; Set EOF marker to zero - not EOF 457FH POP H ; POP PSW and discard 4580H POP H ; Restore address of FD control 4581H POP D ; Restore DE 4582H PUSH D ; Save DE back to stack 4583H PUSH H ; Save FD control address back to stack 4584H MOV D,C ; Save TPDD file attribute byte to D 4585H MOV A,E ; Move open mode to A (8=Append,1=Read,2=Write) 4586H ANI 07H ; Mask all but lower 3 bits so we get 0, 1, or 2 4588H LXI H,4AE4H ; Get address of RST 7,32h open mode to TPDD Open mode mapping 458BH MOV C,A ; Save mapping mode table offset to C 458CH MVI B,00H ; Clear MSB of offset for 16-bit add 458EH DAD B ; Calculate index address into mapping table 458FH MOV A,M ; Load TPDD open mode from mapping 4590H DCR A ; Test if TPDD open mode is Write 4591H JZ 45CDH ; Jump if opening for write mode 4594H DCR A ; Test if TPDD open mode is Append 4595H JNZ 45E0H ; Jump to open TPDD for Read mode if not zero 4598H LDA FD1CH ; Load attribute byte from RX buffer 459BH ANA A ; Opening for Append, test if file already exists 459CH JNZ 45A1H ; Jump to perform open for append if file already exists 459FH INX H ; Opening for append but file doesn't exist, increment mapping to Write 45A0H INX H ; Increment again to skip "read" mapping in table ; ========================================================================================= ; Open TPDD file with open mode as specified by RST 7,32h mapping table ; ========================================================================================= 45A1H MOV A,M ; Reload the TPDD open mode from the mapping table 45A2H STA FCE8H ; Point to TX buffer data area (payload) 45A5H LXI H,0101H ; Load TPDD_OPEN opcode in HL 45A8H CALL 409BH ; Send Request in HL and await response 45ABH LHLD FCCEH ; Get address of FD control 45AEH LXI D,0007H ; Load offset of write buffer length within FD control 45B1H DAD D ; Point to write buffer length within FD control 45B2H XRA A ; Clear A 45B3H MOV M,A ; Set the write buffer length to zero - just opened the file 45B4H INX H ; Increment to write buffer output pointer address 45B5H MOV D,H ; Save HL to DE to update write buffer output pointer 45B6H MOV E,L ; Save LSB of HL to DE 45B7H INX H ; Increment to MSB of write buffer output pointer 45B8H INX H ; Increment to write buffer location 45B9H SHLX ; Reset write buffer output poiner to beginning of buffer 45BAH POP H ; Restore address of FD control 45BBH POP D ; Restore DE from stack 45BCH MOV A,E ; Load RST 7,32h open mode into A 45BDH CPI 08H ; Test if open mode is Append 45BFH JNZ 45C4H ; Jump to retain open mode if not append 45C2H MVI E,02H ; Change Append open mode value to "Write" 45C4H MOV M,E ; Save open status to FD control 45C5H XTHL ; HL <--> (SP) Prepare to change our return address, saving HL 45C6H LXI H,14DEH ; Load new return address in ROM "LCD and PRT file open" routine 45C9H XTHL ; Put return address back to stack, restoring HL 45CAH JMP 00A6H ; Return to the new address in LCD and PRT file open routine in Main ROM ; ========================================================================================= ; RST 7,30h open file for write mode. The Attribute byte from the Dir Ref opcode is in D ; ========================================================================================= 45CDH MOV A,D ; Get the File attribute byte from the Dir Reference operation 45CEH ORA A ; Test if the file exists (will be 'F' if the file exists) 45CFH JZ 45A1H ; Jump to create the file if it doesn't already exist 45D2H PUSH H ; Save HL to the stack for restoration 45D3H CALL 431AH ; Issue TPDD Delete file Opcode - Overwriting existing file 45D6H LXI H,FC93H ; Filename of current BASIC program 45D9H CALL 4A57H ; Send Dir Reference for filename at (HL) - Need new Dir Ref 45DCH POP H ; Restore HL from stack 45DDH JMP 45A1H ; Open TPDD file with open mode as specified by RST 7,32h mapping table ; ========================================================================================= ; RST 7,30h open file for read mode. Ensure the file exists via the attribute byte in D ; ========================================================================================= 45E0H MOV A,D ; Load the file attribute byte from the Dir Ref opcode 45E1H ORA A ; Test if attribute byte is zero 45E2H JZ 487BH ; Generate "FF" error if file doesn't exist 45E5H JMP 45A1H ; Jump to open the file ; ========================================================================================= ; RST 7,30h Sub command - CLOSE FILE ; ========================================================================================= 45E8H POP PSW ; Retrieve A PUSHed by RST 7,32a entry 45E9H POP H ; Retrieve HL 45EAH POP D ; Retrieve DE 45EBH PUSH H ; Save FD control pointer to stack 45ECH MOV A,M ; Get FD control status byte 45EDH MVI M,00H ; Change FD control status to "closed" 45EFH CPI 02H ; Test if status 45F1H CZ 46DDH ; Call flush output buffer routine if opened for write mode 45F4H LXI H,0002H ; Load TPDD_CLOSE opcode into HL 45F7H CALL 409BH ; Send Request in HL and await response 45FAH CALL 4AC4H ; Restore original baud settings 45FDH POP H ; Restore FD control pointer 45FEH XTHL ; HL <--> (SP) so we can preserve HL through POP 45FFH POP H ; Pop return address (actually FD control address) from stack 4600H LXI H,4D59H ; Load new reuturn address - LCD, CRT, and LPT file close routine 4603H PUSH H ; Push new return address to stack - not returning to caller 4604H JMP 00A6H ; Return to Main ROM ; ========================================================================================= ; RST 7,30h Sub command - EOF ; ========================================================================================= 4607H CALL 465BH ; Calculate offset of BASIC instruction file # EOF marker 460AH MOV A,M ; Get the current EOF marker 460BH MVI M,00H ; Set the EOF marker to zero to reset it 460DH ANA A ; Test if at EOF for this file 460EH JNZ 4627H ; Jump if EOF marker for this file not zero 4611H LHLD FCCEH ; Get address of FD control 4614H LXI B,0007H ; Offset of write buffer length within FD control 4617H DAD B ; Point to write buffer length 4618H MOV A,M ; Get current write buffer length 4619H INX H ; Point to LSB of read/write buffer output pointer within FD control 461AH PUSH H ; Save address of read/write buffer output pointer to stack 461BH ANA A ; Test if data left in the buffer 461CH CZ 4663H ; Call to read more data from TPDD if buffer empty 461FH POP D ; Restore address of read/write output buffer within FD control 4620H LHLX ; Get current read/write pointer location from FD control 4621H MOV A,M ; Read the next byte from the buffer 4622H INX H ; Increment buffer pointer to the next byte 4623H SHLX ; Save read/write buffer pointer back to FD control 4624H DCX D ; Decrement back to read/write buffer length within FD control 4625H XCHG ; HL <--> DE Prepare to update buffer length 4626H DCR M ; Decrement length since we just read a byte ; ========================================================================================= ; Test if EOF for BASIC file # ; ========================================================================================= 4627H CPI 1AH ; Test if byte is EOF marker 4629H STC ; Ensure the Carry flag is set 462AH CMC ; And now clear it to indicate not EOF 462BH JNZ 4633H ; Jump if not at end of file 462EH CALL 465BH ; Calculate offset of BASIC instruction file # EOF marker 4631H MOV M,A ; Save EOF marker for this file # 4632H STC ; Set Carry to indicate EOF ; ========================================================================================= ; Save EOF status ; ========================================================================================= 4633H PUSH PSW ; Save EOF indication in Carry flag and marker value to stack 4634H LDES 10H ; Load offset to our return address (we PUSHed a bunch to the stack) 4636H LHLX ; Load HL with our return address from the stack 4637H LXI B,189AH ; Load address of return within EOF function 463AH DSUB ; Test if we were called from the EOF function 463BH JNZ 464FH ; Jump if not called from ROM EOF function - don't to EOF logical testing 463EH CALL 465BH ; Calculate offset of BASIC instruction file # EOF marker 4641H POP PSW ; Retreive EOF and marker value from stack 4642H MOV M,A ; Save the marker value to the file # marker storage location 4643H MOV C,A ; Save marker value in C 4644H SBB A ; Subtract with borrow (C was set if EOF) 4645H CALL 4BCBH ; Call into SGN function to set FAC1 with sign of A (EOF test) 4648H LDES 12H ; Prepare to "POP" 6 register pairs from the stack all at once 464AH XCHG ; HL <--> DE HL now has new stack value 464BH SPHL ; HL <--> SP "POP" 6 values from the stack 464CH JMP 00A6H ; Return to Main ROM ; ========================================================================================= ; Non-EOF function call return ; ========================================================================================= 464FH POP PSW ; Restore PSW with EOF indication (C flag) 4650H POP H ; Pop old PSW - we don't want it 4651H POP H ; Resore HL from stack 4652H POP D ; Restore DE from stack 4653H XTHL ; Push HL to stack to set new return address 4654H LXI H,4E8AH ; Load address of a "Stack frame retrun" routine 4657H XTHL ; Stack gets new return address, restore HL 4658H JMP 00A6H ; Return to the new address (not returning to parent) ; ========================================================================================= ; Calculate offset of BASIC instruction file # EOF marker ; ========================================================================================= 465BH LHLD FAA2H ; Get file # of active BASIC instruction (EOF, LINE INPUT, etc.) 465EH LXI D,FA91H ; Load base address of file status array 4661H DAD D ; Add offset to base of file status byte array 4662H RET ; ========================================================================================= ; RST 7,30A Read data from server (TPDD) into FD file buffer ; ========================================================================================= 4663H LXI H,0003H ; Load TPDD_READ opcode in HL 4666H CALL 4822H ; Send TPDD Command/Len in HL 4669H CALL 47CCH ; Receive a packet 466CH LDA FD02H ; Get response byte from storage for RX packet 466FH CPI 10H ; Test for valid read file response 4671H JNZ 469EH ; Branch if not valid read from file response 4674H LDA FD03H ; Get length of read from RX buffer 4677H LHLD FCCEH ; Get pointer to FD control 467AH LXI D,0008H ; Offset of address of read/write buffer relative to FD control 467DH DAD D ; Point to address of read/write buffer within FD control 467EH PUSH H ; Save address of read/write buffer to stack 467FH MOV D,H ; Move address of read/write buffer to DE for update 4680H MOV E,L ; Move LSB 4681H INX H ; Increment to MSB of read/write buffer address in FD control 4682H INX H ; Increment to read/write buffer 4683H SHLX ; Reset pointer to read/write buffer - we just read more data 4684H LXI D,FD04H ; DE points to the RX data in the buffer 4687H XCHG ; HL <--> DE Prepare to move data from RX buffer to FD buffer 4688H MOV C,A ; Move the RX data length to C 4689H MVI B,00H ; Clear MSB of BC count 468BH CALL 4A05H ; Move BC bytes from M to (DE) with increment - copy to FD buffer 468EH LDA FD03H ; Get length of RX read data again 4691H CPI 80H ; Test for maximum read length 4693H JZ 469AH ; If maximum read, skip writing EOF marker to read/write buffer 4696H XCHG ; HL = destination address in FD buffer 4697H MVI M,1AH ; Terminate .DO file in FD read/write buffer with EOF marker 4699H INR A ; Increment length to reflect EOF marker ; ========================================================================================= ; RST 7,32A Read - not max read size ; ========================================================================================= 469AH POP H ; Get address of read/write buffer in FD control from stack 469BH DCX H ; Decrement to FD control read/write buffer length location 469CH MOV M,A ; Save length of data in read/write buffer to FD control 469DH RET ; ========================================================================================= ; RST 7,32A Read - unsuccessful TPDD read ; ========================================================================================= 469EH LHLD FCCEH ; Get address of FD control 46A1H LXI D,0007H ; Load offset of output buffer count in FD control 46A4H DAD D ; Point to output buffer length in FD control 46A5H MVI M,01H ; Set read/write buffer length to 1 to indicate EOF marker 46A7H INX H ; Increment to LSB of read/write buffer output address in FD control 46A8H MOV D,H ; Save HL in DE for update of read/write buffer output in FD control 46A9H MOV E,L ; Save LSB of HL to DE 46AAH INX H ; Increment to MSB of read/write buffer in FD control 46ABH INX H ; Increment to the FD read/write buffer 46ACH SHLX ; Reset the FD control read/write buffer pointer to begining of buffer 46ADH MVI M,1AH ; Write an EOF marker to the buffer 46AFH RET ; ========================================================================================= ; RST 7,32h PRINT # sub-operation ; ========================================================================================= 46B0H LHLD FCCEH ; Pointer to FD control 46B3H LXI D,0007H ; ?Offset to output byte count 46B6H DAD D ; Get pointer to file's output byte count 46B7H MOV A,M ; Load byte count of pending bytes to write 46B8H CPI 80H ; Test if 128 bytes to write 46BAH CZ 46DDH ; Call routine to flush output buffer to file 46BDH POP PSW ; Restore A from stack (from RST 7,32h entry) 46BEH POP H ; Restore HL from stack 46BFH POP D ; Restore DE from stack 46C0H POP H ; Pop the return address - we will return via JMP 46C1H POP PSW ; Get the caller's A so we know what byte is being written 46C2H PUSH PSW ; Put it back on the stack...it isn't ours 46C3H CPI 1AH ; Test if writing an EOF marker to the file 46C5H JZ 46D6H ; Jump if writing EOF marder to the file - don't actually write it 46C8H LHLD FCCEH ; Get address of FD control 46CBH LXI D,0007H ; Get offset of output buffer length within FD control 46CEH DAD D ; Point to output buffer length address 46CFH INR M ; Increment the output buffer length - writing 1 byte 46D0H INX H ; Point to current file location pointer in FD control 46D1H XCHG ; HL <--> DE Move address of file location pointer to DE 46D2H LHLX ; Load current file location address to HL 46D3H MOV M,A ; Save the byte in the buffer (RX buffer for subsequent write) 46D4H INX H ; Increment the curent file location pointer (we will flush later) 46D5H SHLX ; Save the update current file location pointer to FD control 46D6H LXI H,14EAH ; Load address to update automatic timer and POP regs from the stack 46D9H PUSH H ; Push new return address. We will return to the parent's caller 46DAH JMP 00A6H ; Return to Main ROM
Navigate to: