M100 TS-DOS ROM OptROM Support

From Bitchin100 DocGarden
Jump to navigationJump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

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: