M100 TS-DOS ROM OptROM Support
From Bitchin100 DocGarden
Jump to navigationJump to search
TS-DOS Model 100/102 ROM OptROM Support
This code defines the variables used throughout the TS-DOS application as well as the support routines needed to navigate between the Main ROM and the Option ROM (most of them). Also included is the TS-DOS startup code. The assembly labels defined are open for discussion and have not been applied to any of the disassembled code yet.
========================================================================================= ; TS-DOS M100 ROM version Disassembly ; ; Initial Disassembly By Kenneth D. Pettit ; March, 2009 ; ; ========================================================================================= ; ========================================================================================= ; Variables in ALTLCD buffer ; ========================================================================================= NB_CUR_DIR equ FCC0H ; NADSBox current directory ("MYFILE.<> ") TPDD_BANK equ FCCAH ; TPDD2 Bank (side) NB_TPDD_FLG equ FCCBH ; NADSBox/Desklink/TPDD2 flag (0=TPDD, 1=TPDD2, 2=NADSBox) LAST_TAG equ FCCCH ; Tag/Untag last operation code CUR_FILE equ FCCDH ; Currently selected file index on UI (1 based) LJ_SP equ FCCEH ; Stack pointer upon entry for Long Jump LJ_RET equ FCD0H ; Return vector for Long Jump "RETURN" ERR_MODE equ FCD2H ; Print Error Messages flag, 1=Print, 0=Generate System Error FDC_OPCODE equ FCD3H ; FDC Emulation mode opcode CUR_PAGE equ FCD4H ; Current page of files being displayed (0 based) TMP_FILE_IDX equ FCD5H ; Currently selected file index on UI - temp FILE_COUNT equ FCD6H ; Count of files currently displayed on LCD MAX_FILES equ FCD7H ; Maximum files that fit on the LCD DISP_MODE equ FCD9H ; RAM / Disk Display mode (0=RAM, 1=DISK) SKIP_PAGE equ FCDAH ; TPDD "skip page" count (number of pages to read and discard) FILE_LEN equ FCDBH ; Pointer to "Current file" length bytes (in keyboard buffer) PHYS_SCTR equ FCDDH ; FDC Emulation Physical Sector Number / Active File Length LSB LOG_SCTR equ FCDEH ; FDC Emulation Logical Sector Number / Active File Length MSB KEY_TYPE equ FCDFH ; Storage for FDC emulation / New file type code / Keypress storage FILE_ADDR equ FCE0H ; Address of file being displayed/printed/loaded/saved FILE_BUFF equ FCE2H ; Pointer for TPDD direct read data / address of file being read/written TX_PKT_BUF equ FCE6H ; Storage for TX packets (28 bytes) RX_PKT_BUF equ FD02H ; Storage for RX packets (130 bytes ??) ; ========================================================================================= ; Main Entry point when called from "CALL 63013,1" ; ========================================================================================= .org 0000H 0000H JMP 00B2H ; Jump to entry point handler ; ========================================================================================= ; Pop registers after we power back up from a powerdown (I think) ; ========================================================================================= 0003H POP H 0004H POP D 0005H POP B 0006H POP PSW 0007H RET ; ========================================================================================= ; RST 1 - Call Main ROM at location whose address follows RST 1 opcode ; ========================================================================================= 0008H (C3H) JMP 0080H ; BASIC statement keyword table END to NEW ; ========================================================================================= ; RST 2 - Call Main ROM's RST 2 routine ; ========================================================================================= 0010H (CFH) RST 1 ; Call main ROM at address in following 2 bytes 0011H DW 0010H ; Call the Main ROM's RST 2 function 0013H (C9H) RET ; ========================================================================================= ; RST 3 routine - Compare HL and DE ; ========================================================================================= 0018H JMP 006CH ; Jump to comparison routine ; ========================================================================================= ; Return to Main ROM. After issuing the OUT E0H, we will be in Main ROM. The next opcode ; in Main ROM after this OUT statement occurs will be a RET (part of RST 1). We have ; PUSHed a return address to the stack, so the main ROM's RET instruction will get us ; where to intend to go. ; ========================================================================================= 001BH OUT E0H ; Send A to the ROM bank port to switch to Main ROM 001DH RET ; Should never execute this instruction, but just in case ; ========================================================================================= ; Send a space to the screen/printer - Not called from anywhere. Copy of Main ROM. ; ========================================================================================= 001EH (3EH) MVI A,20H ; Prepare to print a SPACE ; ========================================================================================= ; RST 3 routine - Send character in A to the screen / printer ; ========================================================================================= 0020H (CFH) RST 1 ; Call main ROM at address in following 2 bytes 0021H DW 0020H ; Main ROM's RST 3 routine 0023H (C9H) RET ; ========================================================================================= ; Power down TRAP. Let Main ROM deal with it. ; ========================================================================================= 0024H DI ; Disable interrupts while we jump 0025H CALL 0097H ; Jump to Main ROM's RST handler for this vector 0028H POP H 0029H JMP 0003H ; Pop regs after we power back up from a power-down? ; ========================================================================================= ; Hardware Interrupt - Let Main ROM deal with it - Bar Code Reader ; ========================================================================================= 002CH DI ; Disable interrupts while we jump 002DH CALL 0097H ; Jump to Main ROM's RST handler for this vector ; ========================================================================================= ; Return from Main ROM hook in RAM returns here via RST 6 ; ========================================================================================= 0030H POP PSW ; Cleanup stack 0031H POP PSW ; Cleanup stack 0032H RET ; Return to OptROM execution point 0033H NOP ; Filler ; ========================================================================================= ; Hardware Interrupt - Let Main ROM deal with it - RS232 character pending ; ========================================================================================= 0034H DI ; Disable interrupts while we jump 0035H CALL 0097H ; Jump to Main ROM's RST handler for this vector 0038H JMP 00A6H ; Stack cleanup 003BH NOP ; UNUSED - filler ; ========================================================================================= ; Hardware Interrupt - Let Main ROM deal with it - Timer background task ; ========================================================================================= 003CH DI ; Disable interrupts 003DH CALL 0097H ; Jump to Main ROM's RST handler for this vector ; ========================================================================================= ; This routine gets copied to RAM to be used for switching back to the TS-DOS ROM after ; calling a routine in the Main ROM. ; ========================================================================================= 0040H PUSH PSW ; Preserve the PSW 0041H LDA FF45H ; Contents of port E8H 0044H INR A ; Prepare to switch to OptRom 0045H OUT E0H ; Switch to OptRom 0047H RST 6 ; Get sign of FAC1 ; ========================================================================================= ; This routine gets copied to RAM and appears to detect the presence of the TS-DOS ROM ; after power-up and copies the original "External ROM" detection routine to RAM ; if the TS-DOS ROM is no longer present. At least I think that's what it's doing. ; ========================================================================================= 0048H LXI D,F605H ; Copy address for "Ext ROM detect" routine 004BH INR A ; Set bit to enable OptROM 004CH OUT E0H ; Switch to OptROM 004EH XRA A ; Prepare to switch back to Main ROM 004FH LHLD 0049H ; Load target address of the LXI D instruction above 0052H OUT E0H ; Switch back to Main ROM 0054H RST 3 ; Compare DE and HL - Test if OptROM is TS-DOS 0055H CPI 01H ; Test for TS-DOS ROM 0057H RC ; Return if TS-DOS ROM 0058H LXI H,111DH ; Load "Return" address to the CALL below 005BH SHLD FAE0H 005EH SHLD F5F2H ; Save a "Restart signature" ??? 0061H CALL 2905H ; Copy the DB number of bytes from the DW address to (DE) 0064H DB 24H ; ....copy 24H bytes 0065H DW 036FH ; ....from ROM addres 036F (external ROM detect) 0067H RST 0 ; I'm not sure it it every actually returns here or not 0068H NOP 0069H CALL FAA4H ; Call our installed RAM hook to return to TS-DOS ; ========================================================================================= ; Compare HL and DE - called by the RST 3 routine ; ========================================================================================= 006CH MOV A,H ; Move H into A for comparison 006DH SUB D ; Compare MSB first 006EH RNZ ; Return if no match 006FH MOV A,L ; Now move L into A 0070H SUB E ; Compare LSB 0071H RET ; Return with flags set ; ========================================================================================= ; Copy 8 bytes from DE to HL ; ========================================================================================= 0072H LXI B,0008H ; Prepare to copy 8 bytes ; ========================================================================================= ; Copy BC bytes from DE to HL ; ========================================================================================= 0075H LDAX D ; Load value from (DE) 0076H MOV M,A ; Save value to (HL) 0077H INX D ; Increment DE 0078H INX H ; Increment HL 0079H DCX B ; Decrement counter 007AH MOV A,B ; Prepare to test counter for zero 007BH ORA C ; Test counter for zero 007CH JNZ 0075H ; Keep looping until 8 bytes copied 007FH RET ; ========================================================================================= ; Handle the RST 1 routine. Read the Main ROM address from the 2 bytes after the RST 1 ; ========================================================================================= 0080H SHLD F9B2H ; Save HL off in "RickY" Cat entry so we don't clobber it 0083H POP H ; Get out return address (location of the ROM address to call 0084H PUSH D ; Push the return address back to the stack as storage 0085H MOV E,M ; Get LSB of the ROM address to call 0086H INX H ; Point to MSB of ROM address to call 0087H MOV D,M ; Get MSB of the ROM address to call 0088H INX H ; Point to return address after the RST 1 DB address 0089H XTHL ; Put the return address on the stack so we return after the RST 1 008AH XCHG ; Now get the address within ROM to call 008BH PUSH H ; Push the target ROM address to the stack so we "RETurn" there 008CH LXI H,FAA4H ; Load address of our RAM hook to switch back to our ROM bank and RET 008FH XTHL ; Push that address on the stack for after the ROM call is complete 0090H PUSH H ; Now put the ROM address back on the stack so we will RET there 0091H LHLD F9B2H ; Restore HL from temp storage in "RickY" 0094H JMP 00A6H ; Branch to switch to Main ROM and "RET" to the address we pushed ; ========================================================================================= ; RST handler for calling the Main ROM's RST handlers. This routine restores the original ; RST vector address to the stack, and jumps to the Main ROM's RST routine while ; preserving all register values. ; ========================================================================================= 0097H SHLD F9B4H ; Save HL temporarily (somewhere in RickY's name) 009AH LXI H,FAA4H ; Point to our RAM hook for returning to TS-DOS 009DH XTHL ; Put the hook address as the return address on the stack 009EH DCX H ; Decrement the return address by 4 009FH DCX H ; ...this will result in the starting address of the RST 00A0H DCX H ; ...that brought us here 00A1H DCX H 00A2H PUSH H ; Push the RST vector address to the stack 00A3H LHLD F9B4H ; Restore HL upon entry 00A6H PUSH PSW ; Save A to the stack 00A7H PUSH H ; Save the HL to the stack so we can preserve through XTHL 00A8H LXI H,1488H ; Load a RETurn address in the Main ROM (a POP PSW & RET) 00ABH XTHL ; Push the address and get HL back 00ACH LDA FF45H ; Contents of port E8H - prepare for jump to Main ROM 00AFH JMP 001BH ; Jump to Main ROM & our custom "RET" address in the ROM ; ========================================================================================= ; Manual invocation entry point. This is where we jump when "CALL 63013,1" is invoked ; ========================================================================================= 00B2H DI ; Disable interrupts so nobody bugs us yet 00B3H CPI 08H ; Check the invocation parameter to test for recovery request 00B5H JNC 0100H ; Jump to test for recovery mode 00B8H MOV B,A ; Save the calling paramter to B 00B9H PUSH B ; Save BC to the stack 00BAH PUSH D ; Save DE to the stack 00BBH PUSH H ; Save HL to the stack 00BCH LXI D,0040H ; Load address of our "Change to OptROM" routine 00BFH LXI H,FAA4H ; Load pointer to somewhere in RAM to hold our routine 00C2H CALL 0072H ; Copy 8 bytes from DE to HL 00C5H LXI B,0024H ; Now prepare to copy 36 bytes worth of "routine" 00C8H LXI H,F605H ; Point to another RAM location 00CBH CALL 0075H ; Copy the next "ROM Bank Switching" routine from our ROM 00CEH POP H ; Restore HL 00CFH POP D ; Restore DE 00D0H POP PSW ; Restore A 00D1H EI ; Allow interrupts again 00D2H JMP 0100H ; Go test if a "Cold Start" recovery is being requested .org 100H ; ========================================================================================= ; Test if cold-start recovery requested ; ========================================================================================= 0100H MOV A,H ; Move H to A to test HL for zero 0101H ORA L ; Test for zero 0102H JZ 7000H ; Call recovery routine if requested 0105H POP H ; Pop the return address. We will exit manually 0106H CALL 0117H ; Ensure the TS-DOS progam is installed in the MENU 0109H JMP 3535H ; Jump to the TS-DOS UI ; ========================================================================================= ; Move BC bytes from (HL) to (DE) with increment ; ========================================================================================= 010CH MOV A,M ; Get next byte from (HL) 010DH STAX D ; Save byte in (DE) 010EH INX H ; Increment source pointer 010FH INX D ; Increment destination pointer 0110H DCX B ; Decrement loop control 0111H MOV A,B ; Move MSB to A to test for zero 0112H ORA C ; OR in LSB to test for zero 0113H JNZ 010CH ; Branch to copy next byte until done 0116H RET ; ========================================================================================= ; Insert the "TS-DOS" invocation program (BASIC program) into the Catalog / MENU. ; we always insert ourselves at the lowest RAM address. ; ========================================================================================= 0117H LXI H,01E1H ; Point to "TS-DOS" catalog entry in our ROM 011AH PUSH H ; Save the address on the stack for later 011BH INX H ; Point to the text portion of the catalog entry 011CH LXI B,0008H ; Prepare to copy 8 filename byte 011FH LXI D,FC93H ; Filename of current BASIC program 0122H CALL 010CH ; Copy BC bytes from HL to DE - put "TS-DOS " in cur. BASIC prog. 0125H XCHG ; HL <--> DE DE now has the address of the invocation program 0126H LHLX ; Get the length of the BASIC program into HL 0127H SHLD FCC4H ; Save the BASIC program length in the ALTLCD buffer for now 012AH INX D ; Point to MSB of the length 012BH INX D ; Point to LSB of the pointer to the "Next" BASIC instruction 012CH XCHG ; HL <--> DE HL has the pointer to the "Next" BASIC inst address 012DH SHLD FCC8H ; Save the "Next" BASIC inst pointer to ALTLCD (start of program) 0130H CALL 01D1H ; Update the System pointers 0133H CALL 01CDH ; Search Catalog for entry matching current BASIC program 0136H POP B ; Pop address in case we return 0137H RNZ ; Return if "TS-DOS" is already in the catalog 0138H LHLD F99AH ; Get the BASIC program not saved pointer - insert before that 013BH SHLD FCC2H ; Save storage location for the TS-DOS invocation progam 013EH LDAX B ; Load the file type byte from our ROM (B has the address from above) 013FH STA FCC6H ; Store the Type byte in the ALTLCD 0142H CALL 0185H ; Find empty entry in Catalog 0145H RC ; Return if catalog full 0146H PUSH H ; Save the address of the empty catalog entry to the stack 0147H LHLD FCC4H ; Restore the BASIC program length from ALTLCD 014AH MOV B,H ; Move BASIC program length to BC for copy 014BH MOV C,L ; Move LSB of length 014CH PUSH B ; Save Length to the stack 014DH LHLD FCC2H ; Get address of insertion for TS-DOS just before the unsaved BASIC prog. 0150H CALL 01DDH ; Call Main ROM's Insert BC spaces at M routine 0153H JC 0182H ; Abort if RAM full 0156H LHLD FCC2H ; Get address of insertion point again 0159H XCHG ; DE now has insertion point for BASIC program 015AH LHLD FCC8H ; Get the address of the BASIC program (in our ROM) from ALTLCD 015DH POP B ; Restore copy length of the BASIC program 015EH CALL 010CH ; Move BC bytes from (HL) to (DE) with increment 0161H POP D ; Get the address of the empty catalog entry we will use for TS-DOS 0162H PUSH D ; Save it back to the stack 0163H LHLD FBAEH ; Load the start of DO files pointer 0166H DCX H ; Derement the start of DO files pointer 0167H SHLD F99AH ; Save it as the new BASIC program not saved pointer 016AH INX H ; Point to start of DO files again 016BH XCHG ; Move it to DE 016CH LHLD FCC4H ; Load the TS-DOS BASIC progam length from ALTLCD 016FH DAD D ; Offset the start of DO files by the insertion amount 0170H SHLD FBAEH ; Save the new start of DO files pointer 0173H POP D ; Restore the address of the empty catalog entry 0174H LHLD FCC2H ; Get the starting address of the newly inserted TS-DOS program 0177H XCHG ; HL <--> DE Swap for the call to the catalog insertion routine 0178H LDA FCC6H ; Load A with the file type byte 017BH CALL 01D5H ; Save current BASIC program to the Catalog entry at HL 017EH CALL 01D1H ; Update system pointers 0181H RET ; ========================================================================================= ; Insert "TS-DOS" RAM full abort routine ... stack cleanup. ; ========================================================================================= 0182H POP H ; Pop the BASIC program length from the stack 0183H POP H ; Pop the catalog entry address from the stack 0184H RET ; ========================================================================================= ; Find an empty entry in the Catalog. HL points to start of new entry ; This routine appears again at address 3E48H ; ========================================================================================= 0185H LXI H,F9AFH ; Point to "RickY" to start search at beginning of catalog 0188H LXI B,000BH ; Get length of each entry in the Catalog 018BH DAD B ; Point to next entry in the catalog 018CH MOV A,M ; Get the File Attribute byte from the catalog for this file 018DH CPI FFH ; Test if at end of the catalog 018FH JZ 0197H ; Jump to set Carry flag and exit if at end 0192H ADD A ; Test if MSB set (test if entry available) 0193H JC 018BH ; Branch to get next entry if this one is used 0196H RET ; Return with Carry clear to indicate entry found ; ========================================================================================= ; Empty catalog entry not found in Catalog, set Carry and return ; ========================================================================================= 0197H STC ; Set the Carry flag - not found 0198H RET ; ========================================================================================= ; Call Main ROM's Display function key line routine ; ========================================================================================= 0199H RST 1 ; Call main ROM at address in following 2 bytes 019AH DW 42A8H 019CH RET ; ========================================================================================= ; Call Main ROM's Erase function key display routine ; ========================================================================================= 019DH RST 1 ; Call main ROM at address in following 2 bytes 019EH DW 428AH 01A0H RET ; ========================================================================================= ; Call Main ROM's Set new function key table routine ; ========================================================================================= 01A1H RST 1 ; Call main ROM at address in following 2 bytes 01A2H DW 5A7CH 01A4H RET ; ========================================================================================= ; Call Main ROM's Wait for key from keyboard routine ; ========================================================================================= 01A5H RST 1 ; Call main ROM at address in following 2 bytes 01A6H DW 12CBH 01A8H RET ; ========================================================================================= ; Call Main ROM's Scan keyboard for character (CTRL-BREAK ==> CTRL-C) routine ; This appears later in the code also ; ========================================================================================= 01A9H RST 1 ; Call main ROM at address in following 2 bytes 01AAH DW 7242H 01ACH RET ; ========================================================================================= ; Call Main ROM's Power Down routine ; This appears later in the code also ; ========================================================================================= 01ADH RST 1 ; Call main ROM at address in following 2 bytes 01AEH DW 13B5H 01B0H RET ; ========================================================================================= ; Call Main ROM's Renew automatic power-off counter routine ; This apears later in the code also ; ========================================================================================= 01B1H RST 1 ; Call main ROM at address in following 2 bytes 01B2H DW 1BB1H 01B4H RET ; ========================================================================================= ; Call Main ROM's CLS statement routine ; This apears later in the code also ; ========================================================================================= 01B5H RST 1 ; Call main ROM at address in following 2 bytes 01B6H DW 4231H 01B8H RET ; ========================================================================================= ; Call Main ROM's Start inverse character mode routine ; This appears later in the code also ; ========================================================================================= 01B9H RST 1 ; Call main ROM at address in following 2 bytes 01BAH DW 4269H 01BCH RET ; ========================================================================================= ; Call Main ROM's Cancel inverse video routine ; This appears later in the code also ; ========================================================================================= 01BDH RST 1 ; Call main ROM at address in following 2 bytes 01BEH DW 426EH 01C0H RET ; ========================================================================================= ; Call Main ROM's Check keyboard queue for pending characters routine ; This appers later in the code also ; ========================================================================================= 01C1H RST 1 ; Call main ROM at address in following 2 bytes 01C2H DW 13DBH 01C4H RET ; ========================================================================================= ; Call Main ROM's Stop automatic scrolling routine ; This appers later in the code also ; ========================================================================================= 01C5H RST 1 ; Call main ROM at address in following 2 bytes 01C6H DW 423FH 01C8H RET ; ========================================================================================= ; Call Main ROM's Reset vector routine ; ========================================================================================= 01C9H RST 1 ; Call main ROM at address in following 2 bytes 01CAH DW 0000H 01CCH RET ; ========================================================================================= ; Search Catalog for entry matching current BASIC program ; ========================================================================================= 01CDH RST 1 ; Call main ROM at address in following 2 bytes 01CEH DW 20AFH 01D0H RET ; ========================================================================================= ; Call Main ROM's Update system pointers routine ; ========================================================================================= 01D1H RST 1 ; Call main ROM at address in following 2 bytes 01D2H DW 2146H 01D4H RET ; ========================================================================================= ; Call Main ROM's routine to save current BASIC program to the Catalog entry at HL ; ========================================================================================= 01D5H RST 1 ; Call main ROM at address in following 2 bytes 01D6H DW 2239H 01D8H RET ; ========================================================================================= ; Not a valid entry into ROM and not called anywhere ; ========================================================================================= 01D9H RST 1 ; Call main ROM at address in following 2 bytes 01DAH DW 5825H 01DCH RET ; ========================================================================================= ; Call Main ROM's Insert BC spaces at M routine ; ========================================================================================= 01DDH RST 1 ; Call main ROM at address in following 2 bytes 01DEH DB 6B6DH 01E0H RET ; ========================================================================================= ; TS-DOS entry that will be inserted into the catalog for invoking TS-DOS ; ========================================================================================= 01E1H DB 80H ; TS-DOS file type for catalog entry 01E2H DB "TS-DOS " ; TS-DOS Catalog name entry ; ========================================================================================= ; BASIC program that will be inserted into RAM to launch TS-DOS from the MENU/Catalog entry ; ========================================================================================= 01EAH DB 0FH,00H,0EH,80H ; BASIC program length and pointer to "Next" BASIC instruction 01EDH DB 0AH,00H,B9H ; BASIC Line number "10" and BASIC token for CALL 01EFH DB "63013,1" ; CALL argument 01F5H DB 00H,00H ; BASIC terminating zeros
End of disassembly for OptROM Support.
Navigate to M100 TS-DOS ROM UI Code