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  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: