M100 TS-DOS ROM UI Code

From Bitchin100 DocGarden
Revision as of 23:57, 2 April 2009 by Kpettit (talk | contribs)
Jump to navigationJump to search

== TS-DOS Model 100/102 User Interface Code

; =========================================================================================
; TS-DOS UI Entry location
; =========================================================================================
 
    .org  3535H

3535H  LXI H,FCC0H          ; Start of Alt LCD character buffer
3538H  MVI B,B4H            ; Prepare to clear 180 bytes from the ALTLCD buffer 
353AH  XRA A                ; Prepare to clear the ALTLCD buffer
353BH  CALL 4A34H           ; Fill (HL) with B bytes of A        
353EH  LXI H,0000H          ; Prepare to get current stack pointer
3541H  DAD SP               ; Copy SP into HL
3542H  SHLD FCCEH           ; Stack pointer upon entry - pointer to arguments
3545H  MVI A,01H            ; Set flag to print error message to LCD - GUI mode
3547H  CALL 4A85H           ; Save the currently selected baud rate settings
354AH  XRA A                ; Zero A to clear our vars
354BH  STA FCD4H            ; Current Page of files being displayed
354EH  STA FCDAH            ; TPDD "skip page" count
3551H  STA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)
3554H  STA FCCAH            ; TPDD2 Bank number
3557H  INR A                ; A = 1 to select 1st file on page
3558H  STA FCCDH            ; Currently selected file index
355BH  LXI H,3564H          ; Get pointer to main loop routine
355EH  SHLD FCD0H           ; Return vector after error
3561H  CALL 4C27H           ; CLS statement

; =========================================================================================
; UI Main loop
; =========================================================================================
3564H  CALL 4C5AH           ; Resume automatic scrolling
3567H  CALL 3611H           ; Print Copyright and files
356AH  LDA FCD5H            ; Load currently selected index from temp storage
356DH  STA FCCDH            ; Currently selected file index
3570H  CALL 362FH           ; Print length of selected file using inverse video

; =========================================================================================
; Code will return here when a funtion key is pressed (except F4 & F6)
; =========================================================================================
3573H  LXI H,48B5H          ; Get address of "Long jump"
3576H  PUSH H               ; Push "Long jump" address to stack
3577H  PUSH PSW             ; Save function key press to stack
3578H  CPI 02H              ; Test if function key is F5-F8 (Non file operation F Keys)
357AH  JNC 35B9H            ; Jump to Function key handler if F5-F8 (No tagging to process)
357DH  LDA FCCCH            ; Last Tag/Untag operation code
3580H  ANA A                ; Test if a tag operation was performed
3581H  JZ 35B9H             ; Jump to Function key handler if no tag operation performed
3584H  LDA FCD6H            ; Count of files on screen
3587H  MOV C,A              ; Save count of files for loop decrementing 
3588H  INR C                ; Increment by 1 for loop bounding
3589H  MVI B,00H            ; Start with index zero on the LCD
358BH  PUSH B               ; Save the current index on the stack

; =========================================================================================
; Display next file
; =========================================================================================
358CH  LDA FCCDH            ; Currently selected file index
358FH  STA FCD5H            ; Currently selected file index - temp
3592H  CALL 3AC4H           ; Print selected file using normal video
3595H  POP B                ; Restore index from stack
3596H  INR B                ; Increment to the next file index to display
3597H  DCR C                ; Decrement the loop control
3598H  JZ 48B5H             ; Branch to perform "Long Jump" if all files printed to LCD
359BH  MOV A,B              ; Get the index of the current file
359CH  STA FCD5H            ; Save in temporary "current file" area
359FH  STA FCCDH            ; Currently selected file index
35A2H  PUSH B               ; Push the value on the stack for the next iteration
35A3H  CALL 3AB2H           ; Print currently selected file using inverse video
35A6H  LHLD FCE4H           ; LCD Buffer address of current file selection
35A9H  DCX H                ; Decrement to the Tag area for the file
35AAH  MOV A,M              ; Get the file's Tag code
35ABH  CPI 3EH              ; Compare with '>'
35ADH  JNZ 358CH            ; Jump to process next file if not tagged
35B0H  POP B                ; Pop currently selected file value from stack
35B1H  POP PSW    
35B2H  LXI H,358CH          ; Return address to display the next file
35B5H  PUSH PSW             ; ? Stack trickery
35B6H  PUSH B               ; Save current file index to stack for use after a RET operation
35B7H  PUSH H               ; Setup "Display next file" as a return address for RET
35B8H  PUSH PSW             ; ? More stack trickery

; =========================================================================================
; Function key handler - Disk mode and dispatch to RAM mode
; =========================================================================================
35B9H  CALL 4C56H           ; Stop automatic scrolling
35BCH  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)
35BFH  ORA A     
35C0H  JZ 35E2H             ; Branch if in RAM mode
35C3H  POP PSW   
35C4H  ANA A                ; Test for F1
35C5H  JZ 3B2EH             ; Branch to F1 handler for disk
35C8H  DCR A                ; Test for F2
35C9H  JZ 3D73H  
35CCH  DCR A                ; Test for F3
35CDH  JZ 3D9FH  
35D0H  DCR A                ; Skip F4 - handled at lower level
35D1H  DCR A                ; Test for F5
35D2H  JZ 3D53H  
35D5H  DCR A                ; Skip F6 - handled at lower level
35D6H  DCR A                ; Test for F7
35D7H  JZ 3D00H  
35DAH  DCR A                ; Test for F8
35DBH  POP H     
35DCH  JZ 35FEH             ; Jump to exit if F8
35DFH  JMP 3564H            ; Jump to main loop

; =========================================================================================
; Function key handler - RAM mode
; =========================================================================================
35E2H  POP PSW  
35E3H  ANA A                ; Test for F1 
35E4H  JZ 3C4BH 
35E7H  DCR A                ; Test for F2
35E8H  JZ 3C2BH 
35EBH  DCR A                ; Test for F3
35ECH  JZ 3AF8H 
35EFH  DCR A                ; Skip F4 - handled at lower level
35F0H  DCR A                ; Test for F5
35F1H  JZ 3E5CH 
35F4H  DCR A                ; Skip F6 - handled at lower level
35F5H  DCR A                ; Skip F7 - not defined for RAM
35F6H  DCR A                ; Test for F8
35F7H  POP H    
35F8H  JZ 35FEH             ; Jump to exit if F8
35FBH  JMP 3564H            ; Jump back to main loop

; =========================================================================================
; This is the UI exit routine
; =========================================================================================
35FEH  CALL 4AC4H           ; Restore original baud settings
3601H  CALL 4BD7H           ; Wait for TX empty and Reset UART to accept mode bits
3604H  CALL 4C27H           ; CLS statement
3607H  CALL 4C5AH           ; Resume automatic scrolling
360AH  LXI H,0000H
360DH  PUSH H
360EH  JMP 00A6H            ; Exit TS-DOS

; =========================================================================================
; Print Copyright string and files
; =========================================================================================
3611H  LXI H,0101H          ; Goto top left corner
3614H  SHLD F639H           ; Cursor row (1-8)
3617H  LXI H,3E69H          ; Point to "TS-DOS" copyright string
361AH  CALL 4A2CH           ; Send buffer at M to screen
361DH  XRA A                ; Indicate no previous Tag/Untag operation
361EH  STA FCCCH            ; Last Tag/Untag operation code
3621H  MVI A,01H            ; Start with 1st file in list
3623H  STA FCD5H            ; Currently selected file index - temp
3626H  LXI H,0202H          ; Goto first file entry location
3629H  SHLD F639H           ; Cursor row (1-8)
362CH  JMP 383BH            ; Draw the display

; =========================================================================================
; Print length of selected file using inverse video
; =========================================================================================
362FH  LDA FCCDH            ; Currently selected file index      
3632H  STA FCD5H            ; Currently selected file index - temp      
3635H  CALL 3AB2H           ; Print currently seleted file using inverse video       
3638H  LDA FCD5H            ; Currently selected file index - temp      
363BH  DCR A                ; Make index zero based for multiply x2  
363CH  STC                  ; Set Carry flag
363DH  CMC                  ; Compliment (clear) carry flag
363EH  RLC                  ; Rotate left circular 
363FH  MOV E,A              ; E = File index * 2 to point to file length value    
3640H  MVI D,00H            ; Clear MSB of file length offset      
3642H  LXI H,F685H          ; Keyboard buffer - store file lengths        
3645H  DAD D                ; Add file lenght offset from beginning of keyboard buffer  
3646H  XCHG                 ; HL <--> DE Save file length address pointer in DE 
3647H  LXI H,2307H          ; Load position of File Size area on LCD
364AH  SHLD F639H           ; Cursor row (1-8) 
364DH  CALL 4C2BH           ; Erase from cursor to end of line
3650H  LHLX                 ; Load HL with file length 
3651H  CALL 4C2FH           ; Start inverse character mode       
3654H  CALL 4C3EH           ; Print binary number in HL at current position       
3657H  CALL 4C33H           ; Cancel inverse character mode         

; =========================================================================================
; Keyboard scan loop
; =========================================================================================
365AH  CALL 3DFEH           ; Process automatic power off logic
365DH  CALL 4BEFH           ; Scan keyboard for character (CTRL-BREAK ==> CTRL-C)
3660H  JZ 365AH             ; Jump to scan keyboard again if no key pressed 
3663H  JC 380CH             ; Jump to Function Key Handler if FKey 
3666H  CPI 0DH              ; Test for CR
3668H  JZ 3722H   
366BH  CPI 17H              ; Test for Ctrl-Up key
366DH  JZ 37AAH   
3670H  CPI 14H              ; Test for Shift-Up key
3672H  JZ 3798H   
3675H  CPI 5DH              ; Test for "]" key
3677H  JZ 3798H   
367AH  CPI 3FH              ; Test for "?" key
367CH  JZ 3777H   
367FH  CPI 02H              ; Test for Shift-Down arrow key
3681H  JZ 3777H   
3684H  CPI 1EH              ; Test for up key
3686H  JZ 36EEH   
3689H  CPI 1FH              ; Test for down key
368BH  JZ 36FCH   
368EH  CPI 1DH              ; Test for "left arrow" key
3690H  JZ 36DDH   
3693H  CPI 1CH              ; Test for "Right arrow" key
3695H  JZ 36CAH   
3698H  CPI 20H              ; Test for space key 
369AH  JZ 36CAH             ; Treat space the same as right arrow  
369DH  ANI DFH              ; Convert to Upper case 
369FH  CPI 52H              ; Test for 'R' character  
36A1H  JZ 3759H   
36A4H  CPI 54H              ; Test for 'T' character 
36A6H  JZ 37EEH   
36A9H  CPI 41H              ; Test for "A" key 
36ABH  JZ 3715H   
36AEH  CPI 47H              ; Test for "G" key 
36B0H  JZ 3715H   
36B3H  CPI 55H              ; Test for "U" key 
36B5H  JZ 37AEH   
36B8H  CPI 44H              ; Test for "D" key 
36BAH  JZ 39B9H   
36BDH  CPI 4CH              ; Test for "L" key 
36BFH  JZ 39C2H   
36C2H  CPI 50H              ; Test for "P" key 
36C4H  JZ 39C2H   
36C7H  JMP 365AH            ; Go scan keyboard again   

; =========================================================================================
; Handle Right Arrow key from TS-DOS key scan
; =========================================================================================
36CAH  MVI A,01H            ; Prepare to add 1 to selected file    
36CCH  LXI H,FCD5H          ; Currently selected file index - temp storage
36CFH  ADD M                ; Add 1 to the selected file index
36D0H  INX H                ; Point to file count on screen
36D1H  CMP M                ; Compare new index with screen file count
36D2H  JC 370AH             ; Jump to process new file if we didn't wrap   
36D5H  JZ 370AH             ; Jump to process new file if = file count   
36D8H  MVI A,01H            ; Wrap to the first file    
36DAH  JMP 370AH            ; Go process file 1 as the new selection    

; =========================================================================================
; Handle Left Arrow key from TS-DOS key scan
; =========================================================================================
36DDH  LDA FCD5H            ; Currently selected file index - temp storage
36E0H  DCR A                ; Move to next lowest file index
36E1H  JNZ 370AH            ; If no wrap, jump to process new selection
36E4H  LDA FCD6H            ; Count of files on screen
36E7H  ANA A                ; Ensure there is at least 1 file on the screen 
36E8H  JZ 365AH             ; Jump to keyboard scan loop if no files on LCD
36EBH  JMP 370AH            ; Go process new selection as the max (wrap-around)

; =========================================================================================
; Handle Up Arrow key from TS-DOS key scan
; =========================================================================================
36EEH  LDA FCD5H            ; Currently selected file index - temp storage
36F1H  SUI 04H              ; Subtract 4 from file count (4 files per line)
36F3H  JC 365AH             ; Jump to keysacn loop if negative
36F6H  JZ 365AH             ; Jump to keysacn loop if zero
36F9H  JMP 370AH            ; Go process the new file index setting

; =========================================================================================
; Handle Down Arrow key from TS-DOS key scan
; =========================================================================================
36FCH  MVI A,04H            ; There are 4 files per line 
36FEH  LXI H,FCD5H          ; Currently selected file index - temp storage
3701H  ADD M                ; Add 4 to the index number
3702H  MOV C,A              ; Save new index for comparison and further processing  
3703H  INX H                ; Maximum file index count
3704H  MOV A,M              ; Load maximum index for bounds  
3705H  CMP C                ; Compare new index with maximum
3706H  JC 365AH             ; Jump to keyboard scan if moving past last file   
3709H  MOV A,C              ; Restore new current file index  
370AH  PUSH PSW             ; Save new file index for storage after the call   
370BH  CALL 3AC4H           ; Print selected file using normal video     
370EH  POP PSW              ; Restore new file index from stack  
370FH  STA FCCDH            ; Save the new file index    
3712H  JMP 362FH            ; Print length of selected file using inverse video.    

; =========================================================================================
; Handle "A" or "G" key from TS-DOS key scan
; =========================================================================================
3715H  MVI A,3EH            ; Load ">" for the tag symbol
3717H  CALL 37CAH           ; Go tag all files on the LCD
371AH  MVI A,01H            ; Indicate last operation as "Tag All"
371CH  STA FCCCH            ; Last Tag/Untag operation code
371FH  JMP 362FH            ; Print length of selected file using inverse video.

; =========================================================================================
; Handle Enter key from TS-DOS key scan - Change Directory
; =========================================================================================
3722H  LDA FCCBH            ; Get NADSBox/Desklink/TPDD2 flag     
3725H  CPI 02H              ; Test if NADSBox current directory valid   
3727H  JNZ 365AH            ; Back to keyscan if no "current directory" - Enter is meaningless     
372AH  LHLD FCE4H           ; LCD Buffer address of current file selection      
372DH  LXI B,0007H          ; Load offset of file extension       
3730H  DAD B                ; Point to file extension of selected file 
3731H  MOV A,M              ; Load the 1st byte of the file extension   
3732H  CPI 3CH              ; Test if 1st byte of extension is "<"   
3734H  JNZ 365AH            ; Jump to keyscan if current selection not directory entry     
3737H  CALL 4A3BH           ; Initialize blank filename and attribute byte      
373AH  LHLD FCE4H           ; LCD Buffer address of current file selection      
373DH  CALL 3D95H           ; Copy filename at (HL) to TX buffer      
3740H  CALL 408AH           ; Open TPDD file for Read Mode      
3743H  LXI H,0002H          ; Load opcode to close currently opened file       
3746H  CALL 409BH           ; Send Request in HL and await response      
3749H  LHLD FCE4H           ; LCD Buffer address of current file selection      
374CH  LXI D,FCC0H          ; NADSBox current directory storage    
374FH  LXI B,0009H          ; Copy 9 bytes of NADSBox directory to the LCD       
3752H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      
3755H  XRA A                ; Clear A to show 1st page of files 
3756H  JMP 378AH            ; Branch to show the page of files in A     

; =========================================================================================
; Handle "R" key from TS-DOS key scan
; =========================================================================================
3759H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)
375CH  ANA A                ; Test if in Disk mode
375DH  JNZ 362FH            ; Jump to keyscan if in Disk mode
3760H  LHLD FCE4H           ; LCD Buffer address of current file selection       
3763H  CALL 4902H           ; Copy filename at (HL) to current BASIC program
3766H  CALL 4A51H           ; Get RAM directory address of current BASIC program          
3769H  CPI C0H              ; Test if filetype is .DO
376BH  CZ 5000H             ; Call routine to Compress / Decompress .DO files
376EH  CALL 4C0FH           ; Update system pointers       
3771H  CALL 3611H           ; Print Copyright and files
3774H  JMP 362FH            ; Jump to keyscan 

; =========================================================================================
; Handle "?" and Shift-Down key from TS-DOS key scan
; =========================================================================================
3777H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)
377AH  ANA A                ; Test if RAM mode 
377BH  JZ 365AH             ; Branch to keyscan if in RAM mode    
377EH  LDA FCD6H            ; Count of files on screen     
3781H  CPI 14H              ; Maximum number of files that fit on the screen   
3783H  JC 365AH             ; Branch to keyscan if on last page    
3786H  LDA FCD4H            ; Current Page of files being displayed     
3789H  INR A                ; Increment to next page of files 
				 
; =========================================================================================
; Show the page of files indicated by A
; =========================================================================================
378AH  STA FCD4H            ; Current Page of files being displayed     
378DH  MVI A,01H            ; Go to 1st file on the new page     
378FH  STA FCCDH            ; Currently selected file index     
3792H  CALL 3611H           ; Print copyright and files      
3795H  JMP 362FH            ; Print length of selected file using inverse video     

; =========================================================================================
; Handle "]" and Shift-Up key from TS-DOS key scan
; =========================================================================================
3798H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)
379BH  ANA A                ; Test if RAM mode 
379CH  JZ 365AH             ; Branch to keyscan if in RAM mode    
379FH  LDA FCD4H            ; Current Page of files being displayed     
37A2H  ANA A                ; Test if current page is zero 
37A3H  JZ 365AH             ; Branch to keyscan if already on page 0    
37A6H  DCR A                ; Decrement the page number 
37A7H  JMP 378AH            ; Show the page of files indicated by A

; =========================================================================================
; Handle Ctrl-Up key from TS-DOS key scan
; =========================================================================================
37AAH  XRA A                ; Go to page zero
37ABH  JMP 378AH            ; Show the page of files indicated by A

; =========================================================================================
; Handle "U" key from TS-DOS key scan - Remove all tags
; =========================================================================================
37AEH  MVI A,20H            ; Display ' ' as the tag marker
37B0H  CALL 37CAH           ; Go process tag for all files
37B3H  XRA A                ; Indicate last tag operation was untag
37B4H  STA FCCCH            ; Store as "last tag" operation
37B7H  JMP 362FH            ; Print length of selected file using inverse video

; =========================================================================================
; Swap TPDD2 Bank number
; =========================================================================================
37BAH  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag
37BDH  DCR A                ; Test if the flag = 1 (TPDD2)
37BEH  JNZ 365AH            ; Jump to keyscan if not 1
37C1H  LDA FCCAH            ; Get TPDD Bank Number
37C4H  XRI 01H              ; Switch to the other bank
37C6H  STA FCCAH            ; Save TPDD bank number
37C9H  RET

; =========================================================================================
; Process Tag or Untag for all files on screen
; =========================================================================================
37CAH  STA FCCCH            ; Store tag/untag code for later      
37CDH  LDA FCD6H            ; Get Maximum file count on screen      
37D0H  ANA A                ; Test for zero  
37D1H  RZ		            ; Return if no files on screen
37D2H  XRA A                ; Clear A  
37D3H  INR A                ; A=1 to selet 1st file  
37D4H  STA FCD5H            ; Currently selected file index      
37D7H  CALL 3ACDH           ; Calculate Row and Column of soon-to-be (newly) selected file       
37DAH  LHLD FCE4H           ; LCD Buffer address of current file selection       
37DDH  DCX H                ; Point to Tag location for the file  
37DEH  LDA FCCCH            ; Get the tag/untag code      
37E1H  RST 4                ; Display A to the LCD    
37E2H  LDA FCD5H            ; Get currently selected file index      
37E5H  LXI H,FCD6H          ; Point to count of files on screen        
37E8H  CMP M                ; Compare current selection with count of files on LCD  
37E9H  JC 37D3H             ; Jump to process next file if more files left     
37ECH  ANA A                ; Set zero flag to indicate files were tagged/untagged  
37EDH  RET

; =========================================================================================
; Handle "T" key key from TS-DOS key scan - TAG
; =========================================================================================
37EEH  CALL 3ACDH           ; Calculate Row and Column of soon-to-be (newly) selected file    
37F1H  CALL 4C2FH           ; Start inverse character mode    
37F4H  LHLD FCE4H           ; LCD Buffer address of current file selection    
37F7H  DCX H	            ; Point to the "Tag" area for the file
37F8H  MVI A,3EH            ; Load the code for ">"   
37FAH  CMP M                ; Compare if file is already tagged     
37FBH  JNZ 3800H            ; Skip ahead if already tagged   
37FEH  MVI A,20H            ; Need to untag - load the untag code   
3800H  RST 4                ; Display the tag code on the LCD   
3801H  CALL 4C33H           ; Cancel inverse character mode    
3804H  LXI H,FCCCH          ; Point to "last tag" operation code     
3807H  MVI M,01H            ; Indicate last operation was "tag"   
3809H  JMP 36CAH            ; Move to next file - jump to Right Arrow key handler   

; =========================================================================================
; 1st level Function Key Handler (handles F4 and F6)
; =========================================================================================
380CH  CPI 08H              ; Test for valid function key code     
380EH  JNC 365AH            ; Branch back to scan loop if invalid       
3811H  CPI 05H              ; Test for F6     
3813H  JZ 3833H             ; Jump if F6 pressed      
3816H  CPI 03H              ; Test for F4     
3818H  RNZ                  ; Return to "Main Loop" if not F4 pressed 
3819H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)       
381CH  XRI 01H              ; Swap RAM/DISK mode     
381EH  STA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)       
3821H  XRA A                ; Clear A to go to 1st page of files   
3822H  STA FCD4H            ; Current Page of files being displayed       
3825H  MVI A,01H            ; Select the 1st file in the page       
3827H  STA FCCDH            ; Currently selected file index       
382AH  CALL 4C27H           ; CLS statement     
382DH  CALL 3611H           ; Print the title bar and files        
3830H  JMP 362FH            ; Print length of selected file using inverse video.       

; =========================================================================================
; F6 Function Key Handler
; =========================================================================================
3833H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)
3836H  ANA A                ; Test if in RAM or DISK mode
3837H  RZ                   ; Return if RAM mode
3838H  JMP 37AAH            ; Jump to Ctrl-Up key handler

; =========================================================================================
; Draw the display.  This takes care of RAM and Disk mode displays, handles
;    skipping page number to the proper "Disk" page, displaying the Bank# or
;    current directory for NADSBox/Desklink, showing free space, filling in
;    empty slots with "-.-", etc.
; =========================================================================================
383BH  LXI H,F685H          ; Keyboard buffer  
383EH  SHLD FCDBH           ; Initialize pointer to file length table (in keyboard buffer)     
3841H  XRA A                ; Prepare to set 1st file lenght to zero
3842H  MOV M,A              ; Set LSB of length of 1st file to zero  
3843H  INX H                ; Increment to MSB of length
3844H  MOV M,A              ; Set MSB of length of file to zero  
3845H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)    
3848H  ANA A                ; Test if RAM or DISK
3849H  JZ 395DH             ; Jump to show RAM files if in RAM mode   
384CH  XRA A                ; Prepare to initialize the "page being processed" variable
384DH  STA FCDAH            ; Clear the "page being processed" variable    
3850H  CALL 4735H           ; Clear #files displayed, init TPDD and send 1st file dir referene opcode     
3853H  JNZ 390FH            ; Process unformated disk (empty slots and error message)    
3856H  LDA FCD4H            ; Current Page of files being displayed    
3859H  ANA A                ; Test if displaying page 0
385AH  JZ 3871H             ; Jump if showing page 0 - don't need to skikp any pages   
385DH  STA FCDAH            ; Initialize the number of pages left to skip count    
3860H  CALL 4742H           ; Read next page of files from server     
3863H  LDA FCDAH            ; Get the "Pages left to skip" count    
3866H  DCR A                ; Decrement the remaining skip page count 
3867H  JNZ 385DH            ; Keep reading pages until we have skipped enough pages     
386AH  XRA A                ; Prepare to clear the remaining skip page count 
386BH  STA FCDAH            ; Clear the remaining skip page count     
386EH  STA FCD6H            ; Count of files on screen     
3871H  CALL 4742H           ; Read next page of files from server      
3874H  LDA FCD6H            ; Count of files on screen     
3877H  CPI 14H              ; Test if all file slots are full   
3879H  CC 39AAH             ; Print "-.-" for all empty file slots (if any)    

; =========================================================================================
; Print NADSBox directory or TPDD Bank number to LCD
; =========================================================================================
387CH  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag    
387FH  ANA A                ; Test if server is TPDD
3880H  JZ 389FH             ; Skip processing Bank # or Current Dir if TPDD   
3883H  DCR A                ; Test if server is TPDD2
3884H  JZ 388DH             ; Jump to print bank number if TPDD2   
3887H  LXI H,FCC0H          ; Load pointer to NADSBox current directory storage    
388AH  JMP 38A5H            ; Jump to print the NADSBox / Desklink directory    

; =========================================================================================
; Print the TPDD Bank number to LCD
; =========================================================================================
388DH  LXI H,2401H          ; Go to Row 1, column 24
3890H  SHLD F639H           ; Cursor row (1-8) 
3893H  CALL 4C2FH           ; Start inverse character mode 
3896H  MVI A,23H            ; ASCII code for '#' 
3898H  RST 4                ; Send character in A to the LCD
3899H  LDA FCCAH            ; Load TPDD Bank number 
389CH  ADI 30H              ; Convert to ASCII digit   
389EH  RST 4                ; Send it to the LCD  
389FH  CALL 4C33H           ; Cancel inverse character mode
38A2H  JMP 38B8H            ; Branch to print the function menu, RAM/Disk free, etc.

; =========================================================================================
; Print the NADSBox / Desklink current directory in title bar
; =========================================================================================
38A5H  PUSH H               ; Save address of the directory string     
38A6H  LXI H,2101H          ; Prepare to position the cursor in the title bar          
38A9H  SHLD F639H           ; Cursor row (1-8)         
38ACH  CALL 4C2FH           ; Start inverse character mode         
38AFH  POP H                ; Retrieve the directory string from the stack    
38B0H  MVI C,06H            ; Prepare to redraw 6 chars with inverse video        
38B2H  CALL 48E5H           ; Redraw C characters from buffer at HL using current video mode         
38B5H  CALL 4C33H           ; Cancel inverse character mode         

; =========================================================================================
; Print funtion menu, RAM/Disk free & selected file length
; =========================================================================================
38B8H  LXI H,3E97H          ; Point to Disk function menu          
38BBH  LXI B,3936H          ; Routine to print free disk space          
38BEH  LDA FCD9H            ; RAM/Disk mode        
38C1H  ANA A                ; Test if in Disk mode and skip ahead to print Disk FKeys    
38C2H  JNZ 38CBH            ; Skip ahead if in disk mode to keep vectors        
38C5H  LXI H,3ED9H          ; Point to RAM function menu          
38C8H  LXI B,3922H          ; Routine to print free RAM space          
38CBH  PUSH B               ; Save routine address to stack     
38CCH  PUSH H               ; Save pointer to function text to stack     
38CDH  LDA FCCDH            ; Currently selected file index        
38D0H  LXI H,FCD6H          ; Count of files on screen          
38D3H  CMP M                ; Compare selected file with count of files on screen    
38D4H  JC 38DDH             ; Branch if within bounds       
38D7H  MOV A,M              ; Get the file count      
38D8H  ANA A                ; Test if #files = 0    
38D9H  JNZ 38DDH            ; Skip ahead if not zero        
38DCH  INR A                ; Don't allow a count of zero - must be 1    
38DDH  STA FCD5H            ; Currently selected file index - temp       
38E0H  LXI H,0B07H          ; Row & column of start of text          
38E3H  SHLD F639H           ; Cursor row (1-8)          
38E6H  POP H                ; Get address of text from the stack and display it   
38E7H  CALL 4A2CH           ; Send buffer at M to screen        
38EAH  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)       
38EDH  ANA A                ; Test if in RAM mode   
38EEH  JZ 3905H             ; Jump if in RAM mode (0 = RAM)       
38F1H  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag   
38F4H  ANA A                ; Test if server is TPDD      
38F5H  JZ 3905H             ; Skip printing of "Bank" or "Mkdr" if TPDD       
38F8H  LXI H,3FE9H          ; Point to text for "Bank"     
38FBH  DCR A                ; Test if server is TPDD2      
38FCH  JZ 3902H             ; Jump to print "Bank" if TPDD2         
38FFH  LXI H,3FD8H          ; Point to text for "Mkdr"        
3902H  CALL 4A2CH           ; Send buffer at M to screen                  
3905H  CALL 3940H           ; Display DISK ON/OFF status on LCD         
3908H  LXI H,1507H          ; Point to location for "Free" space (RAM or DISK)
390BH  SHLD F639H           ; Cursor row (1-8)          
390EH  RET                  

; =========================================================================================
; Handle unformatted disks.  Print message and show empty slots.
; =========================================================================================
390FH  XRA A                ; Starting with slot zero...
3910H  CALL 39AAH           ; Print "-.-" for all empty file slots
3913H  LXI H,3E97H          ; Point to Disk Function menu string
3916H  LXI B,391CH          ; Print NOT FORMATTED to the display
3919H  JMP 38CBH            ; Go process the print and jump to error handler

; =========================================================================================
; Print "NOT FORMATTED" on the LCD and return
; =========================================================================================
391CH  LXI H,`H             ; Point to "NOT FORMATTED" string
391FH  JMP 4A2CH            ; Send buffer at M to screen

; =========================================================================================
; Print RAM free space at current posiiton
; =========================================================================================
3922H  LHLD FBB2H           ; Start of variable data pointer  
3925H  XCHG                 ; HL <--> DE
3926H  LHLD F678H           ; BASIC string buffer pointer  
3929H  MOV A,L              ; Prepare for 16 bit subtract   
392AH  SUB E                ; Subtract LSB 
392BH  MOV L,A              ; Save LSB of difference for printing   
392CH  MOV A,H              ; Prepare for subtrating MSB   
392DH  SBB D                ; Subtract MSB 
392EH  MOV H,A              ; Save in H for printing   
392FH  LXI B,FFF2H          ; Load signed number -14       
3932H  DAD B                ; Subtract 14 from free memory 
3933H  JMP 4C3EH            ; Print binary number in HL at current position     

; =========================================================================================
; Display free space on disk
; =========================================================================================
3936H  CALL 4A10H           ; Calculate free space on disk
3939H  CALL 4C3EH           ; Print binary number in HL at current position
393CH  MVI A,30H            ; Prepare to add an extra '0' since calc is /10
393EH  RST 4                ; Send A to the LCD      
393FH  RET       

; =========================================================================================
; Display DISK ON/OFF status on LCD
; =========================================================================================
3940H  LDA FCD9H            ; DISK/RAM mode (0=RAM, 1=DISK)       
3943H  ANA A                ; Test if in RAM mode   
3944H  RNZ                  ; Return if not in RAM mode  
3945H  LDA FB2CH            ; DISK-OFF/ON status   
3948H  LXI D,3FF2H          ; Load pointer to "OFF" text         
394BH  CPI DBH              ; Test if DISK mode (vector LSB) indicates ON or OFF     
394DH  JZ 3953H             ; Branch if in DISK-OFF mode      
3950H  LXI D,3FF6H          ; Load pointer to "ON" text         
3953H  LXI H,1908H          ; Location of DISK-OFF/ON indication on LCD         
3956H  SHLD F639H           ; Cursor row (1-8)   
3959H  XCHG                 ; HL = pointer to text in DE  
395AH  JMP 4A2CH            ; Send buffer at M to screen       

; =========================================================================================
; Display RAM files to LCD and calculate file lengths
; =========================================================================================
395DH  LXI H,F9BAH          ; Load pointer to 1st available file slot in catalog
3960H  XRA A                ; Set count of RAM files on screen to zero 
3961H  STA FCD6H            ; Count of files on screen     
3964H  MVI A,14H            ; Get max # files that will fit on LCD     
3966H  DCR A                ; Decrement the max file count 
3967H  PUSH PSW             ; Save count to the stack    
3968H  MOV A,M              ; Get file type   
3969H  XRI 80H              ; Compliment ?active bit   
396BH  ANI 9FH              ; Test if file is active and should be displayed   
396DH  JNZ 3996H            ; Branch to test next file if not displayed     
3970H  PUSH H               ; Save address of current catalog file  
3971H  INX H                ; Point to file address 
3972H  MOV E,M              ; Get LSB of file address   
3973H  INX H                ; Point to MSB of address 
3974H  MOV D,M              ; Get MSB of file address   
3975H  XTHL                 ; HL <--> (SP)  Get address of file within catalog
3976H  PUSH H               ; Push pointer to MSB of address on stack  
3977H  CALL 3CD3H           ; Calculate length of RAM file      
397AH  XCHG                 ; HL <--> DE DE has the length
397BH  CALL 4791H           ; Store next file length to keyboard buffer      
397EH  POP H                ; Get catalog address of current file from stack 
397FH  XTHL                 ; HL <--> (SP) swap catalog address with pointer to MSB of file address
3980H  INX H                ; Increment to filename 
3981H  MVI C,06H            ; Prepare to print 6 characters of filename     
3983H  CALL 48E5H           ; Redraw C characters from buffer at HL using current video mode       
3986H  MVI A,2EH            ; Load code for '.'      
3988H  RST 4                ; Send A to the LCD                
3989H  MVI C,02H            ; Prepare to print 2 ext bytes to LCD      
398BH  CALL 48E5H           ; Redraw C characters from buffer at HL using current video mode       
398EH  MVI A,20H            ; Load code for space      
3990H  RST 4                ; Send A to the LCD           
3991H  LXI H,FCD6H          ; Count of files on screen        
3994H  INR M                ; Increment number of files displayed on LCD  
3995H  POP H                ; Get catalog address of file from stack  
3996H  LXI D,000BH          ; Load offset to next file locaion in catalog        
3999H  DAD D                ; Offset HL to next file  
399AH  POP PSW              ; Restore the file count from the stack    
399BH  DCR A                ; Decrement the max file count on the LCD  
399CH  JNZ 3967H            ; Branch to test and display next file until zero      
399FH  LDA FCD6H            ; Get the count of files actually displayed on screen              
39A2H  CPI 14H              ; Test if max number of files displayed    
39A4H  CC 39AAH             ; Branch to display "-.-" for remaining empty slots if not max     
39A7H  JMP 387CH            ; Print NADSBox directory or TPDD Bank number to LCD      
				  
; =========================================================================================
; Print "-.-" for all empty file slots
; =========================================================================================
39AAH  PUSH PSW             ; Save current file index count on stack 
39ABH  LXI H,3FCDH          ; Point to "-.-" text
39AEH  CALL 4A2CH           ; Send buffer at M to screen 
39B1H  POP PSW              ; Restore current count 
39B2H  INR A                ; Increment file index number
39B3H  CPI 14H              ; Compare A with max files that fit on LCD
39B5H  JNZ 39AAH            ; Jump to print next "-.-" if not done
39B8H  RET

; =========================================================================================
; Handle "D" key from TS-DOS key scan
; =========================================================================================
39B9H  CALL 3AA8H           ; Test if printer busy.  Return if not busy or error
39BCH  CALL 4C52H           ; LCOPY statement
39BFH  JMP 362FH            ; Print length of selected file using inverse video.

; =========================================================================================
; Handle "L", "P" and "O" keys from TS-DOS key scan - list or print .DO file contents
; =========================================================================================
39C2H  STA FCDFH            ; Save key pressed       
39C5H  LXI D,0007H          ; Load offset of Extension bytes         
39C8H  LHLD FCE4H           ; LCD Buffer address of current file selection        
39CBH  DAD D                ; Point to extension bytes in LCD buffer   
39CCH  MOV A,M              ; Get 1st extension byte     
39CDH  CPI 44H              ; Compare byte with "D"     
39CFH  JNZ 362FH            ; Print length of selected file using inverse video if not "D"       
39D2H  INX H                ; Point to 2nd extension byte  
39D3H  MOV A,M              ; Load 2nd extension byte for comparison
39D4H  CPI 4FH              ; Compare with "0"
39D6H  JNZ 3A06H            ; Jump to print compressed file
39D9H  CALL 3A49H           ; Prepare file for reading (open disk file, address of RAM file)        
39DCH  LDA FCDFH            ; Restore key pressed       
39DFH  CPI 4CH              ; Test if key was "L" - List to LCD     
39E1H  CZ 4C27H             ; CLS statement if LCD      
39E4H  CNZ 3AA8H            ; Test if printer busy.  Return if not busy or error       
39E7H  CALL 3A24H           ; Get next block of data to display/print (HL=address)        
39EAH  PUSH PSW             ; Push Z flag indicating if a full 128 bytes was read      
39EBH  CALL 3A6BH           ; Display / print file data bytes at HL, A has length                 
39EEH  POP PSW              ; Get Z flag indicating if 128 bytes read     
39EFH  JZ 39E7H             ; Jump to process more if 128 bytes were read last time      
39F2H  LDA FCDFH            ; Restore key pressed       
39F5H  CPI 4CH              ; Test if key was "L"              
39F7H  JNZ 3A00H            ; Skip beep if printing       
39FAH  MVI A,07H            ; Load code for BELL       
39FCH  RST 4                ; Go print a BELL (beep)    
39FDH  CALL 3DF8H           ; Process power-off logic and wait for a key from keyboard        

; =========================================================================================
; Clear screen and perform Long Jump
; =========================================================================================
3A00H  CALL 4C27H           ; CLS statement         
3A03H  JMP 48B5H            ; Branch to "Long Jump" operation        

; =========================================================================================
; Handler for the "O" key - print a compressed file?? 
; =========================================================================================
3A06H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)
3A09H  ANA A                ; Test if in Disk mode 
3A0AH  JNZ 362FH            ; Jump to keyscan if in Disk mode
3A0DH  LHLD FCE4H           ; LCD Buffer address of current file selection      
3A10H  CALL 4902H           ; Copy filename at (HL) to current BASIC program
3A13H  CALL 4A51H           ; Get RAM directory address of current BASIC program
3A16H  CPI C0H              ; Test if filetype is .DO
3A18H  CZ 5004H             ; Call routine to Compress / Decompress .DO files
3A1BH  CALL 4C0FH           ; Update system pointers       
3A1EH  CALL 3611H           ; Print Copyright and files
3A21H  JMP 362FH            ; Jump to keyscan 

; =========================================================================================
; Get next 128 bytes (or less) of data from RAM or disk file for display
; =========================================================================================
3A24H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)      
3A27H  ANA A                ; Test if RAM mode  
3A28H  JNZ 40B6H            ; If not RAM mode, go send TPDD_READ data opcode and recieve response      
3A2BH  LHLD FCDDH           ; Get length of file to be displayed / printed       
3A2EH  LXI B,0080H          ; Prepare to subtract 128 from length
3A31H  MOV A,C              ; Save 128 to A    
3A32H  DSUB                 ; Subtract 128 from file length 
3A33H  JNC 3A3AH            ; Branch if length >= 128      
3A36H  DAD B                ; Add 128 back to length to print "partial" buffer  
3A37H  MOV A,L              ; Move remainder of bytes to display/print    
3A38H  MOV L,H              ; Clear LSB of remainder    
3A39H  MOV C,A              ; Move LSB of remainder to C    
3A3AH  SHLD FCDDH           ; Save new remaining file length       
3A3DH  LHLD FCE0H           ; Load the address to be printed / saved       
3A40H  PUSH H               ; Save on stack    
3A41H  DAD B                ; Update address to be used for display/printing next time  
3A42H  SHLD FCE0H           ; Save address to be displayed / printed       
3A45H  POP H                ; Retrieve address to be printed this loop from stack  
3A46H  CPI 80H              ; Compare length with maximum    
3A48H  RET

; =========================================================================================
; Initialize Selected file for display (RAM or Disk)
; =========================================================================================
3A49H  CALL 4A3BH           ; Initialize blank filename and attribute byte
3A4CH  LHLD FCE4H           ; LCD Buffer address of current file selection
3A4FH  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)     
3A52H  ANA A                ; Test if in RAM mode 
3A53H  JNZ 3A65H            ; Branch to process Disk files if in Disk mode     
3A56H  CALL 4A4BH           ; Get RAM directory address of selected file
3A59H  PUSH D               ; Push file address to stack  
3A5AH  CALL 3CD3H           ; Calculate length of RAM file, HL=address of catalog entry, DE=file address
3A5DH  SHLD FCDDH           ; Save length to FDC emulation sector storage area
3A60H  POP H                ; Pop address of file into H 
3A61H  SHLD FCE0H           ; Save file address
3A64H  RET		 
				 
; =====================================================================================
; Send TPDD Open command to open selected file
; =====================================================================================
3A65H  CALL 3D95H           ; Copy filename at (HL) to TX buffer
3A68H  JMP 408AH            ; Open TPDD file for Read Mode

; =====================================================================================
; Display / print file data bytes at HL, A has length
; =====================================================================================
3A6BH  XCHG                 ; HL <--> DE  
3A6CH  ORA A                ; Test if length = 0   
3A6DH  RZ                   ; Return if length = 0
3A6EH  MOV C,A              ; Save length count in C     
3A6FH  LDA FCDFH            ; Load key press value       
3A72H  CPI 4CH              ; Test if key was "L"     
3A74H  JNZ 3A82H            ; Jump to print contents if not "L"       
3A77H  CALL 3A8FH           ; Check for CTRL-C
3A7AH  LDAX D               ; Load next byte from src pointer    
3A7BH  RST 4                ; Send A to LCD           
3A7CH  INX D                ; Increment the pointer   
3A7DH  DCR C                ; Decrement the length count   
3A7EH  JNZ 3A77H            ; Keep looping until all data displayed       
3A81H  RET        

; =====================================================================================
; Print file data bytes at HL, A has length
; =====================================================================================
3A82H  CALL 3A8FH           ; Test for CTRL-C, etc.
3A85H  LDAX D               ; Load next file byte from source poiner 
3A86H  CALL 4C42H           ; Print A to printer, expanding tabs if necessary
3A89H  INX D                ; Increment pointer
3A8AH  DCR C                ; Decrement length count
3A8BH  JNZ 3A82H            ; Keep looping until all data printed    
3A8EH  RET

; =========================================================================================
; Test for ESC, CTRL-C or Space
; =========================================================================================
3A8FH  CALL 4C4AH           ; Check keyboard queue for pending characters
3A92H  RZ                   ; Return if no pending characters
3A93H  CALL 4BEBH           ; Wait for key from keyboard
3A96H  CPI 03H              ; Test for F4 maybe?  
3A98H  JZ 3A00H             ; Clear screen and perform Long Jump if F4 maybe?   
3A9BH  CPI 1BH              ; Test for ESC key  
3A9DH  JZ 3A00H             ; Clear screen and perform Long Jump if ESC   
3AA0H  CPI 20H              ; Test for space key  
3AA2H  JNZ 3A8FH            ; Branch back to wait for ESC, CTRL-C or space if not space    
3AA5H  JMP 4BEBH            ; Wait for key from keyboard    

; =========================================================================================
; Test if printer busy.  Return if not busy, print error if it is
; =========================================================================================
3AA8H  IN BBH               ; Get printer port input     
3AAAH  ANI 06H              ; Mask all but BUSY and /BUSY      
3AACH  XRI 02H              ; Compliment /BUSY      
3AAEH  JNZ 487BH            ; Printer not ready / FF error        
3AB1H  RET        

; =========================================================================================
; Print currently selected file using inverse video
; =========================================================================================
3AB2H  CALL 3ACDH           ; Calculate Row and Column of newly selected file
3AB5H  SHLD FCE4H           ; LCD Buffer address of current file selection
3AB8H  CALL 4C2FH           ; Start inverse character mode
3ABBH  DCX H                ; Start drawing from left edge of selection (include space)   
3ABCH  MVI C,0AH            ; Draw 10 characters       
3ABEH  CALL 48E5H           ; Redraw C characters from buffer at HL using current video mode
3AC1H  JMP 4C33H            ; Cancel inverse character mode       

; =========================================================================================
; Print selected file using normal video to "unselect" it
; =========================================================================================
3AC4H  CALL 4C33H           ; Cancel inverse character mode
3AC7H  CALL 3ACDH           ; Calculate row and column of newly selected file
3ACAH  JMP 3ABBH            ; Print the file to the LCD       

; =========================================================================================
; Calculate Row and Column of soon-to-be (newly) selected file
; =========================================================================================
3ACDH  LDA FCD5H            ; Currently selected file index       
3AD0H  DCR A                ; Make selected file zero based   
3AD1H  MOV L,A              ; Save index to 16-bit HL
3AD2H  MVI H,00H            ; Make MSB zero
3AD4H  LXI D,000AH          ; Prepare to multiply index * 10 cols      
3AD7H  CALL 4C1FH           ; Signed integer muliply (FAC1=HL*DE)
3ADAH  LXI D,FE28H          ; Load address of line 2 in the LCD buffer
3ADDH  DAD D                ; Calculate starting LCD buffer address for this file
3ADEH  INX H                ; Skip the "tag" space on the LCD
3ADFH  PUSH H               ; Save address on the stack
3AE0H  LXI B,FE00H          ; Load starting address of LCD character buffer
3AE3H  DSUB                 ; Calculate file start offset from start of LCD buffer
3AE4H  LXI D,0028H          ; Load 1 LCD line width
3AE7H  XCHG                 ; HL <--> DE  Prepare for divide
3AE8H  CALL 4C1BH           ; Signed integer divide (FAC1=DE/HL)
3AEBH  MOV A,L              ; Save selected file's row number to A
3AECH  INR A                ; Make row 1-based
3AEDH  STA F639H            ; Cursor row (1-8)
3AF0H  XCHG                 ; HL <--> DE  DE had remainder*2 from divide
3AF1H  ASHR                 ; Divide HL by 2
3AF2H  MOV A,L              ; Prepare to save remainder as the column
3AF3H  STA F63AH            ; Cursor column (1-40)
3AF6H  POP H                ; Restore address of LCD buffer location from stack
3AF7H  RET

; =========================================================================================
; F3 Function key handler for RAM mode - Rename
; =========================================================================================
3AF8H  CALL 4A4BH           ; Get RAM directory address of selected file          
3AFBH  SHLD FCE0H           ; Save address of file being processed          
3AFEH  LXI H,3F4AH          ; Address of "New name" string           
3B01H  CALL 3E1AH           ; Get 6-byte input filename from keyboard          
3B04H  RZ                   ; Return if no input provided  
3B05H  CALL 4902H           ; Copy filename at (HL) to current BASIC program          
3B08H  LHLD FCE0H           ; Load RAM directory address of file being renamed          
3B0BH  LXI B,0009H          ; Load offset of extension within catalog entry           
3B0EH  DAD B                ; Point to extension bytes     
3B0FH  LXI D,FC99H          ; Load address of extension field of current BASIC program name           
3B12H  MOV A,M              ; Get 1st byte of extension of catalog file being renamed       
3B13H  STAX D               ; Save extension byte in current BASIC program filename - preserve EXT      
3B14H  INX D                ; Point to 2nd ext byte of BASIC program name     
3B15H  INX H                ; Point to 2nd ext byte of catalog filename     
3B16H  MOV A,M              ; Get 2nd extension byte from catalog filename       
3B17H  STAX D               ; Save byte in current BASIC program filename area      
3B18H  CALL 4A51H           ; Get RAM directory address of current BASIC program          
3B1BH  JNZ 487EH            ; If found, jump to File Exists Error         
3B1EH  LHLD FCE0H           ; Load catalog address of file being renamed          
3B21H  INX H                ; Point to LSB of file address     
3B22H  INX H                ; Point to MSB of file address     
3B23H  INX H                ; Point to name     
3B24H  LXI D,FC93H          ; Load address of filename of current BASIC program    
3B27H  LXI B,0006H          ; Prepare to copy 6 bytes of filename (ext doesn't change)           
3B2AH  XCHG                 ; HL <--> DE    
3B2BH  JMP 4A05H            ; Move BC bytes from M to (DE) with increment         

; =========================================================================================
; F1 Function key handler for DISK mode - Load
; =========================================================================================
3B2EH  CALL 4A3BH           ; Initialize blank filename and attribute byte      
3B31H  LHLD FCE4H           ; LCD Buffer address of current file selection      
3B34H  CALL 3D95H           ; Copy filename at (HL) to TX buffer      
3B37H  LDA FCCCH            ; Last Tag/Untag operation code     
3B3AH  ANA A                ; Test if a tag operation is pending 
3B3BH  JNZ 3B56H            ; Branch if doing tag load operation     
3B3EH  LXI H,3F7AH          ; Point to "Load as:" text       
3B41H  CALL 3E1AH           ; Get 6-byte filename input from keyboard      
3B44H  JZ 3B56H             ; Jump to use existing disk name as filename    
3B47H  CALL 4902H           ; Copy filename at (HL) to current BASIC program      
3B4AH  LXI B,0002H          ; Prepare to copy 2 extension bytes to current BASIC program space       
3B4DH  LXI H,FCEFH          ; Point to disk file extension in TX buffer       
3B50H  LXI D,FC99H          ; Point to current BASIC program extension address       
3B53H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      
3B56H  CALL 4A51H           ; Get RAM directory address of current BASIC program      
3B59H  JZ 3B69H             ; Branch to load if file doesn't already exist    
3B5CH  LXI H,3FB0H          ; Point to "File Exists, Replace?" text       
3B5FH  CALL 48F4H           ; Print string at HL to col 1 on the bottom line      
3B62H  CALL 3DEEH           ; Get key from keyboard and test for 'Y' or 'y'      
3B65H  RNZ                  ; Return if isn't 'y' or 'Y' 
3B66H  CALL 3C38H           ; Kill file in current BASIC program space      
3B69H  LHLD FD1DH           ; Get file size from RX buffer      
3B6CH  MOV A,H              ; Swap bytes (big endian in RX buffer)   
3B6DH  MOV H,L              ; Move LSB to MSB   
3B6EH  MOV L,A              ; Move MSB to LSB   
3B6FH  SHLD FD1DH           ; Save with little endian to RX buffer      
3B72H  LDA FCEFH            ; Get 1st byte of extension from TX buffer     
3B75H  CPI 44H              ; Test if 1st extension byte is "D"   
3B77H  JNZ 3B82H            ; Jump if not "D" to check for "C" or "B"     
3B7AH  LHLD FBAEH           ; Get start of DO files pointer for location of new file       
3B7DH  MVI A,C0H            ; Load file type code for .DO files     
3B7FH  JMP 3BA3H            ; Process the file load      

; =========================================================================================
; Test file exension type in A for .CO files
; =========================================================================================
3B82H  CPI 43H              ; Test if A contains "C" 
3B84H  JNZ 3B95H            ; Branch if not .CO file
3B87H  LHLD FBB0H           ; Start of CO files pointer
3B8AH  SHLD FCD5H           ; Save in currently selected file index storage area
3B8DH  LHLD FBB2H           ; Get Start of variable data pointer as location for new file
3B90H  MVI A,A0H            ; Load file type code for .CO files
3B92H  JMP 3BA3H            ; Process the file load

; =========================================================================================
; Process load of .BA file
; =========================================================================================
3B95H  LHLD FD1DH           ; Get file size from RX buffer
3B98H  SHLD FCD5H           ; Save in Currently selected file index storage
3B9BH  LHLD F99AH           ; Get BASIC program not saved pointer     
3B9EH  SHLD FCE0H           ; Save as address of file being processed
3BA1H  MVI A,80H            ; Load file type code for .BA files     

; =========================================================================================
; Process file load operation
; =========================================================================================
3BA3H  STA FCDFH            ; Save file type code for later     
3BA6H  SHLD FCE2H           ; Save address for new file 
3BA9H  LHLD FD1DH           ; Get file size from RX buffer
3BACH  SHLD FCDDH           ; Save in FDC emulation physical/logical sector storage area
3BAFH  PUSH H               ; Save file size on stack  
3BB0H  POP B                ; Copy file size to BC 
3BB1H  LDA FCDFH            ; Get file type code     
3BB4H  CPI A0H              ; Test for .CO file   
3BB6H  JZ 3BC0H             ; Skip increment if .CO file (.BA has trailing 0x0000, .DO a 0x1A)    
3BB9H  INX B                ; Increment file length for .BA and .DO files 
3BBAH  CPI 80H              ; Test if file is .BA   
3BBCH  JNZ 3BC0H            ; Skip additional increment if .BA     
3BBFH  INX B                ; Add 1 more to length for .BA files to account for both trailing 0's 
3BC0H  PUSH B               ; Save updated length on stack  
3BC1H  CALL 3E48H           ; Find empty catalog entry      
3BC4H  JC 4887H             ; Generate system error 0x0A ("DD") if full
3BC7H  POP B                ; Get length from stack 
3BC8H  PUSH H               ; Save new file catalog address on stack  
3BC9H  PUSH B               ; Save new file length on stack  
3BCAH  LHLD FCE2H           ; Get address for new contents of new file      
3BCDH  CALL 4C0BH           ; Insert BC spaces at M - make room      
3BD0H  JC 488AH	            ; Branch if error - RAM full error
3BD3H  LHLD FCE2H           ; Restore address of new file contents
3BD6H  POP B                ; Get file length from stack   
3BD7H  MVI M,00H            ; Fill newly created file space with zero's       
3BD9H  INX H                ; Increment pointer   
3BDAH  DCX B                ; Decrement count   
3BDBH  MOV A,C              ; Move LSB to A to check for zero - could use JNX here!     
3BDCH  ORA B                ; Or in MSB to check for zero   
3BDDH  JNZ 3BD7H            ; Keep looping until all are zero       
3BE0H  DCX H                ; Decrement pointer to last byte in new file   
3BE1H  POP D                ; Get File catalog address from stack   
3BE2H  LDA FCDFH            ; Load file type code byte       
3BE5H  CPI C0H              ; Test for .DO file     
3BE7H  JNZ 3BF3H            ; Branch if not .DO file       
3BEAH  MVI M,1AH            ; Terminate .DO file with EOF marker       
3BECH  LHLD FCE2H           ; Reload address of new file contents        
3BEFH  DCX H                ; Decrement pointer to jump into middle of loop   
3BF0H  JMP 3C1BH            ; Write file entry to catalog       

; =========================================================================================
; Process end-of-file / file length for .CO and .BA files
; =========================================================================================
3BF3H  CPI A0H              ; Test if new file is .CO  
3BF5H  JNZ 3C04H            ; Branch if not .CO - must be .BA 
3BF8H  LHLD FCD5H           ; Get old start of CO files pointer
3BFBH  SHLD FBB0H           ; Save as current start of CO files pointer     
3BFEH  LHLD FCE2H           ; Reload address of new file contents
3C01H  JMP 3C1BH            ; Write file entry to catalog 

; =========================================================================================
; Process end-of-file for .BA files
; =========================================================================================
3C04H  PUSH D               ; Push file catalog address to stack    
3C05H  LHLD FBAEH           ; Get start of DO files pointer          
3C08H  DCX H                ; Decrement address by 1   
3C09H  SHLD F99AH           ; Save as new BASIC program not saved pointer          
3C0CH  INX H                ; Increment back to start of .DO files   
3C0DH  XCHG                 ; HL <--> DE  DE has start of DO files  
3C0EH  LHLD FCD5H           ; Get BA file size        
3C11H  INX H                ; Increment file size to account for trailing 0's   
3C12H  INX H                ; Increment file size to account for trailing 0's   
3C13H  DAD D                ; Add new length to start of DO files pointer   
3C14H  SHLD FBAEH           ; Save new start of DO files pointer          
3C17H  POP D                ; Retrieve file catalog address from stack   
3C18H  LHLD FCE0H           ; Reload address of new file contents        

; =========================================================================================
; Write file entry to catalog
; =========================================================================================
3C1BH  XCHG                 ; HL <--> DE  DE has file address, HL has catalog address         
3C1CH  CALL 4C17H           ; Write new entry to catalog (A=type, DE=file address,HL=catalog address)       
3C1FH  CALL 4127H           ; Open TPDD file and read data to file address being processed       
3C22H  CALL 4C0FH           ; Update system pointers       
3C25H  LXI H,0002H          ; Load TPDD_READ opcode in HL        
3C28H  JMP 409BH            ; Send Request in HL and await response      

; =========================================================================================
; F2 Function key handler for RAM mode - Kill
; =========================================================================================
3C2BH  LDA FCCCH            ; Get last Tag/Untag operation code       
3C2EH  ANA A                ; Test if there is a pending tag operation
3C2FH  CZ 3DE1H             ; Display "Sure ?", validate and return if validated if no tag
3C32H  LHLD FCE4H           ; LCD Buffer address of current file selection
3C35H  CALL 4902H           ; Copy filename at (HL) to current BASIC program

; =========================================================================================
; Kill file in current BASIC program space
; =========================================================================================
3C38H  CALL 4A51H           ; Get RAM directory address of current BASIC program
3C3BH  CPI C0H              ; Test if file is .DO 
3C3DH  JZ 4BFFH             ; Kill .DO file  
3C40H  CPI A0H              ; Test if file is .CO 
3C42H  JZ 4C07H             ; Kill .CO file 
3C45H  CPI 80H              ; Test if file is .BA
3C47H  JZ 4C03H             ; Kill .BA file
3C4AH  RET

; =========================================================================================
; F1 Function key handler for RAM mode - Save
; =========================================================================================
3C4BH  CALL 4A3BH           ; Initialize blank filename and attribute byte      
3C4EH  CALL 4A4BH           ; Get RAM directory address of selected file      
3C51H  PUSH D               ; Push file address to stack  
3C52H  PUSH H               ; Push file catalog address to stack  
3C53H  INX H                ; Point to LSB of file address 
3C54H  INX H                ; Point to MSB of file address 
3C55H  INX H                ; Point to filename in catalog 
3C56H  LXI D,FCE8H          ; Point to TX buffer data area (payload)
3C59H  LXI B,0006H          ; Prepare to copy 6 filename bytes to TX packet data
3C5CH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      
3C5FH  MVI A,2EH            ; Load code for '.'     
3C61H  STAX D               ; Store '.' separator in TX packet data  
3C62H  INX D                ; Increment TX packet data pointer 
3C63H  LXI B,0002H          ; Prepare to copy 2 extention bytes from catalog
3C66H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      
3C69H  LDA FCCCH            ; Last Tag/Untag operation code     
3C6CH  ANA A                ; Test if a tag save operation is being performed 
3C6DH  JNZ 3C88H            ; Jump ahead if doing a tag save - skip filename questioning     
3C70H  LXI H,3F71H          ; Point to "Save as:" text
3C73H  CALL 3E1AH           ; Get 6-byte input filename from keyboard      
3C76H  JZ 3C88H             ; Skip ahead to use catalog name if no input given    
3C79H  CALL 4902H           ; Copy filename at (HL) to current BASIC program             
3C7CH  LXI B,0006H          ; Prepare to copy 6 filename bytes from input string       
3C7FH  LXI D,FCE8H          ; Point to filename area in TX buffer       
3C82H  LXI H,FC93H          ; Filename of current BASIC program         
3C85H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      
3C88H  POP H                ; Restore file catalog address from stack 
3C89H  POP D                ; Restore file address from stack 
3C8AH  PUSH D               ; Save file address on stack  
3C8BH  CALL 3CD3H           ; Calculate length of RAM file, HL=address of catalog entry, DE=file address
3C8EH  MOV A,H              ; Test for zero length file - move H to A    
3C8FH  ORA L                ; OR LSB to test for zero  
3C90H  JZ 4884H             ; Branch if empty - File Empty Error     
3C93H  PUSH H               ; Save file address to stack   
3C94H  MVI A,01H            ; Set file open mode to new file      
3C96H  STA FCD6H            ; Save open mode to pass to open routine      
3C99H  CALL 4943H           ; Configure baud, test for NADSBox, get NADSBox dir       
3C9CH  CALL 4A72H           ; Send Dir Reference opcode       
3C9FH  JZ 3CCEH             ; Jump to write data if file doesn't exist (size = 0)     
3CA2H  LXI H,3F8BH          ; Point to "File Exists, A)ppend R)eplace Q)uit" text        
3CA5H  CALL 48F4H           ; Print string at HL to col 1 on the bottom line       
3CA8H  CALL 3DF8H           ; Process power-off logic and wait for a key from keyboard       
3CABH  ANI DFH              ; Make key uppercase    
3CADH  RST 4                ; Display key on LCD            
3CAEH  CPI 52H              ; Test if key is 'R'    
3CB0H  JNZ 3CBCH            ; Jump if not 'R'eplace                      
3CB3H  CALL 431AH           ; Issue TPDD Delete file Opcode       
3CB6H  CALL 4A72H           ; Send Dir Reference opcode       
3CB9H  JMP 3CCEH            ; Go write data to the file      

; =========================================================================================
; F1-Save: Test for 'A'ppend
; =========================================================================================
3CBCH  POP H                ; Get file length from stack    
3CBDH  POP D                ; Get file address from stack    
3CBEH  CPI 41H              ; Test if response is 'A'ppend      
3CC0H  RNZ                  ; Return if not 'A'  
3CC1H  LDA FCEFH            ; Load 1st byte of extension from TX buffer        
3CC4H  CPI 44H              ; Test if file is "D"O file      
3CC6H  RNZ                  ; Don't allow appending non DO files  
3CC7H  MVI A,02H            ; Set open mode to open existing (append)        
3CC9H  STA FCD6H            ; Save mode to pass to open routine        
3CCCH  PUSH D               ; Save file address on stack     
3CCDH  PUSH H               ; Save file length on stack     

; =========================================================================================
; Save function - Replace or new file, write data to file
; =========================================================================================
3CCEH  POP H                ; Retrieve file length from stack    
3CCFH  POP D                ; Retrieve file address from stack    
3CD0H  JMP 40C8H            ; Write HL bytes of data from (DE) to TPDD        

; =========================================================================================
; Calculate length of RAM file, HL=address of catalog entry, DE=file address
; =========================================================================================
3CD3H  MOV A,M              ; Get RAM file type from catalog   
3CD4H  CPI C0H              ; Test for .DO file   
3CD6H  JZ 3CE6H             ; Jump to calculate length if .DO file    
3CD9H  CPI A0H              ; Test for .CO file         
3CDBH  JZ 3CF5H             ; Jump to calculate length if .CO file    
3CDEH  PUSH D               ; Save address of start of BASIC program to stack  
3CDFH  CALL 4C13H           ; Call ROM routine to find BASIC end of program
3CE2H  POP B                ; Get BASIC program start address from stack 
3CE3H  DSUB                 ; Subtract starting address from end address
3CE4H  DCX H                ; Don't count trailing 0x00 as part of BASIC program length 
3CE5H  RET

; =========================================================================================
; Calculate length of .DO file, HL=Catalog address, DE=file address
; =========================================================================================
3CE6H  XCHG                 ; HL <--> DE Get file address in HL 
3CE7H  LXI D,0000H          ; Clear file length
3CEAH  MOV A,M              ; Get next byte from .DO file    
3CEBH  INX H                ; Increment pointer  
3CECH  INX D                ; Increment length  
3CEDH  CPI 1AH              ; Test for EOF marker    
3CEFH  JNZ 3CEAH            ; Branch to next byte if not EOF      
3CF2H  DCX D                ; Subtract EOF marker from file length  
3CF3H  XCHG                 ; HL <--> DE  HL=length 
3CF4H  RET

; =========================================================================================
; Calculate length of .CO file, HL=Catalog address, DE=file address
; =========================================================================================
3CF5H  XCHG                 ; HL <--> DE  Get file address in HL 
3CF6H  INX H                ; Increment past .CO load address 
3CF7H  INX H                ; Increment past MSB of load address
3CF8H  MOV C,M              ; Get LSB of length  
3CF9H  INX H                ; Increment to MSB of length
3CFAH  MOV B,M              ; Get MSB of length
3CFBH  LXI H,0006H          ; Prepare to add 6-byte header to length
3CFEH  DAD B                ; Add 6-byte header to length
3CFFH  RET

; =========================================================================================
; F7 Function key handler for DISK mode - Mkdir
; =========================================================================================
3D00H  LDA FCCBH            ; NADSBox / TPDD2 / Desklink flag        
3D03H  ANA A                ; Test if server is TPDD    
3D04H  RZ                   ; Return if not NADSBox or TPDD2 
3D05H  DCR A                ; Test if TPDD2    
3D06H  JZ 37BAH             ; Go Swap TPDD Bank Number if TPDD2       
3D09H  CALL 4A3BH           ; Must be NADSBOx Initialize blank filename         
3D0CH  LXI H,3F61H          ; Load pointer to "Directory name:" text          
3D0FH  CALL 3E1AH           ; Get 6-byte input filename from keyboard         
3D12H  RZ                   ; Return if no input given 
3D13H  CALL 4902H           ; Copy filename at (HL) to current BASIC program         
3D16H  LXI H,FC93H          ; Filename of current BASIC program              
3D19H  LXI D,FCE8H          ; Point to TX buffer data area (payload)          
3D1CH  LXI B,0006H          ; Prepare to copy 6 filename bytes to TX buffer          
3D1FH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment         
3D22H  LXI H,3E3CH          ; Load code for "<>"          
3D25H  SHLD FCEFH           ; Save "<>" extension bytes in TX buffer - NADSBox Mkdir                   
3D28H  MVI A,2EH            ; Load code for '.' extension separator        
3D2AH  STA FCEEH            ; Save "." to TX buffer        
3D2DH  CALL 4943H           ; Configure baud, test for NADSBox, get NADSBox dir         
3D30H  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag        
3D33H  CPI 02H              ; Test if we have NADSBox current directory      
3D35H  RNZ                  ; Return if we don't have current directory  
3D36H  CALL 4A72H           ; Send Directory Reference opcode         
3D39H  JNZ 3D4DH            ; If the file exists, branch to open it for READ mode        
3D3CH  MVI A,01H            ; Load OPEN_WRITE mode into A to create the directory        
3D3EH  STA FCE8H            ; Save A in TX data storage mode field        
3D41H  LXI H,0101H          ; Load opcode to open a file          
3D44H  CALL 409BH           ; Send Request in HL and await response         
3D47H  LXI H,0002H          ; Load opcode to close the file          
3D4AH  JMP 409BH            ; Send Request in HL and await response        

; =========================================================================================
; Open and close a directory file (from above)
; =========================================================================================
3D4DH  CALL 408AH           ; Open TPDD file for Read Mode
3D50H  JMP 3D47H            ; Branch to close the directory open request

; =========================================================================================
; F5 Function key handler for DISK mode - Format
; =========================================================================================
3D53H  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag       
3D56H  CPI 02H              ; Test if we have "current directory" name     
3D58H  RZ                   ; Return if server is NADSBox / Desklink - No format supported
3D59H  LXI H,3F1BH          ; Load pointer to "Insert Disk" string
3D5CH  CALL 48F4H           ; Print string at HL to col 1 on the bottom line        
3D5FH  CALL 3DEEH           ; Get key from keyboard and test for 'Y' or 'y'        
3D62H  RNZ                  ; Return if response not 'Y' 
3D63H  CALL 4943H           ; Configure baud, test for NADSBox, get NADSBox dir        
3D66H  CALL 49E3H           ; Delay routine - about 3ms        
3D69H  LXI H,0006H          ; Load TPDD_FORMAT opcode in HL
3D6CH  CALL 409BH           ; Send Request in HL and await response        
3D6FH  MVI A,07H            ; Load code for BELL       
3D72H  RET		            ; Go beep to indicate format

; =========================================================================================
; F2 Function key handler for DISK mode - Kill
; =========================================================================================
3D73H  LDA FCCCH            ; Last Tag/Untag operation code      
3D76H  ANA A                ; Test if there's an active tag group
3D77H  CZ 3DE1H             ; Display "Sure ?", validate and return if validated if no tag
3D7AH  CALL 4A3BH           ; Initialize blank filename and attribute byte
3D7DH  CALL 3D83H           ; Copy selected filename to TX buffer and init TPDD/NADSBox
3D80H  JMP 431AH            ; Issue TPDD Delete file Opcode            

; =========================================================================================
; Copy selected filename to TX buffer and init TPDD/NADSBox
; =========================================================================================
3D83H  LXI B,0009H          ; Prepare to copy 9 filename bytes
3D86H  LHLD FCE4H           ; LCD Buffer address of current file selection
3D89H  LXI D,FCE8H          ; Address of TX packet data
3D8CH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment
3D8FH  CALL 4943H           ; Configure baud, test for NADSBox, get NADSBox dir
3D92H  JMP 4A72H            ; Send Dir Reference opcode

; =========================================================================================
; Copy filename at (HL) to TX buffer
; =========================================================================================
3D95H  CALL 4902H           ; Copy filename at (HL) to current BASIC program
3D98H  LXI H,FC93H          ; Filename of current BASIC program
3D9BH  CALL 4A57H           ; Send Dir Reference for filename at (HL)
3D9EH  RET        

; =========================================================================================
; F3 Function key handler for DISK mode - Name
; =========================================================================================
3D9FH  CALL 4A3BH           ; Initialize blank filename and attribute byte          
3DA2H  CALL 3D83H           ; Copy selected filename to TX buffer and init TPDD/NADSBox          
3DA5H  LXI H,FCE8H          ; Point to TX buffer data area (payload)
3DA8H  LXI D,FC9CH          ; Filename of last program loaded from tape  
3DABH  LXI B,0009H          ; Prepare to copy 9 bytes to "last program loaded" filename
3DAEH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment          
3DB1H  LHLD FD1DH           ; Get file size from RX buffer          
3DB4H  MOV C,H              ; Save file size MSB to C (swap endian)       
3DB5H  MOV B,L              ; Save file size LSB to B (swap endian)       
3DB6H  LXI H,7CC0H          ; ? Load HL with 31936
3DB9H  DSUB                 ; ? Compare file length with 31936    
3DBAH  LXI H,3F4AH          ; Address of "New name" string
3DBDH  JNZ 3DD7H            ; Branch to change filename if not 30656         
3DC0H  LXI B,0009H          ; Allow a 9-byte filename input string
3DC3H  CALL 3E1DH           ; Get max BC length input for filename and convert to uppercase          
3DC6H  RZ                   ; Return if no input provided  
3DC7H  PUSH H               ; Save pointer to input string to stack      
3DC8H  PUSH PSW             ; Save string length to stack        
3DC9H  CALL 4A3BH           ; Initialize blank filename and attribute byte          
3DCCH  POP PSW              ; Get string length from stack       
3DCDH  POP H                ; Get string address from stack     
3DCEH  LXI D,FCE8H          ; Point to TX buffer data area (payload)           
3DD1H  MOV C,A              ; Copy length to BC       
3DD2H  MVI B,00H            ; Make MSB of length = 0         
3DD4H  JMP 41B0H            ; Rename the TPDD file whose name is in (HL)         

; =========================================================================================
; Get filename from keyboard and rename Disk file, filename in "current BASIC program"
; =========================================================================================
3DD7H  CALL 3E1AH           ; Get 6-byte input filename from keyboard
3DDAH  RZ                   ; Return if no input provided 
3DDBH  CALL 4902H           ; Copy filename at (HL) to current BASIC program
3DDEH  JMP 41A7H            ; Rename the TPDD file whose name is in "current BASIC program" 

; =========================================================================================
; Display "Sure ?", validate and return if validated
; =========================================================================================
3DE1H  LXI H,3F83H          ; Load pointer to "Sure ?" string
3DE4H  CALL 48F4H           ; Print string at HL to col 1 on the bottom line 
3DE7H  CALL 3DEEH           ; Get key and test for 'Y' or 'y' 
3DEAH  JNZ 48B5H            ; Branch to "Long jump" operation to abort if not 'y' 
3DEDH  RET

; =========================================================================================
; Get key from keyboard and test for 'Y' or 'y'
; =========================================================================================
3DEEH  CALL 3DF8H           ; Process power-off logic and wait for a key from keyboard
3DF1H  RST 4                ; Display the key on the LCD 
3DF2H  CPI 59H              ; Test if key pressed was 'Y'      
3DF4H  RZ                   ; Return if key pressed was 'Y' 
3DF5H  CPI 79H              ; Test if key pressed was 'y'      
3DF7H  RET

; =========================================================================================
; Process power-off logic and wait for a key from keyboard
; =========================================================================================
3DF8H  CALL 3DFEH           ; Process automatic poweroff logic
3DFBH  JMP 4BEBH            ; Wait for key from keyboard

; =========================================================================================
; Process automatic power-off logic during key scan loop
; =========================================================================================
3DFEH  XRA A                ; Clear A  
3DFFH  DCR A                ; Set A to 0xFF   
3E00H  STA F656H            ; Power off exit condition switch  
3E03H  CALL 4C4AH           ; Check keyboard queue for pending characters
3E06H  JZ 3DFEH             ; Branch back if no keyboard characters in queue - wait for key
3E09H  XRA A                ; Clear A  
3E0AH  STA F656H            ; Power off exit condition switch  
3E0DH  LXI H,F932H          ; Load address of "Renew Automatic Poweroff Counter Flag"
3E10H  ORA M                ; Test if auto poweroff counter should be renewed
3E11H  JZ 4BF7H             ; Renew automatic power-off counter if enabled
3E14H  CALL 4BF3H           ; Turn off the computer
3E17H  JMP 3DFEH            ; Branch back to continue processing power off logic

; =========================================================================================
; Get max 6-byte input for filename and convert to uppercase
; =========================================================================================
3E1AH  LXI B,0006H          ; Get maximum 6 characters of input

; =========================================================================================
; Get max BC length input for filename and convert to uppercase
; =========================================================================================
3E1DH  CALL 3E2FH           ; Get max BC length input string from keyboard
3E20H  RZ                   ; Return if no input provided 
3E21H  PUSH H               ; Preserve pointer to input string     
3E22H  PUSH PSW             ; Preserve flags from input       
3E23H  CALL 4C5EH           ; Get char at M and convert to uppercase
3E26H  MOV M,A              ; Save uppercase char back to string      
3E27H  INX H                ; Point to next byte in input     
3E28H  ANA A                ; Test for NULL - end of string    
3E29H  JNZ 3E23H            ; Keep looping until end of string        
3E2CH  POP PSW              ; Restore flags from input routine      
3E2DH  POP H                ; Restore pointer to input string    
3E2EH  RET

; =========================================================================================
; Get maximum BC length input character string from keyboard
; =========================================================================================
3E2FH  PUSH B               ; Save maximum input length to stack     
3E30H  CALL 48F4H           ; Print string at HL to col 1 on the bottom line
3E33H  CALL 4C46H           ; Input and display (no "?") line and store
3E36H  JC 48B5H             ; Branch to "Long jump" if CTRL-C       
3E39H  INX H                ; Point to start of input string    
3E3AH  MOV A,B              ; Get string length (counting NULL)      
3E3BH  DCR A                ; Remove NULL from count    
3E3CH  POP D                ; Restore maximum input length    
3E3DH  RZ                   ; Return if string length is zero 
3E3EH  CMP E                ; Compare expected length with actual length    
3E3FH  RC                   ; Return if string is shorter than expected          
3E40H  PUSH H               ; Save pointer to start of string on stack     
3E41H  DAD D                ; Add Expected length to pointer    
3E42H  MVI M,00H            ; Truncate the string to the max length        
3E44H  POP H                ; Restore pointer to input string    
3E45H  MOV A,E              ; Update length to reflect maximum      
3E46H  ORA A                ; Clear zero flag to indicate input provided    
3E47H  RET

; =========================================================================================
; Find Empty catalog entry (only 9 instructions...Don't bother with Main ROM)
; =========================================================================================
3E48H  LXI H,F9AFH         ; Point to the "RickY" catalog entry (start of valid entries)
3E4BH  LXI B,000BH         ; Load length of each catalog entry
3E4EH  DAD B               ; Point to next catalog entry to test if empty
3E4FH  MOV A,M             ; Get file attribute byte from catalog entry
3E50H  CPI FFH             ; Test if at end of catalog
3E52H  JZ 3E5AH            ; Jump to report directory full if at end
3E55H  ADD A               ; Test if MSB is set (entry being used)
3E56H  JC 3E4EH            ; Jump to test next enry if MSB set
3E59H  RET                 ; Entry found...return with Carry clear

; =========================================================================================
; Empty catalog entry not found...set Carry and exit
; =========================================================================================
3E5AH  STC                 ; Indicate empty entry not found
3E5BH  RET

; =========================================================================================
; F5 Function key handler for RAM mode - DOS ON/OF
; =========================================================================================
3E5CH  LHLD FB2CH          ; Get LFILES statement hook address
3E5FH  LXI B,08DBH         ; Load address of default (DOS-OFF) hook for LFILES
3E62H  DSUB                ; Test if in DOS-OFF mode
3E63H  JZ 401FH            ; Jump to add our custom RST 7 hooks if in DOS-OFF mode
3E66H  JMP 3FFAH           ; Must be in DOS-ON mode, jump to turn it off

; =========================================================================================
; Strings
; =========================================================================================
3E69H  DB	0x1B, "p TS-DOS (100 v4.00) (c)87,TSI.          ",0x1B,'q',0x00
3E97H  DB   "DISK Free:         File:",0DH,0AH,"Load Kill Name Ram  Frmt Log       Menu",00H
3ED9H  DB   " RAM Free:         File:",0DH,0AH,"Save Kill Name Disk DOS-           Menu",00H
3F1BH  DB   "Insert Disk, Press \"Y\" to begin ",00H
3F3CH  DB   "NOT FORMATTED",00H
3F4AH  DB   "New Name:",00H
3F54H  DB   "System name:",00H
3F61H  DB   "Directory name:",00H
3F71H  DB   "Save as:",00H
3F7AH  DB   "Load as:",00H
3F83H  DB   "Sure ? ",00H
3F8BH  DB   "File exists, A)ppend R)eplace Q)uit:",00H
3FB0H  DB   "File exists, Replace? (Y/N):",00H
3FCDH  DB   "-.-       ",00H
3FD8H  DB   0x1B,"Y74    ",1BH,"Y7>MkDr",00H     ;  TODO: Check this
3FE9H  DB   0x1B,"Y7>Bank",00H                   ;  TODO: Check this
3FF2H  DB   "OFF",00H
3FF6H  DB   "ON ",00H

Navigate to: