M100 TS-DOS ROM UI Code
From Bitchin100 DocGarden
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: