M100 TS-DOS ROM OptROM Support
From Bitchin100 DocGarden
(Redirected from M100 ROM OptROM Support)
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 JMP 0080H ; BASIC statement keyword table END to NEW
; =========================================================================================
; RST 2 - Call Main ROM's RST 2 routine
; =========================================================================================
0010H RST 1 ; Call main ROM at address in following 2 bytes
0011H DW 0010H ; Call the Main ROM's RST 2 function
0013H 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 MVI A,20H ; Prepare to print a SPACE
; =========================================================================================
; RST 3 routine - Send character in A to the screen / printer
; =========================================================================================
0020H RST 1 ; Call main ROM at address in following 2 bytes
0021H DW 0020H ; Main ROM's RST 3 routine
0023H 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 insert ourselves just before the "unsaved BASIC program".
; =========================================================================================
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: