<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://bitchin100.com/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Kpettit</id>
	<title>Bitchin100 DocGarden - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://bitchin100.com/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Kpettit"/>
	<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=Special:Contributions/Kpettit"/>
	<updated>2026-04-14T12:03:54Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.3</generator>
	<entry>
		<id>https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_UI_Code&amp;diff=1388</id>
		<title>M100 TS-DOS ROM UI Code</title>
		<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_UI_Code&amp;diff=1388"/>
		<updated>2009-04-03T08:52:27Z</updated>

		<summary type="html">&lt;p&gt;Kpettit: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== TS-DOS Model 100/102 User Interface Code ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; TS-DOS UI Entry location&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
 &lt;br /&gt;
    .org  3535H&lt;br /&gt;
&lt;br /&gt;
3535H  LXI H,FCC0H          ; Start of Alt LCD character buffer&lt;br /&gt;
3538H  MVI B,B4H            ; Prepare to clear 180 bytes from the ALTLCD buffer &lt;br /&gt;
353AH  XRA A                ; Prepare to clear the ALTLCD buffer&lt;br /&gt;
353BH  CALL 4A34H           ; Fill (HL) with B bytes of A        &lt;br /&gt;
353EH  LXI H,0000H          ; Prepare to get current stack pointer&lt;br /&gt;
3541H  DAD SP               ; Copy SP into HL&lt;br /&gt;
3542H  SHLD FCCEH           ; Stack pointer upon entry - pointer to arguments&lt;br /&gt;
3545H  MVI A,01H            ; Set flag to print error message to LCD - GUI mode&lt;br /&gt;
3547H  CALL 4A85H           ; Save the currently selected baud rate settings&lt;br /&gt;
354AH  XRA A                ; Zero A to clear our vars&lt;br /&gt;
354BH  STA FCD4H            ; Current Page of files being displayed&lt;br /&gt;
354EH  STA FCDAH            ; TPDD &amp;quot;skip page&amp;quot; count&lt;br /&gt;
3551H  STA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
3554H  STA FCCAH            ; TPDD2 Bank number&lt;br /&gt;
3557H  INR A                ; A = 1 to select 1st file on page&lt;br /&gt;
3558H  STA FCCDH            ; Currently selected file index&lt;br /&gt;
355BH  LXI H,3564H          ; Get pointer to main loop routine&lt;br /&gt;
355EH  SHLD FCD0H           ; Return vector after error&lt;br /&gt;
3561H  CALL 4C27H           ; CLS statement&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; UI Main loop&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3564H  CALL 4C5AH           ; Resume automatic scrolling&lt;br /&gt;
3567H  CALL 3611H           ; Print Copyright and files&lt;br /&gt;
356AH  LDA FCD5H            ; Load currently selected index from temp storage&lt;br /&gt;
356DH  STA FCCDH            ; Currently selected file index&lt;br /&gt;
3570H  CALL 362FH           ; Print length of selected file using inverse video&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Code will return here when a funtion key is pressed (except F4 &amp;amp; F6)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3573H  LXI H,48B5H          ; Get address of &amp;quot;Long jump&amp;quot;&lt;br /&gt;
3576H  PUSH H               ; Push &amp;quot;Long jump&amp;quot; address to stack&lt;br /&gt;
3577H  PUSH PSW             ; Save function key press to stack&lt;br /&gt;
3578H  CPI 02H              ; Test if function key is F5-F8 (Non file operation F Keys)&lt;br /&gt;
357AH  JNC 35B9H            ; Jump to Function key handler if F5-F8 (No tagging to process)&lt;br /&gt;
357DH  LDA FCCCH            ; Last Tag/Untag operation code&lt;br /&gt;
3580H  ANA A                ; Test if a tag operation was performed&lt;br /&gt;
3581H  JZ 35B9H             ; Jump to Function key handler if no tag operation performed&lt;br /&gt;
3584H  LDA FCD6H            ; Count of files on screen&lt;br /&gt;
3587H  MOV C,A              ; Save count of files for loop decrementing &lt;br /&gt;
3588H  INR C                ; Increment by 1 for loop bounding&lt;br /&gt;
3589H  MVI B,00H            ; Start with index zero on the LCD&lt;br /&gt;
358BH  PUSH B               ; Save the current index on the stack&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display next file&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
358CH  LDA FCCDH            ; Currently selected file index&lt;br /&gt;
358FH  STA FCD5H            ; Currently selected file index - temp&lt;br /&gt;
3592H  CALL 3AC4H           ; Print selected file using normal video&lt;br /&gt;
3595H  POP B                ; Restore index from stack&lt;br /&gt;
3596H  INR B                ; Increment to the next file index to display&lt;br /&gt;
3597H  DCR C                ; Decrement the loop control&lt;br /&gt;
3598H  JZ 48B5H             ; Branch to perform &amp;quot;Long Jump&amp;quot; if all files printed to LCD&lt;br /&gt;
359BH  MOV A,B              ; Get the index of the current file&lt;br /&gt;
359CH  STA FCD5H            ; Save in temporary &amp;quot;current file&amp;quot; area&lt;br /&gt;
359FH  STA FCCDH            ; Currently selected file index&lt;br /&gt;
35A2H  PUSH B               ; Push the value on the stack for the next iteration&lt;br /&gt;
35A3H  CALL 3AB2H           ; Print currently selected file using inverse video&lt;br /&gt;
35A6H  LHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
35A9H  DCX H                ; Decrement to the Tag area for the file&lt;br /&gt;
35AAH  MOV A,M              ; Get the file&#039;s Tag code&lt;br /&gt;
35ABH  CPI 3EH              ; Compare with &#039;&amp;gt;&#039;&lt;br /&gt;
35ADH  JNZ 358CH            ; Jump to process next file if not tagged&lt;br /&gt;
35B0H  POP B                ; Pop currently selected file value from stack&lt;br /&gt;
35B1H  POP PSW    &lt;br /&gt;
35B2H  LXI H,358CH          ; Return address to display the next file&lt;br /&gt;
35B5H  PUSH PSW             ; ? Stack trickery&lt;br /&gt;
35B6H  PUSH B               ; Save current file index to stack for use after a RET operation&lt;br /&gt;
35B7H  PUSH H               ; Setup &amp;quot;Display next file&amp;quot; as a return address for RET&lt;br /&gt;
35B8H  PUSH PSW             ; ? More stack trickery&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Function key handler - Disk mode and dispatch to RAM mode&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
35B9H  CALL 4C56H           ; Stop automatic scrolling&lt;br /&gt;
35BCH  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
35BFH  ORA A     &lt;br /&gt;
35C0H  JZ 35E2H             ; Branch if in RAM mode&lt;br /&gt;
35C3H  POP PSW   &lt;br /&gt;
35C4H  ANA A                ; Test for F1&lt;br /&gt;
35C5H  JZ 3B2EH             ; Branch to F1 handler for disk&lt;br /&gt;
35C8H  DCR A                ; Test for F2&lt;br /&gt;
35C9H  JZ 3D73H  &lt;br /&gt;
35CCH  DCR A                ; Test for F3&lt;br /&gt;
35CDH  JZ 3D9FH  &lt;br /&gt;
35D0H  DCR A                ; Skip F4 - handled at lower level&lt;br /&gt;
35D1H  DCR A                ; Test for F5&lt;br /&gt;
35D2H  JZ 3D53H  &lt;br /&gt;
35D5H  DCR A                ; Skip F6 - handled at lower level&lt;br /&gt;
35D6H  DCR A                ; Test for F7&lt;br /&gt;
35D7H  JZ 3D00H  &lt;br /&gt;
35DAH  DCR A                ; Test for F8&lt;br /&gt;
35DBH  POP H     &lt;br /&gt;
35DCH  JZ 35FEH             ; Jump to exit if F8&lt;br /&gt;
35DFH  JMP 3564H            ; Jump to main loop&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Function key handler - RAM mode&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
35E2H  POP PSW  &lt;br /&gt;
35E3H  ANA A                ; Test for F1 &lt;br /&gt;
35E4H  JZ 3C4BH &lt;br /&gt;
35E7H  DCR A                ; Test for F2&lt;br /&gt;
35E8H  JZ 3C2BH &lt;br /&gt;
35EBH  DCR A                ; Test for F3&lt;br /&gt;
35ECH  JZ 3AF8H &lt;br /&gt;
35EFH  DCR A                ; Skip F4 - handled at lower level&lt;br /&gt;
35F0H  DCR A                ; Test for F5&lt;br /&gt;
35F1H  JZ 3E5CH &lt;br /&gt;
35F4H  DCR A                ; Skip F6 - handled at lower level&lt;br /&gt;
35F5H  DCR A                ; Skip F7 - not defined for RAM&lt;br /&gt;
35F6H  DCR A                ; Test for F8&lt;br /&gt;
35F7H  POP H    &lt;br /&gt;
35F8H  JZ 35FEH             ; Jump to exit if F8&lt;br /&gt;
35FBH  JMP 3564H            ; Jump back to main loop&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; This is the UI exit routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
35FEH  CALL 4AC4H           ; Restore original baud settings&lt;br /&gt;
3601H  CALL 4BD7H           ; Wait for TX empty and Reset UART to accept mode bits&lt;br /&gt;
3604H  CALL 4C27H           ; CLS statement&lt;br /&gt;
3607H  CALL 4C5AH           ; Resume automatic scrolling&lt;br /&gt;
360AH  LXI H,0000H&lt;br /&gt;
360DH  PUSH H&lt;br /&gt;
360EH  JMP 00A6H            ; Exit TS-DOS&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print Copyright string and files&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3611H  LXI H,0101H          ; Goto top left corner&lt;br /&gt;
3614H  SHLD F639H           ; Cursor row (1-8)&lt;br /&gt;
3617H  LXI H,3E69H          ; Point to &amp;quot;TS-DOS&amp;quot; copyright string&lt;br /&gt;
361AH  CALL 4A2CH           ; Send buffer at M to screen&lt;br /&gt;
361DH  XRA A                ; Indicate no previous Tag/Untag operation&lt;br /&gt;
361EH  STA FCCCH            ; Last Tag/Untag operation code&lt;br /&gt;
3621H  MVI A,01H            ; Start with 1st file in list&lt;br /&gt;
3623H  STA FCD5H            ; Currently selected file index - temp&lt;br /&gt;
3626H  LXI H,0202H          ; Goto first file entry location&lt;br /&gt;
3629H  SHLD F639H           ; Cursor row (1-8)&lt;br /&gt;
362CH  JMP 383BH            ; Draw the display&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print length of selected file using inverse video&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
362FH  LDA FCCDH            ; Currently selected file index      &lt;br /&gt;
3632H  STA FCD5H            ; Currently selected file index - temp      &lt;br /&gt;
3635H  CALL 3AB2H           ; Print currently seleted file using inverse video       &lt;br /&gt;
3638H  LDA FCD5H            ; Currently selected file index - temp      &lt;br /&gt;
363BH  DCR A                ; Make index zero based for multiply x2  &lt;br /&gt;
363CH  STC                  ; Set Carry flag&lt;br /&gt;
363DH  CMC                  ; Compliment (clear) carry flag&lt;br /&gt;
363EH  RLC                  ; Rotate left circular &lt;br /&gt;
363FH  MOV E,A              ; E = File index * 2 to point to file length value    &lt;br /&gt;
3640H  MVI D,00H            ; Clear MSB of file length offset      &lt;br /&gt;
3642H  LXI H,F685H          ; Keyboard buffer - store file lengths        &lt;br /&gt;
3645H  DAD D                ; Add file lenght offset from beginning of keyboard buffer  &lt;br /&gt;
3646H  XCHG                 ; HL &amp;lt;--&amp;gt; DE Save file length address pointer in DE &lt;br /&gt;
3647H  LXI H,2307H          ; Load position of File Size area on LCD&lt;br /&gt;
364AH  SHLD F639H           ; Cursor row (1-8) &lt;br /&gt;
364DH  CALL 4C2BH           ; Erase from cursor to end of line&lt;br /&gt;
3650H  LHLX                 ; Load HL with file length &lt;br /&gt;
3651H  CALL 4C2FH           ; Start inverse character mode       &lt;br /&gt;
3654H  CALL 4C3EH           ; Print binary number in HL at current position       &lt;br /&gt;
3657H  CALL 4C33H           ; Cancel inverse character mode         &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Keyboard scan loop&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
365AH  CALL 3DFEH           ; Process automatic power off logic&lt;br /&gt;
365DH  CALL 4BEFH           ; Scan keyboard for character (CTRL-BREAK ==&amp;gt; CTRL-C)&lt;br /&gt;
3660H  JZ 365AH             ; Jump to scan keyboard again if no key pressed &lt;br /&gt;
3663H  JC 380CH             ; Jump to Function Key Handler if FKey &lt;br /&gt;
3666H  CPI 0DH              ; Test for CR&lt;br /&gt;
3668H  JZ 3722H   &lt;br /&gt;
366BH  CPI 17H              ; Test for Ctrl-Up key&lt;br /&gt;
366DH  JZ 37AAH   &lt;br /&gt;
3670H  CPI 14H              ; Test for Shift-Up key&lt;br /&gt;
3672H  JZ 3798H   &lt;br /&gt;
3675H  CPI 5DH              ; Test for &amp;quot;]&amp;quot; key&lt;br /&gt;
3677H  JZ 3798H   &lt;br /&gt;
367AH  CPI 3FH              ; Test for &amp;quot;?&amp;quot; key&lt;br /&gt;
367CH  JZ 3777H   &lt;br /&gt;
367FH  CPI 02H              ; Test for Shift-Down arrow key&lt;br /&gt;
3681H  JZ 3777H   &lt;br /&gt;
3684H  CPI 1EH              ; Test for up key&lt;br /&gt;
3686H  JZ 36EEH   &lt;br /&gt;
3689H  CPI 1FH              ; Test for down key&lt;br /&gt;
368BH  JZ 36FCH   &lt;br /&gt;
368EH  CPI 1DH              ; Test for &amp;quot;left arrow&amp;quot; key&lt;br /&gt;
3690H  JZ 36DDH   &lt;br /&gt;
3693H  CPI 1CH              ; Test for &amp;quot;Right arrow&amp;quot; key&lt;br /&gt;
3695H  JZ 36CAH   &lt;br /&gt;
3698H  CPI 20H              ; Test for space key &lt;br /&gt;
369AH  JZ 36CAH             ; Treat space the same as right arrow  &lt;br /&gt;
369DH  ANI DFH              ; Convert to Upper case &lt;br /&gt;
369FH  CPI 52H              ; Test for &#039;R&#039; character  &lt;br /&gt;
36A1H  JZ 3759H   &lt;br /&gt;
36A4H  CPI 54H              ; Test for &#039;T&#039; character &lt;br /&gt;
36A6H  JZ 37EEH   &lt;br /&gt;
36A9H  CPI 41H              ; Test for &amp;quot;A&amp;quot; key &lt;br /&gt;
36ABH  JZ 3715H   &lt;br /&gt;
36AEH  CPI 47H              ; Test for &amp;quot;G&amp;quot; key &lt;br /&gt;
36B0H  JZ 3715H   &lt;br /&gt;
36B3H  CPI 55H              ; Test for &amp;quot;U&amp;quot; key &lt;br /&gt;
36B5H  JZ 37AEH   &lt;br /&gt;
36B8H  CPI 44H              ; Test for &amp;quot;D&amp;quot; key &lt;br /&gt;
36BAH  JZ 39B9H   &lt;br /&gt;
36BDH  CPI 4CH              ; Test for &amp;quot;L&amp;quot; key &lt;br /&gt;
36BFH  JZ 39C2H   &lt;br /&gt;
36C2H  CPI 50H              ; Test for &amp;quot;P&amp;quot; key &lt;br /&gt;
36C4H  JZ 39C2H   &lt;br /&gt;
36C7H  JMP 365AH            ; Go scan keyboard again   &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Right Arrow key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
36CAH  MVI A,01H            ; Prepare to add 1 to selected file    &lt;br /&gt;
36CCH  LXI H,FCD5H          ; Currently selected file index - temp storage&lt;br /&gt;
36CFH  ADD M                ; Add 1 to the selected file index&lt;br /&gt;
36D0H  INX H                ; Point to file count on screen&lt;br /&gt;
36D1H  CMP M                ; Compare new index with screen file count&lt;br /&gt;
36D2H  JC 370AH             ; Jump to process new file if we didn&#039;t wrap   &lt;br /&gt;
36D5H  JZ 370AH             ; Jump to process new file if = file count   &lt;br /&gt;
36D8H  MVI A,01H            ; Wrap to the first file    &lt;br /&gt;
36DAH  JMP 370AH            ; Go process file 1 as the new selection    &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Left Arrow key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
36DDH  LDA FCD5H            ; Currently selected file index - temp storage&lt;br /&gt;
36E0H  DCR A                ; Move to next lowest file index&lt;br /&gt;
36E1H  JNZ 370AH            ; If no wrap, jump to process new selection&lt;br /&gt;
36E4H  LDA FCD6H            ; Count of files on screen&lt;br /&gt;
36E7H  ANA A                ; Ensure there is at least 1 file on the screen &lt;br /&gt;
36E8H  JZ 365AH             ; Jump to keyboard scan loop if no files on LCD&lt;br /&gt;
36EBH  JMP 370AH            ; Go process new selection as the max (wrap-around)&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Up Arrow key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
36EEH  LDA FCD5H            ; Currently selected file index - temp storage&lt;br /&gt;
36F1H  SUI 04H              ; Subtract 4 from file count (4 files per line)&lt;br /&gt;
36F3H  JC 365AH             ; Jump to keysacn loop if negative&lt;br /&gt;
36F6H  JZ 365AH             ; Jump to keysacn loop if zero&lt;br /&gt;
36F9H  JMP 370AH            ; Go process the new file index setting&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Down Arrow key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
36FCH  MVI A,04H            ; There are 4 files per line &lt;br /&gt;
36FEH  LXI H,FCD5H          ; Currently selected file index - temp storage&lt;br /&gt;
3701H  ADD M                ; Add 4 to the index number&lt;br /&gt;
3702H  MOV C,A              ; Save new index for comparison and further processing  &lt;br /&gt;
3703H  INX H                ; Maximum file index count&lt;br /&gt;
3704H  MOV A,M              ; Load maximum index for bounds  &lt;br /&gt;
3705H  CMP C                ; Compare new index with maximum&lt;br /&gt;
3706H  JC 365AH             ; Jump to keyboard scan if moving past last file   &lt;br /&gt;
3709H  MOV A,C              ; Restore new current file index  &lt;br /&gt;
370AH  PUSH PSW             ; Save new file index for storage after the call   &lt;br /&gt;
370BH  CALL 3AC4H           ; Print selected file using normal video     &lt;br /&gt;
370EH  POP PSW              ; Restore new file index from stack  &lt;br /&gt;
370FH  STA FCCDH            ; Save the new file index    &lt;br /&gt;
3712H  JMP 362FH            ; Print length of selected file using inverse video.    &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;A&amp;quot; or &amp;quot;G&amp;quot; key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3715H  MVI A,3EH            ; Load &amp;quot;&amp;gt;&amp;quot; for the tag symbol&lt;br /&gt;
3717H  CALL 37CAH           ; Go tag all files on the LCD&lt;br /&gt;
371AH  MVI A,01H            ; Indicate last operation as &amp;quot;Tag All&amp;quot;&lt;br /&gt;
371CH  STA FCCCH            ; Last Tag/Untag operation code&lt;br /&gt;
371FH  JMP 362FH            ; Print length of selected file using inverse video.&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Enter key from TS-DOS key scan - Change Directory&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3722H  LDA FCCBH            ; Get NADSBox/Desklink/TPDD2 flag     &lt;br /&gt;
3725H  CPI 02H              ; Test if NADSBox current directory valid   &lt;br /&gt;
3727H  JNZ 365AH            ; Back to keyscan if no &amp;quot;current directory&amp;quot; - Enter is meaningless     &lt;br /&gt;
372AH  LHLD FCE4H           ; LCD Buffer address of current file selection      &lt;br /&gt;
372DH  LXI B,0007H          ; Load offset of file extension       &lt;br /&gt;
3730H  DAD B                ; Point to file extension of selected file &lt;br /&gt;
3731H  MOV A,M              ; Load the 1st byte of the file extension   &lt;br /&gt;
3732H  CPI 3CH              ; Test if 1st byte of extension is &amp;quot;&amp;lt;&amp;quot;   &lt;br /&gt;
3734H  JNZ 365AH            ; Jump to keyscan if current selection not directory entry     &lt;br /&gt;
3737H  CALL 4A3BH           ; Initialize blank filename and attribute byte      &lt;br /&gt;
373AH  LHLD FCE4H           ; LCD Buffer address of current file selection      &lt;br /&gt;
373DH  CALL 3D95H           ; Copy filename at (HL) to TX buffer      &lt;br /&gt;
3740H  CALL 408AH           ; Open TPDD file for Read Mode      &lt;br /&gt;
3743H  LXI H,0002H          ; Load opcode to close currently opened file       &lt;br /&gt;
3746H  CALL 409BH           ; Send Request in HL and await response      &lt;br /&gt;
3749H  LHLD FCE4H           ; LCD Buffer address of current file selection      &lt;br /&gt;
374CH  LXI D,FCC0H          ; NADSBox current directory storage    &lt;br /&gt;
374FH  LXI B,0009H          ; Copy 9 bytes of NADSBox directory to the LCD       &lt;br /&gt;
3752H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
3755H  XRA A                ; Clear A to show 1st page of files &lt;br /&gt;
3756H  JMP 378AH            ; Branch to show the page of files in A     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;R&amp;quot; key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3759H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
375CH  ANA A                ; Test if in Disk mode&lt;br /&gt;
375DH  JNZ 362FH            ; Jump to keyscan if in Disk mode&lt;br /&gt;
3760H  LHLD FCE4H           ; LCD Buffer address of current file selection       &lt;br /&gt;
3763H  CALL 4902H           ; Copy filename at (HL) to current BASIC program&lt;br /&gt;
3766H  CALL 4A51H           ; Get RAM directory address of current BASIC program          &lt;br /&gt;
3769H  CPI C0H              ; Test if filetype is .DO&lt;br /&gt;
376BH  CZ 5000H             ; Call routine to Compress / Decompress .DO files&lt;br /&gt;
376EH  CALL 4C0FH           ; Update system pointers       &lt;br /&gt;
3771H  CALL 3611H           ; Print Copyright and files&lt;br /&gt;
3774H  JMP 362FH            ; Jump to keyscan &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;?&amp;quot; and Shift-Down key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3777H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
377AH  ANA A                ; Test if RAM mode &lt;br /&gt;
377BH  JZ 365AH             ; Branch to keyscan if in RAM mode    &lt;br /&gt;
377EH  LDA FCD6H            ; Count of files on screen     &lt;br /&gt;
3781H  CPI 14H              ; Maximum number of files that fit on the screen   &lt;br /&gt;
3783H  JC 365AH             ; Branch to keyscan if on last page    &lt;br /&gt;
3786H  LDA FCD4H            ; Current Page of files being displayed     &lt;br /&gt;
3789H  INR A                ; Increment to next page of files &lt;br /&gt;
				 &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Show the page of files indicated by A&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
378AH  STA FCD4H            ; Current Page of files being displayed     &lt;br /&gt;
378DH  MVI A,01H            ; Go to 1st file on the new page     &lt;br /&gt;
378FH  STA FCCDH            ; Currently selected file index     &lt;br /&gt;
3792H  CALL 3611H           ; Print copyright and files      &lt;br /&gt;
3795H  JMP 362FH            ; Print length of selected file using inverse video     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;]&amp;quot; and Shift-Up key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3798H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
379BH  ANA A                ; Test if RAM mode &lt;br /&gt;
379CH  JZ 365AH             ; Branch to keyscan if in RAM mode    &lt;br /&gt;
379FH  LDA FCD4H            ; Current Page of files being displayed     &lt;br /&gt;
37A2H  ANA A                ; Test if current page is zero &lt;br /&gt;
37A3H  JZ 365AH             ; Branch to keyscan if already on page 0    &lt;br /&gt;
37A6H  DCR A                ; Decrement the page number &lt;br /&gt;
37A7H  JMP 378AH            ; Show the page of files indicated by A&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Ctrl-Up key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
37AAH  XRA A                ; Go to page zero&lt;br /&gt;
37ABH  JMP 378AH            ; Show the page of files indicated by A&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;U&amp;quot; key from TS-DOS key scan - Remove all tags&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
37AEH  MVI A,20H            ; Display &#039; &#039; as the tag marker&lt;br /&gt;
37B0H  CALL 37CAH           ; Go process tag for all files&lt;br /&gt;
37B3H  XRA A                ; Indicate last tag operation was untag&lt;br /&gt;
37B4H  STA FCCCH            ; Store as &amp;quot;last tag&amp;quot; operation&lt;br /&gt;
37B7H  JMP 362FH            ; Print length of selected file using inverse video&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Swap TPDD2 Bank number&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
37BAH  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag&lt;br /&gt;
37BDH  DCR A                ; Test if the flag = 1 (TPDD2)&lt;br /&gt;
37BEH  JNZ 365AH            ; Jump to keyscan if not 1&lt;br /&gt;
37C1H  LDA FCCAH            ; Get TPDD Bank Number&lt;br /&gt;
37C4H  XRI 01H              ; Switch to the other bank&lt;br /&gt;
37C6H  STA FCCAH            ; Save TPDD bank number&lt;br /&gt;
37C9H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process Tag or Untag for all files on screen&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
37CAH  STA FCCCH            ; Store tag/untag code for later      &lt;br /&gt;
37CDH  LDA FCD6H            ; Get Maximum file count on screen      &lt;br /&gt;
37D0H  ANA A                ; Test for zero  &lt;br /&gt;
37D1H  RZ                   ; Return if no files on screen&lt;br /&gt;
37D2H  XRA A                ; Clear A  &lt;br /&gt;
37D3H  INR A                ; A=1 to selet 1st file  &lt;br /&gt;
37D4H  STA FCD5H            ; Currently selected file index      &lt;br /&gt;
37D7H  CALL 3ACDH           ; Calculate Row and Column of soon-to-be (newly) selected file       &lt;br /&gt;
37DAH  LHLD FCE4H           ; LCD Buffer address of current file selection       &lt;br /&gt;
37DDH  DCX H                ; Point to Tag location for the file  &lt;br /&gt;
37DEH  LDA FCCCH            ; Get the tag/untag code      &lt;br /&gt;
37E1H  RST 4                ; Display A to the LCD    &lt;br /&gt;
37E2H  LDA FCD5H            ; Get currently selected file index      &lt;br /&gt;
37E5H  LXI H,FCD6H          ; Point to count of files on screen        &lt;br /&gt;
37E8H  CMP M                ; Compare current selection with count of files on LCD  &lt;br /&gt;
37E9H  JC 37D3H             ; Jump to process next file if more files left     &lt;br /&gt;
37ECH  ANA A                ; Set zero flag to indicate files were tagged/untagged  &lt;br /&gt;
37EDH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;T&amp;quot; key key from TS-DOS key scan - TAG&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
37EEH  CALL 3ACDH           ; Calculate Row and Column of soon-to-be (newly) selected file    &lt;br /&gt;
37F1H  CALL 4C2FH           ; Start inverse character mode    &lt;br /&gt;
37F4H  LHLD FCE4H           ; LCD Buffer address of current file selection    &lt;br /&gt;
37F7H  DCX H                ; Point to the &amp;quot;Tag&amp;quot; area for the file&lt;br /&gt;
37F8H  MVI A,3EH            ; Load the code for &amp;quot;&amp;gt;&amp;quot;   &lt;br /&gt;
37FAH  CMP M                ; Compare if file is already tagged     &lt;br /&gt;
37FBH  JNZ 3800H            ; Skip ahead if already tagged   &lt;br /&gt;
37FEH  MVI A,20H            ; Need to untag - load the untag code   &lt;br /&gt;
3800H  RST 4                ; Display the tag code on the LCD   &lt;br /&gt;
3801H  CALL 4C33H           ; Cancel inverse character mode    &lt;br /&gt;
3804H  LXI H,FCCCH          ; Point to &amp;quot;last tag&amp;quot; operation code     &lt;br /&gt;
3807H  MVI M,01H            ; Indicate last operation was &amp;quot;tag&amp;quot;   &lt;br /&gt;
3809H  JMP 36CAH            ; Move to next file - jump to Right Arrow key handler   &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; 1st level Function Key Handler (handles F4 and F6)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
380CH  CPI 08H              ; Test for valid function key code     &lt;br /&gt;
380EH  JNC 365AH            ; Branch back to scan loop if invalid       &lt;br /&gt;
3811H  CPI 05H              ; Test for F6     &lt;br /&gt;
3813H  JZ 3833H             ; Jump if F6 pressed      &lt;br /&gt;
3816H  CPI 03H              ; Test for F4     &lt;br /&gt;
3818H  RNZ                  ; Return to &amp;quot;Main Loop&amp;quot; if not F4 pressed &lt;br /&gt;
3819H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)       &lt;br /&gt;
381CH  XRI 01H              ; Swap RAM/DISK mode     &lt;br /&gt;
381EH  STA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)       &lt;br /&gt;
3821H  XRA A                ; Clear A to go to 1st page of files   &lt;br /&gt;
3822H  STA FCD4H            ; Current Page of files being displayed       &lt;br /&gt;
3825H  MVI A,01H            ; Select the 1st file in the page       &lt;br /&gt;
3827H  STA FCCDH            ; Currently selected file index       &lt;br /&gt;
382AH  CALL 4C27H           ; CLS statement     &lt;br /&gt;
382DH  CALL 3611H           ; Print the title bar and files        &lt;br /&gt;
3830H  JMP 362FH            ; Print length of selected file using inverse video.       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F6 Function Key Handler&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3833H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
3836H  ANA A                ; Test if in RAM or DISK mode&lt;br /&gt;
3837H  RZ                   ; Return if RAM mode&lt;br /&gt;
3838H  JMP 37AAH            ; Jump to Ctrl-Up key handler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Draw the display.  This takes care of RAM and Disk mode displays, handles&lt;br /&gt;
;    skipping page number to the proper &amp;quot;Disk&amp;quot; page, displaying the Bank# or&lt;br /&gt;
;    current directory for NADSBox/Desklink, showing free space, filling in&lt;br /&gt;
;    empty slots with &amp;quot;-.-&amp;quot;, etc.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
383BH  LXI H,F685H          ; Keyboard buffer  &lt;br /&gt;
383EH  SHLD FCDBH           ; Initialize pointer to file length table (in keyboard buffer)     &lt;br /&gt;
3841H  XRA A                ; Prepare to set 1st file lenght to zero&lt;br /&gt;
3842H  MOV M,A              ; Set LSB of length of 1st file to zero  &lt;br /&gt;
3843H  INX H                ; Increment to MSB of length&lt;br /&gt;
3844H  MOV M,A              ; Set MSB of length of file to zero  &lt;br /&gt;
3845H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)    &lt;br /&gt;
3848H  ANA A                ; Test if RAM or DISK&lt;br /&gt;
3849H  JZ 395DH             ; Jump to show RAM files if in RAM mode   &lt;br /&gt;
384CH  XRA A                ; Prepare to initialize the &amp;quot;page being processed&amp;quot; variable&lt;br /&gt;
384DH  STA FCDAH            ; Clear the &amp;quot;page being processed&amp;quot; variable    &lt;br /&gt;
3850H  CALL 4735H           ; Clear #files displayed, init TPDD and send 1st file dir referene opcode     &lt;br /&gt;
3853H  JNZ 390FH            ; Process unformated disk (empty slots and error message)    &lt;br /&gt;
3856H  LDA FCD4H            ; Current Page of files being displayed    &lt;br /&gt;
3859H  ANA A                ; Test if displaying page 0&lt;br /&gt;
385AH  JZ 3871H             ; Jump if showing page 0 - don&#039;t need to skikp any pages   &lt;br /&gt;
385DH  STA FCDAH            ; Initialize the number of pages left to skip count    &lt;br /&gt;
3860H  CALL 4742H           ; Read next page of files from server     &lt;br /&gt;
3863H  LDA FCDAH            ; Get the &amp;quot;Pages left to skip&amp;quot; count    &lt;br /&gt;
3866H  DCR A                ; Decrement the remaining skip page count &lt;br /&gt;
3867H  JNZ 385DH            ; Keep reading pages until we have skipped enough pages     &lt;br /&gt;
386AH  XRA A                ; Prepare to clear the remaining skip page count &lt;br /&gt;
386BH  STA FCDAH            ; Clear the remaining skip page count     &lt;br /&gt;
386EH  STA FCD6H            ; Count of files on screen     &lt;br /&gt;
3871H  CALL 4742H           ; Read next page of files from server      &lt;br /&gt;
3874H  LDA FCD6H            ; Count of files on screen     &lt;br /&gt;
3877H  CPI 14H              ; Test if all file slots are full   &lt;br /&gt;
3879H  CC 39AAH             ; Print &amp;quot;-.-&amp;quot; for all empty file slots (if any)    &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print NADSBox directory or TPDD Bank number to LCD&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
387CH  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag    &lt;br /&gt;
387FH  ANA A                ; Test if server is TPDD&lt;br /&gt;
3880H  JZ 389FH             ; Skip processing Bank # or Current Dir if TPDD   &lt;br /&gt;
3883H  DCR A                ; Test if server is TPDD2&lt;br /&gt;
3884H  JZ 388DH             ; Jump to print bank number if TPDD2   &lt;br /&gt;
3887H  LXI H,FCC0H          ; Load pointer to NADSBox current directory storage    &lt;br /&gt;
388AH  JMP 38A5H            ; Jump to print the NADSBox / Desklink directory    &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print the TPDD Bank number to LCD&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
388DH  LXI H,2401H          ; Go to Row 1, column 24&lt;br /&gt;
3890H  SHLD F639H           ; Cursor row (1-8) &lt;br /&gt;
3893H  CALL 4C2FH           ; Start inverse character mode &lt;br /&gt;
3896H  MVI A,23H            ; ASCII code for &#039;#&#039; &lt;br /&gt;
3898H  RST 4                ; Send character in A to the LCD&lt;br /&gt;
3899H  LDA FCCAH            ; Load TPDD Bank number &lt;br /&gt;
389CH  ADI 30H              ; Convert to ASCII digit   &lt;br /&gt;
389EH  RST 4                ; Send it to the LCD  &lt;br /&gt;
389FH  CALL 4C33H           ; Cancel inverse character mode&lt;br /&gt;
38A2H  JMP 38B8H            ; Branch to print the function menu, RAM/Disk free, etc.&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print the NADSBox / Desklink current directory in title bar&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
38A5H  PUSH H               ; Save address of the directory string     &lt;br /&gt;
38A6H  LXI H,2101H          ; Prepare to position the cursor in the title bar          &lt;br /&gt;
38A9H  SHLD F639H           ; Cursor row (1-8)         &lt;br /&gt;
38ACH  CALL 4C2FH           ; Start inverse character mode         &lt;br /&gt;
38AFH  POP H                ; Retrieve the directory string from the stack    &lt;br /&gt;
38B0H  MVI C,06H            ; Prepare to redraw 6 chars with inverse video        &lt;br /&gt;
38B2H  CALL 48E5H           ; Redraw C characters from buffer at HL using current video mode         &lt;br /&gt;
38B5H  CALL 4C33H           ; Cancel inverse character mode         &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print funtion menu, RAM/Disk free &amp;amp; selected file length&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
38B8H  LXI H,3E97H          ; Point to Disk function menu          &lt;br /&gt;
38BBH  LXI B,3936H          ; Routine to print free disk space          &lt;br /&gt;
38BEH  LDA FCD9H            ; RAM/Disk mode        &lt;br /&gt;
38C1H  ANA A                ; Test if in Disk mode and skip ahead to print Disk FKeys    &lt;br /&gt;
38C2H  JNZ 38CBH            ; Skip ahead if in disk mode to keep vectors        &lt;br /&gt;
38C5H  LXI H,3ED9H          ; Point to RAM function menu          &lt;br /&gt;
38C8H  LXI B,3922H          ; Routine to print free RAM space          &lt;br /&gt;
38CBH  PUSH B               ; Save routine address to stack     &lt;br /&gt;
38CCH  PUSH H               ; Save pointer to function text to stack     &lt;br /&gt;
38CDH  LDA FCCDH            ; Currently selected file index        &lt;br /&gt;
38D0H  LXI H,FCD6H          ; Count of files on screen          &lt;br /&gt;
38D3H  CMP M                ; Compare selected file with count of files on screen    &lt;br /&gt;
38D4H  JC 38DDH             ; Branch if within bounds       &lt;br /&gt;
38D7H  MOV A,M              ; Get the file count      &lt;br /&gt;
38D8H  ANA A                ; Test if #files = 0    &lt;br /&gt;
38D9H  JNZ 38DDH            ; Skip ahead if not zero        &lt;br /&gt;
38DCH  INR A                ; Don&#039;t allow a count of zero - must be 1    &lt;br /&gt;
38DDH  STA FCD5H            ; Currently selected file index - temp       &lt;br /&gt;
38E0H  LXI H,0B07H          ; Row &amp;amp; column of start of text          &lt;br /&gt;
38E3H  SHLD F639H           ; Cursor row (1-8)          &lt;br /&gt;
38E6H  POP H                ; Get address of text from the stack and display it   &lt;br /&gt;
38E7H  CALL 4A2CH           ; Send buffer at M to screen        &lt;br /&gt;
38EAH  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)       &lt;br /&gt;
38EDH  ANA A                ; Test if in RAM mode   &lt;br /&gt;
38EEH  JZ 3905H             ; Jump if in RAM mode (0 = RAM)       &lt;br /&gt;
38F1H  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag   &lt;br /&gt;
38F4H  ANA A                ; Test if server is TPDD      &lt;br /&gt;
38F5H  JZ 3905H             ; Skip printing of &amp;quot;Bank&amp;quot; or &amp;quot;Mkdr&amp;quot; if TPDD       &lt;br /&gt;
38F8H  LXI H,3FE9H          ; Point to text for &amp;quot;Bank&amp;quot;     &lt;br /&gt;
38FBH  DCR A                ; Test if server is TPDD2      &lt;br /&gt;
38FCH  JZ 3902H             ; Jump to print &amp;quot;Bank&amp;quot; if TPDD2         &lt;br /&gt;
38FFH  LXI H,3FD8H          ; Point to text for &amp;quot;Mkdr&amp;quot;        &lt;br /&gt;
3902H  CALL 4A2CH           ; Send buffer at M to screen                  &lt;br /&gt;
3905H  CALL 3940H           ; Display DISK ON/OFF status on LCD         &lt;br /&gt;
3908H  LXI H,1507H          ; Point to location for &amp;quot;Free&amp;quot; space (RAM or DISK)&lt;br /&gt;
390BH  SHLD F639H           ; Cursor row (1-8)          &lt;br /&gt;
390EH  RET                  &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle unformatted disks.  Print message and show empty slots.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
390FH  XRA A                ; Starting with slot zero...&lt;br /&gt;
3910H  CALL 39AAH           ; Print &amp;quot;-.-&amp;quot; for all empty file slots&lt;br /&gt;
3913H  LXI H,3E97H          ; Point to Disk Function menu string&lt;br /&gt;
3916H  LXI B,391CH          ; Print NOT FORMATTED to the display&lt;br /&gt;
3919H  JMP 38CBH            ; Go process the print and jump to error handler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print &amp;quot;NOT FORMATTED&amp;quot; on the LCD and return&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
391CH  LXI H,`H             ; Point to &amp;quot;NOT FORMATTED&amp;quot; string&lt;br /&gt;
391FH  JMP 4A2CH            ; Send buffer at M to screen&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print RAM free space at current posiiton&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3922H  LHLD FBB2H           ; Start of variable data pointer  &lt;br /&gt;
3925H  XCHG                 ; HL &amp;lt;--&amp;gt; DE&lt;br /&gt;
3926H  LHLD F678H           ; BASIC string buffer pointer  &lt;br /&gt;
3929H  MOV A,L              ; Prepare for 16 bit subtract   &lt;br /&gt;
392AH  SUB E                ; Subtract LSB &lt;br /&gt;
392BH  MOV L,A              ; Save LSB of difference for printing   &lt;br /&gt;
392CH  MOV A,H              ; Prepare for subtrating MSB   &lt;br /&gt;
392DH  SBB D                ; Subtract MSB &lt;br /&gt;
392EH  MOV H,A              ; Save in H for printing   &lt;br /&gt;
392FH  LXI B,FFF2H          ; Load signed number -14       &lt;br /&gt;
3932H  DAD B                ; Subtract 14 from free memory &lt;br /&gt;
3933H  JMP 4C3EH            ; Print binary number in HL at current position     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display free space on disk&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3936H  CALL 4A10H           ; Calculate free space on disk&lt;br /&gt;
3939H  CALL 4C3EH           ; Print binary number in HL at current position&lt;br /&gt;
393CH  MVI A,30H            ; Prepare to add an extra &#039;0&#039; since calc is /10&lt;br /&gt;
393EH  RST 4                ; Send A to the LCD      &lt;br /&gt;
393FH  RET       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display DISK ON/OFF status on LCD&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3940H  LDA FCD9H            ; DISK/RAM mode (0=RAM, 1=DISK)       &lt;br /&gt;
3943H  ANA A                ; Test if in RAM mode   &lt;br /&gt;
3944H  RNZ                  ; Return if not in RAM mode  &lt;br /&gt;
3945H  LDA FB2CH            ; DISK-OFF/ON status   &lt;br /&gt;
3948H  LXI D,3FF2H          ; Load pointer to &amp;quot;OFF&amp;quot; text         &lt;br /&gt;
394BH  CPI DBH              ; Test if DISK mode (vector LSB) indicates ON or OFF     &lt;br /&gt;
394DH  JZ 3953H             ; Branch if in DISK-OFF mode      &lt;br /&gt;
3950H  LXI D,3FF6H          ; Load pointer to &amp;quot;ON&amp;quot; text         &lt;br /&gt;
3953H  LXI H,1908H          ; Location of DISK-OFF/ON indication on LCD         &lt;br /&gt;
3956H  SHLD F639H           ; Cursor row (1-8)   &lt;br /&gt;
3959H  XCHG                 ; HL = pointer to text in DE  &lt;br /&gt;
395AH  JMP 4A2CH            ; Send buffer at M to screen       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display RAM files to LCD and calculate file lengths&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
395DH  LXI H,F9BAH          ; Load pointer to 1st available file slot in catalog&lt;br /&gt;
3960H  XRA A                ; Set count of RAM files on screen to zero &lt;br /&gt;
3961H  STA FCD6H            ; Count of files on screen     &lt;br /&gt;
3964H  MVI A,14H            ; Get max # files that will fit on LCD     &lt;br /&gt;
3966H  DCR A                ; Decrement the max file count &lt;br /&gt;
3967H  PUSH PSW             ; Save count to the stack    &lt;br /&gt;
3968H  MOV A,M              ; Get file type   &lt;br /&gt;
3969H  XRI 80H              ; Compliment ?active bit   &lt;br /&gt;
396BH  ANI 9FH              ; Test if file is active and should be displayed   &lt;br /&gt;
396DH  JNZ 3996H            ; Branch to test next file if not displayed     &lt;br /&gt;
3970H  PUSH H               ; Save address of current catalog file  &lt;br /&gt;
3971H  INX H                ; Point to file address &lt;br /&gt;
3972H  MOV E,M              ; Get LSB of file address   &lt;br /&gt;
3973H  INX H                ; Point to MSB of address &lt;br /&gt;
3974H  MOV D,M              ; Get MSB of file address   &lt;br /&gt;
3975H  XTHL                 ; HL &amp;lt;--&amp;gt; (SP)  Get address of file within catalog&lt;br /&gt;
3976H  PUSH H               ; Push pointer to MSB of address on stack  &lt;br /&gt;
3977H  CALL 3CD3H           ; Calculate length of RAM file      &lt;br /&gt;
397AH  XCHG                 ; HL &amp;lt;--&amp;gt; DE DE has the length&lt;br /&gt;
397BH  CALL 4791H           ; Store next file length to keyboard buffer      &lt;br /&gt;
397EH  POP H                ; Get catalog address of current file from stack &lt;br /&gt;
397FH  XTHL                 ; HL &amp;lt;--&amp;gt; (SP) swap catalog address with pointer to MSB of file address&lt;br /&gt;
3980H  INX H                ; Increment to filename &lt;br /&gt;
3981H  MVI C,06H            ; Prepare to print 6 characters of filename     &lt;br /&gt;
3983H  CALL 48E5H           ; Redraw C characters from buffer at HL using current video mode       &lt;br /&gt;
3986H  MVI A,2EH            ; Load code for &#039;.&#039;      &lt;br /&gt;
3988H  RST 4                ; Send A to the LCD                &lt;br /&gt;
3989H  MVI C,02H            ; Prepare to print 2 ext bytes to LCD      &lt;br /&gt;
398BH  CALL 48E5H           ; Redraw C characters from buffer at HL using current video mode       &lt;br /&gt;
398EH  MVI A,20H            ; Load code for space      &lt;br /&gt;
3990H  RST 4                ; Send A to the LCD           &lt;br /&gt;
3991H  LXI H,FCD6H          ; Count of files on screen        &lt;br /&gt;
3994H  INR M                ; Increment number of files displayed on LCD  &lt;br /&gt;
3995H  POP H                ; Get catalog address of file from stack  &lt;br /&gt;
3996H  LXI D,000BH          ; Load offset to next file locaion in catalog        &lt;br /&gt;
3999H  DAD D                ; Offset HL to next file  &lt;br /&gt;
399AH  POP PSW              ; Restore the file count from the stack    &lt;br /&gt;
399BH  DCR A                ; Decrement the max file count on the LCD  &lt;br /&gt;
399CH  JNZ 3967H            ; Branch to test and display next file until zero      &lt;br /&gt;
399FH  LDA FCD6H            ; Get the count of files actually displayed on screen              &lt;br /&gt;
39A2H  CPI 14H              ; Test if max number of files displayed    &lt;br /&gt;
39A4H  CC 39AAH             ; Branch to display &amp;quot;-.-&amp;quot; for remaining empty slots if not max     &lt;br /&gt;
39A7H  JMP 387CH            ; Print NADSBox directory or TPDD Bank number to LCD      &lt;br /&gt;
				  &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print &amp;quot;-.-&amp;quot; for all empty file slots&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
39AAH  PUSH PSW             ; Save current file index count on stack &lt;br /&gt;
39ABH  LXI H,3FCDH          ; Point to &amp;quot;-.-&amp;quot; text&lt;br /&gt;
39AEH  CALL 4A2CH           ; Send buffer at M to screen &lt;br /&gt;
39B1H  POP PSW              ; Restore current count &lt;br /&gt;
39B2H  INR A                ; Increment file index number&lt;br /&gt;
39B3H  CPI 14H              ; Compare A with max files that fit on LCD&lt;br /&gt;
39B5H  JNZ 39AAH            ; Jump to print next &amp;quot;-.-&amp;quot; if not done&lt;br /&gt;
39B8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;D&amp;quot; key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
39B9H  CALL 3AA8H           ; Test if printer busy.  Return if not busy or error&lt;br /&gt;
39BCH  CALL 4C52H           ; LCOPY statement&lt;br /&gt;
39BFH  JMP 362FH            ; Print length of selected file using inverse video.&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;L&amp;quot;, &amp;quot;P&amp;quot; and &amp;quot;O&amp;quot; keys from TS-DOS key scan - list or print .DO file contents&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
39C2H  STA FCDFH            ; Save key pressed       &lt;br /&gt;
39C5H  LXI D,0007H          ; Load offset of Extension bytes         &lt;br /&gt;
39C8H  LHLD FCE4H           ; LCD Buffer address of current file selection        &lt;br /&gt;
39CBH  DAD D                ; Point to extension bytes in LCD buffer   &lt;br /&gt;
39CCH  MOV A,M              ; Get 1st extension byte     &lt;br /&gt;
39CDH  CPI 44H              ; Compare byte with &amp;quot;D&amp;quot;     &lt;br /&gt;
39CFH  JNZ 362FH            ; Print length of selected file using inverse video if not &amp;quot;D&amp;quot;       &lt;br /&gt;
39D2H  INX H                ; Point to 2nd extension byte  &lt;br /&gt;
39D3H  MOV A,M              ; Load 2nd extension byte for comparison&lt;br /&gt;
39D4H  CPI 4FH              ; Compare with &amp;quot;0&amp;quot;&lt;br /&gt;
39D6H  JNZ 3A06H            ; Jump to print compressed file&lt;br /&gt;
39D9H  CALL 3A49H           ; Prepare file for reading (open disk file, address of RAM file)        &lt;br /&gt;
39DCH  LDA FCDFH            ; Restore key pressed       &lt;br /&gt;
39DFH  CPI 4CH              ; Test if key was &amp;quot;L&amp;quot; - List to LCD     &lt;br /&gt;
39E1H  CZ 4C27H             ; CLS statement if LCD      &lt;br /&gt;
39E4H  CNZ 3AA8H            ; Test if printer busy.  Return if not busy or error       &lt;br /&gt;
39E7H  CALL 3A24H           ; Get next block of data to display/print (HL=address)        &lt;br /&gt;
39EAH  PUSH PSW             ; Push Z flag indicating if a full 128 bytes was read      &lt;br /&gt;
39EBH  CALL 3A6BH           ; Display / print file data bytes at HL, A has length                 &lt;br /&gt;
39EEH  POP PSW              ; Get Z flag indicating if 128 bytes read     &lt;br /&gt;
39EFH  JZ 39E7H             ; Jump to process more if 128 bytes were read last time      &lt;br /&gt;
39F2H  LDA FCDFH            ; Restore key pressed       &lt;br /&gt;
39F5H  CPI 4CH              ; Test if key was &amp;quot;L&amp;quot;              &lt;br /&gt;
39F7H  JNZ 3A00H            ; Skip beep if printing       &lt;br /&gt;
39FAH  MVI A,07H            ; Load code for BELL       &lt;br /&gt;
39FCH  RST 4                ; Go print a BELL (beep)    &lt;br /&gt;
39FDH  CALL 3DF8H           ; Process power-off logic and wait for a key from keyboard        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Clear screen and perform Long Jump&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3A00H  CALL 4C27H           ; CLS statement         &lt;br /&gt;
3A03H  JMP 48B5H            ; Branch to &amp;quot;Long Jump&amp;quot; operation        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handler for the &amp;quot;O&amp;quot; key - print a compressed file?? &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3A06H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
3A09H  ANA A                ; Test if in Disk mode &lt;br /&gt;
3A0AH  JNZ 362FH            ; Jump to keyscan if in Disk mode&lt;br /&gt;
3A0DH  LHLD FCE4H           ; LCD Buffer address of current file selection      &lt;br /&gt;
3A10H  CALL 4902H           ; Copy filename at (HL) to current BASIC program&lt;br /&gt;
3A13H  CALL 4A51H           ; Get RAM directory address of current BASIC program&lt;br /&gt;
3A16H  CPI C0H              ; Test if filetype is .DO&lt;br /&gt;
3A18H  CZ 5004H             ; Call routine to Compress / Decompress .DO files&lt;br /&gt;
3A1BH  CALL 4C0FH           ; Update system pointers       &lt;br /&gt;
3A1EH  CALL 3611H           ; Print Copyright and files&lt;br /&gt;
3A21H  JMP 362FH            ; Jump to keyscan &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get next 128 bytes (or less) of data from RAM or disk file for display&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3A24H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)      &lt;br /&gt;
3A27H  ANA A                ; Test if RAM mode  &lt;br /&gt;
3A28H  JNZ 40B6H            ; If not RAM mode, go send TPDD_READ data opcode and recieve response      &lt;br /&gt;
3A2BH  LHLD FCDDH           ; Get length of file to be displayed / printed       &lt;br /&gt;
3A2EH  LXI B,0080H          ; Prepare to subtract 128 from length&lt;br /&gt;
3A31H  MOV A,C              ; Save 128 to A    &lt;br /&gt;
3A32H  DSUB                 ; Subtract 128 from file length &lt;br /&gt;
3A33H  JNC 3A3AH            ; Branch if length &amp;gt;= 128      &lt;br /&gt;
3A36H  DAD B                ; Add 128 back to length to print &amp;quot;partial&amp;quot; buffer  &lt;br /&gt;
3A37H  MOV A,L              ; Move remainder of bytes to display/print    &lt;br /&gt;
3A38H  MOV L,H              ; Clear LSB of remainder    &lt;br /&gt;
3A39H  MOV C,A              ; Move LSB of remainder to C    &lt;br /&gt;
3A3AH  SHLD FCDDH           ; Save new remaining file length       &lt;br /&gt;
3A3DH  LHLD FCE0H           ; Load the address to be printed / saved       &lt;br /&gt;
3A40H  PUSH H               ; Save on stack    &lt;br /&gt;
3A41H  DAD B                ; Update address to be used for display/printing next time  &lt;br /&gt;
3A42H  SHLD FCE0H           ; Save address to be displayed / printed       &lt;br /&gt;
3A45H  POP H                ; Retrieve address to be printed this loop from stack  &lt;br /&gt;
3A46H  CPI 80H              ; Compare length with maximum    &lt;br /&gt;
3A48H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Initialize Selected file for display (RAM or Disk)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3A49H  CALL 4A3BH           ; Initialize blank filename and attribute byte&lt;br /&gt;
3A4CH  LHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
3A4FH  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)     &lt;br /&gt;
3A52H  ANA A                ; Test if in RAM mode &lt;br /&gt;
3A53H  JNZ 3A65H            ; Branch to process Disk files if in Disk mode     &lt;br /&gt;
3A56H  CALL 4A4BH           ; Get RAM directory address of selected file&lt;br /&gt;
3A59H  PUSH D               ; Push file address to stack  &lt;br /&gt;
3A5AH  CALL 3CD3H           ; Calculate length of RAM file, HL=address of catalog entry, DE=file address&lt;br /&gt;
3A5DH  SHLD FCDDH           ; Save length to FDC emulation sector storage area&lt;br /&gt;
3A60H  POP H                ; Pop address of file into H &lt;br /&gt;
3A61H  SHLD FCE0H           ; Save file address&lt;br /&gt;
3A64H  RET		 &lt;br /&gt;
				 &lt;br /&gt;
; =====================================================================================&lt;br /&gt;
; Send TPDD Open command to open selected file&lt;br /&gt;
; =====================================================================================&lt;br /&gt;
3A65H  CALL 3D95H           ; Copy filename at (HL) to TX buffer&lt;br /&gt;
3A68H  JMP 408AH            ; Open TPDD file for Read Mode&lt;br /&gt;
&lt;br /&gt;
; =====================================================================================&lt;br /&gt;
; Display / print file data bytes at HL, A has length&lt;br /&gt;
; =====================================================================================&lt;br /&gt;
3A6BH  XCHG                 ; HL &amp;lt;--&amp;gt; DE  &lt;br /&gt;
3A6CH  ORA A                ; Test if length = 0   &lt;br /&gt;
3A6DH  RZ                   ; Return if length = 0&lt;br /&gt;
3A6EH  MOV C,A              ; Save length count in C     &lt;br /&gt;
3A6FH  LDA FCDFH            ; Load key press value       &lt;br /&gt;
3A72H  CPI 4CH              ; Test if key was &amp;quot;L&amp;quot;     &lt;br /&gt;
3A74H  JNZ 3A82H            ; Jump to print contents if not &amp;quot;L&amp;quot;       &lt;br /&gt;
3A77H  CALL 3A8FH           ; Check for CTRL-C&lt;br /&gt;
3A7AH  LDAX D               ; Load next byte from src pointer    &lt;br /&gt;
3A7BH  RST 4                ; Send A to LCD           &lt;br /&gt;
3A7CH  INX D                ; Increment the pointer   &lt;br /&gt;
3A7DH  DCR C                ; Decrement the length count   &lt;br /&gt;
3A7EH  JNZ 3A77H            ; Keep looping until all data displayed       &lt;br /&gt;
3A81H  RET        &lt;br /&gt;
&lt;br /&gt;
; =====================================================================================&lt;br /&gt;
; Print file data bytes at HL, A has length&lt;br /&gt;
; =====================================================================================&lt;br /&gt;
3A82H  CALL 3A8FH           ; Test for CTRL-C, etc.&lt;br /&gt;
3A85H  LDAX D               ; Load next file byte from source poiner &lt;br /&gt;
3A86H  CALL 4C42H           ; Print A to printer, expanding tabs if necessary&lt;br /&gt;
3A89H  INX D                ; Increment pointer&lt;br /&gt;
3A8AH  DCR C                ; Decrement length count&lt;br /&gt;
3A8BH  JNZ 3A82H            ; Keep looping until all data printed    &lt;br /&gt;
3A8EH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test for ESC, CTRL-C or Space&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3A8FH  CALL 4C4AH           ; Check keyboard queue for pending characters&lt;br /&gt;
3A92H  RZ                   ; Return if no pending characters&lt;br /&gt;
3A93H  CALL 4BEBH           ; Wait for key from keyboard&lt;br /&gt;
3A96H  CPI 03H              ; Test for F4 maybe?  &lt;br /&gt;
3A98H  JZ 3A00H             ; Clear screen and perform Long Jump if F4 maybe?   &lt;br /&gt;
3A9BH  CPI 1BH              ; Test for ESC key  &lt;br /&gt;
3A9DH  JZ 3A00H             ; Clear screen and perform Long Jump if ESC   &lt;br /&gt;
3AA0H  CPI 20H              ; Test for space key  &lt;br /&gt;
3AA2H  JNZ 3A8FH            ; Branch back to wait for ESC, CTRL-C or space if not space    &lt;br /&gt;
3AA5H  JMP 4BEBH            ; Wait for key from keyboard    &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test if printer busy.  Return if not busy, print error if it is&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3AA8H  IN BBH               ; Get printer port input     &lt;br /&gt;
3AAAH  ANI 06H              ; Mask all but BUSY and /BUSY      &lt;br /&gt;
3AACH  XRI 02H              ; Compliment /BUSY      &lt;br /&gt;
3AAEH  JNZ 487BH            ; Printer not ready / FF error        &lt;br /&gt;
3AB1H  RET        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print currently selected file using inverse video&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3AB2H  CALL 3ACDH           ; Calculate Row and Column of newly selected file&lt;br /&gt;
3AB5H  SHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
3AB8H  CALL 4C2FH           ; Start inverse character mode&lt;br /&gt;
3ABBH  DCX H                ; Start drawing from left edge of selection (include space)   &lt;br /&gt;
3ABCH  MVI C,0AH            ; Draw 10 characters       &lt;br /&gt;
3ABEH  CALL 48E5H           ; Redraw C characters from buffer at HL using current video mode&lt;br /&gt;
3AC1H  JMP 4C33H            ; Cancel inverse character mode       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print selected file using normal video to &amp;quot;unselect&amp;quot; it&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3AC4H  CALL 4C33H           ; Cancel inverse character mode&lt;br /&gt;
3AC7H  CALL 3ACDH           ; Calculate row and column of newly selected file&lt;br /&gt;
3ACAH  JMP 3ABBH            ; Print the file to the LCD       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Calculate Row and Column of soon-to-be (newly) selected file&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3ACDH  LDA FCD5H            ; Currently selected file index       &lt;br /&gt;
3AD0H  DCR A                ; Make selected file zero based   &lt;br /&gt;
3AD1H  MOV L,A              ; Save index to 16-bit HL&lt;br /&gt;
3AD2H  MVI H,00H            ; Make MSB zero&lt;br /&gt;
3AD4H  LXI D,000AH          ; Prepare to multiply index * 10 cols      &lt;br /&gt;
3AD7H  CALL 4C1FH           ; Signed integer muliply (FAC1=HL*DE)&lt;br /&gt;
3ADAH  LXI D,FE28H          ; Load address of line 2 in the LCD buffer&lt;br /&gt;
3ADDH  DAD D                ; Calculate starting LCD buffer address for this file&lt;br /&gt;
3ADEH  INX H                ; Skip the &amp;quot;tag&amp;quot; space on the LCD&lt;br /&gt;
3ADFH  PUSH H               ; Save address on the stack&lt;br /&gt;
3AE0H  LXI B,FE00H          ; Load starting address of LCD character buffer&lt;br /&gt;
3AE3H  DSUB                 ; Calculate file start offset from start of LCD buffer&lt;br /&gt;
3AE4H  LXI D,0028H          ; Load 1 LCD line width&lt;br /&gt;
3AE7H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  Prepare for divide&lt;br /&gt;
3AE8H  CALL 4C1BH           ; Signed integer divide (FAC1=DE/HL)&lt;br /&gt;
3AEBH  MOV A,L              ; Save selected file&#039;s row number to A&lt;br /&gt;
3AECH  INR A                ; Make row 1-based&lt;br /&gt;
3AEDH  STA F639H            ; Cursor row (1-8)&lt;br /&gt;
3AF0H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  DE had remainder*2 from divide&lt;br /&gt;
3AF1H  ASHR                 ; Divide HL by 2&lt;br /&gt;
3AF2H  MOV A,L              ; Prepare to save remainder as the column&lt;br /&gt;
3AF3H  STA F63AH            ; Cursor column (1-40)&lt;br /&gt;
3AF6H  POP H                ; Restore address of LCD buffer location from stack&lt;br /&gt;
3AF7H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F3 Function key handler for RAM mode - Rename&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3AF8H  CALL 4A4BH           ; Get RAM directory address of selected file          &lt;br /&gt;
3AFBH  SHLD FCE0H           ; Save address of file being processed          &lt;br /&gt;
3AFEH  LXI H,3F4AH          ; Address of &amp;quot;New name&amp;quot; string           &lt;br /&gt;
3B01H  CALL 3E1AH           ; Get 6-byte input filename from keyboard          &lt;br /&gt;
3B04H  RZ                   ; Return if no input provided  &lt;br /&gt;
3B05H  CALL 4902H           ; Copy filename at (HL) to current BASIC program          &lt;br /&gt;
3B08H  LHLD FCE0H           ; Load RAM directory address of file being renamed          &lt;br /&gt;
3B0BH  LXI B,0009H          ; Load offset of extension within catalog entry           &lt;br /&gt;
3B0EH  DAD B                ; Point to extension bytes     &lt;br /&gt;
3B0FH  LXI D,FC99H          ; Load address of extension field of current BASIC program name           &lt;br /&gt;
3B12H  MOV A,M              ; Get 1st byte of extension of catalog file being renamed       &lt;br /&gt;
3B13H  STAX D               ; Save extension byte in current BASIC program filename - preserve EXT      &lt;br /&gt;
3B14H  INX D                ; Point to 2nd ext byte of BASIC program name     &lt;br /&gt;
3B15H  INX H                ; Point to 2nd ext byte of catalog filename     &lt;br /&gt;
3B16H  MOV A,M              ; Get 2nd extension byte from catalog filename       &lt;br /&gt;
3B17H  STAX D               ; Save byte in current BASIC program filename area      &lt;br /&gt;
3B18H  CALL 4A51H           ; Get RAM directory address of current BASIC program          &lt;br /&gt;
3B1BH  JNZ 487EH            ; If found, jump to File Exists Error         &lt;br /&gt;
3B1EH  LHLD FCE0H           ; Load catalog address of file being renamed          &lt;br /&gt;
3B21H  INX H                ; Point to LSB of file address     &lt;br /&gt;
3B22H  INX H                ; Point to MSB of file address     &lt;br /&gt;
3B23H  INX H                ; Point to name     &lt;br /&gt;
3B24H  LXI D,FC93H          ; Load address of filename of current BASIC program    &lt;br /&gt;
3B27H  LXI B,0006H          ; Prepare to copy 6 bytes of filename (ext doesn&#039;t change)           &lt;br /&gt;
3B2AH  XCHG                 ; HL &amp;lt;--&amp;gt; DE    &lt;br /&gt;
3B2BH  JMP 4A05H            ; Move BC bytes from M to (DE) with increment         &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F1 Function key handler for DISK mode - Load&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3B2EH  CALL 4A3BH           ; Initialize blank filename and attribute byte      &lt;br /&gt;
3B31H  LHLD FCE4H           ; LCD Buffer address of current file selection      &lt;br /&gt;
3B34H  CALL 3D95H           ; Copy filename at (HL) to TX buffer      &lt;br /&gt;
3B37H  LDA FCCCH            ; Last Tag/Untag operation code     &lt;br /&gt;
3B3AH  ANA A                ; Test if a tag operation is pending &lt;br /&gt;
3B3BH  JNZ 3B56H            ; Branch if doing tag load operation     &lt;br /&gt;
3B3EH  LXI H,3F7AH          ; Point to &amp;quot;Load as:&amp;quot; text       &lt;br /&gt;
3B41H  CALL 3E1AH           ; Get 6-byte filename input from keyboard      &lt;br /&gt;
3B44H  JZ 3B56H             ; Jump to use existing disk name as filename    &lt;br /&gt;
3B47H  CALL 4902H           ; Copy filename at (HL) to current BASIC program      &lt;br /&gt;
3B4AH  LXI B,0002H          ; Prepare to copy 2 extension bytes to current BASIC program space       &lt;br /&gt;
3B4DH  LXI H,FCEFH          ; Point to disk file extension in TX buffer       &lt;br /&gt;
3B50H  LXI D,FC99H          ; Point to current BASIC program extension address       &lt;br /&gt;
3B53H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
3B56H  CALL 4A51H           ; Get RAM directory address of current BASIC program      &lt;br /&gt;
3B59H  JZ 3B69H             ; Branch to load if file doesn&#039;t already exist    &lt;br /&gt;
3B5CH  LXI H,3FB0H          ; Point to &amp;quot;File Exists, Replace?&amp;quot; text       &lt;br /&gt;
3B5FH  CALL 48F4H           ; Print string at HL to col 1 on the bottom line      &lt;br /&gt;
3B62H  CALL 3DEEH           ; Get key from keyboard and test for &#039;Y&#039; or &#039;y&#039;      &lt;br /&gt;
3B65H  RNZ                  ; Return if isn&#039;t &#039;y&#039; or &#039;Y&#039; &lt;br /&gt;
3B66H  CALL 3C38H           ; Kill file in current BASIC program space      &lt;br /&gt;
3B69H  LHLD FD1DH           ; Get file size from RX buffer      &lt;br /&gt;
3B6CH  MOV A,H              ; Swap bytes (big endian in RX buffer)   &lt;br /&gt;
3B6DH  MOV H,L              ; Move LSB to MSB   &lt;br /&gt;
3B6EH  MOV L,A              ; Move MSB to LSB   &lt;br /&gt;
3B6FH  SHLD FD1DH           ; Save with little endian to RX buffer      &lt;br /&gt;
3B72H  LDA FCEFH            ; Get 1st byte of extension from TX buffer     &lt;br /&gt;
3B75H  CPI 44H              ; Test if 1st extension byte is &amp;quot;D&amp;quot;   &lt;br /&gt;
3B77H  JNZ 3B82H            ; Jump if not &amp;quot;D&amp;quot; to check for &amp;quot;C&amp;quot; or &amp;quot;B&amp;quot;     &lt;br /&gt;
3B7AH  LHLD FBAEH           ; Get start of DO files pointer for location of new file       &lt;br /&gt;
3B7DH  MVI A,C0H            ; Load file type code for .DO files     &lt;br /&gt;
3B7FH  JMP 3BA3H            ; Process the file load      &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test file exension type in A for .CO files&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3B82H  CPI 43H              ; Test if A contains &amp;quot;C&amp;quot; &lt;br /&gt;
3B84H  JNZ 3B95H            ; Branch if not .CO file&lt;br /&gt;
3B87H  LHLD FBB0H           ; Start of CO files pointer&lt;br /&gt;
3B8AH  SHLD FCD5H           ; Save in currently selected file index storage area&lt;br /&gt;
3B8DH  LHLD FBB2H           ; Get Start of variable data pointer as location for new file&lt;br /&gt;
3B90H  MVI A,A0H            ; Load file type code for .CO files&lt;br /&gt;
3B92H  JMP 3BA3H            ; Process the file load&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process load of .BA file&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3B95H  LHLD FD1DH           ; Get file size from RX buffer&lt;br /&gt;
3B98H  SHLD FCD5H           ; Save in Currently selected file index storage&lt;br /&gt;
3B9BH  LHLD F99AH           ; Get BASIC program not saved pointer     &lt;br /&gt;
3B9EH  SHLD FCE0H           ; Save as address of file being processed&lt;br /&gt;
3BA1H  MVI A,80H            ; Load file type code for .BA files     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process file load operation&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3BA3H  STA FCDFH            ; Save file type code for later     &lt;br /&gt;
3BA6H  SHLD FCE2H           ; Save address for new file &lt;br /&gt;
3BA9H  LHLD FD1DH           ; Get file size from RX buffer&lt;br /&gt;
3BACH  SHLD FCDDH           ; Save in FDC emulation physical/logical sector storage area&lt;br /&gt;
3BAFH  PUSH H               ; Save file size on stack  &lt;br /&gt;
3BB0H  POP B                ; Copy file size to BC &lt;br /&gt;
3BB1H  LDA FCDFH            ; Get file type code     &lt;br /&gt;
3BB4H  CPI A0H              ; Test for .CO file   &lt;br /&gt;
3BB6H  JZ 3BC0H             ; Skip increment if .CO file (.BA has trailing 0x0000, .DO a 0x1A)    &lt;br /&gt;
3BB9H  INX B                ; Increment file length for .BA and .DO files &lt;br /&gt;
3BBAH  CPI 80H              ; Test if file is .BA   &lt;br /&gt;
3BBCH  JNZ 3BC0H            ; Skip additional increment if .BA     &lt;br /&gt;
3BBFH  INX B                ; Add 1 more to length for .BA files to account for both trailing 0&#039;s &lt;br /&gt;
3BC0H  PUSH B               ; Save updated length on stack  &lt;br /&gt;
3BC1H  CALL 3E48H           ; Find empty catalog entry      &lt;br /&gt;
3BC4H  JC 4887H             ; Generate system error 0x0A (&amp;quot;DD&amp;quot;) if full&lt;br /&gt;
3BC7H  POP B                ; Get length from stack &lt;br /&gt;
3BC8H  PUSH H               ; Save new file catalog address on stack  &lt;br /&gt;
3BC9H  PUSH B               ; Save new file length on stack  &lt;br /&gt;
3BCAH  LHLD FCE2H           ; Get address for new contents of new file      &lt;br /&gt;
3BCDH  CALL 4C0BH           ; Insert BC spaces at M - make room      &lt;br /&gt;
3BD0H  JC 488AH             ; Branch if error - RAM full error&lt;br /&gt;
3BD3H  LHLD FCE2H           ; Restore address of new file contents&lt;br /&gt;
3BD6H  POP B                ; Get file length from stack   &lt;br /&gt;
3BD7H  MVI M,00H            ; Fill newly created file space with zero&#039;s       &lt;br /&gt;
3BD9H  INX H                ; Increment pointer   &lt;br /&gt;
3BDAH  DCX B                ; Decrement count   &lt;br /&gt;
3BDBH  MOV A,C              ; Move LSB to A to check for zero - could use JNX here!     &lt;br /&gt;
3BDCH  ORA B                ; Or in MSB to check for zero   &lt;br /&gt;
3BDDH  JNZ 3BD7H            ; Keep looping until all are zero       &lt;br /&gt;
3BE0H  DCX H                ; Decrement pointer to last byte in new file   &lt;br /&gt;
3BE1H  POP D                ; Get File catalog address from stack   &lt;br /&gt;
3BE2H  LDA FCDFH            ; Load file type code byte       &lt;br /&gt;
3BE5H  CPI C0H              ; Test for .DO file     &lt;br /&gt;
3BE7H  JNZ 3BF3H            ; Branch if not .DO file       &lt;br /&gt;
3BEAH  MVI M,1AH            ; Terminate .DO file with EOF marker       &lt;br /&gt;
3BECH  LHLD FCE2H           ; Reload address of new file contents        &lt;br /&gt;
3BEFH  DCX H                ; Decrement pointer to jump into middle of loop   &lt;br /&gt;
3BF0H  JMP 3C1BH            ; Write file entry to catalog       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process end-of-file / file length for .CO and .BA files&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3BF3H  CPI A0H              ; Test if new file is .CO  &lt;br /&gt;
3BF5H  JNZ 3C04H            ; Branch if not .CO - must be .BA &lt;br /&gt;
3BF8H  LHLD FCD5H           ; Get old start of CO files pointer&lt;br /&gt;
3BFBH  SHLD FBB0H           ; Save as current start of CO files pointer     &lt;br /&gt;
3BFEH  LHLD FCE2H           ; Reload address of new file contents&lt;br /&gt;
3C01H  JMP 3C1BH            ; Write file entry to catalog &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process end-of-file for .BA files&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3C04H  PUSH D               ; Push file catalog address to stack    &lt;br /&gt;
3C05H  LHLD FBAEH           ; Get start of DO files pointer          &lt;br /&gt;
3C08H  DCX H                ; Decrement address by 1   &lt;br /&gt;
3C09H  SHLD F99AH           ; Save as new BASIC program not saved pointer          &lt;br /&gt;
3C0CH  INX H                ; Increment back to start of .DO files   &lt;br /&gt;
3C0DH  XCHG                 ; HL &amp;lt;--&amp;gt; DE  DE has start of DO files  &lt;br /&gt;
3C0EH  LHLD FCD5H           ; Get BA file size        &lt;br /&gt;
3C11H  INX H                ; Increment file size to account for trailing 0&#039;s   &lt;br /&gt;
3C12H  INX H                ; Increment file size to account for trailing 0&#039;s   &lt;br /&gt;
3C13H  DAD D                ; Add new length to start of DO files pointer   &lt;br /&gt;
3C14H  SHLD FBAEH           ; Save new start of DO files pointer          &lt;br /&gt;
3C17H  POP D                ; Retrieve file catalog address from stack   &lt;br /&gt;
3C18H  LHLD FCE0H           ; Reload address of new file contents        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Write file entry to catalog&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3C1BH  XCHG                 ; HL &amp;lt;--&amp;gt; DE  DE has file address, HL has catalog address         &lt;br /&gt;
3C1CH  CALL 4C17H           ; Write new entry to catalog (A=type, DE=file address,HL=catalog address)       &lt;br /&gt;
3C1FH  CALL 4127H           ; Open TPDD file and read data to file address being processed       &lt;br /&gt;
3C22H  CALL 4C0FH           ; Update system pointers       &lt;br /&gt;
3C25H  LXI H,0002H          ; Load TPDD_READ opcode in HL        &lt;br /&gt;
3C28H  JMP 409BH            ; Send Request in HL and await response      &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F2 Function key handler for RAM mode - Kill&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3C2BH  LDA FCCCH            ; Get last Tag/Untag operation code       &lt;br /&gt;
3C2EH  ANA A                ; Test if there is a pending tag operation&lt;br /&gt;
3C2FH  CZ 3DE1H             ; Display &amp;quot;Sure ?&amp;quot;, validate and return if validated if no tag&lt;br /&gt;
3C32H  LHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
3C35H  CALL 4902H           ; Copy filename at (HL) to current BASIC program&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Kill file in current BASIC program space&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3C38H  CALL 4A51H           ; Get RAM directory address of current BASIC program&lt;br /&gt;
3C3BH  CPI C0H              ; Test if file is .DO &lt;br /&gt;
3C3DH  JZ 4BFFH             ; Kill .DO file  &lt;br /&gt;
3C40H  CPI A0H              ; Test if file is .CO &lt;br /&gt;
3C42H  JZ 4C07H             ; Kill .CO file &lt;br /&gt;
3C45H  CPI 80H              ; Test if file is .BA&lt;br /&gt;
3C47H  JZ 4C03H             ; Kill .BA file&lt;br /&gt;
3C4AH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F1 Function key handler for RAM mode - Save&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3C4BH  CALL 4A3BH           ; Initialize blank filename and attribute byte      &lt;br /&gt;
3C4EH  CALL 4A4BH           ; Get RAM directory address of selected file      &lt;br /&gt;
3C51H  PUSH D               ; Push file address to stack  &lt;br /&gt;
3C52H  PUSH H               ; Push file catalog address to stack  &lt;br /&gt;
3C53H  INX H                ; Point to LSB of file address &lt;br /&gt;
3C54H  INX H                ; Point to MSB of file address &lt;br /&gt;
3C55H  INX H                ; Point to filename in catalog &lt;br /&gt;
3C56H  LXI D,FCE8H          ; Point to TX buffer data area (payload)&lt;br /&gt;
3C59H  LXI B,0006H          ; Prepare to copy 6 filename bytes to TX packet data&lt;br /&gt;
3C5CH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
3C5FH  MVI A,2EH            ; Load code for &#039;.&#039;     &lt;br /&gt;
3C61H  STAX D               ; Store &#039;.&#039; separator in TX packet data  &lt;br /&gt;
3C62H  INX D                ; Increment TX packet data pointer &lt;br /&gt;
3C63H  LXI B,0002H          ; Prepare to copy 2 extention bytes from catalog&lt;br /&gt;
3C66H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
3C69H  LDA FCCCH            ; Last Tag/Untag operation code     &lt;br /&gt;
3C6CH  ANA A                ; Test if a tag save operation is being performed &lt;br /&gt;
3C6DH  JNZ 3C88H            ; Jump ahead if doing a tag save - skip filename questioning     &lt;br /&gt;
3C70H  LXI H,3F71H          ; Point to &amp;quot;Save as:&amp;quot; text&lt;br /&gt;
3C73H  CALL 3E1AH           ; Get 6-byte input filename from keyboard      &lt;br /&gt;
3C76H  JZ 3C88H             ; Skip ahead to use catalog name if no input given    &lt;br /&gt;
3C79H  CALL 4902H           ; Copy filename at (HL) to current BASIC program             &lt;br /&gt;
3C7CH  LXI B,0006H          ; Prepare to copy 6 filename bytes from input string       &lt;br /&gt;
3C7FH  LXI D,FCE8H          ; Point to filename area in TX buffer       &lt;br /&gt;
3C82H  LXI H,FC93H          ; Filename of current BASIC program         &lt;br /&gt;
3C85H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
3C88H  POP H                ; Restore file catalog address from stack &lt;br /&gt;
3C89H  POP D                ; Restore file address from stack &lt;br /&gt;
3C8AH  PUSH D               ; Save file address on stack  &lt;br /&gt;
3C8BH  CALL 3CD3H           ; Calculate length of RAM file, HL=address of catalog entry, DE=file address&lt;br /&gt;
3C8EH  MOV A,H              ; Test for zero length file - move H to A    &lt;br /&gt;
3C8FH  ORA L                ; OR LSB to test for zero  &lt;br /&gt;
3C90H  JZ 4884H             ; Branch if empty - File Empty Error     &lt;br /&gt;
3C93H  PUSH H               ; Save file address to stack   &lt;br /&gt;
3C94H  MVI A,01H            ; Set file open mode to new file      &lt;br /&gt;
3C96H  STA FCD6H            ; Save open mode to pass to open routine      &lt;br /&gt;
3C99H  CALL 4943H           ; Configure baud, test for NADSBox, get NADSBox dir       &lt;br /&gt;
3C9CH  CALL 4A72H           ; Send Dir Reference opcode       &lt;br /&gt;
3C9FH  JZ 3CCEH             ; Jump to write data if file doesn&#039;t exist (size = 0)     &lt;br /&gt;
3CA2H  LXI H,3F8BH          ; Point to &amp;quot;File Exists, A)ppend R)eplace Q)uit&amp;quot; text        &lt;br /&gt;
3CA5H  CALL 48F4H           ; Print string at HL to col 1 on the bottom line       &lt;br /&gt;
3CA8H  CALL 3DF8H           ; Process power-off logic and wait for a key from keyboard       &lt;br /&gt;
3CABH  ANI DFH              ; Make key uppercase    &lt;br /&gt;
3CADH  RST 4                ; Display key on LCD            &lt;br /&gt;
3CAEH  CPI 52H              ; Test if key is &#039;R&#039;    &lt;br /&gt;
3CB0H  JNZ 3CBCH            ; Jump if not &#039;R&#039;eplace                      &lt;br /&gt;
3CB3H  CALL 431AH           ; Issue TPDD Delete file Opcode       &lt;br /&gt;
3CB6H  CALL 4A72H           ; Send Dir Reference opcode       &lt;br /&gt;
3CB9H  JMP 3CCEH            ; Go write data to the file      &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F1-Save: Test for &#039;A&#039;ppend&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3CBCH  POP H                ; Get file length from stack    &lt;br /&gt;
3CBDH  POP D                ; Get file address from stack    &lt;br /&gt;
3CBEH  CPI 41H              ; Test if response is &#039;A&#039;ppend      &lt;br /&gt;
3CC0H  RNZ                  ; Return if not &#039;A&#039;  &lt;br /&gt;
3CC1H  LDA FCEFH            ; Load 1st byte of extension from TX buffer        &lt;br /&gt;
3CC4H  CPI 44H              ; Test if file is &amp;quot;D&amp;quot;O file      &lt;br /&gt;
3CC6H  RNZ                  ; Don&#039;t allow appending non DO files  &lt;br /&gt;
3CC7H  MVI A,02H            ; Set open mode to open existing (append)        &lt;br /&gt;
3CC9H  STA FCD6H            ; Save mode to pass to open routine        &lt;br /&gt;
3CCCH  PUSH D               ; Save file address on stack     &lt;br /&gt;
3CCDH  PUSH H               ; Save file length on stack     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Save function - Replace or new file, write data to file&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3CCEH  POP H                ; Retrieve file length from stack    &lt;br /&gt;
3CCFH  POP D                ; Retrieve file address from stack    &lt;br /&gt;
3CD0H  JMP 40C8H            ; Write HL bytes of data from (DE) to TPDD        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Calculate length of RAM file, HL=address of catalog entry, DE=file address&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3CD3H  MOV A,M              ; Get RAM file type from catalog   &lt;br /&gt;
3CD4H  CPI C0H              ; Test for .DO file   &lt;br /&gt;
3CD6H  JZ 3CE6H             ; Jump to calculate length if .DO file    &lt;br /&gt;
3CD9H  CPI A0H              ; Test for .CO file         &lt;br /&gt;
3CDBH  JZ 3CF5H             ; Jump to calculate length if .CO file    &lt;br /&gt;
3CDEH  PUSH D               ; Save address of start of BASIC program to stack  &lt;br /&gt;
3CDFH  CALL 4C13H           ; Call ROM routine to find BASIC end of program&lt;br /&gt;
3CE2H  POP B                ; Get BASIC program start address from stack &lt;br /&gt;
3CE3H  DSUB                 ; Subtract starting address from end address&lt;br /&gt;
3CE4H  DCX H                ; Don&#039;t count trailing 0x00 as part of BASIC program length &lt;br /&gt;
3CE5H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Calculate length of .DO file, HL=Catalog address, DE=file address&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3CE6H  XCHG                 ; HL &amp;lt;--&amp;gt; DE Get file address in HL &lt;br /&gt;
3CE7H  LXI D,0000H          ; Clear file length&lt;br /&gt;
3CEAH  MOV A,M              ; Get next byte from .DO file    &lt;br /&gt;
3CEBH  INX H                ; Increment pointer  &lt;br /&gt;
3CECH  INX D                ; Increment length  &lt;br /&gt;
3CEDH  CPI 1AH              ; Test for EOF marker    &lt;br /&gt;
3CEFH  JNZ 3CEAH            ; Branch to next byte if not EOF      &lt;br /&gt;
3CF2H  DCX D                ; Subtract EOF marker from file length  &lt;br /&gt;
3CF3H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  HL=length &lt;br /&gt;
3CF4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Calculate length of .CO file, HL=Catalog address, DE=file address&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3CF5H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  Get file address in HL &lt;br /&gt;
3CF6H  INX H                ; Increment past .CO load address &lt;br /&gt;
3CF7H  INX H                ; Increment past MSB of load address&lt;br /&gt;
3CF8H  MOV C,M              ; Get LSB of length  &lt;br /&gt;
3CF9H  INX H                ; Increment to MSB of length&lt;br /&gt;
3CFAH  MOV B,M              ; Get MSB of length&lt;br /&gt;
3CFBH  LXI H,0006H          ; Prepare to add 6-byte header to length&lt;br /&gt;
3CFEH  DAD B                ; Add 6-byte header to length&lt;br /&gt;
3CFFH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F7 Function key handler for DISK mode - Mkdir&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D00H  LDA FCCBH            ; NADSBox / TPDD2 / Desklink flag        &lt;br /&gt;
3D03H  ANA A                ; Test if server is TPDD    &lt;br /&gt;
3D04H  RZ                   ; Return if not NADSBox or TPDD2 &lt;br /&gt;
3D05H  DCR A                ; Test if TPDD2    &lt;br /&gt;
3D06H  JZ 37BAH             ; Go Swap TPDD Bank Number if TPDD2       &lt;br /&gt;
3D09H  CALL 4A3BH           ; Must be NADSBOx Initialize blank filename         &lt;br /&gt;
3D0CH  LXI H,3F61H          ; Load pointer to &amp;quot;Directory name:&amp;quot; text          &lt;br /&gt;
3D0FH  CALL 3E1AH           ; Get 6-byte input filename from keyboard         &lt;br /&gt;
3D12H  RZ                   ; Return if no input given &lt;br /&gt;
3D13H  CALL 4902H           ; Copy filename at (HL) to current BASIC program         &lt;br /&gt;
3D16H  LXI H,FC93H          ; Filename of current BASIC program              &lt;br /&gt;
3D19H  LXI D,FCE8H          ; Point to TX buffer data area (payload)          &lt;br /&gt;
3D1CH  LXI B,0006H          ; Prepare to copy 6 filename bytes to TX buffer          &lt;br /&gt;
3D1FH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment         &lt;br /&gt;
3D22H  LXI H,3E3CH          ; Load code for &amp;quot;&amp;lt;&amp;gt;&amp;quot;          &lt;br /&gt;
3D25H  SHLD FCEFH           ; Save &amp;quot;&amp;lt;&amp;gt;&amp;quot; extension bytes in TX buffer - NADSBox Mkdir                   &lt;br /&gt;
3D28H  MVI A,2EH            ; Load code for &#039;.&#039; extension separator        &lt;br /&gt;
3D2AH  STA FCEEH            ; Save &amp;quot;.&amp;quot; to TX buffer        &lt;br /&gt;
3D2DH  CALL 4943H           ; Configure baud, test for NADSBox, get NADSBox dir         &lt;br /&gt;
3D30H  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag        &lt;br /&gt;
3D33H  CPI 02H              ; Test if we have NADSBox current directory      &lt;br /&gt;
3D35H  RNZ                  ; Return if we don&#039;t have current directory  &lt;br /&gt;
3D36H  CALL 4A72H           ; Send Directory Reference opcode         &lt;br /&gt;
3D39H  JNZ 3D4DH            ; If the file exists, branch to open it for READ mode        &lt;br /&gt;
3D3CH  MVI A,01H            ; Load OPEN_WRITE mode into A to create the directory        &lt;br /&gt;
3D3EH  STA FCE8H            ; Save A in TX data storage mode field        &lt;br /&gt;
3D41H  LXI H,0101H          ; Load opcode to open a file          &lt;br /&gt;
3D44H  CALL 409BH           ; Send Request in HL and await response         &lt;br /&gt;
3D47H  LXI H,0002H          ; Load opcode to close the file          &lt;br /&gt;
3D4AH  JMP 409BH            ; Send Request in HL and await response        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Open and close a directory file (from above)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D4DH  CALL 408AH           ; Open TPDD file for Read Mode&lt;br /&gt;
3D50H  JMP 3D47H            ; Branch to close the directory open request&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F5 Function key handler for DISK mode - Format&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D53H  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag       &lt;br /&gt;
3D56H  CPI 02H              ; Test if we have &amp;quot;current directory&amp;quot; name     &lt;br /&gt;
3D58H  RZ                   ; Return if server is NADSBox / Desklink - No format supported&lt;br /&gt;
3D59H  LXI H,3F1BH          ; Load pointer to &amp;quot;Insert Disk&amp;quot; string&lt;br /&gt;
3D5CH  CALL 48F4H           ; Print string at HL to col 1 on the bottom line        &lt;br /&gt;
3D5FH  CALL 3DEEH           ; Get key from keyboard and test for &#039;Y&#039; or &#039;y&#039;        &lt;br /&gt;
3D62H  RNZ                  ; Return if response not &#039;Y&#039; &lt;br /&gt;
3D63H  CALL 4943H           ; Configure baud, test for NADSBox, get NADSBox dir        &lt;br /&gt;
3D66H  CALL 49E3H           ; Delay routine - about 3ms        &lt;br /&gt;
3D69H  LXI H,0006H          ; Load TPDD_FORMAT opcode in HL&lt;br /&gt;
3D6CH  CALL 409BH           ; Send Request in HL and await response        &lt;br /&gt;
3D6FH  MVI A,07H            ; Load code for BELL       &lt;br /&gt;
3D72H  RET                  ; Go beep to indicate format&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F2 Function key handler for DISK mode - Kill&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D73H  LDA FCCCH            ; Last Tag/Untag operation code      &lt;br /&gt;
3D76H  ANA A                ; Test if there&#039;s an active tag group&lt;br /&gt;
3D77H  CZ 3DE1H             ; Display &amp;quot;Sure ?&amp;quot;, validate and return if validated if no tag&lt;br /&gt;
3D7AH  CALL 4A3BH           ; Initialize blank filename and attribute byte&lt;br /&gt;
3D7DH  CALL 3D83H           ; Copy selected filename to TX buffer and init TPDD/NADSBox&lt;br /&gt;
3D80H  JMP 431AH            ; Issue TPDD Delete file Opcode            &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Copy selected filename to TX buffer and init TPDD/NADSBox&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D83H  LXI B,0009H          ; Prepare to copy 9 filename bytes&lt;br /&gt;
3D86H  LHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
3D89H  LXI D,FCE8H          ; Address of TX packet data&lt;br /&gt;
3D8CH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment&lt;br /&gt;
3D8FH  CALL 4943H           ; Configure baud, test for NADSBox, get NADSBox dir&lt;br /&gt;
3D92H  JMP 4A72H            ; Send Dir Reference opcode&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Copy filename at (HL) to TX buffer&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D95H  CALL 4902H           ; Copy filename at (HL) to current BASIC program&lt;br /&gt;
3D98H  LXI H,FC93H          ; Filename of current BASIC program&lt;br /&gt;
3D9BH  CALL 4A57H           ; Send Dir Reference for filename at (HL)&lt;br /&gt;
3D9EH  RET        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F3 Function key handler for DISK mode - Name&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D9FH  CALL 4A3BH           ; Initialize blank filename and attribute byte          &lt;br /&gt;
3DA2H  CALL 3D83H           ; Copy selected filename to TX buffer and init TPDD/NADSBox          &lt;br /&gt;
3DA5H  LXI H,FCE8H          ; Point to TX buffer data area (payload)&lt;br /&gt;
3DA8H  LXI D,FC9CH          ; Filename of last program loaded from tape  &lt;br /&gt;
3DABH  LXI B,0009H          ; Prepare to copy 9 bytes to &amp;quot;last program loaded&amp;quot; filename&lt;br /&gt;
3DAEH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment          &lt;br /&gt;
3DB1H  LHLD FD1DH           ; Get file size from RX buffer          &lt;br /&gt;
3DB4H  MOV C,H              ; Save file size MSB to C (swap endian)       &lt;br /&gt;
3DB5H  MOV B,L              ; Save file size LSB to B (swap endian)       &lt;br /&gt;
3DB6H  LXI H,7CC0H          ; ? Load HL with 31936&lt;br /&gt;
3DB9H  DSUB                 ; ? Compare file length with 31936    &lt;br /&gt;
3DBAH  LXI H,3F4AH          ; Address of &amp;quot;New name&amp;quot; string&lt;br /&gt;
3DBDH  JNZ 3DD7H            ; Branch to change filename if not 30656         &lt;br /&gt;
3DC0H  LXI B,0009H          ; Allow a 9-byte filename input string&lt;br /&gt;
3DC3H  CALL 3E1DH           ; Get max BC length input for filename and convert to uppercase          &lt;br /&gt;
3DC6H  RZ                   ; Return if no input provided  &lt;br /&gt;
3DC7H  PUSH H               ; Save pointer to input string to stack      &lt;br /&gt;
3DC8H  PUSH PSW             ; Save string length to stack        &lt;br /&gt;
3DC9H  CALL 4A3BH           ; Initialize blank filename and attribute byte          &lt;br /&gt;
3DCCH  POP PSW              ; Get string length from stack       &lt;br /&gt;
3DCDH  POP H                ; Get string address from stack     &lt;br /&gt;
3DCEH  LXI D,FCE8H          ; Point to TX buffer data area (payload)           &lt;br /&gt;
3DD1H  MOV C,A              ; Copy length to BC       &lt;br /&gt;
3DD2H  MVI B,00H            ; Make MSB of length = 0         &lt;br /&gt;
3DD4H  JMP 41B0H            ; Rename the TPDD file whose name is in (HL)         &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get filename from keyboard and rename Disk file, filename in &amp;quot;current BASIC program&amp;quot;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3DD7H  CALL 3E1AH           ; Get 6-byte input filename from keyboard&lt;br /&gt;
3DDAH  RZ                   ; Return if no input provided &lt;br /&gt;
3DDBH  CALL 4902H           ; Copy filename at (HL) to current BASIC program&lt;br /&gt;
3DDEH  JMP 41A7H            ; Rename the TPDD file whose name is in &amp;quot;current BASIC program&amp;quot; &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display &amp;quot;Sure ?&amp;quot;, validate and return if validated&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3DE1H  LXI H,3F83H          ; Load pointer to &amp;quot;Sure ?&amp;quot; string&lt;br /&gt;
3DE4H  CALL 48F4H           ; Print string at HL to col 1 on the bottom line &lt;br /&gt;
3DE7H  CALL 3DEEH           ; Get key and test for &#039;Y&#039; or &#039;y&#039; &lt;br /&gt;
3DEAH  JNZ 48B5H            ; Branch to &amp;quot;Long jump&amp;quot; operation to abort if not &#039;y&#039; &lt;br /&gt;
3DEDH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get key from keyboard and test for &#039;Y&#039; or &#039;y&#039;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3DEEH  CALL 3DF8H           ; Process power-off logic and wait for a key from keyboard&lt;br /&gt;
3DF1H  RST 4                ; Display the key on the LCD &lt;br /&gt;
3DF2H  CPI 59H              ; Test if key pressed was &#039;Y&#039;      &lt;br /&gt;
3DF4H  RZ                   ; Return if key pressed was &#039;Y&#039; &lt;br /&gt;
3DF5H  CPI 79H              ; Test if key pressed was &#039;y&#039;      &lt;br /&gt;
3DF7H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process power-off logic and wait for a key from keyboard&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3DF8H  CALL 3DFEH           ; Process automatic poweroff logic&lt;br /&gt;
3DFBH  JMP 4BEBH            ; Wait for key from keyboard&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process automatic power-off logic during key scan loop&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3DFEH  XRA A                ; Clear A  &lt;br /&gt;
3DFFH  DCR A                ; Set A to 0xFF   &lt;br /&gt;
3E00H  STA F656H            ; Power off exit condition switch  &lt;br /&gt;
3E03H  CALL 4C4AH           ; Check keyboard queue for pending characters&lt;br /&gt;
3E06H  JZ 3DFEH             ; Branch back if no keyboard characters in queue - wait for key&lt;br /&gt;
3E09H  XRA A                ; Clear A  &lt;br /&gt;
3E0AH  STA F656H            ; Power off exit condition switch  &lt;br /&gt;
3E0DH  LXI H,F932H          ; Load address of &amp;quot;Renew Automatic Poweroff Counter Flag&amp;quot;&lt;br /&gt;
3E10H  ORA M                ; Test if auto poweroff counter should be renewed&lt;br /&gt;
3E11H  JZ 4BF7H             ; Renew automatic power-off counter if enabled&lt;br /&gt;
3E14H  CALL 4BF3H           ; Turn off the computer&lt;br /&gt;
3E17H  JMP 3DFEH            ; Branch back to continue processing power off logic&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get max 6-byte input for filename and convert to uppercase&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E1AH  LXI B,0006H          ; Get maximum 6 characters of input&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get max BC length input for filename and convert to uppercase&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E1DH  CALL 3E2FH           ; Get max BC length input string from keyboard&lt;br /&gt;
3E20H  RZ                   ; Return if no input provided &lt;br /&gt;
3E21H  PUSH H               ; Preserve pointer to input string     &lt;br /&gt;
3E22H  PUSH PSW             ; Preserve flags from input       &lt;br /&gt;
3E23H  CALL 4C5EH           ; Get char at M and convert to uppercase&lt;br /&gt;
3E26H  MOV M,A              ; Save uppercase char back to string      &lt;br /&gt;
3E27H  INX H                ; Point to next byte in input     &lt;br /&gt;
3E28H  ANA A                ; Test for NULL - end of string    &lt;br /&gt;
3E29H  JNZ 3E23H            ; Keep looping until end of string        &lt;br /&gt;
3E2CH  POP PSW              ; Restore flags from input routine      &lt;br /&gt;
3E2DH  POP H                ; Restore pointer to input string    &lt;br /&gt;
3E2EH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get maximum BC length input character string from keyboard&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E2FH  PUSH B               ; Save maximum input length to stack     &lt;br /&gt;
3E30H  CALL 48F4H           ; Print string at HL to col 1 on the bottom line&lt;br /&gt;
3E33H  CALL 4C46H           ; Input and display (no &amp;quot;?&amp;quot;) line and store&lt;br /&gt;
3E36H  JC 48B5H             ; Branch to &amp;quot;Long jump&amp;quot; if CTRL-C       &lt;br /&gt;
3E39H  INX H                ; Point to start of input string    &lt;br /&gt;
3E3AH  MOV A,B              ; Get string length (counting NULL)      &lt;br /&gt;
3E3BH  DCR A                ; Remove NULL from count    &lt;br /&gt;
3E3CH  POP D                ; Restore maximum input length    &lt;br /&gt;
3E3DH  RZ                   ; Return if string length is zero &lt;br /&gt;
3E3EH  CMP E                ; Compare expected length with actual length    &lt;br /&gt;
3E3FH  RC                   ; Return if string is shorter than expected          &lt;br /&gt;
3E40H  PUSH H               ; Save pointer to start of string on stack     &lt;br /&gt;
3E41H  DAD D                ; Add Expected length to pointer    &lt;br /&gt;
3E42H  MVI M,00H            ; Truncate the string to the max length        &lt;br /&gt;
3E44H  POP H                ; Restore pointer to input string    &lt;br /&gt;
3E45H  MOV A,E              ; Update length to reflect maximum      &lt;br /&gt;
3E46H  ORA A                ; Clear zero flag to indicate input provided    &lt;br /&gt;
3E47H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Find Empty catalog entry (only 9 instructions...Don&#039;t bother with Main ROM)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E48H  LXI H,F9AFH         ; Point to the &amp;quot;RickY&amp;quot; catalog entry (start of valid entries)&lt;br /&gt;
3E4BH  LXI B,000BH         ; Load length of each catalog entry&lt;br /&gt;
3E4EH  DAD B               ; Point to next catalog entry to test if empty&lt;br /&gt;
3E4FH  MOV A,M             ; Get file attribute byte from catalog entry&lt;br /&gt;
3E50H  CPI FFH             ; Test if at end of catalog&lt;br /&gt;
3E52H  JZ 3E5AH            ; Jump to report directory full if at end&lt;br /&gt;
3E55H  ADD A               ; Test if MSB is set (entry being used)&lt;br /&gt;
3E56H  JC 3E4EH            ; Jump to test next enry if MSB set&lt;br /&gt;
3E59H  RET                 ; Entry found...return with Carry clear&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Empty catalog entry not found...set Carry and exit&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E5AH  STC                 ; Indicate empty entry not found&lt;br /&gt;
3E5BH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F5 Function key handler for RAM mode - DOS ON/OF&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E5CH  LHLD FB2CH          ; Get LFILES statement hook address&lt;br /&gt;
3E5FH  LXI B,08DBH         ; Load address of default (DOS-OFF) hook for LFILES&lt;br /&gt;
3E62H  DSUB                ; Test if in DOS-OFF mode&lt;br /&gt;
3E63H  JZ 401FH            ; Jump to add our custom RST 7 hooks if in DOS-OFF mode&lt;br /&gt;
3E66H  JMP 3FFAH           ; Must be in DOS-ON mode, jump to turn it off&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Strings&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E69H  DB	0x1B, &amp;quot;p TS-DOS (100 v4.00) (c)87,TSI.          &amp;quot;,0x1B,&#039;q&#039;,0x00&lt;br /&gt;
3E97H  DB   &amp;quot;DISK Free:         File:&amp;quot;,0DH,0AH,&amp;quot;Load Kill Name Ram  Frmt Log       Menu&amp;quot;,00H&lt;br /&gt;
3ED9H  DB   &amp;quot; RAM Free:         File:&amp;quot;,0DH,0AH,&amp;quot;Save Kill Name Disk DOS-           Menu&amp;quot;,00H&lt;br /&gt;
3F1BH  DB   &amp;quot;Insert Disk, Press \&amp;quot;Y\&amp;quot; to begin &amp;quot;,00H&lt;br /&gt;
3F3CH  DB   &amp;quot;NOT FORMATTED&amp;quot;,00H&lt;br /&gt;
3F4AH  DB   &amp;quot;New Name:&amp;quot;,00H&lt;br /&gt;
3F54H  DB   &amp;quot;System name:&amp;quot;,00H&lt;br /&gt;
3F61H  DB   &amp;quot;Directory name:&amp;quot;,00H&lt;br /&gt;
3F71H  DB   &amp;quot;Save as:&amp;quot;,00H&lt;br /&gt;
3F7AH  DB   &amp;quot;Load as:&amp;quot;,00H&lt;br /&gt;
3F83H  DB   &amp;quot;Sure ? &amp;quot;,00H&lt;br /&gt;
3F8BH  DB   &amp;quot;File exists, A)ppend R)eplace Q)uit:&amp;quot;,00H&lt;br /&gt;
3FB0H  DB   &amp;quot;File exists, Replace? (Y/N):&amp;quot;,00H&lt;br /&gt;
3FCDH  DB   &amp;quot;-.-       &amp;quot;,00H&lt;br /&gt;
3FD8H  DB   0x1B,&amp;quot;Y74    &amp;quot;,1BH,&amp;quot;Y7&amp;gt;MkDr&amp;quot;,00H     ;  TODO: Check this&lt;br /&gt;
3FE9H  DB   0x1B,&amp;quot;Y7&amp;gt;Bank&amp;quot;,00H                   ;  TODO: Check this&lt;br /&gt;
3FF2H  DB   &amp;quot;OFF&amp;quot;,00H&lt;br /&gt;
3FF6H  DB   &amp;quot;ON &amp;quot;,00H&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Navigate to:&lt;br /&gt;
* [[Dissasembly of RAM and ROM versions of TS-DOS]]&lt;br /&gt;
* [[M100 TS-DOS ROM OptROM Support]]&lt;br /&gt;
* [[M100 TS-DOS ROM RST 7 Handlers]]&lt;br /&gt;
* [[M100 TS-DOS ROM TPDD Protocol]]&lt;br /&gt;
* [[M100 TS-DOS ROM Compression]]&lt;br /&gt;
* [[M100 TS-DOS ROM Cold Boot Recovery]]&lt;/div&gt;</summary>
		<author><name>Kpettit</name></author>
	</entry>
	<entry>
		<id>https://bitchin100.com/wiki/index.php?title=Disassembly_of_RAM_and_ROM_versions_of_TS-DOS&amp;diff=1387</id>
		<title>Disassembly of RAM and ROM versions of TS-DOS</title>
		<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=Disassembly_of_RAM_and_ROM_versions_of_TS-DOS&amp;diff=1387"/>
		<updated>2009-04-03T08:35:37Z</updated>

		<summary type="html">&lt;p&gt;Kpettit: /* Model 200 RAM Version */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== TS-DOS Dissassembly ==&lt;br /&gt;
&lt;br /&gt;
There are various version of TS-DOS for The Model 100/102, for T200 and for the PC-8201a.  Additionally each of these versions has a ROM and a RAM.  While the majority of the code is equivalent across the various incarnations of TS-DOS, there are some differences due to varying RS-232 hardware and to accomodate execution from OptROM vs. RAM.&lt;br /&gt;
&lt;br /&gt;
The goal of the disassembly is to create a fully commented source file that can be assembled and subsequently modified / enhanced for new functionality.  The disassembly is split into several sections to keep each page &amp;quot;relatively&amp;quot; short.  The disassembly currently will not assemble as it contains absolute addresses that must be converted into assembly labels, or deleted where not needed.&lt;br /&gt;
&lt;br /&gt;
== Model 100/102 ROM Version ==&lt;br /&gt;
* [[M100 TS-DOS ROM OptROM Support]]&lt;br /&gt;
* [[M100 TS-DOS ROM UI Code]]&lt;br /&gt;
* [[M100 TS-DOS ROM RST 7 Handlers]]&lt;br /&gt;
* [[M100 TS-DOS ROM TPDD Protocol]]&lt;br /&gt;
&lt;br /&gt;
Not Completed Yet&lt;br /&gt;
* [[M100 TS-DOS ROM Compression]]&lt;br /&gt;
* [[M100 TS-DOS ROM Cold Boot Recovery]]&lt;br /&gt;
&lt;br /&gt;
== Model 200 RAM Version ==&lt;br /&gt;
&lt;br /&gt;
* [[T200 TS-DOS RAM UI Code]]&lt;br /&gt;
* [[T200 TS-DOS RAM RST 7 Handlers]]&lt;br /&gt;
* [[T200 TS-DOS RAM TPDD Protocol]]&lt;/div&gt;</summary>
		<author><name>Kpettit</name></author>
	</entry>
	<entry>
		<id>https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_UI_Code&amp;diff=1386</id>
		<title>M100 TS-DOS ROM UI Code</title>
		<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_UI_Code&amp;diff=1386"/>
		<updated>2009-04-03T08:34:18Z</updated>

		<summary type="html">&lt;p&gt;Kpettit: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== TS-DOS Model 100/102 User Interface Code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; TS-DOS UI Entry location&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
 &lt;br /&gt;
    .org  3535H&lt;br /&gt;
&lt;br /&gt;
3535H  LXI H,FCC0H          ; Start of Alt LCD character buffer&lt;br /&gt;
3538H  MVI B,B4H            ; Prepare to clear 180 bytes from the ALTLCD buffer &lt;br /&gt;
353AH  XRA A                ; Prepare to clear the ALTLCD buffer&lt;br /&gt;
353BH  CALL 4A34H           ; Fill (HL) with B bytes of A        &lt;br /&gt;
353EH  LXI H,0000H          ; Prepare to get current stack pointer&lt;br /&gt;
3541H  DAD SP               ; Copy SP into HL&lt;br /&gt;
3542H  SHLD FCCEH           ; Stack pointer upon entry - pointer to arguments&lt;br /&gt;
3545H  MVI A,01H            ; Set flag to print error message to LCD - GUI mode&lt;br /&gt;
3547H  CALL 4A85H           ; Save the currently selected baud rate settings&lt;br /&gt;
354AH  XRA A                ; Zero A to clear our vars&lt;br /&gt;
354BH  STA FCD4H            ; Current Page of files being displayed&lt;br /&gt;
354EH  STA FCDAH            ; TPDD &amp;quot;skip page&amp;quot; count&lt;br /&gt;
3551H  STA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
3554H  STA FCCAH            ; TPDD2 Bank number&lt;br /&gt;
3557H  INR A                ; A = 1 to select 1st file on page&lt;br /&gt;
3558H  STA FCCDH            ; Currently selected file index&lt;br /&gt;
355BH  LXI H,3564H          ; Get pointer to main loop routine&lt;br /&gt;
355EH  SHLD FCD0H           ; Return vector after error&lt;br /&gt;
3561H  CALL 4C27H           ; CLS statement&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; UI Main loop&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3564H  CALL 4C5AH           ; Resume automatic scrolling&lt;br /&gt;
3567H  CALL 3611H           ; Print Copyright and files&lt;br /&gt;
356AH  LDA FCD5H            ; Load currently selected index from temp storage&lt;br /&gt;
356DH  STA FCCDH            ; Currently selected file index&lt;br /&gt;
3570H  CALL 362FH           ; Print length of selected file using inverse video&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Code will return here when a funtion key is pressed (except F4 &amp;amp; F6)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3573H  LXI H,48B5H          ; Get address of &amp;quot;Long jump&amp;quot;&lt;br /&gt;
3576H  PUSH H               ; Push &amp;quot;Long jump&amp;quot; address to stack&lt;br /&gt;
3577H  PUSH PSW             ; Save function key press to stack&lt;br /&gt;
3578H  CPI 02H              ; Test if function key is F5-F8 (Non file operation F Keys)&lt;br /&gt;
357AH  JNC 35B9H            ; Jump to Function key handler if F5-F8 (No tagging to process)&lt;br /&gt;
357DH  LDA FCCCH            ; Last Tag/Untag operation code&lt;br /&gt;
3580H  ANA A                ; Test if a tag operation was performed&lt;br /&gt;
3581H  JZ 35B9H             ; Jump to Function key handler if no tag operation performed&lt;br /&gt;
3584H  LDA FCD6H            ; Count of files on screen&lt;br /&gt;
3587H  MOV C,A              ; Save count of files for loop decrementing &lt;br /&gt;
3588H  INR C                ; Increment by 1 for loop bounding&lt;br /&gt;
3589H  MVI B,00H            ; Start with index zero on the LCD&lt;br /&gt;
358BH  PUSH B               ; Save the current index on the stack&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display next file&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
358CH  LDA FCCDH            ; Currently selected file index&lt;br /&gt;
358FH  STA FCD5H            ; Currently selected file index - temp&lt;br /&gt;
3592H  CALL 3AC4H           ; Print selected file using normal video&lt;br /&gt;
3595H  POP B                ; Restore index from stack&lt;br /&gt;
3596H  INR B                ; Increment to the next file index to display&lt;br /&gt;
3597H  DCR C                ; Decrement the loop control&lt;br /&gt;
3598H  JZ 48B5H             ; Branch to perform &amp;quot;Long Jump&amp;quot; if all files printed to LCD&lt;br /&gt;
359BH  MOV A,B              ; Get the index of the current file&lt;br /&gt;
359CH  STA FCD5H            ; Save in temporary &amp;quot;current file&amp;quot; area&lt;br /&gt;
359FH  STA FCCDH            ; Currently selected file index&lt;br /&gt;
35A2H  PUSH B               ; Push the value on the stack for the next iteration&lt;br /&gt;
35A3H  CALL 3AB2H           ; Print currently selected file using inverse video&lt;br /&gt;
35A6H  LHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
35A9H  DCX H                ; Decrement to the Tag area for the file&lt;br /&gt;
35AAH  MOV A,M              ; Get the file&#039;s Tag code&lt;br /&gt;
35ABH  CPI 3EH              ; Compare with &#039;&amp;gt;&#039;&lt;br /&gt;
35ADH  JNZ 358CH            ; Jump to process next file if not tagged&lt;br /&gt;
35B0H  POP B                ; Pop currently selected file value from stack&lt;br /&gt;
35B1H  POP PSW    &lt;br /&gt;
35B2H  LXI H,358CH          ; Return address to display the next file&lt;br /&gt;
35B5H  PUSH PSW             ; ? Stack trickery&lt;br /&gt;
35B6H  PUSH B               ; Save current file index to stack for use after a RET operation&lt;br /&gt;
35B7H  PUSH H               ; Setup &amp;quot;Display next file&amp;quot; as a return address for RET&lt;br /&gt;
35B8H  PUSH PSW             ; ? More stack trickery&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Function key handler - Disk mode and dispatch to RAM mode&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
35B9H  CALL 4C56H           ; Stop automatic scrolling&lt;br /&gt;
35BCH  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
35BFH  ORA A     &lt;br /&gt;
35C0H  JZ 35E2H             ; Branch if in RAM mode&lt;br /&gt;
35C3H  POP PSW   &lt;br /&gt;
35C4H  ANA A                ; Test for F1&lt;br /&gt;
35C5H  JZ 3B2EH             ; Branch to F1 handler for disk&lt;br /&gt;
35C8H  DCR A                ; Test for F2&lt;br /&gt;
35C9H  JZ 3D73H  &lt;br /&gt;
35CCH  DCR A                ; Test for F3&lt;br /&gt;
35CDH  JZ 3D9FH  &lt;br /&gt;
35D0H  DCR A                ; Skip F4 - handled at lower level&lt;br /&gt;
35D1H  DCR A                ; Test for F5&lt;br /&gt;
35D2H  JZ 3D53H  &lt;br /&gt;
35D5H  DCR A                ; Skip F6 - handled at lower level&lt;br /&gt;
35D6H  DCR A                ; Test for F7&lt;br /&gt;
35D7H  JZ 3D00H  &lt;br /&gt;
35DAH  DCR A                ; Test for F8&lt;br /&gt;
35DBH  POP H     &lt;br /&gt;
35DCH  JZ 35FEH             ; Jump to exit if F8&lt;br /&gt;
35DFH  JMP 3564H            ; Jump to main loop&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Function key handler - RAM mode&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
35E2H  POP PSW  &lt;br /&gt;
35E3H  ANA A                ; Test for F1 &lt;br /&gt;
35E4H  JZ 3C4BH &lt;br /&gt;
35E7H  DCR A                ; Test for F2&lt;br /&gt;
35E8H  JZ 3C2BH &lt;br /&gt;
35EBH  DCR A                ; Test for F3&lt;br /&gt;
35ECH  JZ 3AF8H &lt;br /&gt;
35EFH  DCR A                ; Skip F4 - handled at lower level&lt;br /&gt;
35F0H  DCR A                ; Test for F5&lt;br /&gt;
35F1H  JZ 3E5CH &lt;br /&gt;
35F4H  DCR A                ; Skip F6 - handled at lower level&lt;br /&gt;
35F5H  DCR A                ; Skip F7 - not defined for RAM&lt;br /&gt;
35F6H  DCR A                ; Test for F8&lt;br /&gt;
35F7H  POP H    &lt;br /&gt;
35F8H  JZ 35FEH             ; Jump to exit if F8&lt;br /&gt;
35FBH  JMP 3564H            ; Jump back to main loop&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; This is the UI exit routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
35FEH  CALL 4AC4H           ; Restore original baud settings&lt;br /&gt;
3601H  CALL 4BD7H           ; Wait for TX empty and Reset UART to accept mode bits&lt;br /&gt;
3604H  CALL 4C27H           ; CLS statement&lt;br /&gt;
3607H  CALL 4C5AH           ; Resume automatic scrolling&lt;br /&gt;
360AH  LXI H,0000H&lt;br /&gt;
360DH  PUSH H&lt;br /&gt;
360EH  JMP 00A6H            ; Exit TS-DOS&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print Copyright string and files&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3611H  LXI H,0101H          ; Goto top left corner&lt;br /&gt;
3614H  SHLD F639H           ; Cursor row (1-8)&lt;br /&gt;
3617H  LXI H,3E69H          ; Point to &amp;quot;TS-DOS&amp;quot; copyright string&lt;br /&gt;
361AH  CALL 4A2CH           ; Send buffer at M to screen&lt;br /&gt;
361DH  XRA A                ; Indicate no previous Tag/Untag operation&lt;br /&gt;
361EH  STA FCCCH            ; Last Tag/Untag operation code&lt;br /&gt;
3621H  MVI A,01H            ; Start with 1st file in list&lt;br /&gt;
3623H  STA FCD5H            ; Currently selected file index - temp&lt;br /&gt;
3626H  LXI H,0202H          ; Goto first file entry location&lt;br /&gt;
3629H  SHLD F639H           ; Cursor row (1-8)&lt;br /&gt;
362CH  JMP 383BH            ; Draw the display&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print length of selected file using inverse video&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
362FH  LDA FCCDH            ; Currently selected file index      &lt;br /&gt;
3632H  STA FCD5H            ; Currently selected file index - temp      &lt;br /&gt;
3635H  CALL 3AB2H           ; Print currently seleted file using inverse video       &lt;br /&gt;
3638H  LDA FCD5H            ; Currently selected file index - temp      &lt;br /&gt;
363BH  DCR A                ; Make index zero based for multiply x2  &lt;br /&gt;
363CH  STC                  ; Set Carry flag&lt;br /&gt;
363DH  CMC                  ; Compliment (clear) carry flag&lt;br /&gt;
363EH  RLC                  ; Rotate left circular &lt;br /&gt;
363FH  MOV E,A              ; E = File index * 2 to point to file length value    &lt;br /&gt;
3640H  MVI D,00H            ; Clear MSB of file length offset      &lt;br /&gt;
3642H  LXI H,F685H          ; Keyboard buffer - store file lengths        &lt;br /&gt;
3645H  DAD D                ; Add file lenght offset from beginning of keyboard buffer  &lt;br /&gt;
3646H  XCHG                 ; HL &amp;lt;--&amp;gt; DE Save file length address pointer in DE &lt;br /&gt;
3647H  LXI H,2307H          ; Load position of File Size area on LCD&lt;br /&gt;
364AH  SHLD F639H           ; Cursor row (1-8) &lt;br /&gt;
364DH  CALL 4C2BH           ; Erase from cursor to end of line&lt;br /&gt;
3650H  LHLX                 ; Load HL with file length &lt;br /&gt;
3651H  CALL 4C2FH           ; Start inverse character mode       &lt;br /&gt;
3654H  CALL 4C3EH           ; Print binary number in HL at current position       &lt;br /&gt;
3657H  CALL 4C33H           ; Cancel inverse character mode         &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Keyboard scan loop&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
365AH  CALL 3DFEH           ; Process automatic power off logic&lt;br /&gt;
365DH  CALL 4BEFH           ; Scan keyboard for character (CTRL-BREAK ==&amp;gt; CTRL-C)&lt;br /&gt;
3660H  JZ 365AH             ; Jump to scan keyboard again if no key pressed &lt;br /&gt;
3663H  JC 380CH             ; Jump to Function Key Handler if FKey &lt;br /&gt;
3666H  CPI 0DH              ; Test for CR&lt;br /&gt;
3668H  JZ 3722H   &lt;br /&gt;
366BH  CPI 17H              ; Test for Ctrl-Up key&lt;br /&gt;
366DH  JZ 37AAH   &lt;br /&gt;
3670H  CPI 14H              ; Test for Shift-Up key&lt;br /&gt;
3672H  JZ 3798H   &lt;br /&gt;
3675H  CPI 5DH              ; Test for &amp;quot;]&amp;quot; key&lt;br /&gt;
3677H  JZ 3798H   &lt;br /&gt;
367AH  CPI 3FH              ; Test for &amp;quot;?&amp;quot; key&lt;br /&gt;
367CH  JZ 3777H   &lt;br /&gt;
367FH  CPI 02H              ; Test for Shift-Down arrow key&lt;br /&gt;
3681H  JZ 3777H   &lt;br /&gt;
3684H  CPI 1EH              ; Test for up key&lt;br /&gt;
3686H  JZ 36EEH   &lt;br /&gt;
3689H  CPI 1FH              ; Test for down key&lt;br /&gt;
368BH  JZ 36FCH   &lt;br /&gt;
368EH  CPI 1DH              ; Test for &amp;quot;left arrow&amp;quot; key&lt;br /&gt;
3690H  JZ 36DDH   &lt;br /&gt;
3693H  CPI 1CH              ; Test for &amp;quot;Right arrow&amp;quot; key&lt;br /&gt;
3695H  JZ 36CAH   &lt;br /&gt;
3698H  CPI 20H              ; Test for space key &lt;br /&gt;
369AH  JZ 36CAH             ; Treat space the same as right arrow  &lt;br /&gt;
369DH  ANI DFH              ; Convert to Upper case &lt;br /&gt;
369FH  CPI 52H              ; Test for &#039;R&#039; character  &lt;br /&gt;
36A1H  JZ 3759H   &lt;br /&gt;
36A4H  CPI 54H              ; Test for &#039;T&#039; character &lt;br /&gt;
36A6H  JZ 37EEH   &lt;br /&gt;
36A9H  CPI 41H              ; Test for &amp;quot;A&amp;quot; key &lt;br /&gt;
36ABH  JZ 3715H   &lt;br /&gt;
36AEH  CPI 47H              ; Test for &amp;quot;G&amp;quot; key &lt;br /&gt;
36B0H  JZ 3715H   &lt;br /&gt;
36B3H  CPI 55H              ; Test for &amp;quot;U&amp;quot; key &lt;br /&gt;
36B5H  JZ 37AEH   &lt;br /&gt;
36B8H  CPI 44H              ; Test for &amp;quot;D&amp;quot; key &lt;br /&gt;
36BAH  JZ 39B9H   &lt;br /&gt;
36BDH  CPI 4CH              ; Test for &amp;quot;L&amp;quot; key &lt;br /&gt;
36BFH  JZ 39C2H   &lt;br /&gt;
36C2H  CPI 50H              ; Test for &amp;quot;P&amp;quot; key &lt;br /&gt;
36C4H  JZ 39C2H   &lt;br /&gt;
36C7H  JMP 365AH            ; Go scan keyboard again   &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Right Arrow key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
36CAH  MVI A,01H            ; Prepare to add 1 to selected file    &lt;br /&gt;
36CCH  LXI H,FCD5H          ; Currently selected file index - temp storage&lt;br /&gt;
36CFH  ADD M                ; Add 1 to the selected file index&lt;br /&gt;
36D0H  INX H                ; Point to file count on screen&lt;br /&gt;
36D1H  CMP M                ; Compare new index with screen file count&lt;br /&gt;
36D2H  JC 370AH             ; Jump to process new file if we didn&#039;t wrap   &lt;br /&gt;
36D5H  JZ 370AH             ; Jump to process new file if = file count   &lt;br /&gt;
36D8H  MVI A,01H            ; Wrap to the first file    &lt;br /&gt;
36DAH  JMP 370AH            ; Go process file 1 as the new selection    &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Left Arrow key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
36DDH  LDA FCD5H            ; Currently selected file index - temp storage&lt;br /&gt;
36E0H  DCR A                ; Move to next lowest file index&lt;br /&gt;
36E1H  JNZ 370AH            ; If no wrap, jump to process new selection&lt;br /&gt;
36E4H  LDA FCD6H            ; Count of files on screen&lt;br /&gt;
36E7H  ANA A                ; Ensure there is at least 1 file on the screen &lt;br /&gt;
36E8H  JZ 365AH             ; Jump to keyboard scan loop if no files on LCD&lt;br /&gt;
36EBH  JMP 370AH            ; Go process new selection as the max (wrap-around)&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Up Arrow key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
36EEH  LDA FCD5H            ; Currently selected file index - temp storage&lt;br /&gt;
36F1H  SUI 04H              ; Subtract 4 from file count (4 files per line)&lt;br /&gt;
36F3H  JC 365AH             ; Jump to keysacn loop if negative&lt;br /&gt;
36F6H  JZ 365AH             ; Jump to keysacn loop if zero&lt;br /&gt;
36F9H  JMP 370AH            ; Go process the new file index setting&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Down Arrow key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
36FCH  MVI A,04H            ; There are 4 files per line &lt;br /&gt;
36FEH  LXI H,FCD5H          ; Currently selected file index - temp storage&lt;br /&gt;
3701H  ADD M                ; Add 4 to the index number&lt;br /&gt;
3702H  MOV C,A              ; Save new index for comparison and further processing  &lt;br /&gt;
3703H  INX H                ; Maximum file index count&lt;br /&gt;
3704H  MOV A,M              ; Load maximum index for bounds  &lt;br /&gt;
3705H  CMP C                ; Compare new index with maximum&lt;br /&gt;
3706H  JC 365AH             ; Jump to keyboard scan if moving past last file   &lt;br /&gt;
3709H  MOV A,C              ; Restore new current file index  &lt;br /&gt;
370AH  PUSH PSW             ; Save new file index for storage after the call   &lt;br /&gt;
370BH  CALL 3AC4H           ; Print selected file using normal video     &lt;br /&gt;
370EH  POP PSW              ; Restore new file index from stack  &lt;br /&gt;
370FH  STA FCCDH            ; Save the new file index    &lt;br /&gt;
3712H  JMP 362FH            ; Print length of selected file using inverse video.    &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;A&amp;quot; or &amp;quot;G&amp;quot; key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3715H  MVI A,3EH            ; Load &amp;quot;&amp;gt;&amp;quot; for the tag symbol&lt;br /&gt;
3717H  CALL 37CAH           ; Go tag all files on the LCD&lt;br /&gt;
371AH  MVI A,01H            ; Indicate last operation as &amp;quot;Tag All&amp;quot;&lt;br /&gt;
371CH  STA FCCCH            ; Last Tag/Untag operation code&lt;br /&gt;
371FH  JMP 362FH            ; Print length of selected file using inverse video.&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Enter key from TS-DOS key scan - Change Directory&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3722H  LDA FCCBH            ; Get NADSBox/Desklink/TPDD2 flag     &lt;br /&gt;
3725H  CPI 02H              ; Test if NADSBox current directory valid   &lt;br /&gt;
3727H  JNZ 365AH            ; Back to keyscan if no &amp;quot;current directory&amp;quot; - Enter is meaningless     &lt;br /&gt;
372AH  LHLD FCE4H           ; LCD Buffer address of current file selection      &lt;br /&gt;
372DH  LXI B,0007H          ; Load offset of file extension       &lt;br /&gt;
3730H  DAD B                ; Point to file extension of selected file &lt;br /&gt;
3731H  MOV A,M              ; Load the 1st byte of the file extension   &lt;br /&gt;
3732H  CPI 3CH              ; Test if 1st byte of extension is &amp;quot;&amp;lt;&amp;quot;   &lt;br /&gt;
3734H  JNZ 365AH            ; Jump to keyscan if current selection not directory entry     &lt;br /&gt;
3737H  CALL 4A3BH           ; Initialize blank filename and attribute byte      &lt;br /&gt;
373AH  LHLD FCE4H           ; LCD Buffer address of current file selection      &lt;br /&gt;
373DH  CALL 3D95H           ; Copy filename at (HL) to TX buffer      &lt;br /&gt;
3740H  CALL 408AH           ; Open TPDD file for Read Mode      &lt;br /&gt;
3743H  LXI H,0002H          ; Load opcode to close currently opened file       &lt;br /&gt;
3746H  CALL 409BH           ; Send Request in HL and await response      &lt;br /&gt;
3749H  LHLD FCE4H           ; LCD Buffer address of current file selection      &lt;br /&gt;
374CH  LXI D,FCC0H          ; NADSBox current directory storage    &lt;br /&gt;
374FH  LXI B,0009H          ; Copy 9 bytes of NADSBox directory to the LCD       &lt;br /&gt;
3752H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
3755H  XRA A                ; Clear A to show 1st page of files &lt;br /&gt;
3756H  JMP 378AH            ; Branch to show the page of files in A     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;R&amp;quot; key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3759H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
375CH  ANA A                ; Test if in Disk mode&lt;br /&gt;
375DH  JNZ 362FH            ; Jump to keyscan if in Disk mode&lt;br /&gt;
3760H  LHLD FCE4H           ; LCD Buffer address of current file selection       &lt;br /&gt;
3763H  CALL 4902H           ; Copy filename at (HL) to current BASIC program&lt;br /&gt;
3766H  CALL 4A51H           ; Get RAM directory address of current BASIC program          &lt;br /&gt;
3769H  CPI C0H              ; Test if filetype is .DO&lt;br /&gt;
376BH  CZ 5000H             ; Call routine to Compress / Decompress .DO files&lt;br /&gt;
376EH  CALL 4C0FH           ; Update system pointers       &lt;br /&gt;
3771H  CALL 3611H           ; Print Copyright and files&lt;br /&gt;
3774H  JMP 362FH            ; Jump to keyscan &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;?&amp;quot; and Shift-Down key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3777H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
377AH  ANA A                ; Test if RAM mode &lt;br /&gt;
377BH  JZ 365AH             ; Branch to keyscan if in RAM mode    &lt;br /&gt;
377EH  LDA FCD6H            ; Count of files on screen     &lt;br /&gt;
3781H  CPI 14H              ; Maximum number of files that fit on the screen   &lt;br /&gt;
3783H  JC 365AH             ; Branch to keyscan if on last page    &lt;br /&gt;
3786H  LDA FCD4H            ; Current Page of files being displayed     &lt;br /&gt;
3789H  INR A                ; Increment to next page of files &lt;br /&gt;
				 &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Show the page of files indicated by A&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
378AH  STA FCD4H            ; Current Page of files being displayed     &lt;br /&gt;
378DH  MVI A,01H            ; Go to 1st file on the new page     &lt;br /&gt;
378FH  STA FCCDH            ; Currently selected file index     &lt;br /&gt;
3792H  CALL 3611H           ; Print copyright and files      &lt;br /&gt;
3795H  JMP 362FH            ; Print length of selected file using inverse video     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;]&amp;quot; and Shift-Up key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3798H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
379BH  ANA A                ; Test if RAM mode &lt;br /&gt;
379CH  JZ 365AH             ; Branch to keyscan if in RAM mode    &lt;br /&gt;
379FH  LDA FCD4H            ; Current Page of files being displayed     &lt;br /&gt;
37A2H  ANA A                ; Test if current page is zero &lt;br /&gt;
37A3H  JZ 365AH             ; Branch to keyscan if already on page 0    &lt;br /&gt;
37A6H  DCR A                ; Decrement the page number &lt;br /&gt;
37A7H  JMP 378AH            ; Show the page of files indicated by A&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Ctrl-Up key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
37AAH  XRA A                ; Go to page zero&lt;br /&gt;
37ABH  JMP 378AH            ; Show the page of files indicated by A&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;U&amp;quot; key from TS-DOS key scan - Remove all tags&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
37AEH  MVI A,20H            ; Display &#039; &#039; as the tag marker&lt;br /&gt;
37B0H  CALL 37CAH           ; Go process tag for all files&lt;br /&gt;
37B3H  XRA A                ; Indicate last tag operation was untag&lt;br /&gt;
37B4H  STA FCCCH            ; Store as &amp;quot;last tag&amp;quot; operation&lt;br /&gt;
37B7H  JMP 362FH            ; Print length of selected file using inverse video&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Swap TPDD2 Bank number&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
37BAH  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag&lt;br /&gt;
37BDH  DCR A                ; Test if the flag = 1 (TPDD2)&lt;br /&gt;
37BEH  JNZ 365AH            ; Jump to keyscan if not 1&lt;br /&gt;
37C1H  LDA FCCAH            ; Get TPDD Bank Number&lt;br /&gt;
37C4H  XRI 01H              ; Switch to the other bank&lt;br /&gt;
37C6H  STA FCCAH            ; Save TPDD bank number&lt;br /&gt;
37C9H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process Tag or Untag for all files on screen&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
37CAH  STA FCCCH            ; Store tag/untag code for later      &lt;br /&gt;
37CDH  LDA FCD6H            ; Get Maximum file count on screen      &lt;br /&gt;
37D0H  ANA A                ; Test for zero  &lt;br /&gt;
37D1H  RZ                   ; Return if no files on screen&lt;br /&gt;
37D2H  XRA A                ; Clear A  &lt;br /&gt;
37D3H  INR A                ; A=1 to selet 1st file  &lt;br /&gt;
37D4H  STA FCD5H            ; Currently selected file index      &lt;br /&gt;
37D7H  CALL 3ACDH           ; Calculate Row and Column of soon-to-be (newly) selected file       &lt;br /&gt;
37DAH  LHLD FCE4H           ; LCD Buffer address of current file selection       &lt;br /&gt;
37DDH  DCX H                ; Point to Tag location for the file  &lt;br /&gt;
37DEH  LDA FCCCH            ; Get the tag/untag code      &lt;br /&gt;
37E1H  RST 4                ; Display A to the LCD    &lt;br /&gt;
37E2H  LDA FCD5H            ; Get currently selected file index      &lt;br /&gt;
37E5H  LXI H,FCD6H          ; Point to count of files on screen        &lt;br /&gt;
37E8H  CMP M                ; Compare current selection with count of files on LCD  &lt;br /&gt;
37E9H  JC 37D3H             ; Jump to process next file if more files left     &lt;br /&gt;
37ECH  ANA A                ; Set zero flag to indicate files were tagged/untagged  &lt;br /&gt;
37EDH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;T&amp;quot; key key from TS-DOS key scan - TAG&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
37EEH  CALL 3ACDH           ; Calculate Row and Column of soon-to-be (newly) selected file    &lt;br /&gt;
37F1H  CALL 4C2FH           ; Start inverse character mode    &lt;br /&gt;
37F4H  LHLD FCE4H           ; LCD Buffer address of current file selection    &lt;br /&gt;
37F7H  DCX H                ; Point to the &amp;quot;Tag&amp;quot; area for the file&lt;br /&gt;
37F8H  MVI A,3EH            ; Load the code for &amp;quot;&amp;gt;&amp;quot;   &lt;br /&gt;
37FAH  CMP M                ; Compare if file is already tagged     &lt;br /&gt;
37FBH  JNZ 3800H            ; Skip ahead if already tagged   &lt;br /&gt;
37FEH  MVI A,20H            ; Need to untag - load the untag code   &lt;br /&gt;
3800H  RST 4                ; Display the tag code on the LCD   &lt;br /&gt;
3801H  CALL 4C33H           ; Cancel inverse character mode    &lt;br /&gt;
3804H  LXI H,FCCCH          ; Point to &amp;quot;last tag&amp;quot; operation code     &lt;br /&gt;
3807H  MVI M,01H            ; Indicate last operation was &amp;quot;tag&amp;quot;   &lt;br /&gt;
3809H  JMP 36CAH            ; Move to next file - jump to Right Arrow key handler   &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; 1st level Function Key Handler (handles F4 and F6)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
380CH  CPI 08H              ; Test for valid function key code     &lt;br /&gt;
380EH  JNC 365AH            ; Branch back to scan loop if invalid       &lt;br /&gt;
3811H  CPI 05H              ; Test for F6     &lt;br /&gt;
3813H  JZ 3833H             ; Jump if F6 pressed      &lt;br /&gt;
3816H  CPI 03H              ; Test for F4     &lt;br /&gt;
3818H  RNZ                  ; Return to &amp;quot;Main Loop&amp;quot; if not F4 pressed &lt;br /&gt;
3819H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)       &lt;br /&gt;
381CH  XRI 01H              ; Swap RAM/DISK mode     &lt;br /&gt;
381EH  STA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)       &lt;br /&gt;
3821H  XRA A                ; Clear A to go to 1st page of files   &lt;br /&gt;
3822H  STA FCD4H            ; Current Page of files being displayed       &lt;br /&gt;
3825H  MVI A,01H            ; Select the 1st file in the page       &lt;br /&gt;
3827H  STA FCCDH            ; Currently selected file index       &lt;br /&gt;
382AH  CALL 4C27H           ; CLS statement     &lt;br /&gt;
382DH  CALL 3611H           ; Print the title bar and files        &lt;br /&gt;
3830H  JMP 362FH            ; Print length of selected file using inverse video.       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F6 Function Key Handler&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3833H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
3836H  ANA A                ; Test if in RAM or DISK mode&lt;br /&gt;
3837H  RZ                   ; Return if RAM mode&lt;br /&gt;
3838H  JMP 37AAH            ; Jump to Ctrl-Up key handler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Draw the display.  This takes care of RAM and Disk mode displays, handles&lt;br /&gt;
;    skipping page number to the proper &amp;quot;Disk&amp;quot; page, displaying the Bank# or&lt;br /&gt;
;    current directory for NADSBox/Desklink, showing free space, filling in&lt;br /&gt;
;    empty slots with &amp;quot;-.-&amp;quot;, etc.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
383BH  LXI H,F685H          ; Keyboard buffer  &lt;br /&gt;
383EH  SHLD FCDBH           ; Initialize pointer to file length table (in keyboard buffer)     &lt;br /&gt;
3841H  XRA A                ; Prepare to set 1st file lenght to zero&lt;br /&gt;
3842H  MOV M,A              ; Set LSB of length of 1st file to zero  &lt;br /&gt;
3843H  INX H                ; Increment to MSB of length&lt;br /&gt;
3844H  MOV M,A              ; Set MSB of length of file to zero  &lt;br /&gt;
3845H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)    &lt;br /&gt;
3848H  ANA A                ; Test if RAM or DISK&lt;br /&gt;
3849H  JZ 395DH             ; Jump to show RAM files if in RAM mode   &lt;br /&gt;
384CH  XRA A                ; Prepare to initialize the &amp;quot;page being processed&amp;quot; variable&lt;br /&gt;
384DH  STA FCDAH            ; Clear the &amp;quot;page being processed&amp;quot; variable    &lt;br /&gt;
3850H  CALL 4735H           ; Clear #files displayed, init TPDD and send 1st file dir referene opcode     &lt;br /&gt;
3853H  JNZ 390FH            ; Process unformated disk (empty slots and error message)    &lt;br /&gt;
3856H  LDA FCD4H            ; Current Page of files being displayed    &lt;br /&gt;
3859H  ANA A                ; Test if displaying page 0&lt;br /&gt;
385AH  JZ 3871H             ; Jump if showing page 0 - don&#039;t need to skikp any pages   &lt;br /&gt;
385DH  STA FCDAH            ; Initialize the number of pages left to skip count    &lt;br /&gt;
3860H  CALL 4742H           ; Read next page of files from server     &lt;br /&gt;
3863H  LDA FCDAH            ; Get the &amp;quot;Pages left to skip&amp;quot; count    &lt;br /&gt;
3866H  DCR A                ; Decrement the remaining skip page count &lt;br /&gt;
3867H  JNZ 385DH            ; Keep reading pages until we have skipped enough pages     &lt;br /&gt;
386AH  XRA A                ; Prepare to clear the remaining skip page count &lt;br /&gt;
386BH  STA FCDAH            ; Clear the remaining skip page count     &lt;br /&gt;
386EH  STA FCD6H            ; Count of files on screen     &lt;br /&gt;
3871H  CALL 4742H           ; Read next page of files from server      &lt;br /&gt;
3874H  LDA FCD6H            ; Count of files on screen     &lt;br /&gt;
3877H  CPI 14H              ; Test if all file slots are full   &lt;br /&gt;
3879H  CC 39AAH             ; Print &amp;quot;-.-&amp;quot; for all empty file slots (if any)    &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print NADSBox directory or TPDD Bank number to LCD&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
387CH  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag    &lt;br /&gt;
387FH  ANA A                ; Test if server is TPDD&lt;br /&gt;
3880H  JZ 389FH             ; Skip processing Bank # or Current Dir if TPDD   &lt;br /&gt;
3883H  DCR A                ; Test if server is TPDD2&lt;br /&gt;
3884H  JZ 388DH             ; Jump to print bank number if TPDD2   &lt;br /&gt;
3887H  LXI H,FCC0H          ; Load pointer to NADSBox current directory storage    &lt;br /&gt;
388AH  JMP 38A5H            ; Jump to print the NADSBox / Desklink directory    &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print the TPDD Bank number to LCD&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
388DH  LXI H,2401H          ; Go to Row 1, column 24&lt;br /&gt;
3890H  SHLD F639H           ; Cursor row (1-8) &lt;br /&gt;
3893H  CALL 4C2FH           ; Start inverse character mode &lt;br /&gt;
3896H  MVI A,23H            ; ASCII code for &#039;#&#039; &lt;br /&gt;
3898H  RST 4                ; Send character in A to the LCD&lt;br /&gt;
3899H  LDA FCCAH            ; Load TPDD Bank number &lt;br /&gt;
389CH  ADI 30H              ; Convert to ASCII digit   &lt;br /&gt;
389EH  RST 4                ; Send it to the LCD  &lt;br /&gt;
389FH  CALL 4C33H           ; Cancel inverse character mode&lt;br /&gt;
38A2H  JMP 38B8H            ; Branch to print the function menu, RAM/Disk free, etc.&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print the NADSBox / Desklink current directory in title bar&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
38A5H  PUSH H               ; Save address of the directory string     &lt;br /&gt;
38A6H  LXI H,2101H          ; Prepare to position the cursor in the title bar          &lt;br /&gt;
38A9H  SHLD F639H           ; Cursor row (1-8)         &lt;br /&gt;
38ACH  CALL 4C2FH           ; Start inverse character mode         &lt;br /&gt;
38AFH  POP H                ; Retrieve the directory string from the stack    &lt;br /&gt;
38B0H  MVI C,06H            ; Prepare to redraw 6 chars with inverse video        &lt;br /&gt;
38B2H  CALL 48E5H           ; Redraw C characters from buffer at HL using current video mode         &lt;br /&gt;
38B5H  CALL 4C33H           ; Cancel inverse character mode         &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print funtion menu, RAM/Disk free &amp;amp; selected file length&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
38B8H  LXI H,3E97H          ; Point to Disk function menu          &lt;br /&gt;
38BBH  LXI B,3936H          ; Routine to print free disk space          &lt;br /&gt;
38BEH  LDA FCD9H            ; RAM/Disk mode        &lt;br /&gt;
38C1H  ANA A                ; Test if in Disk mode and skip ahead to print Disk FKeys    &lt;br /&gt;
38C2H  JNZ 38CBH            ; Skip ahead if in disk mode to keep vectors        &lt;br /&gt;
38C5H  LXI H,3ED9H          ; Point to RAM function menu          &lt;br /&gt;
38C8H  LXI B,3922H          ; Routine to print free RAM space          &lt;br /&gt;
38CBH  PUSH B               ; Save routine address to stack     &lt;br /&gt;
38CCH  PUSH H               ; Save pointer to function text to stack     &lt;br /&gt;
38CDH  LDA FCCDH            ; Currently selected file index        &lt;br /&gt;
38D0H  LXI H,FCD6H          ; Count of files on screen          &lt;br /&gt;
38D3H  CMP M                ; Compare selected file with count of files on screen    &lt;br /&gt;
38D4H  JC 38DDH             ; Branch if within bounds       &lt;br /&gt;
38D7H  MOV A,M              ; Get the file count      &lt;br /&gt;
38D8H  ANA A                ; Test if #files = 0    &lt;br /&gt;
38D9H  JNZ 38DDH            ; Skip ahead if not zero        &lt;br /&gt;
38DCH  INR A                ; Don&#039;t allow a count of zero - must be 1    &lt;br /&gt;
38DDH  STA FCD5H            ; Currently selected file index - temp       &lt;br /&gt;
38E0H  LXI H,0B07H          ; Row &amp;amp; column of start of text          &lt;br /&gt;
38E3H  SHLD F639H           ; Cursor row (1-8)          &lt;br /&gt;
38E6H  POP H                ; Get address of text from the stack and display it   &lt;br /&gt;
38E7H  CALL 4A2CH           ; Send buffer at M to screen        &lt;br /&gt;
38EAH  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)       &lt;br /&gt;
38EDH  ANA A                ; Test if in RAM mode   &lt;br /&gt;
38EEH  JZ 3905H             ; Jump if in RAM mode (0 = RAM)       &lt;br /&gt;
38F1H  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag   &lt;br /&gt;
38F4H  ANA A                ; Test if server is TPDD      &lt;br /&gt;
38F5H  JZ 3905H             ; Skip printing of &amp;quot;Bank&amp;quot; or &amp;quot;Mkdr&amp;quot; if TPDD       &lt;br /&gt;
38F8H  LXI H,3FE9H          ; Point to text for &amp;quot;Bank&amp;quot;     &lt;br /&gt;
38FBH  DCR A                ; Test if server is TPDD2      &lt;br /&gt;
38FCH  JZ 3902H             ; Jump to print &amp;quot;Bank&amp;quot; if TPDD2         &lt;br /&gt;
38FFH  LXI H,3FD8H          ; Point to text for &amp;quot;Mkdr&amp;quot;        &lt;br /&gt;
3902H  CALL 4A2CH           ; Send buffer at M to screen                  &lt;br /&gt;
3905H  CALL 3940H           ; Display DISK ON/OFF status on LCD         &lt;br /&gt;
3908H  LXI H,1507H          ; Point to location for &amp;quot;Free&amp;quot; space (RAM or DISK)&lt;br /&gt;
390BH  SHLD F639H           ; Cursor row (1-8)          &lt;br /&gt;
390EH  RET                  &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle unformatted disks.  Print message and show empty slots.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
390FH  XRA A                ; Starting with slot zero...&lt;br /&gt;
3910H  CALL 39AAH           ; Print &amp;quot;-.-&amp;quot; for all empty file slots&lt;br /&gt;
3913H  LXI H,3E97H          ; Point to Disk Function menu string&lt;br /&gt;
3916H  LXI B,391CH          ; Print NOT FORMATTED to the display&lt;br /&gt;
3919H  JMP 38CBH            ; Go process the print and jump to error handler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print &amp;quot;NOT FORMATTED&amp;quot; on the LCD and return&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
391CH  LXI H,`H             ; Point to &amp;quot;NOT FORMATTED&amp;quot; string&lt;br /&gt;
391FH  JMP 4A2CH            ; Send buffer at M to screen&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print RAM free space at current posiiton&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3922H  LHLD FBB2H           ; Start of variable data pointer  &lt;br /&gt;
3925H  XCHG                 ; HL &amp;lt;--&amp;gt; DE&lt;br /&gt;
3926H  LHLD F678H           ; BASIC string buffer pointer  &lt;br /&gt;
3929H  MOV A,L              ; Prepare for 16 bit subtract   &lt;br /&gt;
392AH  SUB E                ; Subtract LSB &lt;br /&gt;
392BH  MOV L,A              ; Save LSB of difference for printing   &lt;br /&gt;
392CH  MOV A,H              ; Prepare for subtrating MSB   &lt;br /&gt;
392DH  SBB D                ; Subtract MSB &lt;br /&gt;
392EH  MOV H,A              ; Save in H for printing   &lt;br /&gt;
392FH  LXI B,FFF2H          ; Load signed number -14       &lt;br /&gt;
3932H  DAD B                ; Subtract 14 from free memory &lt;br /&gt;
3933H  JMP 4C3EH            ; Print binary number in HL at current position     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display free space on disk&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3936H  CALL 4A10H           ; Calculate free space on disk&lt;br /&gt;
3939H  CALL 4C3EH           ; Print binary number in HL at current position&lt;br /&gt;
393CH  MVI A,30H            ; Prepare to add an extra &#039;0&#039; since calc is /10&lt;br /&gt;
393EH  RST 4                ; Send A to the LCD      &lt;br /&gt;
393FH  RET       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display DISK ON/OFF status on LCD&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3940H  LDA FCD9H            ; DISK/RAM mode (0=RAM, 1=DISK)       &lt;br /&gt;
3943H  ANA A                ; Test if in RAM mode   &lt;br /&gt;
3944H  RNZ                  ; Return if not in RAM mode  &lt;br /&gt;
3945H  LDA FB2CH            ; DISK-OFF/ON status   &lt;br /&gt;
3948H  LXI D,3FF2H          ; Load pointer to &amp;quot;OFF&amp;quot; text         &lt;br /&gt;
394BH  CPI DBH              ; Test if DISK mode (vector LSB) indicates ON or OFF     &lt;br /&gt;
394DH  JZ 3953H             ; Branch if in DISK-OFF mode      &lt;br /&gt;
3950H  LXI D,3FF6H          ; Load pointer to &amp;quot;ON&amp;quot; text         &lt;br /&gt;
3953H  LXI H,1908H          ; Location of DISK-OFF/ON indication on LCD         &lt;br /&gt;
3956H  SHLD F639H           ; Cursor row (1-8)   &lt;br /&gt;
3959H  XCHG                 ; HL = pointer to text in DE  &lt;br /&gt;
395AH  JMP 4A2CH            ; Send buffer at M to screen       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display RAM files to LCD and calculate file lengths&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
395DH  LXI H,F9BAH          ; Load pointer to 1st available file slot in catalog&lt;br /&gt;
3960H  XRA A                ; Set count of RAM files on screen to zero &lt;br /&gt;
3961H  STA FCD6H            ; Count of files on screen     &lt;br /&gt;
3964H  MVI A,14H            ; Get max # files that will fit on LCD     &lt;br /&gt;
3966H  DCR A                ; Decrement the max file count &lt;br /&gt;
3967H  PUSH PSW             ; Save count to the stack    &lt;br /&gt;
3968H  MOV A,M              ; Get file type   &lt;br /&gt;
3969H  XRI 80H              ; Compliment ?active bit   &lt;br /&gt;
396BH  ANI 9FH              ; Test if file is active and should be displayed   &lt;br /&gt;
396DH  JNZ 3996H            ; Branch to test next file if not displayed     &lt;br /&gt;
3970H  PUSH H               ; Save address of current catalog file  &lt;br /&gt;
3971H  INX H                ; Point to file address &lt;br /&gt;
3972H  MOV E,M              ; Get LSB of file address   &lt;br /&gt;
3973H  INX H                ; Point to MSB of address &lt;br /&gt;
3974H  MOV D,M              ; Get MSB of file address   &lt;br /&gt;
3975H  XTHL                 ; HL &amp;lt;--&amp;gt; (SP)  Get address of file within catalog&lt;br /&gt;
3976H  PUSH H               ; Push pointer to MSB of address on stack  &lt;br /&gt;
3977H  CALL 3CD3H           ; Calculate length of RAM file      &lt;br /&gt;
397AH  XCHG                 ; HL &amp;lt;--&amp;gt; DE DE has the length&lt;br /&gt;
397BH  CALL 4791H           ; Store next file length to keyboard buffer      &lt;br /&gt;
397EH  POP H                ; Get catalog address of current file from stack &lt;br /&gt;
397FH  XTHL                 ; HL &amp;lt;--&amp;gt; (SP) swap catalog address with pointer to MSB of file address&lt;br /&gt;
3980H  INX H                ; Increment to filename &lt;br /&gt;
3981H  MVI C,06H            ; Prepare to print 6 characters of filename     &lt;br /&gt;
3983H  CALL 48E5H           ; Redraw C characters from buffer at HL using current video mode       &lt;br /&gt;
3986H  MVI A,2EH            ; Load code for &#039;.&#039;      &lt;br /&gt;
3988H  RST 4                ; Send A to the LCD                &lt;br /&gt;
3989H  MVI C,02H            ; Prepare to print 2 ext bytes to LCD      &lt;br /&gt;
398BH  CALL 48E5H           ; Redraw C characters from buffer at HL using current video mode       &lt;br /&gt;
398EH  MVI A,20H            ; Load code for space      &lt;br /&gt;
3990H  RST 4                ; Send A to the LCD           &lt;br /&gt;
3991H  LXI H,FCD6H          ; Count of files on screen        &lt;br /&gt;
3994H  INR M                ; Increment number of files displayed on LCD  &lt;br /&gt;
3995H  POP H                ; Get catalog address of file from stack  &lt;br /&gt;
3996H  LXI D,000BH          ; Load offset to next file locaion in catalog        &lt;br /&gt;
3999H  DAD D                ; Offset HL to next file  &lt;br /&gt;
399AH  POP PSW              ; Restore the file count from the stack    &lt;br /&gt;
399BH  DCR A                ; Decrement the max file count on the LCD  &lt;br /&gt;
399CH  JNZ 3967H            ; Branch to test and display next file until zero      &lt;br /&gt;
399FH  LDA FCD6H            ; Get the count of files actually displayed on screen              &lt;br /&gt;
39A2H  CPI 14H              ; Test if max number of files displayed    &lt;br /&gt;
39A4H  CC 39AAH             ; Branch to display &amp;quot;-.-&amp;quot; for remaining empty slots if not max     &lt;br /&gt;
39A7H  JMP 387CH            ; Print NADSBox directory or TPDD Bank number to LCD      &lt;br /&gt;
				  &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print &amp;quot;-.-&amp;quot; for all empty file slots&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
39AAH  PUSH PSW             ; Save current file index count on stack &lt;br /&gt;
39ABH  LXI H,3FCDH          ; Point to &amp;quot;-.-&amp;quot; text&lt;br /&gt;
39AEH  CALL 4A2CH           ; Send buffer at M to screen &lt;br /&gt;
39B1H  POP PSW              ; Restore current count &lt;br /&gt;
39B2H  INR A                ; Increment file index number&lt;br /&gt;
39B3H  CPI 14H              ; Compare A with max files that fit on LCD&lt;br /&gt;
39B5H  JNZ 39AAH            ; Jump to print next &amp;quot;-.-&amp;quot; if not done&lt;br /&gt;
39B8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;D&amp;quot; key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
39B9H  CALL 3AA8H           ; Test if printer busy.  Return if not busy or error&lt;br /&gt;
39BCH  CALL 4C52H           ; LCOPY statement&lt;br /&gt;
39BFH  JMP 362FH            ; Print length of selected file using inverse video.&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;L&amp;quot;, &amp;quot;P&amp;quot; and &amp;quot;O&amp;quot; keys from TS-DOS key scan - list or print .DO file contents&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
39C2H  STA FCDFH            ; Save key pressed       &lt;br /&gt;
39C5H  LXI D,0007H          ; Load offset of Extension bytes         &lt;br /&gt;
39C8H  LHLD FCE4H           ; LCD Buffer address of current file selection        &lt;br /&gt;
39CBH  DAD D                ; Point to extension bytes in LCD buffer   &lt;br /&gt;
39CCH  MOV A,M              ; Get 1st extension byte     &lt;br /&gt;
39CDH  CPI 44H              ; Compare byte with &amp;quot;D&amp;quot;     &lt;br /&gt;
39CFH  JNZ 362FH            ; Print length of selected file using inverse video if not &amp;quot;D&amp;quot;       &lt;br /&gt;
39D2H  INX H                ; Point to 2nd extension byte  &lt;br /&gt;
39D3H  MOV A,M              ; Load 2nd extension byte for comparison&lt;br /&gt;
39D4H  CPI 4FH              ; Compare with &amp;quot;0&amp;quot;&lt;br /&gt;
39D6H  JNZ 3A06H            ; Jump to print compressed file&lt;br /&gt;
39D9H  CALL 3A49H           ; Prepare file for reading (open disk file, address of RAM file)        &lt;br /&gt;
39DCH  LDA FCDFH            ; Restore key pressed       &lt;br /&gt;
39DFH  CPI 4CH              ; Test if key was &amp;quot;L&amp;quot; - List to LCD     &lt;br /&gt;
39E1H  CZ 4C27H             ; CLS statement if LCD      &lt;br /&gt;
39E4H  CNZ 3AA8H            ; Test if printer busy.  Return if not busy or error       &lt;br /&gt;
39E7H  CALL 3A24H           ; Get next block of data to display/print (HL=address)        &lt;br /&gt;
39EAH  PUSH PSW             ; Push Z flag indicating if a full 128 bytes was read      &lt;br /&gt;
39EBH  CALL 3A6BH           ; Display / print file data bytes at HL, A has length                 &lt;br /&gt;
39EEH  POP PSW              ; Get Z flag indicating if 128 bytes read     &lt;br /&gt;
39EFH  JZ 39E7H             ; Jump to process more if 128 bytes were read last time      &lt;br /&gt;
39F2H  LDA FCDFH            ; Restore key pressed       &lt;br /&gt;
39F5H  CPI 4CH              ; Test if key was &amp;quot;L&amp;quot;              &lt;br /&gt;
39F7H  JNZ 3A00H            ; Skip beep if printing       &lt;br /&gt;
39FAH  MVI A,07H            ; Load code for BELL       &lt;br /&gt;
39FCH  RST 4                ; Go print a BELL (beep)    &lt;br /&gt;
39FDH  CALL 3DF8H           ; Process power-off logic and wait for a key from keyboard        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Clear screen and perform Long Jump&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3A00H  CALL 4C27H           ; CLS statement         &lt;br /&gt;
3A03H  JMP 48B5H            ; Branch to &amp;quot;Long Jump&amp;quot; operation        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handler for the &amp;quot;O&amp;quot; key - print a compressed file?? &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3A06H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
3A09H  ANA A                ; Test if in Disk mode &lt;br /&gt;
3A0AH  JNZ 362FH            ; Jump to keyscan if in Disk mode&lt;br /&gt;
3A0DH  LHLD FCE4H           ; LCD Buffer address of current file selection      &lt;br /&gt;
3A10H  CALL 4902H           ; Copy filename at (HL) to current BASIC program&lt;br /&gt;
3A13H  CALL 4A51H           ; Get RAM directory address of current BASIC program&lt;br /&gt;
3A16H  CPI C0H              ; Test if filetype is .DO&lt;br /&gt;
3A18H  CZ 5004H             ; Call routine to Compress / Decompress .DO files&lt;br /&gt;
3A1BH  CALL 4C0FH           ; Update system pointers       &lt;br /&gt;
3A1EH  CALL 3611H           ; Print Copyright and files&lt;br /&gt;
3A21H  JMP 362FH            ; Jump to keyscan &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get next 128 bytes (or less) of data from RAM or disk file for display&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3A24H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)      &lt;br /&gt;
3A27H  ANA A                ; Test if RAM mode  &lt;br /&gt;
3A28H  JNZ 40B6H            ; If not RAM mode, go send TPDD_READ data opcode and recieve response      &lt;br /&gt;
3A2BH  LHLD FCDDH           ; Get length of file to be displayed / printed       &lt;br /&gt;
3A2EH  LXI B,0080H          ; Prepare to subtract 128 from length&lt;br /&gt;
3A31H  MOV A,C              ; Save 128 to A    &lt;br /&gt;
3A32H  DSUB                 ; Subtract 128 from file length &lt;br /&gt;
3A33H  JNC 3A3AH            ; Branch if length &amp;gt;= 128      &lt;br /&gt;
3A36H  DAD B                ; Add 128 back to length to print &amp;quot;partial&amp;quot; buffer  &lt;br /&gt;
3A37H  MOV A,L              ; Move remainder of bytes to display/print    &lt;br /&gt;
3A38H  MOV L,H              ; Clear LSB of remainder    &lt;br /&gt;
3A39H  MOV C,A              ; Move LSB of remainder to C    &lt;br /&gt;
3A3AH  SHLD FCDDH           ; Save new remaining file length       &lt;br /&gt;
3A3DH  LHLD FCE0H           ; Load the address to be printed / saved       &lt;br /&gt;
3A40H  PUSH H               ; Save on stack    &lt;br /&gt;
3A41H  DAD B                ; Update address to be used for display/printing next time  &lt;br /&gt;
3A42H  SHLD FCE0H           ; Save address to be displayed / printed       &lt;br /&gt;
3A45H  POP H                ; Retrieve address to be printed this loop from stack  &lt;br /&gt;
3A46H  CPI 80H              ; Compare length with maximum    &lt;br /&gt;
3A48H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Initialize Selected file for display (RAM or Disk)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3A49H  CALL 4A3BH           ; Initialize blank filename and attribute byte&lt;br /&gt;
3A4CH  LHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
3A4FH  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)     &lt;br /&gt;
3A52H  ANA A                ; Test if in RAM mode &lt;br /&gt;
3A53H  JNZ 3A65H            ; Branch to process Disk files if in Disk mode     &lt;br /&gt;
3A56H  CALL 4A4BH           ; Get RAM directory address of selected file&lt;br /&gt;
3A59H  PUSH D               ; Push file address to stack  &lt;br /&gt;
3A5AH  CALL 3CD3H           ; Calculate length of RAM file, HL=address of catalog entry, DE=file address&lt;br /&gt;
3A5DH  SHLD FCDDH           ; Save length to FDC emulation sector storage area&lt;br /&gt;
3A60H  POP H                ; Pop address of file into H &lt;br /&gt;
3A61H  SHLD FCE0H           ; Save file address&lt;br /&gt;
3A64H  RET		 &lt;br /&gt;
				 &lt;br /&gt;
; =====================================================================================&lt;br /&gt;
; Send TPDD Open command to open selected file&lt;br /&gt;
; =====================================================================================&lt;br /&gt;
3A65H  CALL 3D95H           ; Copy filename at (HL) to TX buffer&lt;br /&gt;
3A68H  JMP 408AH            ; Open TPDD file for Read Mode&lt;br /&gt;
&lt;br /&gt;
; =====================================================================================&lt;br /&gt;
; Display / print file data bytes at HL, A has length&lt;br /&gt;
; =====================================================================================&lt;br /&gt;
3A6BH  XCHG                 ; HL &amp;lt;--&amp;gt; DE  &lt;br /&gt;
3A6CH  ORA A                ; Test if length = 0   &lt;br /&gt;
3A6DH  RZ                   ; Return if length = 0&lt;br /&gt;
3A6EH  MOV C,A              ; Save length count in C     &lt;br /&gt;
3A6FH  LDA FCDFH            ; Load key press value       &lt;br /&gt;
3A72H  CPI 4CH              ; Test if key was &amp;quot;L&amp;quot;     &lt;br /&gt;
3A74H  JNZ 3A82H            ; Jump to print contents if not &amp;quot;L&amp;quot;       &lt;br /&gt;
3A77H  CALL 3A8FH           ; Check for CTRL-C&lt;br /&gt;
3A7AH  LDAX D               ; Load next byte from src pointer    &lt;br /&gt;
3A7BH  RST 4                ; Send A to LCD           &lt;br /&gt;
3A7CH  INX D                ; Increment the pointer   &lt;br /&gt;
3A7DH  DCR C                ; Decrement the length count   &lt;br /&gt;
3A7EH  JNZ 3A77H            ; Keep looping until all data displayed       &lt;br /&gt;
3A81H  RET        &lt;br /&gt;
&lt;br /&gt;
; =====================================================================================&lt;br /&gt;
; Print file data bytes at HL, A has length&lt;br /&gt;
; =====================================================================================&lt;br /&gt;
3A82H  CALL 3A8FH           ; Test for CTRL-C, etc.&lt;br /&gt;
3A85H  LDAX D               ; Load next file byte from source poiner &lt;br /&gt;
3A86H  CALL 4C42H           ; Print A to printer, expanding tabs if necessary&lt;br /&gt;
3A89H  INX D                ; Increment pointer&lt;br /&gt;
3A8AH  DCR C                ; Decrement length count&lt;br /&gt;
3A8BH  JNZ 3A82H            ; Keep looping until all data printed    &lt;br /&gt;
3A8EH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test for ESC, CTRL-C or Space&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3A8FH  CALL 4C4AH           ; Check keyboard queue for pending characters&lt;br /&gt;
3A92H  RZ                   ; Return if no pending characters&lt;br /&gt;
3A93H  CALL 4BEBH           ; Wait for key from keyboard&lt;br /&gt;
3A96H  CPI 03H              ; Test for F4 maybe?  &lt;br /&gt;
3A98H  JZ 3A00H             ; Clear screen and perform Long Jump if F4 maybe?   &lt;br /&gt;
3A9BH  CPI 1BH              ; Test for ESC key  &lt;br /&gt;
3A9DH  JZ 3A00H             ; Clear screen and perform Long Jump if ESC   &lt;br /&gt;
3AA0H  CPI 20H              ; Test for space key  &lt;br /&gt;
3AA2H  JNZ 3A8FH            ; Branch back to wait for ESC, CTRL-C or space if not space    &lt;br /&gt;
3AA5H  JMP 4BEBH            ; Wait for key from keyboard    &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test if printer busy.  Return if not busy, print error if it is&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3AA8H  IN BBH               ; Get printer port input     &lt;br /&gt;
3AAAH  ANI 06H              ; Mask all but BUSY and /BUSY      &lt;br /&gt;
3AACH  XRI 02H              ; Compliment /BUSY      &lt;br /&gt;
3AAEH  JNZ 487BH            ; Printer not ready / FF error        &lt;br /&gt;
3AB1H  RET        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print currently selected file using inverse video&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3AB2H  CALL 3ACDH           ; Calculate Row and Column of newly selected file&lt;br /&gt;
3AB5H  SHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
3AB8H  CALL 4C2FH           ; Start inverse character mode&lt;br /&gt;
3ABBH  DCX H                ; Start drawing from left edge of selection (include space)   &lt;br /&gt;
3ABCH  MVI C,0AH            ; Draw 10 characters       &lt;br /&gt;
3ABEH  CALL 48E5H           ; Redraw C characters from buffer at HL using current video mode&lt;br /&gt;
3AC1H  JMP 4C33H            ; Cancel inverse character mode       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print selected file using normal video to &amp;quot;unselect&amp;quot; it&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3AC4H  CALL 4C33H           ; Cancel inverse character mode&lt;br /&gt;
3AC7H  CALL 3ACDH           ; Calculate row and column of newly selected file&lt;br /&gt;
3ACAH  JMP 3ABBH            ; Print the file to the LCD       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Calculate Row and Column of soon-to-be (newly) selected file&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3ACDH  LDA FCD5H            ; Currently selected file index       &lt;br /&gt;
3AD0H  DCR A                ; Make selected file zero based   &lt;br /&gt;
3AD1H  MOV L,A              ; Save index to 16-bit HL&lt;br /&gt;
3AD2H  MVI H,00H            ; Make MSB zero&lt;br /&gt;
3AD4H  LXI D,000AH          ; Prepare to multiply index * 10 cols      &lt;br /&gt;
3AD7H  CALL 4C1FH           ; Signed integer muliply (FAC1=HL*DE)&lt;br /&gt;
3ADAH  LXI D,FE28H          ; Load address of line 2 in the LCD buffer&lt;br /&gt;
3ADDH  DAD D                ; Calculate starting LCD buffer address for this file&lt;br /&gt;
3ADEH  INX H                ; Skip the &amp;quot;tag&amp;quot; space on the LCD&lt;br /&gt;
3ADFH  PUSH H               ; Save address on the stack&lt;br /&gt;
3AE0H  LXI B,FE00H          ; Load starting address of LCD character buffer&lt;br /&gt;
3AE3H  DSUB                 ; Calculate file start offset from start of LCD buffer&lt;br /&gt;
3AE4H  LXI D,0028H          ; Load 1 LCD line width&lt;br /&gt;
3AE7H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  Prepare for divide&lt;br /&gt;
3AE8H  CALL 4C1BH           ; Signed integer divide (FAC1=DE/HL)&lt;br /&gt;
3AEBH  MOV A,L              ; Save selected file&#039;s row number to A&lt;br /&gt;
3AECH  INR A                ; Make row 1-based&lt;br /&gt;
3AEDH  STA F639H            ; Cursor row (1-8)&lt;br /&gt;
3AF0H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  DE had remainder*2 from divide&lt;br /&gt;
3AF1H  ASHR                 ; Divide HL by 2&lt;br /&gt;
3AF2H  MOV A,L              ; Prepare to save remainder as the column&lt;br /&gt;
3AF3H  STA F63AH            ; Cursor column (1-40)&lt;br /&gt;
3AF6H  POP H                ; Restore address of LCD buffer location from stack&lt;br /&gt;
3AF7H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F3 Function key handler for RAM mode - Rename&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3AF8H  CALL 4A4BH           ; Get RAM directory address of selected file          &lt;br /&gt;
3AFBH  SHLD FCE0H           ; Save address of file being processed          &lt;br /&gt;
3AFEH  LXI H,3F4AH          ; Address of &amp;quot;New name&amp;quot; string           &lt;br /&gt;
3B01H  CALL 3E1AH           ; Get 6-byte input filename from keyboard          &lt;br /&gt;
3B04H  RZ                   ; Return if no input provided  &lt;br /&gt;
3B05H  CALL 4902H           ; Copy filename at (HL) to current BASIC program          &lt;br /&gt;
3B08H  LHLD FCE0H           ; Load RAM directory address of file being renamed          &lt;br /&gt;
3B0BH  LXI B,0009H          ; Load offset of extension within catalog entry           &lt;br /&gt;
3B0EH  DAD B                ; Point to extension bytes     &lt;br /&gt;
3B0FH  LXI D,FC99H          ; Load address of extension field of current BASIC program name           &lt;br /&gt;
3B12H  MOV A,M              ; Get 1st byte of extension of catalog file being renamed       &lt;br /&gt;
3B13H  STAX D               ; Save extension byte in current BASIC program filename - preserve EXT      &lt;br /&gt;
3B14H  INX D                ; Point to 2nd ext byte of BASIC program name     &lt;br /&gt;
3B15H  INX H                ; Point to 2nd ext byte of catalog filename     &lt;br /&gt;
3B16H  MOV A,M              ; Get 2nd extension byte from catalog filename       &lt;br /&gt;
3B17H  STAX D               ; Save byte in current BASIC program filename area      &lt;br /&gt;
3B18H  CALL 4A51H           ; Get RAM directory address of current BASIC program          &lt;br /&gt;
3B1BH  JNZ 487EH            ; If found, jump to File Exists Error         &lt;br /&gt;
3B1EH  LHLD FCE0H           ; Load catalog address of file being renamed          &lt;br /&gt;
3B21H  INX H                ; Point to LSB of file address     &lt;br /&gt;
3B22H  INX H                ; Point to MSB of file address     &lt;br /&gt;
3B23H  INX H                ; Point to name     &lt;br /&gt;
3B24H  LXI D,FC93H          ; Load address of filename of current BASIC program    &lt;br /&gt;
3B27H  LXI B,0006H          ; Prepare to copy 6 bytes of filename (ext doesn&#039;t change)           &lt;br /&gt;
3B2AH  XCHG                 ; HL &amp;lt;--&amp;gt; DE    &lt;br /&gt;
3B2BH  JMP 4A05H            ; Move BC bytes from M to (DE) with increment         &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F1 Function key handler for DISK mode - Load&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3B2EH  CALL 4A3BH           ; Initialize blank filename and attribute byte      &lt;br /&gt;
3B31H  LHLD FCE4H           ; LCD Buffer address of current file selection      &lt;br /&gt;
3B34H  CALL 3D95H           ; Copy filename at (HL) to TX buffer      &lt;br /&gt;
3B37H  LDA FCCCH            ; Last Tag/Untag operation code     &lt;br /&gt;
3B3AH  ANA A                ; Test if a tag operation is pending &lt;br /&gt;
3B3BH  JNZ 3B56H            ; Branch if doing tag load operation     &lt;br /&gt;
3B3EH  LXI H,3F7AH          ; Point to &amp;quot;Load as:&amp;quot; text       &lt;br /&gt;
3B41H  CALL 3E1AH           ; Get 6-byte filename input from keyboard      &lt;br /&gt;
3B44H  JZ 3B56H             ; Jump to use existing disk name as filename    &lt;br /&gt;
3B47H  CALL 4902H           ; Copy filename at (HL) to current BASIC program      &lt;br /&gt;
3B4AH  LXI B,0002H          ; Prepare to copy 2 extension bytes to current BASIC program space       &lt;br /&gt;
3B4DH  LXI H,FCEFH          ; Point to disk file extension in TX buffer       &lt;br /&gt;
3B50H  LXI D,FC99H          ; Point to current BASIC program extension address       &lt;br /&gt;
3B53H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
3B56H  CALL 4A51H           ; Get RAM directory address of current BASIC program      &lt;br /&gt;
3B59H  JZ 3B69H             ; Branch to load if file doesn&#039;t already exist    &lt;br /&gt;
3B5CH  LXI H,3FB0H          ; Point to &amp;quot;File Exists, Replace?&amp;quot; text       &lt;br /&gt;
3B5FH  CALL 48F4H           ; Print string at HL to col 1 on the bottom line      &lt;br /&gt;
3B62H  CALL 3DEEH           ; Get key from keyboard and test for &#039;Y&#039; or &#039;y&#039;      &lt;br /&gt;
3B65H  RNZ                  ; Return if isn&#039;t &#039;y&#039; or &#039;Y&#039; &lt;br /&gt;
3B66H  CALL 3C38H           ; Kill file in current BASIC program space      &lt;br /&gt;
3B69H  LHLD FD1DH           ; Get file size from RX buffer      &lt;br /&gt;
3B6CH  MOV A,H              ; Swap bytes (big endian in RX buffer)   &lt;br /&gt;
3B6DH  MOV H,L              ; Move LSB to MSB   &lt;br /&gt;
3B6EH  MOV L,A              ; Move MSB to LSB   &lt;br /&gt;
3B6FH  SHLD FD1DH           ; Save with little endian to RX buffer      &lt;br /&gt;
3B72H  LDA FCEFH            ; Get 1st byte of extension from TX buffer     &lt;br /&gt;
3B75H  CPI 44H              ; Test if 1st extension byte is &amp;quot;D&amp;quot;   &lt;br /&gt;
3B77H  JNZ 3B82H            ; Jump if not &amp;quot;D&amp;quot; to check for &amp;quot;C&amp;quot; or &amp;quot;B&amp;quot;     &lt;br /&gt;
3B7AH  LHLD FBAEH           ; Get start of DO files pointer for location of new file       &lt;br /&gt;
3B7DH  MVI A,C0H            ; Load file type code for .DO files     &lt;br /&gt;
3B7FH  JMP 3BA3H            ; Process the file load      &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test file exension type in A for .CO files&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3B82H  CPI 43H              ; Test if A contains &amp;quot;C&amp;quot; &lt;br /&gt;
3B84H  JNZ 3B95H            ; Branch if not .CO file&lt;br /&gt;
3B87H  LHLD FBB0H           ; Start of CO files pointer&lt;br /&gt;
3B8AH  SHLD FCD5H           ; Save in currently selected file index storage area&lt;br /&gt;
3B8DH  LHLD FBB2H           ; Get Start of variable data pointer as location for new file&lt;br /&gt;
3B90H  MVI A,A0H            ; Load file type code for .CO files&lt;br /&gt;
3B92H  JMP 3BA3H            ; Process the file load&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process load of .BA file&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3B95H  LHLD FD1DH           ; Get file size from RX buffer&lt;br /&gt;
3B98H  SHLD FCD5H           ; Save in Currently selected file index storage&lt;br /&gt;
3B9BH  LHLD F99AH           ; Get BASIC program not saved pointer     &lt;br /&gt;
3B9EH  SHLD FCE0H           ; Save as address of file being processed&lt;br /&gt;
3BA1H  MVI A,80H            ; Load file type code for .BA files     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process file load operation&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3BA3H  STA FCDFH            ; Save file type code for later     &lt;br /&gt;
3BA6H  SHLD FCE2H           ; Save address for new file &lt;br /&gt;
3BA9H  LHLD FD1DH           ; Get file size from RX buffer&lt;br /&gt;
3BACH  SHLD FCDDH           ; Save in FDC emulation physical/logical sector storage area&lt;br /&gt;
3BAFH  PUSH H               ; Save file size on stack  &lt;br /&gt;
3BB0H  POP B                ; Copy file size to BC &lt;br /&gt;
3BB1H  LDA FCDFH            ; Get file type code     &lt;br /&gt;
3BB4H  CPI A0H              ; Test for .CO file   &lt;br /&gt;
3BB6H  JZ 3BC0H             ; Skip increment if .CO file (.BA has trailing 0x0000, .DO a 0x1A)    &lt;br /&gt;
3BB9H  INX B                ; Increment file length for .BA and .DO files &lt;br /&gt;
3BBAH  CPI 80H              ; Test if file is .BA   &lt;br /&gt;
3BBCH  JNZ 3BC0H            ; Skip additional increment if .BA     &lt;br /&gt;
3BBFH  INX B                ; Add 1 more to length for .BA files to account for both trailing 0&#039;s &lt;br /&gt;
3BC0H  PUSH B               ; Save updated length on stack  &lt;br /&gt;
3BC1H  CALL 3E48H           ; Find empty catalog entry      &lt;br /&gt;
3BC4H  JC 4887H             ; Generate system error 0x0A (&amp;quot;DD&amp;quot;) if full&lt;br /&gt;
3BC7H  POP B                ; Get length from stack &lt;br /&gt;
3BC8H  PUSH H               ; Save new file catalog address on stack  &lt;br /&gt;
3BC9H  PUSH B               ; Save new file length on stack  &lt;br /&gt;
3BCAH  LHLD FCE2H           ; Get address for new contents of new file      &lt;br /&gt;
3BCDH  CALL 4C0BH           ; Insert BC spaces at M - make room      &lt;br /&gt;
3BD0H  JC 488AH             ; Branch if error - RAM full error&lt;br /&gt;
3BD3H  LHLD FCE2H           ; Restore address of new file contents&lt;br /&gt;
3BD6H  POP B                ; Get file length from stack   &lt;br /&gt;
3BD7H  MVI M,00H            ; Fill newly created file space with zero&#039;s       &lt;br /&gt;
3BD9H  INX H                ; Increment pointer   &lt;br /&gt;
3BDAH  DCX B                ; Decrement count   &lt;br /&gt;
3BDBH  MOV A,C              ; Move LSB to A to check for zero - could use JNX here!     &lt;br /&gt;
3BDCH  ORA B                ; Or in MSB to check for zero   &lt;br /&gt;
3BDDH  JNZ 3BD7H            ; Keep looping until all are zero       &lt;br /&gt;
3BE0H  DCX H                ; Decrement pointer to last byte in new file   &lt;br /&gt;
3BE1H  POP D                ; Get File catalog address from stack   &lt;br /&gt;
3BE2H  LDA FCDFH            ; Load file type code byte       &lt;br /&gt;
3BE5H  CPI C0H              ; Test for .DO file     &lt;br /&gt;
3BE7H  JNZ 3BF3H            ; Branch if not .DO file       &lt;br /&gt;
3BEAH  MVI M,1AH            ; Terminate .DO file with EOF marker       &lt;br /&gt;
3BECH  LHLD FCE2H           ; Reload address of new file contents        &lt;br /&gt;
3BEFH  DCX H                ; Decrement pointer to jump into middle of loop   &lt;br /&gt;
3BF0H  JMP 3C1BH            ; Write file entry to catalog       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process end-of-file / file length for .CO and .BA files&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3BF3H  CPI A0H              ; Test if new file is .CO  &lt;br /&gt;
3BF5H  JNZ 3C04H            ; Branch if not .CO - must be .BA &lt;br /&gt;
3BF8H  LHLD FCD5H           ; Get old start of CO files pointer&lt;br /&gt;
3BFBH  SHLD FBB0H           ; Save as current start of CO files pointer     &lt;br /&gt;
3BFEH  LHLD FCE2H           ; Reload address of new file contents&lt;br /&gt;
3C01H  JMP 3C1BH            ; Write file entry to catalog &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process end-of-file for .BA files&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3C04H  PUSH D               ; Push file catalog address to stack    &lt;br /&gt;
3C05H  LHLD FBAEH           ; Get start of DO files pointer          &lt;br /&gt;
3C08H  DCX H                ; Decrement address by 1   &lt;br /&gt;
3C09H  SHLD F99AH           ; Save as new BASIC program not saved pointer          &lt;br /&gt;
3C0CH  INX H                ; Increment back to start of .DO files   &lt;br /&gt;
3C0DH  XCHG                 ; HL &amp;lt;--&amp;gt; DE  DE has start of DO files  &lt;br /&gt;
3C0EH  LHLD FCD5H           ; Get BA file size        &lt;br /&gt;
3C11H  INX H                ; Increment file size to account for trailing 0&#039;s   &lt;br /&gt;
3C12H  INX H                ; Increment file size to account for trailing 0&#039;s   &lt;br /&gt;
3C13H  DAD D                ; Add new length to start of DO files pointer   &lt;br /&gt;
3C14H  SHLD FBAEH           ; Save new start of DO files pointer          &lt;br /&gt;
3C17H  POP D                ; Retrieve file catalog address from stack   &lt;br /&gt;
3C18H  LHLD FCE0H           ; Reload address of new file contents        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Write file entry to catalog&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3C1BH  XCHG                 ; HL &amp;lt;--&amp;gt; DE  DE has file address, HL has catalog address         &lt;br /&gt;
3C1CH  CALL 4C17H           ; Write new entry to catalog (A=type, DE=file address,HL=catalog address)       &lt;br /&gt;
3C1FH  CALL 4127H           ; Open TPDD file and read data to file address being processed       &lt;br /&gt;
3C22H  CALL 4C0FH           ; Update system pointers       &lt;br /&gt;
3C25H  LXI H,0002H          ; Load TPDD_READ opcode in HL        &lt;br /&gt;
3C28H  JMP 409BH            ; Send Request in HL and await response      &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F2 Function key handler for RAM mode - Kill&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3C2BH  LDA FCCCH            ; Get last Tag/Untag operation code       &lt;br /&gt;
3C2EH  ANA A                ; Test if there is a pending tag operation&lt;br /&gt;
3C2FH  CZ 3DE1H             ; Display &amp;quot;Sure ?&amp;quot;, validate and return if validated if no tag&lt;br /&gt;
3C32H  LHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
3C35H  CALL 4902H           ; Copy filename at (HL) to current BASIC program&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Kill file in current BASIC program space&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3C38H  CALL 4A51H           ; Get RAM directory address of current BASIC program&lt;br /&gt;
3C3BH  CPI C0H              ; Test if file is .DO &lt;br /&gt;
3C3DH  JZ 4BFFH             ; Kill .DO file  &lt;br /&gt;
3C40H  CPI A0H              ; Test if file is .CO &lt;br /&gt;
3C42H  JZ 4C07H             ; Kill .CO file &lt;br /&gt;
3C45H  CPI 80H              ; Test if file is .BA&lt;br /&gt;
3C47H  JZ 4C03H             ; Kill .BA file&lt;br /&gt;
3C4AH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F1 Function key handler for RAM mode - Save&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3C4BH  CALL 4A3BH           ; Initialize blank filename and attribute byte      &lt;br /&gt;
3C4EH  CALL 4A4BH           ; Get RAM directory address of selected file      &lt;br /&gt;
3C51H  PUSH D               ; Push file address to stack  &lt;br /&gt;
3C52H  PUSH H               ; Push file catalog address to stack  &lt;br /&gt;
3C53H  INX H                ; Point to LSB of file address &lt;br /&gt;
3C54H  INX H                ; Point to MSB of file address &lt;br /&gt;
3C55H  INX H                ; Point to filename in catalog &lt;br /&gt;
3C56H  LXI D,FCE8H          ; Point to TX buffer data area (payload)&lt;br /&gt;
3C59H  LXI B,0006H          ; Prepare to copy 6 filename bytes to TX packet data&lt;br /&gt;
3C5CH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
3C5FH  MVI A,2EH            ; Load code for &#039;.&#039;     &lt;br /&gt;
3C61H  STAX D               ; Store &#039;.&#039; separator in TX packet data  &lt;br /&gt;
3C62H  INX D                ; Increment TX packet data pointer &lt;br /&gt;
3C63H  LXI B,0002H          ; Prepare to copy 2 extention bytes from catalog&lt;br /&gt;
3C66H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
3C69H  LDA FCCCH            ; Last Tag/Untag operation code     &lt;br /&gt;
3C6CH  ANA A                ; Test if a tag save operation is being performed &lt;br /&gt;
3C6DH  JNZ 3C88H            ; Jump ahead if doing a tag save - skip filename questioning     &lt;br /&gt;
3C70H  LXI H,3F71H          ; Point to &amp;quot;Save as:&amp;quot; text&lt;br /&gt;
3C73H  CALL 3E1AH           ; Get 6-byte input filename from keyboard      &lt;br /&gt;
3C76H  JZ 3C88H             ; Skip ahead to use catalog name if no input given    &lt;br /&gt;
3C79H  CALL 4902H           ; Copy filename at (HL) to current BASIC program             &lt;br /&gt;
3C7CH  LXI B,0006H          ; Prepare to copy 6 filename bytes from input string       &lt;br /&gt;
3C7FH  LXI D,FCE8H          ; Point to filename area in TX buffer       &lt;br /&gt;
3C82H  LXI H,FC93H          ; Filename of current BASIC program         &lt;br /&gt;
3C85H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
3C88H  POP H                ; Restore file catalog address from stack &lt;br /&gt;
3C89H  POP D                ; Restore file address from stack &lt;br /&gt;
3C8AH  PUSH D               ; Save file address on stack  &lt;br /&gt;
3C8BH  CALL 3CD3H           ; Calculate length of RAM file, HL=address of catalog entry, DE=file address&lt;br /&gt;
3C8EH  MOV A,H              ; Test for zero length file - move H to A    &lt;br /&gt;
3C8FH  ORA L                ; OR LSB to test for zero  &lt;br /&gt;
3C90H  JZ 4884H             ; Branch if empty - File Empty Error     &lt;br /&gt;
3C93H  PUSH H               ; Save file address to stack   &lt;br /&gt;
3C94H  MVI A,01H            ; Set file open mode to new file      &lt;br /&gt;
3C96H  STA FCD6H            ; Save open mode to pass to open routine      &lt;br /&gt;
3C99H  CALL 4943H           ; Configure baud, test for NADSBox, get NADSBox dir       &lt;br /&gt;
3C9CH  CALL 4A72H           ; Send Dir Reference opcode       &lt;br /&gt;
3C9FH  JZ 3CCEH             ; Jump to write data if file doesn&#039;t exist (size = 0)     &lt;br /&gt;
3CA2H  LXI H,3F8BH          ; Point to &amp;quot;File Exists, A)ppend R)eplace Q)uit&amp;quot; text        &lt;br /&gt;
3CA5H  CALL 48F4H           ; Print string at HL to col 1 on the bottom line       &lt;br /&gt;
3CA8H  CALL 3DF8H           ; Process power-off logic and wait for a key from keyboard       &lt;br /&gt;
3CABH  ANI DFH              ; Make key uppercase    &lt;br /&gt;
3CADH  RST 4                ; Display key on LCD            &lt;br /&gt;
3CAEH  CPI 52H              ; Test if key is &#039;R&#039;    &lt;br /&gt;
3CB0H  JNZ 3CBCH            ; Jump if not &#039;R&#039;eplace                      &lt;br /&gt;
3CB3H  CALL 431AH           ; Issue TPDD Delete file Opcode       &lt;br /&gt;
3CB6H  CALL 4A72H           ; Send Dir Reference opcode       &lt;br /&gt;
3CB9H  JMP 3CCEH            ; Go write data to the file      &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F1-Save: Test for &#039;A&#039;ppend&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3CBCH  POP H                ; Get file length from stack    &lt;br /&gt;
3CBDH  POP D                ; Get file address from stack    &lt;br /&gt;
3CBEH  CPI 41H              ; Test if response is &#039;A&#039;ppend      &lt;br /&gt;
3CC0H  RNZ                  ; Return if not &#039;A&#039;  &lt;br /&gt;
3CC1H  LDA FCEFH            ; Load 1st byte of extension from TX buffer        &lt;br /&gt;
3CC4H  CPI 44H              ; Test if file is &amp;quot;D&amp;quot;O file      &lt;br /&gt;
3CC6H  RNZ                  ; Don&#039;t allow appending non DO files  &lt;br /&gt;
3CC7H  MVI A,02H            ; Set open mode to open existing (append)        &lt;br /&gt;
3CC9H  STA FCD6H            ; Save mode to pass to open routine        &lt;br /&gt;
3CCCH  PUSH D               ; Save file address on stack     &lt;br /&gt;
3CCDH  PUSH H               ; Save file length on stack     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Save function - Replace or new file, write data to file&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3CCEH  POP H                ; Retrieve file length from stack    &lt;br /&gt;
3CCFH  POP D                ; Retrieve file address from stack    &lt;br /&gt;
3CD0H  JMP 40C8H            ; Write HL bytes of data from (DE) to TPDD        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Calculate length of RAM file, HL=address of catalog entry, DE=file address&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3CD3H  MOV A,M              ; Get RAM file type from catalog   &lt;br /&gt;
3CD4H  CPI C0H              ; Test for .DO file   &lt;br /&gt;
3CD6H  JZ 3CE6H             ; Jump to calculate length if .DO file    &lt;br /&gt;
3CD9H  CPI A0H              ; Test for .CO file         &lt;br /&gt;
3CDBH  JZ 3CF5H             ; Jump to calculate length if .CO file    &lt;br /&gt;
3CDEH  PUSH D               ; Save address of start of BASIC program to stack  &lt;br /&gt;
3CDFH  CALL 4C13H           ; Call ROM routine to find BASIC end of program&lt;br /&gt;
3CE2H  POP B                ; Get BASIC program start address from stack &lt;br /&gt;
3CE3H  DSUB                 ; Subtract starting address from end address&lt;br /&gt;
3CE4H  DCX H                ; Don&#039;t count trailing 0x00 as part of BASIC program length &lt;br /&gt;
3CE5H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Calculate length of .DO file, HL=Catalog address, DE=file address&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3CE6H  XCHG                 ; HL &amp;lt;--&amp;gt; DE Get file address in HL &lt;br /&gt;
3CE7H  LXI D,0000H          ; Clear file length&lt;br /&gt;
3CEAH  MOV A,M              ; Get next byte from .DO file    &lt;br /&gt;
3CEBH  INX H                ; Increment pointer  &lt;br /&gt;
3CECH  INX D                ; Increment length  &lt;br /&gt;
3CEDH  CPI 1AH              ; Test for EOF marker    &lt;br /&gt;
3CEFH  JNZ 3CEAH            ; Branch to next byte if not EOF      &lt;br /&gt;
3CF2H  DCX D                ; Subtract EOF marker from file length  &lt;br /&gt;
3CF3H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  HL=length &lt;br /&gt;
3CF4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Calculate length of .CO file, HL=Catalog address, DE=file address&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3CF5H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  Get file address in HL &lt;br /&gt;
3CF6H  INX H                ; Increment past .CO load address &lt;br /&gt;
3CF7H  INX H                ; Increment past MSB of load address&lt;br /&gt;
3CF8H  MOV C,M              ; Get LSB of length  &lt;br /&gt;
3CF9H  INX H                ; Increment to MSB of length&lt;br /&gt;
3CFAH  MOV B,M              ; Get MSB of length&lt;br /&gt;
3CFBH  LXI H,0006H          ; Prepare to add 6-byte header to length&lt;br /&gt;
3CFEH  DAD B                ; Add 6-byte header to length&lt;br /&gt;
3CFFH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F7 Function key handler for DISK mode - Mkdir&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D00H  LDA FCCBH            ; NADSBox / TPDD2 / Desklink flag        &lt;br /&gt;
3D03H  ANA A                ; Test if server is TPDD    &lt;br /&gt;
3D04H  RZ                   ; Return if not NADSBox or TPDD2 &lt;br /&gt;
3D05H  DCR A                ; Test if TPDD2    &lt;br /&gt;
3D06H  JZ 37BAH             ; Go Swap TPDD Bank Number if TPDD2       &lt;br /&gt;
3D09H  CALL 4A3BH           ; Must be NADSBOx Initialize blank filename         &lt;br /&gt;
3D0CH  LXI H,3F61H          ; Load pointer to &amp;quot;Directory name:&amp;quot; text          &lt;br /&gt;
3D0FH  CALL 3E1AH           ; Get 6-byte input filename from keyboard         &lt;br /&gt;
3D12H  RZ                   ; Return if no input given &lt;br /&gt;
3D13H  CALL 4902H           ; Copy filename at (HL) to current BASIC program         &lt;br /&gt;
3D16H  LXI H,FC93H          ; Filename of current BASIC program              &lt;br /&gt;
3D19H  LXI D,FCE8H          ; Point to TX buffer data area (payload)          &lt;br /&gt;
3D1CH  LXI B,0006H          ; Prepare to copy 6 filename bytes to TX buffer          &lt;br /&gt;
3D1FH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment         &lt;br /&gt;
3D22H  LXI H,3E3CH          ; Load code for &amp;quot;&amp;lt;&amp;gt;&amp;quot;          &lt;br /&gt;
3D25H  SHLD FCEFH           ; Save &amp;quot;&amp;lt;&amp;gt;&amp;quot; extension bytes in TX buffer - NADSBox Mkdir                   &lt;br /&gt;
3D28H  MVI A,2EH            ; Load code for &#039;.&#039; extension separator        &lt;br /&gt;
3D2AH  STA FCEEH            ; Save &amp;quot;.&amp;quot; to TX buffer        &lt;br /&gt;
3D2DH  CALL 4943H           ; Configure baud, test for NADSBox, get NADSBox dir         &lt;br /&gt;
3D30H  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag        &lt;br /&gt;
3D33H  CPI 02H              ; Test if we have NADSBox current directory      &lt;br /&gt;
3D35H  RNZ                  ; Return if we don&#039;t have current directory  &lt;br /&gt;
3D36H  CALL 4A72H           ; Send Directory Reference opcode         &lt;br /&gt;
3D39H  JNZ 3D4DH            ; If the file exists, branch to open it for READ mode        &lt;br /&gt;
3D3CH  MVI A,01H            ; Load OPEN_WRITE mode into A to create the directory        &lt;br /&gt;
3D3EH  STA FCE8H            ; Save A in TX data storage mode field        &lt;br /&gt;
3D41H  LXI H,0101H          ; Load opcode to open a file          &lt;br /&gt;
3D44H  CALL 409BH           ; Send Request in HL and await response         &lt;br /&gt;
3D47H  LXI H,0002H          ; Load opcode to close the file          &lt;br /&gt;
3D4AH  JMP 409BH            ; Send Request in HL and await response        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Open and close a directory file (from above)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D4DH  CALL 408AH           ; Open TPDD file for Read Mode&lt;br /&gt;
3D50H  JMP 3D47H            ; Branch to close the directory open request&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F5 Function key handler for DISK mode - Format&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D53H  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag       &lt;br /&gt;
3D56H  CPI 02H              ; Test if we have &amp;quot;current directory&amp;quot; name     &lt;br /&gt;
3D58H  RZ                   ; Return if server is NADSBox / Desklink - No format supported&lt;br /&gt;
3D59H  LXI H,3F1BH          ; Load pointer to &amp;quot;Insert Disk&amp;quot; string&lt;br /&gt;
3D5CH  CALL 48F4H           ; Print string at HL to col 1 on the bottom line        &lt;br /&gt;
3D5FH  CALL 3DEEH           ; Get key from keyboard and test for &#039;Y&#039; or &#039;y&#039;        &lt;br /&gt;
3D62H  RNZ                  ; Return if response not &#039;Y&#039; &lt;br /&gt;
3D63H  CALL 4943H           ; Configure baud, test for NADSBox, get NADSBox dir        &lt;br /&gt;
3D66H  CALL 49E3H           ; Delay routine - about 3ms        &lt;br /&gt;
3D69H  LXI H,0006H          ; Load TPDD_FORMAT opcode in HL&lt;br /&gt;
3D6CH  CALL 409BH           ; Send Request in HL and await response        &lt;br /&gt;
3D6FH  MVI A,07H            ; Load code for BELL       &lt;br /&gt;
3D72H  RET                  ; Go beep to indicate format&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F2 Function key handler for DISK mode - Kill&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D73H  LDA FCCCH            ; Last Tag/Untag operation code      &lt;br /&gt;
3D76H  ANA A                ; Test if there&#039;s an active tag group&lt;br /&gt;
3D77H  CZ 3DE1H             ; Display &amp;quot;Sure ?&amp;quot;, validate and return if validated if no tag&lt;br /&gt;
3D7AH  CALL 4A3BH           ; Initialize blank filename and attribute byte&lt;br /&gt;
3D7DH  CALL 3D83H           ; Copy selected filename to TX buffer and init TPDD/NADSBox&lt;br /&gt;
3D80H  JMP 431AH            ; Issue TPDD Delete file Opcode            &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Copy selected filename to TX buffer and init TPDD/NADSBox&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D83H  LXI B,0009H          ; Prepare to copy 9 filename bytes&lt;br /&gt;
3D86H  LHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
3D89H  LXI D,FCE8H          ; Address of TX packet data&lt;br /&gt;
3D8CH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment&lt;br /&gt;
3D8FH  CALL 4943H           ; Configure baud, test for NADSBox, get NADSBox dir&lt;br /&gt;
3D92H  JMP 4A72H            ; Send Dir Reference opcode&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Copy filename at (HL) to TX buffer&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D95H  CALL 4902H           ; Copy filename at (HL) to current BASIC program&lt;br /&gt;
3D98H  LXI H,FC93H          ; Filename of current BASIC program&lt;br /&gt;
3D9BH  CALL 4A57H           ; Send Dir Reference for filename at (HL)&lt;br /&gt;
3D9EH  RET        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F3 Function key handler for DISK mode - Name&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D9FH  CALL 4A3BH           ; Initialize blank filename and attribute byte          &lt;br /&gt;
3DA2H  CALL 3D83H           ; Copy selected filename to TX buffer and init TPDD/NADSBox          &lt;br /&gt;
3DA5H  LXI H,FCE8H          ; Point to TX buffer data area (payload)&lt;br /&gt;
3DA8H  LXI D,FC9CH          ; Filename of last program loaded from tape  &lt;br /&gt;
3DABH  LXI B,0009H          ; Prepare to copy 9 bytes to &amp;quot;last program loaded&amp;quot; filename&lt;br /&gt;
3DAEH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment          &lt;br /&gt;
3DB1H  LHLD FD1DH           ; Get file size from RX buffer          &lt;br /&gt;
3DB4H  MOV C,H              ; Save file size MSB to C (swap endian)       &lt;br /&gt;
3DB5H  MOV B,L              ; Save file size LSB to B (swap endian)       &lt;br /&gt;
3DB6H  LXI H,7CC0H          ; ? Load HL with 31936&lt;br /&gt;
3DB9H  DSUB                 ; ? Compare file length with 31936    &lt;br /&gt;
3DBAH  LXI H,3F4AH          ; Address of &amp;quot;New name&amp;quot; string&lt;br /&gt;
3DBDH  JNZ 3DD7H            ; Branch to change filename if not 30656         &lt;br /&gt;
3DC0H  LXI B,0009H          ; Allow a 9-byte filename input string&lt;br /&gt;
3DC3H  CALL 3E1DH           ; Get max BC length input for filename and convert to uppercase          &lt;br /&gt;
3DC6H  RZ                   ; Return if no input provided  &lt;br /&gt;
3DC7H  PUSH H               ; Save pointer to input string to stack      &lt;br /&gt;
3DC8H  PUSH PSW             ; Save string length to stack        &lt;br /&gt;
3DC9H  CALL 4A3BH           ; Initialize blank filename and attribute byte          &lt;br /&gt;
3DCCH  POP PSW              ; Get string length from stack       &lt;br /&gt;
3DCDH  POP H                ; Get string address from stack     &lt;br /&gt;
3DCEH  LXI D,FCE8H          ; Point to TX buffer data area (payload)           &lt;br /&gt;
3DD1H  MOV C,A              ; Copy length to BC       &lt;br /&gt;
3DD2H  MVI B,00H            ; Make MSB of length = 0         &lt;br /&gt;
3DD4H  JMP 41B0H            ; Rename the TPDD file whose name is in (HL)         &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get filename from keyboard and rename Disk file, filename in &amp;quot;current BASIC program&amp;quot;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3DD7H  CALL 3E1AH           ; Get 6-byte input filename from keyboard&lt;br /&gt;
3DDAH  RZ                   ; Return if no input provided &lt;br /&gt;
3DDBH  CALL 4902H           ; Copy filename at (HL) to current BASIC program&lt;br /&gt;
3DDEH  JMP 41A7H            ; Rename the TPDD file whose name is in &amp;quot;current BASIC program&amp;quot; &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display &amp;quot;Sure ?&amp;quot;, validate and return if validated&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3DE1H  LXI H,3F83H          ; Load pointer to &amp;quot;Sure ?&amp;quot; string&lt;br /&gt;
3DE4H  CALL 48F4H           ; Print string at HL to col 1 on the bottom line &lt;br /&gt;
3DE7H  CALL 3DEEH           ; Get key and test for &#039;Y&#039; or &#039;y&#039; &lt;br /&gt;
3DEAH  JNZ 48B5H            ; Branch to &amp;quot;Long jump&amp;quot; operation to abort if not &#039;y&#039; &lt;br /&gt;
3DEDH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get key from keyboard and test for &#039;Y&#039; or &#039;y&#039;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3DEEH  CALL 3DF8H           ; Process power-off logic and wait for a key from keyboard&lt;br /&gt;
3DF1H  RST 4                ; Display the key on the LCD &lt;br /&gt;
3DF2H  CPI 59H              ; Test if key pressed was &#039;Y&#039;      &lt;br /&gt;
3DF4H  RZ                   ; Return if key pressed was &#039;Y&#039; &lt;br /&gt;
3DF5H  CPI 79H              ; Test if key pressed was &#039;y&#039;      &lt;br /&gt;
3DF7H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process power-off logic and wait for a key from keyboard&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3DF8H  CALL 3DFEH           ; Process automatic poweroff logic&lt;br /&gt;
3DFBH  JMP 4BEBH            ; Wait for key from keyboard&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process automatic power-off logic during key scan loop&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3DFEH  XRA A                ; Clear A  &lt;br /&gt;
3DFFH  DCR A                ; Set A to 0xFF   &lt;br /&gt;
3E00H  STA F656H            ; Power off exit condition switch  &lt;br /&gt;
3E03H  CALL 4C4AH           ; Check keyboard queue for pending characters&lt;br /&gt;
3E06H  JZ 3DFEH             ; Branch back if no keyboard characters in queue - wait for key&lt;br /&gt;
3E09H  XRA A                ; Clear A  &lt;br /&gt;
3E0AH  STA F656H            ; Power off exit condition switch  &lt;br /&gt;
3E0DH  LXI H,F932H          ; Load address of &amp;quot;Renew Automatic Poweroff Counter Flag&amp;quot;&lt;br /&gt;
3E10H  ORA M                ; Test if auto poweroff counter should be renewed&lt;br /&gt;
3E11H  JZ 4BF7H             ; Renew automatic power-off counter if enabled&lt;br /&gt;
3E14H  CALL 4BF3H           ; Turn off the computer&lt;br /&gt;
3E17H  JMP 3DFEH            ; Branch back to continue processing power off logic&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get max 6-byte input for filename and convert to uppercase&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E1AH  LXI B,0006H          ; Get maximum 6 characters of input&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get max BC length input for filename and convert to uppercase&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E1DH  CALL 3E2FH           ; Get max BC length input string from keyboard&lt;br /&gt;
3E20H  RZ                   ; Return if no input provided &lt;br /&gt;
3E21H  PUSH H               ; Preserve pointer to input string     &lt;br /&gt;
3E22H  PUSH PSW             ; Preserve flags from input       &lt;br /&gt;
3E23H  CALL 4C5EH           ; Get char at M and convert to uppercase&lt;br /&gt;
3E26H  MOV M,A              ; Save uppercase char back to string      &lt;br /&gt;
3E27H  INX H                ; Point to next byte in input     &lt;br /&gt;
3E28H  ANA A                ; Test for NULL - end of string    &lt;br /&gt;
3E29H  JNZ 3E23H            ; Keep looping until end of string        &lt;br /&gt;
3E2CH  POP PSW              ; Restore flags from input routine      &lt;br /&gt;
3E2DH  POP H                ; Restore pointer to input string    &lt;br /&gt;
3E2EH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get maximum BC length input character string from keyboard&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E2FH  PUSH B               ; Save maximum input length to stack     &lt;br /&gt;
3E30H  CALL 48F4H           ; Print string at HL to col 1 on the bottom line&lt;br /&gt;
3E33H  CALL 4C46H           ; Input and display (no &amp;quot;?&amp;quot;) line and store&lt;br /&gt;
3E36H  JC 48B5H             ; Branch to &amp;quot;Long jump&amp;quot; if CTRL-C       &lt;br /&gt;
3E39H  INX H                ; Point to start of input string    &lt;br /&gt;
3E3AH  MOV A,B              ; Get string length (counting NULL)      &lt;br /&gt;
3E3BH  DCR A                ; Remove NULL from count    &lt;br /&gt;
3E3CH  POP D                ; Restore maximum input length    &lt;br /&gt;
3E3DH  RZ                   ; Return if string length is zero &lt;br /&gt;
3E3EH  CMP E                ; Compare expected length with actual length    &lt;br /&gt;
3E3FH  RC                   ; Return if string is shorter than expected          &lt;br /&gt;
3E40H  PUSH H               ; Save pointer to start of string on stack     &lt;br /&gt;
3E41H  DAD D                ; Add Expected length to pointer    &lt;br /&gt;
3E42H  MVI M,00H            ; Truncate the string to the max length        &lt;br /&gt;
3E44H  POP H                ; Restore pointer to input string    &lt;br /&gt;
3E45H  MOV A,E              ; Update length to reflect maximum      &lt;br /&gt;
3E46H  ORA A                ; Clear zero flag to indicate input provided    &lt;br /&gt;
3E47H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Find Empty catalog entry (only 9 instructions...Don&#039;t bother with Main ROM)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E48H  LXI H,F9AFH         ; Point to the &amp;quot;RickY&amp;quot; catalog entry (start of valid entries)&lt;br /&gt;
3E4BH  LXI B,000BH         ; Load length of each catalog entry&lt;br /&gt;
3E4EH  DAD B               ; Point to next catalog entry to test if empty&lt;br /&gt;
3E4FH  MOV A,M             ; Get file attribute byte from catalog entry&lt;br /&gt;
3E50H  CPI FFH             ; Test if at end of catalog&lt;br /&gt;
3E52H  JZ 3E5AH            ; Jump to report directory full if at end&lt;br /&gt;
3E55H  ADD A               ; Test if MSB is set (entry being used)&lt;br /&gt;
3E56H  JC 3E4EH            ; Jump to test next enry if MSB set&lt;br /&gt;
3E59H  RET                 ; Entry found...return with Carry clear&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Empty catalog entry not found...set Carry and exit&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E5AH  STC                 ; Indicate empty entry not found&lt;br /&gt;
3E5BH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F5 Function key handler for RAM mode - DOS ON/OF&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E5CH  LHLD FB2CH          ; Get LFILES statement hook address&lt;br /&gt;
3E5FH  LXI B,08DBH         ; Load address of default (DOS-OFF) hook for LFILES&lt;br /&gt;
3E62H  DSUB                ; Test if in DOS-OFF mode&lt;br /&gt;
3E63H  JZ 401FH            ; Jump to add our custom RST 7 hooks if in DOS-OFF mode&lt;br /&gt;
3E66H  JMP 3FFAH           ; Must be in DOS-ON mode, jump to turn it off&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Strings&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E69H  DB	0x1B, &amp;quot;p TS-DOS (100 v4.00) (c)87,TSI.          &amp;quot;,0x1B,&#039;q&#039;,0x00&lt;br /&gt;
3E97H  DB   &amp;quot;DISK Free:         File:&amp;quot;,0DH,0AH,&amp;quot;Load Kill Name Ram  Frmt Log       Menu&amp;quot;,00H&lt;br /&gt;
3ED9H  DB   &amp;quot; RAM Free:         File:&amp;quot;,0DH,0AH,&amp;quot;Save Kill Name Disk DOS-           Menu&amp;quot;,00H&lt;br /&gt;
3F1BH  DB   &amp;quot;Insert Disk, Press \&amp;quot;Y\&amp;quot; to begin &amp;quot;,00H&lt;br /&gt;
3F3CH  DB   &amp;quot;NOT FORMATTED&amp;quot;,00H&lt;br /&gt;
3F4AH  DB   &amp;quot;New Name:&amp;quot;,00H&lt;br /&gt;
3F54H  DB   &amp;quot;System name:&amp;quot;,00H&lt;br /&gt;
3F61H  DB   &amp;quot;Directory name:&amp;quot;,00H&lt;br /&gt;
3F71H  DB   &amp;quot;Save as:&amp;quot;,00H&lt;br /&gt;
3F7AH  DB   &amp;quot;Load as:&amp;quot;,00H&lt;br /&gt;
3F83H  DB   &amp;quot;Sure ? &amp;quot;,00H&lt;br /&gt;
3F8BH  DB   &amp;quot;File exists, A)ppend R)eplace Q)uit:&amp;quot;,00H&lt;br /&gt;
3FB0H  DB   &amp;quot;File exists, Replace? (Y/N):&amp;quot;,00H&lt;br /&gt;
3FCDH  DB   &amp;quot;-.-       &amp;quot;,00H&lt;br /&gt;
3FD8H  DB   0x1B,&amp;quot;Y74    &amp;quot;,1BH,&amp;quot;Y7&amp;gt;MkDr&amp;quot;,00H     ;  TODO: Check this&lt;br /&gt;
3FE9H  DB   0x1B,&amp;quot;Y7&amp;gt;Bank&amp;quot;,00H                   ;  TODO: Check this&lt;br /&gt;
3FF2H  DB   &amp;quot;OFF&amp;quot;,00H&lt;br /&gt;
3FF6H  DB   &amp;quot;ON &amp;quot;,00H&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Navigate to:&lt;br /&gt;
* [[Dissasembly of RAM and ROM versions of TS-DOS]]&lt;br /&gt;
* [[M100 TS-DOS ROM OptROM Support]]&lt;br /&gt;
* [[M100 TS-DOS ROM RST 7 Handlers]]&lt;br /&gt;
* [[M100 TS-DOS ROM TPDD Protocol]]&lt;br /&gt;
* [[M100 TS-DOS ROM Compression]]&lt;br /&gt;
* [[M100 TS-DOS ROM Cold Boot Recovery]]&lt;/div&gt;</summary>
		<author><name>Kpettit</name></author>
	</entry>
	<entry>
		<id>https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_Cold_Boot_Recovery&amp;diff=1385</id>
		<title>M100 TS-DOS ROM Cold Boot Recovery</title>
		<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_Cold_Boot_Recovery&amp;diff=1385"/>
		<updated>2009-04-03T08:16:34Z</updated>

		<summary type="html">&lt;p&gt;Kpettit: New page: == TS-DOS Model 100/102 ROM Cold Start Recovery Routines  This source, as you can see, has not been commented yet.  &amp;lt;pre&amp;gt; ; ================================================================...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== TS-DOS Model 100/102 ROM Cold Start Recovery Routines&lt;br /&gt;
&lt;br /&gt;
This source, as you can see, has not been commented yet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Cold Start File Recovery routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
7000H  (21H) LXI H,7065H&lt;br /&gt;
7003H  (11H) LXI D,FC93H    ; Filename of current BASIC program&lt;br /&gt;
7006H  (01H) LXI B,0008H&lt;br /&gt;
7009H  (CDH) CALL 705AH&lt;br /&gt;
700CH  (2AH) LHLD FBAEH     ; Start of DO files pointer&lt;br /&gt;
700FH  (44H) MOV B,H&lt;br /&gt;
7010H  (4DH) MOV C,L&lt;br /&gt;
7011H  (21H) LXI H,E5F0H&lt;br /&gt;
7014H  (08H) DSUB&lt;br /&gt;
7015H  (50H) MOV D,B&lt;br /&gt;
7016H  (59H) MOV E,C&lt;br /&gt;
7017H  (EBH) XCHG&lt;br /&gt;
7018H  (D5H) PUSH D&lt;br /&gt;
7019H  (7EH) MOV A,M&lt;br /&gt;
701AH  (FEH) CPI 0AH&lt;br /&gt;
701CH  (CAH) JZ 7030H&lt;br /&gt;
701FH  (FEH) CPI 0DH&lt;br /&gt;
7021H  (CAH) JZ 7030H&lt;br /&gt;
7024H  (FEH) CPI 7FH&lt;br /&gt;
7026H  (D2H) JNC 702EH&lt;br /&gt;
7029H  (FEH) CPI 20H&lt;br /&gt;
702BH  (D2H) JNC 7030H&lt;br /&gt;
702EH  (3EH) MVI A,20H&lt;br /&gt;
7030H  (77H) MOV M,A&lt;br /&gt;
7031H  (23H) INX H&lt;br /&gt;
7032H  (1BH) DCX D&lt;br /&gt;
7033H  (7AH) MOV A,D&lt;br /&gt;
7034H  (B3H) ORA E&lt;br /&gt;
7035H  (C2H) JNZ 7019H&lt;br /&gt;
7038H  (C1H) POP B&lt;br /&gt;
7039H  (E5H) PUSH H&lt;br /&gt;
703AH  (2AH) LHLD FBAEH     ; Start of DO files pointer&lt;br /&gt;
703DH  (CDH) CALL 7081H&lt;br /&gt;
7040H  (E1H) POP H&lt;br /&gt;
7041H  (36H) MVI M,1AH&lt;br /&gt;
7043H  (2BH) DCX H&lt;br /&gt;
7044H  (36H) MVI M,1AH&lt;br /&gt;
7046H  (CDH) CALL 706DH&lt;br /&gt;
7049H  (EBH) XCHG&lt;br /&gt;
704AH  (2AH) LHLD FBAEH     ; Start of DO files pointer&lt;br /&gt;
704DH  (2BH) DCX H&lt;br /&gt;
704EH  (EBH) XCHG&lt;br /&gt;
704FH  (3EH) MVI A,C0H&lt;br /&gt;
7051H  (CDH) CALL 7089H&lt;br /&gt;
7054H  (CDH) CALL 7085H&lt;br /&gt;
7057H  (C3H) JMP 708DH&lt;br /&gt;
&lt;br /&gt;
705AH  (7EH) MOV A,M&lt;br /&gt;
705BH  (12H) STAX D&lt;br /&gt;
705CH  (23H) INX H&lt;br /&gt;
705DH  (13H) INX D&lt;br /&gt;
705EH  (0BH) DCX B&lt;br /&gt;
705FH  (78H) MOV A,B&lt;br /&gt;
7060H  (B1H) ORA C&lt;br /&gt;
7061H  (C2H) JNZ 705AH&lt;br /&gt;
7064H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
7065H  (52H) MOV D,D&lt;br /&gt;
7066H  (45H) MOV B,L&lt;br /&gt;
7067H  (43H) MOV B,E&lt;br /&gt;
7068H  (4FH) MOV C,A&lt;br /&gt;
7069H  (56H) MOV D,M&lt;br /&gt;
706AH  (52H) MOV D,D&lt;br /&gt;
706BH  (44H) MOV B,H&lt;br /&gt;
706CH  (4FH) MOV C,A&lt;br /&gt;
706DH  (21H) LXI H,F9AFH&lt;br /&gt;
7070H  (01H) LXI B,000BH&lt;br /&gt;
7073H  (09H) DAD B&lt;br /&gt;
7074H  (7EH) MOV A,M&lt;br /&gt;
7075H  (FEH) CPI FFH&lt;br /&gt;
7077H  (CAH) JZ 707FH&lt;br /&gt;
707AH  (87H) ADD A&lt;br /&gt;
707BH  (DAH) JC 7073H&lt;br /&gt;
707EH  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
707FH  (37H) STC&lt;br /&gt;
7080H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
7081H  (CFH) RST 1          ; Call main ROM at address in following 2 bytes&lt;br /&gt;
7082H  DW    6B6DH&lt;br /&gt;
7084H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
7085H  (CFH) RST 1          ; Call main ROM at address in following 2 bytes&lt;br /&gt;
7086H  DW    2146H&lt;br /&gt;
7088H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
7089H  (CFH) RST 1          ; Call main ROM at address in following 2 bytes&lt;br /&gt;
708AH  DW    2239H)&lt;br /&gt;
708CH  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
708BH  (CFH) RST 1          ; Call main ROM at address in following 2 bytes&lt;br /&gt;
708EH  DW    0000H&lt;br /&gt;
7090H  (C9H) RET&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Navigate to:&lt;br /&gt;
* [[Dissasembly of RAM and ROM versions of TS-DOS]]&lt;br /&gt;
* [[M100 TS-DOS ROM OptROM Support]]&lt;br /&gt;
* [[M100 TS-DOS ROM UI Code]]&lt;br /&gt;
* [[M100 TS-DOS ROM RST 7 Handlers]]&lt;br /&gt;
* [[M100 TS-DOS ROM TPDD Protocol]]&lt;br /&gt;
* [[M100 TS-DOS ROM Compression]]&lt;/div&gt;</summary>
		<author><name>Kpettit</name></author>
	</entry>
	<entry>
		<id>https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_Compression&amp;diff=1384</id>
		<title>M100 TS-DOS ROM Compression</title>
		<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_Compression&amp;diff=1384"/>
		<updated>2009-04-03T08:14:17Z</updated>

		<summary type="html">&lt;p&gt;Kpettit: New page: == TS-DOS Model 100/102 ROM Compression Routines ==  This code, as you can see, has not been disassembled yet.  &amp;lt;pre&amp;gt; ; ====================================================================...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== TS-DOS Model 100/102 ROM Compression Routines ==&lt;br /&gt;
&lt;br /&gt;
This code, as you can see, has not been disassembled yet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Compress / Decompress a file a .DO file&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
5000H  CALL 5008H&lt;br /&gt;
5003H  RET&lt;br /&gt;
&lt;br /&gt;
5004H  CALL 500FH&lt;br /&gt;
5007H  RET&lt;br /&gt;
&lt;br /&gt;
5008H  XRA A&lt;br /&gt;
5009H  STA F69EH&lt;br /&gt;
500CH  JMP 5018H&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Perform compression / decompression&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
500FH  (3EH) MVI A,0CH&lt;br /&gt;
5011H  (32H) STA F69EH&lt;br /&gt;
5014H  (E7H) RST 4          ; Send character in A to screen/printer&lt;br /&gt;
5015H  (CDH) CALL 5347H&lt;br /&gt;
5018H  (22H) SHLD F69BH&lt;br /&gt;
501BH  (21H) LXI H,534BH&lt;br /&gt;
501EH  (11H) LXI D,F685H    ; Keyboard buffer&lt;br /&gt;
5021H  (01H) LXI B,0015H&lt;br /&gt;
5024H  (CDH) CALL 5318H&lt;br /&gt;
5027H  (3EH) MVI A,50H&lt;br /&gt;
5029H  (32H) STA F69DH&lt;br /&gt;
502CH  (AFH) XRA A&lt;br /&gt;
502DH  (32H) STA F69FH&lt;br /&gt;
5030H  (CDH) CALL 533BH&lt;br /&gt;
5033H  (2AH) LHLD F69BH&lt;br /&gt;
5036H  (CDH) CALL 5333H&lt;br /&gt;
5039H  (EBH) XCHG&lt;br /&gt;
503AH  (D5H) PUSH D&lt;br /&gt;
503BH  (CDH) CALL 52ABH&lt;br /&gt;
503EH  (00H) NOP&lt;br /&gt;
503FH  (2EH) MVI L,7EH&lt;br /&gt;
5041H  (C2H) JNZ 5046H&lt;br /&gt;
5044H  (2EH) MVI L,80H&lt;br /&gt;
5046H  (01H) LXI B,0000H&lt;br /&gt;
5049H  (1AH) LDAX D&lt;br /&gt;
504AH  (BDH) CMP L&lt;br /&gt;
504BH  (DAH) JC 504FH&lt;br /&gt;
504EH  (03H) INX B&lt;br /&gt;
504FH  (13H) INX D&lt;br /&gt;
5050H  (FEH) CPI 1AH&lt;br /&gt;
5052H  (C2H) JNZ 5049H&lt;br /&gt;
5055H  (E1H) POP H&lt;br /&gt;
5056H  (3AH) LDA F69EH&lt;br /&gt;
5059H  (D6H) SUI 0CH&lt;br /&gt;
505BH  (C2H) JNZ 5060H      ; Generate IE error&lt;br /&gt;
505EH  (47H) MOV B,A&lt;br /&gt;
505FH  (4FH) MOV C,A&lt;br /&gt;
5060H  (CDH) CALL 533FH&lt;br /&gt;
5063H  (D8H) RC&lt;br /&gt;
5064H  (2BH) DCX H&lt;br /&gt;
5065H  (E5H) PUSH H&lt;br /&gt;
5066H  (CDH) CALL 52A5H&lt;br /&gt;
5069H  (C2H) JNZ 5098H&lt;br /&gt;
506CH  (CDH) CALL 52ABH&lt;br /&gt;
506FH  (DCH) CC 5307H&lt;br /&gt;
5072H  (C3H) JMP 521AH&lt;br /&gt;
&lt;br /&gt;
5075H  (CDH) CALL 5323H&lt;br /&gt;
5078H  (DAH) JC 5075H&lt;br /&gt;
507BH  (CDH) CALL 5337H&lt;br /&gt;
507EH  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
507FH  (4FH) MOV C,A&lt;br /&gt;
5080H  (FEH) CPI 3AH&lt;br /&gt;
5082H  (D0H) RNC&lt;br /&gt;
5083H  (FEH) CPI 20H&lt;br /&gt;
5085H  (37H) STC&lt;br /&gt;
5086H  (C8H) RZ&lt;br /&gt;
5087H  (FEH) CPI 2FH&lt;br /&gt;
5089H  (C8H) RZ&lt;br /&gt;
508AH  (3FH) CMC&lt;br /&gt;
508BH  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
508CH  (D6H) SUI 2FH&lt;br /&gt;
508EH  (D0H) RNC&lt;br /&gt;
508FH  (3EH) MVI A,0BH&lt;br /&gt;
5091H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
5092H  (FEH) CPI 3AH&lt;br /&gt;
5094H  (C0H) RNZ&lt;br /&gt;
5095H  (3EH) MVI A,20H&lt;br /&gt;
5097H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
5098H  (D5H) PUSH D&lt;br /&gt;
5099H  (00H) NOP&lt;br /&gt;
509AH  (00H) NOP&lt;br /&gt;
509BH  (01H) LXI B,0000H&lt;br /&gt;
509EH  (C5H) PUSH B&lt;br /&gt;
509FH  (E1H) POP H&lt;br /&gt;
50A0H  (03H) INX B&lt;br /&gt;
50A1H  (13H) INX D&lt;br /&gt;
50A2H  (1AH) LDAX D&lt;br /&gt;
50A3H  (FEH) CPI 5BH&lt;br /&gt;
50A5H  (D2H) JNC 50A0H&lt;br /&gt;
50A8H  (FEH) CPI 1AH&lt;br /&gt;
50AAH  (CAH) JZ 50B7H&lt;br /&gt;
50ADH  (FEH) CPI 41H&lt;br /&gt;
50AFH  (DAH) JC 50A1H&lt;br /&gt;
50B2H  (00H) NOP&lt;br /&gt;
50B3H  (23H) INX H&lt;br /&gt;
50B4H  (C3H) JMP 50A1H&lt;br /&gt;
&lt;br /&gt;
50B7H  (C5H) PUSH B&lt;br /&gt;
50B8H  (D1H) POP D&lt;br /&gt;
50B9H  (DFH) RST 3          ; Compare DE and HL&lt;br /&gt;
50BAH  (D1H) POP D&lt;br /&gt;
50BBH  (DAH) JC 50C6H&lt;br /&gt;
50BEH  (CDH) CALL 5307H&lt;br /&gt;
50C1H  (3EH) MVI A,43H&lt;br /&gt;
50C3H  (32H) STA F69DH&lt;br /&gt;
50C6H  (AFH) XRA A&lt;br /&gt;
50C7H  (32H) STA F69FH&lt;br /&gt;
50CAH  (CDH) CALL 520AH&lt;br /&gt;
50CDH  (CDH) CALL 518AH&lt;br /&gt;
50D0H  (D2H) JNC 515EH&lt;br /&gt;
50D3H  (CDH) CALL 507FH&lt;br /&gt;
50D6H  (00H) NOP&lt;br /&gt;
50D7H  (D2H) JNC 5117H&lt;br /&gt;
50DAH  (13H) INX D&lt;br /&gt;
50DBH  (1AH) LDAX D&lt;br /&gt;
50DCH  (CDH) CALL 5080H&lt;br /&gt;
50DFH  (1BH) DCX D&lt;br /&gt;
50E0H  (47H) MOV B,A&lt;br /&gt;
50E1H  (79H) MOV A,C&lt;br /&gt;
50E2H  (D2H) JNC 5117H&lt;br /&gt;
50E5H  (C2H) JNZ 50EEH&lt;br /&gt;
50E8H  (B8H) CMP B&lt;br /&gt;
50E9H  (CAH) JZ 5136H&lt;br /&gt;
50ECH  (00H) NOP&lt;br /&gt;
50EDH  (00H) NOP&lt;br /&gt;
50EEH  (13H) INX D&lt;br /&gt;
50EFH  (21H) LXI H,F69FH&lt;br /&gt;
50F2H  (00H) NOP&lt;br /&gt;
50F3H  (7EH) MOV A,M&lt;br /&gt;
50F4H  (B7H) ORA A&lt;br /&gt;
50F5H  (C2H) JNZ 50FFH&lt;br /&gt;
50F8H  (3EH) MVI A,7EH&lt;br /&gt;
50FAH  (77H) MOV M,A&lt;br /&gt;
50FBH  (E1H) POP H&lt;br /&gt;
50FCH  (77H) MOV M,A&lt;br /&gt;
50FDH  (23H) INX H&lt;br /&gt;
50FEH  (E5H) PUSH H&lt;br /&gt;
50FFH  (79H) MOV A,C&lt;br /&gt;
5100H  (CDH) CALL 508CH&lt;br /&gt;
5103H  (00H) NOP&lt;br /&gt;
5104H  (4FH) MOV C,A&lt;br /&gt;
5105H  (78H) MOV A,B&lt;br /&gt;
5106H  (CDH) CALL 508CH&lt;br /&gt;
5109H  (C6H) ADI 0BH&lt;br /&gt;
510BH  (0DH) DCR C&lt;br /&gt;
510CH  (C2H) JNZ 5109H&lt;br /&gt;
510FH  (C6H) ADI 7AH&lt;br /&gt;
5111H  (E1H) POP H&lt;br /&gt;
5112H  (77H) MOV M,A&lt;br /&gt;
5113H  (E5H) PUSH H&lt;br /&gt;
5114H  (C3H) JMP 50CAH&lt;br /&gt;
&lt;br /&gt;
5117H  (E1H) POP H&lt;br /&gt;
5118H  (FEH) CPI 0DH&lt;br /&gt;
511AH  (C2H) JNZ 512AH&lt;br /&gt;
511DH  (13H) INX D&lt;br /&gt;
511EH  (1AH) LDAX D&lt;br /&gt;
511FH  (FEH) CPI 0AH&lt;br /&gt;
5121H  (1BH) DCX D&lt;br /&gt;
5122H  (3EH) MVI A,0DH&lt;br /&gt;
5124H  (C2H) JNZ 512AH&lt;br /&gt;
5127H  (13H) INX D&lt;br /&gt;
5128H  (3EH) MVI A,80H&lt;br /&gt;
512AH  (77H) MOV M,A&lt;br /&gt;
512BH  (E5H) PUSH H&lt;br /&gt;
512CH  (3AH) LDA F69FH&lt;br /&gt;
512FH  (B7H) ORA A&lt;br /&gt;
5130H  (C2H) JNZ 50C6H&lt;br /&gt;
5133H  (00H) NOP&lt;br /&gt;
5134H  (00H) NOP&lt;br /&gt;
5135H  (7EH) MOV A,M&lt;br /&gt;
5136H  (21H) LXI H,F684H&lt;br /&gt;
5139H  (06H) MVI B,07H&lt;br /&gt;
513BH  (05H) DCR B&lt;br /&gt;
513CH  (CAH) JZ 50CAH&lt;br /&gt;
513FH  (23H) INX H&lt;br /&gt;
5140H  (BEH) CMP M&lt;br /&gt;
5141H  (C2H) JNZ 513BH&lt;br /&gt;
5144H  (0EH) MVI C,15H&lt;br /&gt;
5146H  (CDH) CALL 518AH&lt;br /&gt;
5149H  (D2H) JNC 515EH&lt;br /&gt;
514CH  (21H) LXI H,F685H    ; Keyboard buffer&lt;br /&gt;
514FH  (BEH) CMP M&lt;br /&gt;
5150H  (CAH) JZ 517BH&lt;br /&gt;
5153H  (0DH) DCR C&lt;br /&gt;
5154H  (CCH) CZ 520AH&lt;br /&gt;
5157H  (CAH) JZ 5184H&lt;br /&gt;
515AH  (23H) INX H&lt;br /&gt;
515BH  (C3H) JMP 514FH&lt;br /&gt;
&lt;br /&gt;
515EH  (32H) STA F69AH&lt;br /&gt;
5161H  (AFH) XRA A&lt;br /&gt;
5162H  (32H) STA F69FH&lt;br /&gt;
5165H  (78H) MOV A,B&lt;br /&gt;
5166H  (FEH) CPI 07H&lt;br /&gt;
5168H  (D2H) JNC 516EH&lt;br /&gt;
516BH  (CDH) CALL 520AH&lt;br /&gt;
516EH  (E1H) POP H&lt;br /&gt;
516FH  (36H) MVI M,FFH&lt;br /&gt;
5171H  (E5H) PUSH H&lt;br /&gt;
5172H  (3AH) LDA F69AH&lt;br /&gt;
5175H  (CDH) CALL 5195H&lt;br /&gt;
5178H  (C3H) JMP 50CAH&lt;br /&gt;
&lt;br /&gt;
517BH  (79H) MOV A,C&lt;br /&gt;
517CH  (C6H) ADI 15H&lt;br /&gt;
517EH  (05H) DCR B&lt;br /&gt;
517FH  (C2H) JNZ 517CH&lt;br /&gt;
5182H  (C6H) ADI 6BH&lt;br /&gt;
5184H  (E1H) POP H&lt;br /&gt;
5185H  (77H) MOV M,A&lt;br /&gt;
5186H  (E5H) PUSH H&lt;br /&gt;
5187H  (C3H) JMP 50CAH&lt;br /&gt;
&lt;br /&gt;
518AH  (13H) INX D&lt;br /&gt;
518BH  (1AH) LDAX D&lt;br /&gt;
518CH  (FEH) CPI 1AH&lt;br /&gt;
518EH  (CAH) JZ 52BAH&lt;br /&gt;
5191H  (FEH) CPI 7EH&lt;br /&gt;
5193H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
5194H  (7EH) MOV A,M&lt;br /&gt;
5195H  (4FH) MOV C,A&lt;br /&gt;
5196H  (3AH) LDA F69EH&lt;br /&gt;
5199H  (B7H) ORA A&lt;br /&gt;
519AH  (79H) MOV A,C&lt;br /&gt;
519BH  (C1H) POP B&lt;br /&gt;
519CH  (E1H) POP H&lt;br /&gt;
519DH  (23H) INX H&lt;br /&gt;
519EH  (C2H) JNZ 51A2H&lt;br /&gt;
51A1H  (77H) MOV M,A&lt;br /&gt;
51A2H  (E5H) PUSH H&lt;br /&gt;
51A3H  (C5H) PUSH B&lt;br /&gt;
51A4H  (C8H) RZ&lt;br /&gt;
51A5H  (E7H) RST 4          ; Send character in A to screen/printer&lt;br /&gt;
51A6H  (D5H) PUSH D&lt;br /&gt;
51A7H  (6FH) MOV L,A&lt;br /&gt;
51A8H  (3AH) LDA F63AH      ; Cursor column (1-40)&lt;br /&gt;
51ABH  (2FH) CMA&lt;br /&gt;
51ACH  (C6H) ADI 2CH&lt;br /&gt;
51AEH  (67H) MOV H,A&lt;br /&gt;
51AFH  (7DH) MOV A,L&lt;br /&gt;
51B0H  (CDH) CALL 51D7H&lt;br /&gt;
51B3H  (00H) NOP&lt;br /&gt;
51B4H  (00H) NOP&lt;br /&gt;
51B5H  (3FH) CMC&lt;br /&gt;
51B6H  (CAH) JZ 51C4H&lt;br /&gt;
51B9H  (D2H) JNC 51C7H      ; Print current STAT settings&lt;br /&gt;
51BCH  (13H) INX D&lt;br /&gt;
51BDH  (1AH) LDAX D&lt;br /&gt;
51BEH  (CDH) CALL 51D7H&lt;br /&gt;
51C1H  (C3H) JMP 51B6H&lt;br /&gt;
&lt;br /&gt;
51C4H  (CDH) CALL 532FH&lt;br /&gt;
51C7H  (CDH) CALL 5075H&lt;br /&gt;
51CAH  (00H) NOP&lt;br /&gt;
51CBH  (D1H) POP D&lt;br /&gt;
51CCH  (C8H) RZ&lt;br /&gt;
51CDH  (FEH) CPI 20H&lt;br /&gt;
51CFH  (DAH) JC 52BAH&lt;br /&gt;
51D2H  (CCH) CZ 5327H&lt;br /&gt;
51D5H  (00H) NOP&lt;br /&gt;
51D6H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
51D7H  (25H) DCR H&lt;br /&gt;
51D8H  (C8H) RZ&lt;br /&gt;
51D9H  (FEH) CPI 21H&lt;br /&gt;
51DBH  (3FH) CMC&lt;br /&gt;
51DCH  (D0H) RNC&lt;br /&gt;
51DDH  (FEH) CPI FEH&lt;br /&gt;
51DFH  (3DH) DCR A&lt;br /&gt;
51E0H  (D0H) RNC&lt;br /&gt;
51E1H  (D6H) SUI 7FH&lt;br /&gt;
51E3H  (CAH) JZ 5200H&lt;br /&gt;
51E6H  (D8H) RC&lt;br /&gt;
51E7H  (25H) DCR H&lt;br /&gt;
51E8H  (00H) NOP&lt;br /&gt;
51E9H  (C8H) RZ&lt;br /&gt;
51EAH  (F5H) PUSH PSW&lt;br /&gt;
51EBH  (3AH) LDA F69FH&lt;br /&gt;
51EEH  (B7H) ORA A&lt;br /&gt;
51EFH  (01H) LXI B,050BH&lt;br /&gt;
51F2H  (C2H) JNZ 51F8H&lt;br /&gt;
51F5H  (01H) LXI B,0015H&lt;br /&gt;
51F8H  (F1H) POP PSW&lt;br /&gt;
51F9H  (90H) SUB B&lt;br /&gt;
51FAH  (90H) SUB B&lt;br /&gt;
51FBH  (00H) NOP&lt;br /&gt;
51FCH  (D8H) RC&lt;br /&gt;
51FDH  (3CH) INR A&lt;br /&gt;
51FEH  (FEH) CPI 6AH&lt;br /&gt;
5200H  (3DH) DCR A&lt;br /&gt;
5201H  (D0H) RNC&lt;br /&gt;
5202H  (80H) ADD B&lt;br /&gt;
5203H  (91H) SUB C&lt;br /&gt;
5204H  (D8H) RC&lt;br /&gt;
5205H  (C2H) JNZ 5203H&lt;br /&gt;
5208H  (3CH) INR A&lt;br /&gt;
5209H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
520AH  (C1H) POP B&lt;br /&gt;
520BH  (E1H) POP H&lt;br /&gt;
520CH  (23H) INX H&lt;br /&gt;
520DH  (E5H) PUSH H&lt;br /&gt;
520EH  (C5H) PUSH B&lt;br /&gt;
520FH  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
5210H  (AFH) XRA A&lt;br /&gt;
5211H  (32H) STA F69FH&lt;br /&gt;
5214H  (CDH) CALL 518AH&lt;br /&gt;
5217H  (C3H) JMP 522FH      ; TELCOM CALL instruction routine&lt;br /&gt;
&lt;br /&gt;
521AH  (CDH) CALL 52ABH&lt;br /&gt;
521DH  (C2H) JNZ 5210H&lt;br /&gt;
5220H  (CDH) CALL 518AH&lt;br /&gt;
5223H  (DAH) JC 522FH       ; TELCOM CALL instruction routine&lt;br /&gt;
5226H  (C2H) JNZ 5239H&lt;br /&gt;
5229H  (32H) STA F69FH&lt;br /&gt;
522CH  (C3H) JMP 521AH&lt;br /&gt;
&lt;br /&gt;
522FH  (CDH) CALL 5195H&lt;br /&gt;
5232H  (AFH) XRA A&lt;br /&gt;
5233H  (32H) STA F69FH&lt;br /&gt;
5236H  (C3H) JMP 521AH&lt;br /&gt;
&lt;br /&gt;
5239H  (FEH) CPI 80H&lt;br /&gt;
523BH  (C2H) JNZ 5248H&lt;br /&gt;
523EH  (3EH) MVI A,0DH&lt;br /&gt;
5240H  (CDH) CALL 5195H&lt;br /&gt;
5243H  (3EH) MVI A,0AH&lt;br /&gt;
5245H  (C3H) JMP 522FH      ; TELCOM CALL instruction routine&lt;br /&gt;
&lt;br /&gt;
5248H  (FEH) CPI FEH&lt;br /&gt;
524AH  (CAH) JZ 5281H&lt;br /&gt;
524DH  (D2H) JNC 5210H&lt;br /&gt;
5250H  (4FH) MOV C,A&lt;br /&gt;
5251H  (3AH) LDA F69FH&lt;br /&gt;
5254H  (B7H) ORA A&lt;br /&gt;
5255H  (79H) MOV A,C&lt;br /&gt;
5256H  (CAH) JZ 5281H&lt;br /&gt;
5259H  (D6H) SUI 86H&lt;br /&gt;
525BH  (DAH) JC 521AH&lt;br /&gt;
525EH  (01H) LXI B,0000H&lt;br /&gt;
5261H  (0CH) INR C&lt;br /&gt;
5262H  (D6H) SUI 0BH&lt;br /&gt;
5264H  (D2H) JNC 5261H&lt;br /&gt;
5267H  (C6H) ADI 3BH&lt;br /&gt;
5269H  (CDH) CALL 5092H&lt;br /&gt;
526CH  (32H) STA F69AH&lt;br /&gt;
526FH  (79H) MOV A,C&lt;br /&gt;
5270H  (C6H) ADI 2FH&lt;br /&gt;
5272H  (CDH) CALL 5092H&lt;br /&gt;
5275H  (CDH) CALL 5195H&lt;br /&gt;
5278H  (3AH) LDA F69AH&lt;br /&gt;
527BH  (CDH) CALL 5195H&lt;br /&gt;
527EH  (C3H) JMP 521AH&lt;br /&gt;
&lt;br /&gt;
5281H  (D6H) SUI 81H&lt;br /&gt;
5283H  (21H) LXI H,F68BH&lt;br /&gt;
5286H  (2BH) DCX H&lt;br /&gt;
5287H  (D6H) SUI 15H&lt;br /&gt;
5289H  (D2H) JNC 5286H&lt;br /&gt;
528CH  (C6H) ADI 16H&lt;br /&gt;
528EH  (32H) STA F69AH&lt;br /&gt;
5291H  (CDH) CALL 5194H&lt;br /&gt;
5294H  (3AH) LDA F69AH&lt;br /&gt;
5297H  (21H) LXI H,F69AH&lt;br /&gt;
529AH  (2BH) DCX H&lt;br /&gt;
529BH  (3DH) DCR A&lt;br /&gt;
529CH  (C2H) JNZ 529AH&lt;br /&gt;
529FH  (CDH) CALL 5194H&lt;br /&gt;
52A2H  (C3H) JMP 521AH&lt;br /&gt;
&lt;br /&gt;
52A5H  (3AH) LDA F69EH&lt;br /&gt;
52A8H  (FEH) CPI 0CH&lt;br /&gt;
52AAH  (C8H) RZ&lt;br /&gt;
52ABH  (2AH) LHLD F69BH&lt;br /&gt;
52AEH  (01H) LXI B,000AH&lt;br /&gt;
52B1H  (09H) DAD B&lt;br /&gt;
52B2H  (7EH) MOV A,M&lt;br /&gt;
52B3H  (FEH) CPI 50H&lt;br /&gt;
52B5H  (C8H) RZ&lt;br /&gt;
52B6H  (FEH) CPI 43H&lt;br /&gt;
52B8H  (37H) STC&lt;br /&gt;
52B9H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
52BAH  (32H) STA F69AH&lt;br /&gt;
52BDH  (C5H) PUSH B&lt;br /&gt;
52BEH  (CDH) CALL 52A5H&lt;br /&gt;
52C1H  (C1H) POP B&lt;br /&gt;
52C2H  (D1H) POP D&lt;br /&gt;
52C3H  (E1H) POP H&lt;br /&gt;
52C4H  (FEH) CPI 0CH&lt;br /&gt;
52C6H  (C2H) JNZ 52D6H&lt;br /&gt;
52C9H  (3AH) LDA F69AH&lt;br /&gt;
52CCH  (FEH) CPI 1AH&lt;br /&gt;
52CEH  (CCH) CZ 5327H&lt;br /&gt;
52D1H  (CDH) CALL 532BH&lt;br /&gt;
52D4H  (BFH) CMP A&lt;br /&gt;
52D5H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
52D6H  (D6H) SUI 43H&lt;br /&gt;
52D8H  (CAH) JZ 52E6H&lt;br /&gt;
52DBH  (D6H) SUI 0FH&lt;br /&gt;
52DDH  (CAH) JZ 52E6H&lt;br /&gt;
52E0H  (78H) MOV A,B&lt;br /&gt;
52E1H  (FEH) CPI 07H&lt;br /&gt;
52E3H  (D2H) JNC 52E7H&lt;br /&gt;
52E6H  (23H) INX H&lt;br /&gt;
52E7H  (E5H) PUSH H&lt;br /&gt;
52E8H  (2BH) DCX H&lt;br /&gt;
52E9H  (01H) LXI B,FFFFH&lt;br /&gt;
52ECH  (3EH) MVI A,1AH&lt;br /&gt;
52EEH  (03H) INX B&lt;br /&gt;
52EFH  (23H) INX H&lt;br /&gt;
52F0H  (BEH) CMP M&lt;br /&gt;
52F1H  (C2H) JNZ 52EEH&lt;br /&gt;
52F4H  (E1H) POP H&lt;br /&gt;
52F5H  (CDH) CALL 5343H&lt;br /&gt;
52F8H  (CDH) CALL 52ABH&lt;br /&gt;
52FBH  (CAH) JZ 5304H&lt;br /&gt;
52FEH  (3AH) LDA F69DH&lt;br /&gt;
5301H  (77H) MOV M,A&lt;br /&gt;
5302H  (BFH) CMP A&lt;br /&gt;
5303H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
5304H  (36H) MVI M,4FH&lt;br /&gt;
5306H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
5307H  (21H) LXI H,F686H&lt;br /&gt;
530AH  (3EH) MVI A,14H&lt;br /&gt;
530CH  (F5H) PUSH PSW&lt;br /&gt;
530DH  (7EH) MOV A,M&lt;br /&gt;
530EH  (E6H) ANI DFH&lt;br /&gt;
5310H  (77H) MOV M,A&lt;br /&gt;
5311H  (F1H) POP PSW&lt;br /&gt;
5312H  (3DH) DCR A&lt;br /&gt;
5313H  (C8H) RZ&lt;br /&gt;
5314H  (23H) INX H&lt;br /&gt;
5315H  (C3H) JMP 530CH&lt;br /&gt;
&lt;br /&gt;
5318H  (7EH) MOV A,M&lt;br /&gt;
5319H  (12H) STAX D&lt;br /&gt;
531AH  (23H) INX H&lt;br /&gt;
531BH  (13H) INX D&lt;br /&gt;
531CH  (0BH) DCX B&lt;br /&gt;
531DH  (78H) MOV A,B&lt;br /&gt;
531EH  (B1H) ORA C&lt;br /&gt;
531FH  (C2H) JNZ 5318H&lt;br /&gt;
5322H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
5323H  (CFH) RST 1          ; Call main ROM at address in following 2 bytes&lt;br /&gt;
5324H  DW    7283H&lt;br /&gt;
5326H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
5327H  (CFH) RST 1          ; Call main ROM at address in following 2 bytes&lt;br /&gt;
5328H  DW    12CBH&lt;br /&gt;
532AH  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
532BH  (CFH) RST 1          ; Call main ROM at address in following 2 bytes&lt;br /&gt;
532CH  DW    4231H&lt;br /&gt;
532EH  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
532FH  (CFH) RST 1          ; Call main ROM at address in following 2 bytes&lt;br /&gt;
5330H  DW    4222H&lt;br /&gt;
5332H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
5333H  (CFH) RST 1          ; Call main ROM at address in following 2 bytes&lt;br /&gt;
5334H  DW    5AE3H&lt;br /&gt;
5336H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
5337H  (CFH) RST 1          ; Call main ROM at address in following 2 bytes&lt;br /&gt;
5338H  DW    7242H&lt;br /&gt;
533AH  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
533BH  (CFH) RST 1          ; Call main ROM at address in following 2 bytes&lt;br /&gt;
533CH  DW    2146H&lt;br /&gt;
533EH  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
533FH  (CFH) RST 1          ; Call main ROM at address in following 2 bytes&lt;br /&gt;
5340H  DW    6B6DH)&lt;br /&gt;
5342H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
5343H  (CFH) RST 1          ; Call main ROM at address in following 2 bytes&lt;br /&gt;
5344H  DW    6B9FH&lt;br /&gt;
5346H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
5347H  (CFH) RST 1          ; Call main ROM at address in following 2 bytes&lt;br /&gt;
5348H  DW    4244H&lt;br /&gt;
534AH  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Keystoke buffer contents (for performing compression?)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
534BH  DB    &amp;quot;etaoinrshdlfcmugypwb&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Navigate to:&lt;br /&gt;
* [[Dissasembly of RAM and ROM versions of TS-DOS]]&lt;br /&gt;
* [[M100 TS-DOS ROM OptROM Support]]&lt;br /&gt;
* [[M100 TS-DOS ROM UI Code]]&lt;br /&gt;
* [[M100 TS-DOS ROM RST 7 Handlers]]&lt;br /&gt;
* [[M100 TS-DOS ROM TPDD Protocol]]&lt;br /&gt;
* [[M100 TS-DOS ROM Cold Boot Recovery]]&lt;/div&gt;</summary>
		<author><name>Kpettit</name></author>
	</entry>
	<entry>
		<id>https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_TPDD_Protocol&amp;diff=1383</id>
		<title>M100 TS-DOS ROM TPDD Protocol</title>
		<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_TPDD_Protocol&amp;diff=1383"/>
		<updated>2009-04-03T08:10:24Z</updated>

		<summary type="html">&lt;p&gt;Kpettit: New page: == TS-DOS Model 100/102 ROM TPDD Protocol routines ==  &amp;lt;pre&amp;gt; ; ========================================================================================= ; Flush the RX output buffer to the...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== TS-DOS Model 100/102 ROM TPDD Protocol routines ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Flush the RX output buffer to the TPDD file&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
46DDH  LHLD FCCEH           ; Get address of FD control        &lt;br /&gt;
46E0H  LXI B,0007H          ; Load offset of write buffer length         &lt;br /&gt;
46E3H  DAD B                ; Calculate address of write buffer length within FD control   &lt;br /&gt;
46E4H  MOV A,M              ; Load the write buffer length     &lt;br /&gt;
46E5H  PUSH H               ; Save pointer to write buffer length in FD control on stack    &lt;br /&gt;
46E6H  INX H                ; Skip the LSB of the write buffer pointer   &lt;br /&gt;
46E7H  INX H                ; Skip the MSB of the write buffer pointer   &lt;br /&gt;
46E8H  INX H                ; Point to the actual data in the file write buffer   &lt;br /&gt;
46E9H  LXI D,FD04H          ; DE points to the data area in RX buffer         &lt;br /&gt;
46ECH  MOV C,A              ; Load buffer length into BC      &lt;br /&gt;
46EDH  MVI B,00H            ; Make MSB of BC zero       &lt;br /&gt;
46EFH  PUSH PSW             ; Save write buffer length to stack      &lt;br /&gt;
46F0H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment        &lt;br /&gt;
46F3H  POP PSW              ; Retrieve write buffer length from stack     &lt;br /&gt;
46F4H  ANA A                ; Test if write buffer is empty   &lt;br /&gt;
46F5H  CNZ 4095H            ; Send TPDD Write File opcode using RX buffer with length in A if not empty       &lt;br /&gt;
46F8H  POP H                ; Retrieve pointer to write buffer length in FD control from stack   &lt;br /&gt;
46F9H  MVI M,00H            ; Set length of write buffer to zero - it is flushed       &lt;br /&gt;
46FBH  INX H                ; Increment to address in FD control of write buffer    &lt;br /&gt;
46FCH  MOV D,H              ; Save HL to DE for storage of new buffer pointer address     &lt;br /&gt;
46FDH  MOV E,L              ; Save MSB of HL to DE     &lt;br /&gt;
46FEH  INX H                ; Increment to MSB of address in FD conrol of write buffer   &lt;br /&gt;
46FFH  INX H                ; Increment to actual write buffer address   &lt;br /&gt;
4700H  SHLX                 ; Save new write buffer pointer to FD control           &lt;br /&gt;
4701H  RET         &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Appears to be unused code&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4702H  POP PSW&lt;br /&gt;
4703H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display or print all disk files and free space&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4704H  LXI H,F685H          ; Keyboard buffer  &lt;br /&gt;
4707H  SHLD FCDBH           ; Initialize pointer to File Length table       &lt;br /&gt;
470AH  CALL 4735H           ; Clear #files displayed, init TPDD and send 1st file dir referene opode       &lt;br /&gt;
470DH  JNZ 486AH            ; Communication Error &lt;br /&gt;
4710H  XRA A                ; Prepare to initialize &amp;quot;skip page&amp;quot; count to zero  &lt;br /&gt;
4711H  STA FCDAH            ; Load the &amp;quot;skip page&amp;quot; count      &lt;br /&gt;
4714H  STA FCD4H            ; Current Page of files being displayed      &lt;br /&gt;
4717H  DCR A                ; Set A to 0xFF&lt;br /&gt;
4718H  STA FCD7H            ; Save as Page size to print (print 255 files per page)&lt;br /&gt;
471BH  MVI A,01H            ; &lt;br /&gt;
471DH  STA F63AH            ; ???&lt;br /&gt;
4720H  CALL 4747H           ; Get next page of files from server (NADSBox) with page size = 255&lt;br /&gt;
4723H  JMP 4C23H            ; Send CRLF to screen or printer        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display Disk free space on LCD at current position&lt;br /&gt;
;     NOT CALLED!&lt;br /&gt;
;     Old function - reporting of Free space was merged into the printing of the function&lt;br /&gt;
;     key display routine.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4726H  CALL 4A10H           ; Multiply TPDD free sectors len x 128 = free space&lt;br /&gt;
4729H  CALL 4C3EH           ; Print binary number in HL at current position&lt;br /&gt;
472CH  LXI H,4AD1H          ; Point to &amp;quot;0 Bytes free&amp;quot; text&lt;br /&gt;
472FH  CALL 4A2CH           ; Send buffer at M to screen&lt;br /&gt;
4732H  JMP 4C23H            ; Send CRLF to screen or printer&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Clear #files displayed, init TPDD and send 1st file dir referene opode&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4735H  XRA A                ; Indicate zero files being displayed &lt;br /&gt;
4736H  STA FCD6H            ; Count of files on screen&lt;br /&gt;
4739H  CALL 4943H           ; Configure baud, test for NADSBox, get NADSBox dir &lt;br /&gt;
473CH  LXI H,0146H          ; Load code for &amp;quot;F&amp;quot; attribute and First File dir reference&lt;br /&gt;
473FH  JMP 476FH            ; Send Directory Reference opcode with HL=access mode&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get next page of files from server (NADSBox / TPDD)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4742H  MVI A,14H            ; Maximum files that will fit on the display      &lt;br /&gt;
4744H  STA FCD7H            ; Save for comparison of file count      &lt;br /&gt;
4747H  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag      &lt;br /&gt;
474AH  ANA A                ; Test if TPDD  &lt;br /&gt;
474BH  JNZ 4757H            ; Skip 1st invocation of &amp;quot;Next file&amp;quot; if NADSBox or TPDD2??      &lt;br /&gt;
474EH  LXI H,02F6H          ; Load access mode code for &amp;quot;Next entry&amp;quot; dir reference        &lt;br /&gt;
4751H  CALL 476FH           ; Send Directory Reference opcode with HL=access mode       &lt;br /&gt;
4754H  JNZ 47F8H            ; Check RX packet for Noraml Response &amp;amp; report errors      &lt;br /&gt;
4757H  LDA FD04H            ; 1st filename byte      &lt;br /&gt;
475AH  ANA A                ; Test if 1st filename byte is zero  &lt;br /&gt;
475BH  RZ                   ; Return if last file retrieved&lt;br /&gt;
475CH  LDA FCDAH            ; Load the &amp;quot;skip page&amp;quot; count      &lt;br /&gt;
475FH  ANA A                ; Test if this is a &amp;quot;skip page&amp;quot;  &lt;br /&gt;
4760H  CZ 4781H             ; Call routine to display file if not a skip page     &lt;br /&gt;
4763H  LXI H,FCD6H          ; Count of files on screen        &lt;br /&gt;
4766H  INR M                ; Increment #files displayed on LCD  &lt;br /&gt;
4767H  LDA FCD7H            ; Load count of max files that will fit on LCD      &lt;br /&gt;
476AH  CMP M                ; Compare with current file count          &lt;br /&gt;
476BH  JNZ 474EH            ; Jump back to get next file from TPDD if not full      &lt;br /&gt;
476EH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Send Directory Reference opcode with HL=access mode&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
476FH  SHLD FD00H           ; Save file attrib and reference mode to TX buffer     &lt;br /&gt;
4772H  LXI H,1A00H          ; Load code and length for Directory Reference opcode      &lt;br /&gt;
4775H  CALL 4822H           ; Send TPDD Command/Len in HL     &lt;br /&gt;
4778H  CALL 47CCH           ; Receive a packet     &lt;br /&gt;
477BH  LDA FD02H            ; Storage for RX packet - response byte    &lt;br /&gt;
477EH  CPI 11H              ; Test if response was 0x11  (valid Dir Ref response)&lt;br /&gt;
4780H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print filename in RX buffer to LCD and save length info&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4781H  MVI C,09H            ; Prepare to draw 9 bytes of filename to LCD     &lt;br /&gt;
4783H  LXI H,FD04H          ; Location of filename in RX packet       &lt;br /&gt;
4786H  CALL 48E5H           ; Redraw C characters from buffer at HL using current video mode      &lt;br /&gt;
4789H  MVI A,20H            ; Prepare to draw a trailing space            &lt;br /&gt;
478BH  RST 4                ; Send char in A to LCD    &lt;br /&gt;
478CH  LHLD FD1DH           ; Get file size parameter from RX buffer      &lt;br /&gt;
478FH  MOV E,H              ; Save file size LSB in E   &lt;br /&gt;
4790H  MOV D,L              ; Save file size MSB in D          &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Store next file length to keyboard buffer&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4791H  LHLD FCDBH           ; Next storage location for file size info       &lt;br /&gt;
4794H  XCHG                 ; HL &amp;lt;--&amp;gt; DE &lt;br /&gt;
4795H  SHLX                 ; Store file length at address of next file save &lt;br /&gt;
4796H  XCHG                 ; HL &amp;lt;--&amp;gt; DE &lt;br /&gt;
4797H  INX H                ; Increment storage address of next file length  &lt;br /&gt;
4798H  INX H                ; Increment again (2 byte length)  &lt;br /&gt;
4799H  SHLD FCDBH           ; Save new address for lenght storage for next file&lt;br /&gt;
479CH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Receive an RX packet.  This routine gets copied into RAM and executed from there while&lt;br /&gt;
;       the Main ROM is selected.  This allows the RX packet to be recieved without&lt;br /&gt;
;       switching to and from the Main ROM to receive each individual byte.  The jump&lt;br /&gt;
;       addresses represent the RAM execution locations.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
479DH  LXI H,FD02H          ; Storage for RX packet         &lt;br /&gt;
47A0H  PUSH H               ; Save start of packet address on stack    &lt;br /&gt;
47A1H  CALL FDB2H           ; Get next byte from RX into HL        &lt;br /&gt;
47A4H  CALL FDB2H           ; Get next byte from RX into HL        &lt;br /&gt;
47A7H  MOV C,A              ; Move length byte into C     &lt;br /&gt;
47A8H  CALL FDB2H           ; Get next byte from RX into HL        &lt;br /&gt;
47ABH  MOV B,C              ; Move length byte to B     &lt;br /&gt;
47ACH  MOV A,C              ; Move length byte to A for zero test     &lt;br /&gt;
47ADH  ANA A                ; Test if length is zero   &lt;br /&gt;
47AEH  JZ FDA4H             ; Skip reading payload if zero length      &lt;br /&gt;
47B1H  CALL FDB2H           ; Get next byte from RX into HL        &lt;br /&gt;
47B4H  DCR C                ; Decrement length byte   &lt;br /&gt;
47B5H  JNZ FD9DH            ; Keep looping until all data received       &lt;br /&gt;
47B8H  POP H                ; Restore start of RX packet address   &lt;br /&gt;
47B9H  INR B                ; Add opcode byte to length for checksum   &lt;br /&gt;
47BAH  INR B                ; Add length byte to length for checksum   &lt;br /&gt;
47BBH  XRA A                ; Clear A for checksum calculation   &lt;br /&gt;
47BCH  SIM                  ; ?Clear Interrupts &lt;br /&gt;
47BDH  ADD M                ; Add next byte to checksum   &lt;br /&gt;
47BEH  INX H                ; Increment RX data pointer   &lt;br /&gt;
47BFH  DCR B                ; Decrement length counter   &lt;br /&gt;
47C0H  JNZ FDA9H            ; Keep looping until all bytes added       &lt;br /&gt;
47C3H  CMA                  ; Compliment the checksum          &lt;br /&gt;
47C4H  CMP M                ; Compare with received checksum   &lt;br /&gt;
47C5H  RET                  ; Branch if no match - Communication Error&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get next RX byte and store at HL, test for drive ready &amp;amp; print errors&lt;br /&gt;
;    This routine (and the one above) get copied into RAM and then executed&lt;br /&gt;
;    when the Main ROM is selected, so a direct call to the Main ROM address&lt;br /&gt;
;    is allowed.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
47C6H  CALL 6D7EH           ; Get a character from RS232 receive queue&lt;br /&gt;
47C9H  MOV M,A              ; Save byte at HL&lt;br /&gt;
47CAH  INX H                ; Increment HL&lt;br /&gt;
47CBH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Copy the 2 Receive RX Packet routines above to RAM and execute&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
47CCH  LXI H,479DH          ; Point to Receive RX Packet routine&lt;br /&gt;
47CFH  LXI D,FD89H          ; Point to target destination in RAM&lt;br /&gt;
47D2H  LXI B,002FH          ; Length of the routine&lt;br /&gt;
47D5H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
47D8H  CALL 4862H           ; Test if DSR is set - drive ready, error otherwise&lt;br /&gt;
47DBH  CALL 4BDBH           ; Call Main ROM&#039;s Set interrupt to 1DH routine.&lt;br /&gt;
47DEH  RST 1                ; Switch to Main ROM and execute &amp;quot;Receive RX Pakcet&amp;quot; routine&lt;br /&gt;
47DFH  DW   FD89H           ; Address of our RX routine we just copied to RAM&lt;br /&gt;
47E1H  JNZ 486AH            ; Communication Error if no /DSR&lt;br /&gt;
47E4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get next RX byte and store at HL, test for drive ready &amp;amp; print errors&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
47E5H  CALL 47EBH           ; Test drive and get byte from RX&lt;br /&gt;
47E8H  MOV M,A              ; Save byte at HL&lt;br /&gt;
47E9H  INX H                ; Increment HL &lt;br /&gt;
47EAH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test drive ready and get byte from RX,  Report error if not ready&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
47EBH  CALL 4862H           ; Test if DSR is set - Drive Ready&lt;br /&gt;
47EEH  CALL 4BE7H           ; Get a character from RS232 receive queue&lt;br /&gt;
47F1H  JC 488DH             ; Empty Error Text&lt;br /&gt;
47F4H  JNZ 486AH            ; Communication Error&lt;br /&gt;
47F7H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Check RX packet for Normal Response &amp;amp; report errors&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
47F8H  LDA FD02H            ; Storage for RX packet        &lt;br /&gt;
47FBH  CPI 12H              ; Test for normal return code      &lt;br /&gt;
47FDH  JNZ 486AH            ; Communication Error        &lt;br /&gt;
4800H  LDA FD04H            ; Location of error code in RX packet        &lt;br /&gt;
4803H  ANA A                ; Test if error code is zero    &lt;br /&gt;
4804H  RZ                   ; Return if no error &lt;br /&gt;
4805H  CPI 10H        &lt;br /&gt;
4807H  JZ 487EH             ; File Exists Error       &lt;br /&gt;
480AH  CPI 50H        &lt;br /&gt;
480CH  JZ 486DH             ; Write Protect Error       &lt;br /&gt;
480FH  CPI 60H        &lt;br /&gt;
4811H  JZ 4881H             ; Disk Full Error       &lt;br /&gt;
4814H  JC 486AH             ; Communication Error       &lt;br /&gt;
4817H  JZ 4873H             ; Disk not in drive error       &lt;br /&gt;
481AH  CPI 80H        &lt;br /&gt;
481CH  JC 4873H             ; Disk not in drive error       &lt;br /&gt;
481FH  JMP 4870H            ; Drive Trouble Error        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Send TPDD Command/Len in HL,  H=len, L=Cmd. 0XED8A already has data&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4822H  SHLD FCE6H           ; Store TDD CMD/Len passed in HL        &lt;br /&gt;
4825H  LXI H,FCE6H          ; Point to Command/Len storage location         &lt;br /&gt;
&lt;br /&gt;
4828H  PUSH H               ; Save Cmd/Len storage address to stack    &lt;br /&gt;
4829H  LDA FCCAH            ; TPDD Bank Numbere       &lt;br /&gt;
482CH  ANA A                ; Test if reading from side zero   &lt;br /&gt;
482DH  JZ 4837H             ; Skip ahead if reading from side zero      &lt;br /&gt;
4830H  ANI 01H              ; Mask off all but LSB (only side 1 allowed)     &lt;br /&gt;
4832H  RAR                  ; Move the &amp;quot;1&amp;quot; to C          &lt;br /&gt;
4833H  RAR                  ; Move the &amp;quot;1&amp;quot; to bit 7 &lt;br /&gt;
4834H  RAR                  ; Move the &amp;quot;1&amp;quot; to bit 6 (could just do MVI 0x40 !!) &lt;br /&gt;
4835H  ORA M                ; OR the 0x40 with Cmd to access Disk Bank 1   &lt;br /&gt;
4836H  MOV M,A              ; Save the updated cmd value back at (HL)     &lt;br /&gt;
4837H  MOV A,M              ; Get the command value / modified value     &lt;br /&gt;
4838H  INX H                ; Point to length parameter passed in   &lt;br /&gt;
4839H  ADD M                ; Add the length parameter (checksum)   &lt;br /&gt;
483AH  MOV B,A              ; Store checksum in B                                &lt;br /&gt;
483BH  MOV A,M              ; Get the Length parameter     &lt;br /&gt;
483CH  PUSH PSW             ; Save length on stack      &lt;br /&gt;
483DH  INX H                ; Point to data (already loaded before invocation)   &lt;br /&gt;
483EH  ANA A                ; Test if length is zero   &lt;br /&gt;
483FH  JZ 484BH             ; Skip data checksum if length zero        &lt;br /&gt;
4842H  MOV C,A              ; Save current count     &lt;br /&gt;
4843H  MOV A,B              ; Get running checksum value     &lt;br /&gt;
4844H  ADD M                ; Add this byte to checksum   &lt;br /&gt;
4845H  INX H                ; Point to next data byte   &lt;br /&gt;
4846H  DCR C                ; Decrement count   &lt;br /&gt;
4847H  JNZ 4844H            ; Keep looping until count is zero       &lt;br /&gt;
484AH  MOV B,A              ; Save updated checksum in B     &lt;br /&gt;
484BH  MOV A,B              ; Get Checksum from B    &lt;br /&gt;
484CH  CMA                  ; Compliment the checksum (protocol thing) &lt;br /&gt;
484DH  MOV D,A              ; Save complimented checksum in D     &lt;br /&gt;
484EH  LXI B,5A5AH          ; Load &amp;quot;ZZ&amp;quot; header signature into BC         &lt;br /&gt;
4851H  CALL 49DBH           ; Send BC to the serial port using XON/XOFF        &lt;br /&gt;
4854H  POP B                ; Get the length from stack into BC                     &lt;br /&gt;
4855H  MOV C,B              ; Move the length into C     &lt;br /&gt;
4856H  MVI B,00H            ; Clear upper MSB of count       &lt;br /&gt;
4858H  INX B                ; Add Opcode byte to the TX length    &lt;br /&gt;
4859H  INX B                ; Add length byte to the TX length    &lt;br /&gt;
485AH  POP H                ; Get address of TX packet from stack    &lt;br /&gt;
485BH  CALL 48D9H           ; Send BC bytes to RS-232 from (HL) using XON/XOFF                  &lt;br /&gt;
485EH  MOV A,D              ; Get checksum byte for TX       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Send A to RS-232 using XON/XOFF and check DSR when done&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
485FH  CALL 4BE3H           ; Call Main ROM&#039;s Send A to RS-232 using XON/XOFF routine         &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test if DSR is set - drive ready, error otherwise&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4862H  IN BBH               ; Get I/O port with /DSR bit&lt;br /&gt;
4864H  ANI 20H              ; Mask all but the /DSR bit&lt;br /&gt;
4866H  RZ                   ; Return if /DSR is asserted (low = asserted)&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Error jump table.  Loads A with error number and prints&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4867H  (3EH) MVI A,01H&lt;br /&gt;
       DB	0x21            ; Filler - looks like &amp;quot;LXI H,XXXX&amp;quot;&lt;br /&gt;
486AH  MVI A,02H            ; Communication Error&lt;br /&gt;
       DB	0x21&lt;br /&gt;
486DH  MVI A,03H            ; Write Protect Error&lt;br /&gt;
       DB	0x21&lt;br /&gt;
4870H  MVI A,04H            ; Drive Trouble Error&lt;br /&gt;
       DB	0x21&lt;br /&gt;
4873H  MVI A,05H            ; Disk not in drive Error&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; For any of the errors above, change the RAM/Disk mode back to RAM&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4875H  LXI H,FCD9H          ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
4878H  MVI M,00H            ; Go back to RAM mode&lt;br /&gt;
       DB   0x21            ; Filler - looks like &amp;quot;LXI H,XXXX&amp;quot;&lt;br /&gt;
&lt;br /&gt;
487BH  MVI A,06H            ; Printer Not Ready Error&lt;br /&gt;
       DB	0x21&lt;br /&gt;
487EH  MVI A,07H            ; File Exists Error&lt;br /&gt;
       DB	0x21&lt;br /&gt;
4881H  MVI A,08H            ; Disk Full Error&lt;br /&gt;
       DB	0x21&lt;br /&gt;
4884H  MVI A,09H            ; File Empty Error&lt;br /&gt;
       DB	0x21&lt;br /&gt;
4887H  MVI A,0AH            ; Directory Full Error&lt;br /&gt;
       DB	0x21&lt;br /&gt;
488AH  MVI A,0BH            ; Ram Full Error&lt;br /&gt;
       DB	0x21&lt;br /&gt;
488DH  MVI A,0CH            ; ID Error (No text...runtime error only)&lt;br /&gt;
       DB	0x21&lt;br /&gt;
4890H  MVI A,0DH            ; Bad File Name Error&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Generate the error loaded in A above&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4892H  LXI H,4B02H          ; Pointer to error string table&lt;br /&gt;
4895H  MOV C,A              ; Save error number for loop counting   &lt;br /&gt;
4896H  DCR C                ; Decrement error counter to test if string found &lt;br /&gt;
4897H  JZ 48A4H             ; String found in table    &lt;br /&gt;
489AH  MOV A,M              ; Get next byte of error string   &lt;br /&gt;
489BH  INX H                ; Inrcrement pointer &lt;br /&gt;
489CH  CPI 00H              ; Test if end of string   &lt;br /&gt;
489EH  JNZ 489AH            ; Loop until end of string found     &lt;br /&gt;
48A1H  JMP 4896H            ; Branch back to decrement string counter     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print error string at HL from error table&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
48A4H  LDA FCD2H            ; Get the &amp;quot;Print error messages&amp;quot; flag       &lt;br /&gt;
48A7H  ANA A                ; Test if printing allowed   &lt;br /&gt;
48A8H  JZ 48D0H             ; Jump to generate system error if not allowed to print      &lt;br /&gt;
48ABH  MVI A,07H            ; Print BELL to cause a beep       &lt;br /&gt;
48ADH  RST 4                ; Send A to the LCD     &lt;br /&gt;
48AEH  INX H                ; Skip the error code   &lt;br /&gt;
48AFH  CALL 48F4H           ; Print string at HL to col 1 on the bottom line        &lt;br /&gt;
48B2H  CALL 48C7H           ; Display &amp;quot;Press any key&amp;quot; and wait for key     &lt;br /&gt;
   &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Perform Long jump&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
48B5H  LHLD FCCEH           ; Stack pointer upon entry        &lt;br /&gt;
48B8H  SPHL                 ; Restore stack frame  &lt;br /&gt;
48B9H  LHLD FCD0H           ; Get return vector after error        &lt;br /&gt;
48BCH  PUSH H               ; Prepare to return to return vector    &lt;br /&gt;
48BDH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Draw &amp;quot;Press any key&amp;quot; text with pre&amp;amp;post CR and wait for key press&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
48BEH  CALL 4C23H           ; Send CRLF to screen or printer&lt;br /&gt;
48C1H  CALL 48C7H           ; Display &amp;quot;Press any key&amp;quot; and wait for key&lt;br /&gt;
48C4H  JMP 4C23H            ; Send CRLF to screen or printer&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Draw &amp;quot;Press any key&amp;quot; text and wait for key press&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
48C7H  LXI H,4BBBH          ; Point to &amp;quot;Press any key&amp;quot; text&lt;br /&gt;
48CAH  CALL 4A2CH           ; Send buffer at M to screen&lt;br /&gt;
48CDH  JMP 4BEBH            ; Wait for key from keyboard&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Generate system error from code saved at (HL).  This is called in liu of printing when&lt;br /&gt;
;      the print/generate system error flag is set.  The 1st byte of each error entry&lt;br /&gt;
;      contains the system error number to generate.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
48D0H  MOV E,M              ; Get the error code&lt;br /&gt;
48D1H  LHLD FCCEH           ; Stack pointer upon entry&lt;br /&gt;
48D4H  MVI M,00H            ; Indicate all arguments (none) processed&lt;br /&gt;
48D6H  JMP 4C37H            ; Generate error in E&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Send BC bytes to RS-232 from (HL) using XON/XOFF&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
48D9H  MOV A,M              ; Get next byte from (HL)&lt;br /&gt;
48DAH  CALL 485FH           ; Send A to RS-232 using XON/XOFF&lt;br /&gt;
48DDH  INX H                ; Increment poiner &lt;br /&gt;
48DEH  DCX B                ; Decrement byte count &lt;br /&gt;
48DFH  MOV A,C              ; Get C for zero comparison&lt;br /&gt;
48E0H  ORA B                ; Or in MSB of count&lt;br /&gt;
48E1H  JNZ 48D9H            ; Jump to send next byte if not zero&lt;br /&gt;
48E4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Draw C characters to LCD from buffer at HL using current video mode&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
48E5H  MOV A,M              ; Get next byte from LCD buffer &lt;br /&gt;
48E6H  CPI 20H              ; Test if it is a space &lt;br /&gt;
48E8H  JNC 48EDH            ; Test if it&#039;s less than space, jump if not to redraw &lt;br /&gt;
48EBH  MVI A,20H            ; Draw a space for &amp;quot;illegal&amp;quot; values &lt;br /&gt;
48EDH  RST 4                ; Draw byte with current regular/inverse video mode &lt;br /&gt;
48EEH  INX H                ; Increment to next byte in LCD buffer &lt;br /&gt;
48EFH  DCR C                ; Decrement the loop counter &lt;br /&gt;
48F0H  JNZ 48E5H            ; Branch if not done to process next character &lt;br /&gt;
48F3H  RET                  ; Done&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print string at HL to col 1 on the bottom line&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
48F4H  PUSH H               ; Save pointer to error text on stack  &lt;br /&gt;
48F5H  LXI H,0108H          ; Position cursor on col 1 of row 16&lt;br /&gt;
48F8H  SHLD F639H           ; Cursor row (1-8)  &lt;br /&gt;
48FBH  CALL 4C2BH           ; Erase from cursor to end of line      &lt;br /&gt;
48FEH  POP H                ; Restore pointer to error text from stack &lt;br /&gt;
48FFH  JMP 4A2CH            ; Send buffer at M to screen&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Copy filename at (HL) to current BASIC program&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4902H  PUSH H               ; Save pointer to filename on stack    &lt;br /&gt;
4903H  MVI A,20H            ; Load A with code for SPACE       &lt;br /&gt;
4905H  LXI H,FC93H          ; Filename of current BASIC program            &lt;br /&gt;
4908H  MVI B,08H            ; Prepare to fill current BASIC program with 8 spaces       &lt;br /&gt;
490AH  CALL 4A34H           ; Fill (HL) with B bytes of A        &lt;br /&gt;
490DH  POP H                ; Retrieve filename pointer from stack   &lt;br /&gt;
490EH  LXI D,FC93H          ; Filename of current BASIC program             &lt;br /&gt;
4911H  MVI B,06H            ; Prepare to copy 6 bytes of filename before ext       &lt;br /&gt;
4913H  MOV A,M              ; Get next byte of filename from source     &lt;br /&gt;
4914H  CPI 41H              ; Compare byte with &#039;A&#039; to test validity     &lt;br /&gt;
4916H  JC 4890H             ; Bad Filename Error if invalid char      &lt;br /&gt;
4919H  MOV A,M              ; Get next byte again     &lt;br /&gt;
491AH  CPI 2EH              ; Compare with &#039;.&#039;     &lt;br /&gt;
491CH  JZ 492BH             ; Branch if &#039;.&#039; to fill remaining with &#039; &#039;      &lt;br /&gt;
491FH  ORA A                ; Test for zero (NULL term)   &lt;br /&gt;
4920H  RZ                   ; Return if done copying filename (NULL term)&lt;br /&gt;
4921H  STAX D               ; Store next filename byte at (DE)    &lt;br /&gt;
4922H  INX H                ; Increment source pointer   &lt;br /&gt;
4923H  INX D                ; Increment dest pointer   &lt;br /&gt;
4924H  DCR B                ; Decrement counter   &lt;br /&gt;
4925H  JNZ 4919H            ; Keep looping until all bytes copied       &lt;br /&gt;
4928H  JMP 4933H            ; Jump to copy 2 extension bytes       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Fill remainder of filename at (DE) with spaces,  B has count&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
492BH  MVI A,20H            ; Load code for &#039; &#039;        &lt;br /&gt;
492DH  STAX D               ; Save next byte as &#039; &#039;     &lt;br /&gt;
492EH  INX D                ; Increment pointer    &lt;br /&gt;
492FH  DCR B                ; Decrement count    &lt;br /&gt;
4930H  JNZ 492DH            ; Keep looping until full &lt;br /&gt;
       &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Copy 2 extention bytes from (HL) to (DE)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4933H  MVI B,02H            ; Setup count = 2        &lt;br /&gt;
4935H  INX H                ; Skip the &#039;.&#039; in the source name    &lt;br /&gt;
4936H  MOV A,M              ; Load next extension byte from source      &lt;br /&gt;
4937H  ORA A                ; Test for NULL termination    &lt;br /&gt;
4938H  RZ                   ; Return if NULL terminated &lt;br /&gt;
4939H  STAX D               ; Store in destination     &lt;br /&gt;
493AH  INX D                ; Increment destination    &lt;br /&gt;
493BH  DCR B                ; Decrement the counter    &lt;br /&gt;
493CH  JNZ 4935H            ; Keep looping until done        &lt;br /&gt;
493FH  MVI A,00H            ; Load NULL termination byte        &lt;br /&gt;
4941H  STAX D               ; Add NULL termination to filename     &lt;br /&gt;
4942H  RET        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Configure baud, test for NADSBox, get NADSBox dir&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4943H  CALL 4A94H           ; Configure baud (19200 for NADSBox/Desklink, 9600 otherwise)        &lt;br /&gt;
4946H  CALL 49A2H           ; Send M1 and test for NADSBox/Desklink response        &lt;br /&gt;
4949H  CALL 47CCH           ; Receive a packet        &lt;br /&gt;
494CH  CALL 47F8H           ; Check RX packet for Normal Response &amp;amp; report errors        &lt;br /&gt;
494FH  LDA FCCBH            ; NADSBo / Desklink / TPDD2 flag       &lt;br /&gt;
4952H  ANA A                ; Test if server is NADSBox / Desklink   &lt;br /&gt;
4953H  RZ                   ; Return if not NADSBox / Desklink&lt;br /&gt;
4954H  LXI H,0008H          ; Load opcode 0x08 - FDC Emulation mode         &lt;br /&gt;
4957H  CALL 4822H           ; Send TPDD Command/Len in HL        &lt;br /&gt;
495AH  CALL 47CCH           ; Receive a packet - should be the current directory name        &lt;br /&gt;
495DH  LDA FD03H            ; Load length byte from the RX payload area       &lt;br /&gt;
4960H  CPI 01H              ; Test if length 1     &lt;br /&gt;
4962H  JZ 4977H             ; Jump to send mystery opcodes if length = 1      &lt;br /&gt;
4965H  DCR A                ; Subtract 1 from length (skip reserved 0x00 in filename)   &lt;br /&gt;
4966H  MOV C,A              ; Save count in C     &lt;br /&gt;
4967H  MVI A,02H            ; Prepare to indicate we have a NADSBox / Desklink directory name       &lt;br /&gt;
4969H  STA FCCBH            ; NADSBox / Desklink flag = HAVE_NADS_DIR       &lt;br /&gt;
496CH  MVI B,00H            ; Clear MSB of count       &lt;br /&gt;
496EH  LXI H,FD05H          ; Point to filename in RX payload (skip 1st byte)         &lt;br /&gt;
4971H  LXI D,FCC0H          ; Storage area for NADSBox directory           &lt;br /&gt;
4974H  JMP 4A05H            ; Move BC bytes from M to (DE) with increment       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Send mystery opcodes&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4977H  LXI H,0023H          ; Load mystery opcode 23    &lt;br /&gt;
497AH  CALL 4822H           ; Send TPDD Command/Len in HL   &lt;br /&gt;
497DH  CALL 47CCH           ; Receive a packet   &lt;br /&gt;
4980H  LXI H,4AE7H          ; Point to mystery opcode 0x31    &lt;br /&gt;
4983H  CALL 498FH           ; Send 9-byte protocol packet at HL   &lt;br /&gt;
4986H  LXI H,4AF0H          ; Point to 2nd mystery opcode 0x31    &lt;br /&gt;
4989H  CALL 498FH           ; Send 9-byte protocol packet at HL   &lt;br /&gt;
498CH  LXI H,4AF9H          ; Point to 3rd mystery opcode 0x31    &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Send 9-byte protocol packet at HL&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
498FH  LXI B,0009H          ; Load byte counter to send 9 bytes    &lt;br /&gt;
4992H  CALL 48D9H           ; Send BC bytes at (HL) to RS-232 using XON/XOFF   &lt;br /&gt;
4995H  JMP 47CCH            ; Receive a packet  &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Flush the RX queue &amp;amp; discard&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4998H  CALL 4BDFH           ; Check RS232 queue for pending characters&lt;br /&gt;
499BH  RZ                   ; Return if RS232 queue is empty&lt;br /&gt;
499CH  CALL 47EBH           ; Test drive ready and get byte from RX.&lt;br /&gt;
499FH  JMP 4998H            ; Branch to get next byte from RX&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Send M1 and test for NADSBox / Desklink response&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
49A2H  CALL 4862H           ; Test if DSR set - drive ready      &lt;br /&gt;
49A5H  CALL 49CDH           ; Send &amp;quot;M1&amp;quot;,0x0D to TX and delay about 3ms      &lt;br /&gt;
49A8H  CALL 4998H           ; Flush the RX queue &amp;amp; discard      &lt;br /&gt;
49ABH  CALL 419BH           ; Send Opcode 0x08 - FDC emulation mode      &lt;br /&gt;
49AEH  CALL 49D3H           ; Send 0x0D to RS-232 and Delay 3ms      &lt;br /&gt;
49B1H  CALL 4BDFH           ; Check RS232 queue for pending characters      &lt;br /&gt;
49B4H  MVI A,00H            ; NADSBox / Desklink / TPDD2 flag     &lt;br /&gt;
49B6H  JNZ 49BAH            ; Skip setting NADSBox / Desklink flag if no response     &lt;br /&gt;
49B9H  INR A                ; Indicate response from &amp;quot;M1&amp;quot; command = NADSBox / Desklink &lt;br /&gt;
49BAH  STA FCCBH            ; Store NADSBox / Desklink / TPDD2 flag     &lt;br /&gt;
49BDH  CALL 4998H           ; Flush the RX queue &amp;amp; discard      &lt;br /&gt;
49C0H  CALL 49CDH           ; Send &amp;quot;M1&amp;quot; to TX and delay about 3ms      &lt;br /&gt;
49C3H  CALL 4998H           ; Flush the RX queue &amp;amp; discard      &lt;br /&gt;
49C6H  LXI H,0007H          ; Load opcode for Drive Status       &lt;br /&gt;
49C9H  CALL 4822H           ; Send TPDD Command/Len in HL      &lt;br /&gt;
49CCH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Send &amp;quot;M1&amp;quot;,0x0D to RS-232 and delay about 3ms&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
49CDH  LXI B,4D31H          ; Load code for &amp;quot;M1&amp;quot;&lt;br /&gt;
49D0H  CALL 49DBH           ; Send BC to RS-232 using XON/XOFF&lt;br /&gt;
49D3H  MVI A,0DH            ; Load code for CR (0x0D)&lt;br /&gt;
49D5H  CALL 485FH           ; Send A to RS-232 using XON/XOFF&lt;br /&gt;
49D8H  JMP 49E3H            ; Delay routine - about 3ms&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Send BC to RS-232 using XON/XOFF&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
49DBH  MOV A,B              ; Get first byte to send&lt;br /&gt;
49DCH  CALL 485FH           ; Send A to RS-232 using XON/XOFF&lt;br /&gt;
49DFH  MOV A,C              ; Get 2nd byte to send&lt;br /&gt;
49E0H  JMP 485FH            ; Send A to RS-232 using XON/XOFF&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Delay routine - about 72000 cycles = 2.9ms&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
49E3H  MVI H,14H            ; 7 Cycles&lt;br /&gt;
49E5H  MVI L,FFH            ; 7 Cycles&lt;br /&gt;
49E7H  DCR L                ; 4 Cycles  &lt;br /&gt;
49E8H  JNZ 49E7H            ; 10 Cycles to Jump back. 14 * 255 = 3570 cycles inner loop&lt;br /&gt;
49EBH  DCR H                ; 4 Cycles.  But we save 3 cycles from the final JNZ, so 1 cycle  &lt;br /&gt;
49ECH  JNZ 49E5H            ; 10 Cycles to jump back. (3570+1+7)*20+7 = 71567 cycles&lt;br /&gt;
49EFH  RET                  ; 71567 * 403.877ns = 2.8904ms&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Wait for drive to be ready for (0xFF50) counts of 2.9ms.&lt;br /&gt;
; Report error if no data received.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
49F0H  LXI B,FF50H          ; Get count of delay times to wait&lt;br /&gt;
49F3H  CALL 49E3H           ; Delay 2.9ms      &lt;br /&gt;
49F6H  CALL 4BDFH           ; Check RS232 queue for pending characters             &lt;br /&gt;
49F9H  RNZ                  ; Return if data available&lt;br /&gt;
49FAH  DCR B                ; Decrement inner loop count &lt;br /&gt;
49FBH  JNZ 49F3H            ; Branch to delay and test again     &lt;br /&gt;
49FEH  DCR C                ; Decrement outer loop count &lt;br /&gt;
49FFH  JNZ 49F3H            ; Branch to delay and test again     &lt;br /&gt;
4A02H  JMP 4867H            ; No data received - Drive Not Ready error     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Move BC bytes from M to (DE) with increment&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4A05H  MOV A,M              ; Get next byte from (HL)&lt;br /&gt;
4A06H  STAX D               ; Store next byte at (DE)&lt;br /&gt;
4A07H  INX H                ; Increment source pointer&lt;br /&gt;
4A08H  INX D                ; Increment destination poiner&lt;br /&gt;
4A09H  DCX B                ; Decrement loop control&lt;br /&gt;
4A0AH  MOV A,B              ; Prepare to test for zero&lt;br /&gt;
4A0BH  ORA C                ; OR in LSB to test for zero&lt;br /&gt;
4A0CH  JNZ 4A05H            ; Keep looping until done&lt;br /&gt;
4A0FH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Multiply TPDD free sectors len x 128 = free space.  A &#039;0&#039; is added to LCD to convert this&lt;br /&gt;
;      multiplication to x1280 (the TPDD sector size).&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4A10H  LDA FD1FH            ; Get number of free sectors reported from server (TPDD)&lt;br /&gt;
4A13H  MOV L,A              ; Move #free sectors into HL for multiply&lt;br /&gt;
4A14H  MVI H,00H            ; Clear MSB of HL&lt;br /&gt;
4A16H  LXI D,0080H          ; Prepare to multiply #sectors x 128 &lt;br /&gt;
4A19H  JMP 4C1FH            ; Signed integer muliply (FAC1=HL*DE)&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Compare (HL) with (DE), C bytes long&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4A1CH  PUSH D               ; Save pointer to 1st buffer   &lt;br /&gt;
4A1DH  PUSH H               ; Save pointer to 2nd buffer  &lt;br /&gt;
4A1EH  LDAX D               ; Load next byte from 1st buffer  &lt;br /&gt;
4A1FH  SUB M                ; Compare with nex byte from 2nd buffer &lt;br /&gt;
4A20H  JNZ 4A29H            ; Jump to exit if no match     &lt;br /&gt;
4A23H  INX H                ; Increment 2nd buffer pointer &lt;br /&gt;
4A24H  INX D                ; Increment 1st buffer pointer &lt;br /&gt;
4A25H  DCR C                ; Decrement length &lt;br /&gt;
4A26H  JNZ 4A1EH            ; Jump to compare next byte if not at end     &lt;br /&gt;
4A29H  POP H                ; Restore pointer to 2nd buffer &lt;br /&gt;
4A2AH  POP D                ; Restore pointer to 1st buffer &lt;br /&gt;
4A2BH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Send buffer at M to screen&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4A2CH  (7EH) MOV A,M        ; Get next byte to send to LCD&lt;br /&gt;
4A2DH  (A7H) ANA A          ; Test for end of string&lt;br /&gt;
4A2EH  (C8H) RZ             ; Return if end of string (NULL terminated)&lt;br /&gt;
4A2FH  (E7H) RST 4          ; Send character in A to screen/printer&lt;br /&gt;
4A30H  (23H) INX H          ; Increment to next byte&lt;br /&gt;
4A31H  (C3H) JMP 4A2CH      ; Branch to test next byte for zero and print&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Fill (HL) with B bytes of A&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4A34H  MOV M,A              ; Load next byte at (HL) with A&lt;br /&gt;
4A35H  INX H                ; Increment pointer&lt;br /&gt;
4A36H  DCR B                ; Decrement counter&lt;br /&gt;
4A37H  JNZ 4A34H            ; Keep looping until B bytes copied&lt;br /&gt;
4A3AH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Initialize blank filename and attribute byte&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4A3BH  MVI A,20H            ; Prepare to fill TX packet with spaces&lt;br /&gt;
4A3DH  MVI B,18H            ; Fill TX buffer with 24 spaces&lt;br /&gt;
4A3FH  LXI H,FCE8H          ; Address of TX packet data&lt;br /&gt;
4A42H  CALL 4A34H           ; Fill (HL) with B bytes of A&lt;br /&gt;
4A45H  MVI A,46H            ; Load &amp;quot;F&amp;quot; TPDD file attribute flag&lt;br /&gt;
4A47H  STA FD00H            ; Store in TX packet data location&lt;br /&gt;
4A4AH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get RAM directory address of selected file into HL&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4A4BH  LHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
4A4EH  CALL 4902H           ; Copy filename at (HL) to current BASIC program&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get RAM directory address of current BASIC program&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4A51H  CALL 4C0FH           ; Update system pointers&lt;br /&gt;
4A54H  JMP 4BFBH            ; Find catalog entry address of current BASIC program&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Send Dir Reference for filename at (HL)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4A57H  PUSH H               ; Save filename address on stack  &lt;br /&gt;
4A58H  CALL 4A3BH           ; Initialize blank filename and attribute byte      &lt;br /&gt;
4A5BH  POP H                ; Restore filename address &lt;br /&gt;
4A5CH  LXI D,FCE8H          ; Address of TX packet data       &lt;br /&gt;
4A5FH  LXI B,0006H          ; Prepare to copy 6 bytes of TX data       &lt;br /&gt;
4A62H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
4A65H  MVI A,2EH            ; Load code for &#039;.&#039;     &lt;br /&gt;
4A67H  STAX D               ; Add &#039;.&#039; between name and extension  &lt;br /&gt;
4A68H  INX D                ; Increment TX pkt address pointer &lt;br /&gt;
4A69H  LXI B,0002H          ; Prepare to copy extension from filename&lt;br /&gt;
4A6CH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
4A6FH  CALL 4943H           ; Configure baud, test for NADSBox, get NADSBox dir      &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Send Dir Reference opcode&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4A72H  MVI A,00H            ; Set dir reference type to &amp;quot;reference&amp;quot; for open     &lt;br /&gt;
4A74H  STA FD01H            ; Save in dir reference location in TX buffer     &lt;br /&gt;
4A77H  LXI H,1A00H          ; Load opcode for directory reference&lt;br /&gt;
4A7AH  CALL 4822H           ; Send TPDD Command/Len in HL      &lt;br /&gt;
4A7DH  CALL 47CCH           ; Receive a packet      &lt;br /&gt;
4A80H  LDA FD1CH            ; Load attribute byte     &lt;br /&gt;
4A83H  ANA A                ; Test attribute byte for zero &lt;br /&gt;
4A84H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Save OS&#039;s baud rate string to storage area, A = &amp;quot;Print error messages&amp;quot; flag&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4A85H  STA FCD2H            ; Store &amp;quot;Print error messages&amp;quot; flag&lt;br /&gt;
4A88H  LXI D,F9A8H          ; Storage area for previous baud setting&lt;br /&gt;
4A8BH  LXI H,F65BH          ; RS232 parameter setting table   &lt;br /&gt;
4A8EH  LXI B,0005H          ; Copy 7 bytes of parameter data&lt;br /&gt;
4A91H  JMP 4A05H            ; Move BC bytes from M to (DE) with increment&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Configure baud, check for Desklink/NADSBox.  Set to 9600 if not Desklink/NADSBox&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4A94H  CALL 4BD7H           ; Wait for TX empty and Reset UART to accept mode bits         &lt;br /&gt;
4A97H  LXI H,4ADEH          ; Baud rate string for &amp;quot;98N1D&amp;quot;          &lt;br /&gt;
4A9AH  LXI D,F65BH          ; RS232 parameter setting table&lt;br /&gt;
4A9DH  LXI B,0005H          ; Prepare to copy 5 bytes to Baud Parameter table&lt;br /&gt;
4AA0H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment&lt;br /&gt;
4AA3H  LXI H,F65BH          ; Point to RS232 parameter setting table&lt;br /&gt;
4AA6H  STC                  ; Indicate Baud rate is part of string&lt;br /&gt;
4AA7H  CALL 4BD3H           ; Set RS232 parameters from string at M&lt;br /&gt;
4AAAH  CALL 4998H           ; Flush the RX queue &amp;amp; discard&lt;br /&gt;
4AADH  CALL 49A2H           ; Send M1 and test for NADSBox / Desklink response&lt;br /&gt;
4AB0H  CALL 49E3H           ; Delay routine - about 3ms&lt;br /&gt;
4AB3H  CALL 4BDFH           ; Check RS232 queue for pending characters&lt;br /&gt;
4AB6H  JNZ 4998H            ; Jump to flush RX and keep 19200 if NADSBox / Desklink found       &lt;br /&gt;
4AB9H  CALL 4BD7H           ; Wait for TX empty and Reset UART to accept mode bits        &lt;br /&gt;
4ABCH  LXI H,F65BH          ; Baud rate string for &amp;quot;98N1D&amp;quot;   &lt;br /&gt;
4ABFH  DCR M                ; Set baud rate to &#039;8&#039; = 9600 baud   &lt;br /&gt;
4AC0H  STC                  ; Indicate Baud rate is part of string &lt;br /&gt;
4AC1H  JMP 4BD3H            ; Set RS232 parameters from string at M - change to 9600 Baud       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Restore original baud settings&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4AC4H  LXI H,F9A8H          ; Storage for OS&#039;s baud settings&lt;br /&gt;
4AC7H  MOV A,M              ; Get 1st byte of setting   &lt;br /&gt;
4AC8H  SUI 3AH              ; Test if 1st byte is numeric   &lt;br /&gt;
4ACAH  JC 4BD3H             ; Set RS232 parameters from string at M    &lt;br /&gt;
4ACDH  INX H                ; Skip setting baud if 1st byte is &amp;quot;M&amp;quot;odem &lt;br /&gt;
4ACEH  JMP 4BD3H            ; Set RS232 parameters from string at M     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Strings and table data&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4AD1H  DB	&amp;quot;0 Bytes free&amp;quot;,0x00  ; Old Text - NOT USED in ROM version, only RAM version&lt;br /&gt;
4ADEH  DB	&amp;quot;98N1DNN&amp;quot;, 0x00      ; Parameters for setting baud rate&lt;br /&gt;
4ADFH  DB   &amp;quot;8N1D&amp;quot;,0x00&lt;br /&gt;
4AE4H  DB	0x02,0x03,0x01       ; RST 7,30h open mode to TPDD Open mode mapping&lt;br /&gt;
&lt;br /&gt;
4AE9H  DB	&amp;quot;ZZ1&amp;quot;,0x04,0x01,0x00,0x84,0xFF,&amp;quot;F&amp;quot;&lt;br /&gt;
4AF0H  DB	&amp;quot;ZZ1&amp;quot;,0x04,0x01,0x00,0x96,0x0F,0x24&lt;br /&gt;
4AF9H  DB	&amp;quot;ZZ1&amp;quot;,0x04,0x01,0x00,0x94,0x0F,0x26&lt;br /&gt;
&lt;br /&gt;
4B02H  DB	0x12,&amp;quot;Drive Not Ready&amp;quot;,0x00&lt;br /&gt;
       DB	0x12,&amp;quot;Communication Error&amp;quot;,0x00&lt;br /&gt;
       DB	0x12,&amp;quot;Write Protect&amp;quot;,0x00&lt;br /&gt;
       DB	0x12,&amp;quot;Drive Trouble&amp;quot;,0x00&lt;br /&gt;
       DB	0x12,&amp;quot;Disk not in drive&amp;quot;,0x00&lt;br /&gt;
       DB	0x34,&amp;quot;Printer not ready&amp;quot;,0x00&lt;br /&gt;
       DB	0x05,&amp;quot;File Exists&amp;quot;,0x00&lt;br /&gt;
       DB	0x39,&amp;quot;Disk Full&amp;quot;,0x00&lt;br /&gt;
       DB	0x1A,&amp;quot;File Empty&amp;quot;,0x00&lt;br /&gt;
       DB	0x39,&amp;quot;Directory Full&amp;quot;,0x00&lt;br /&gt;
       DB	0x07,&amp;quot;Ram Full&amp;quot;,0x00&lt;br /&gt;
       DB	0x36,0x00&lt;br /&gt;
       DB	0x37,&amp;quot;Bad File Name&amp;quot;,0x00&lt;br /&gt;
4BBBH  DB	&amp;quot; Press any key.&amp;quot;,0x00&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 1 Vectors to Main ROM.  At places in the code where a call is needed to the Main ROM,&lt;br /&gt;
;       a RST 1 followed by a 2-byte address is issued.  The routines will jump to one of&lt;br /&gt;
;       the handler functions below to perform that RST 1 operation.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
&lt;br /&gt;
4BCBH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4BCCH  DW    340AH&lt;br /&gt;
4BCEH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Evaluate expressino at M-1 routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4BCFH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4BD0H  DW    1113H&lt;br /&gt;
4BD2H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Set RS232 parameters from string at M routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4BD3H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4BD4H  DW    17E6H&lt;br /&gt;
4BD6H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Wait for TX empty and Reset UART routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4BD7H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4BD8H  DW    6ECBH&lt;br /&gt;
4BDAH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Set interrupt to 1DH routine.&lt;br /&gt;
;    Seems like it would be easy enough to just do it in this ROM!&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4BDBH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4BDCH  DW    765CH&lt;br /&gt;
4BDEH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Check RS232 queue for pending characters routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4BDFH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4BE0H  DW    6D6DH&lt;br /&gt;
4BE2H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Send A to RS-232 using XON/XOFF routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4BE3H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4BE4H  DW    6E32H&lt;br /&gt;
4BE6H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Get a character from RS232 receive queue routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4BE7H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4BE8H  DW    6D7EH&lt;br /&gt;
4BEAH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Wait for key from keyboard routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4BEBH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4BECH  DW    12CBH&lt;br /&gt;
4BEEH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Scan keyboard for character (CTRL-BREAK ==&amp;gt; CTRL-C) routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4BEFH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4BF0H  DW    7242H&lt;br /&gt;
4BF2H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Power Down routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4BF3H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4BF4H  DW    13B5H&lt;br /&gt;
4BF6H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Renew automatic power-off counter routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4BF7H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4BF8H  DW    1BB1H&lt;br /&gt;
4BFAH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Find Catalog Entry Address of current BASIC program routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4BFBH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4BFCH  DW    20AFH&lt;br /&gt;
4BFEH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Kill .DO file routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4BFFH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C00H  DW    1FBFH&lt;br /&gt;
4C02H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Kill .BA file routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C03H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C04H  DW    2017H&lt;br /&gt;
4C06H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Kill .CO file routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C07H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C08H  DW    1FD9H&lt;br /&gt;
4C0AH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Insert BC spaces at M routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C0BH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C0CH  DW    6B6DH&lt;br /&gt;
4C0EH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Update system pointers routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C0FH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C10H  DW    2146H&lt;br /&gt;
4C12H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Find BASIC end of program routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C13H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C14H  DW    05F4H&lt;br /&gt;
4C16H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main Rom&#039;s Write new entry to catalog routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C17H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C18H  DW    2239H&lt;br /&gt;
4C1AH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Signed integer divide (FAC1=DE/HL) routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C1BH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C1CH  DW    377EH&lt;br /&gt;
4C1EH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Signed integer muliply (FAC1=HL*DE) routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C1FH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C20H  DW    3725H&lt;br /&gt;
4C22H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Send CRLF to LCD routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C23H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C24H  DW    4222H&lt;br /&gt;
4C26H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s CLS statement routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C27H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C28H  DW    4231H&lt;br /&gt;
4C2AH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Erase from cursor to end of line routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C2BH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C2CH  DW    425DH&lt;br /&gt;
4C2EH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Start inverse character mode routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C2FH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C30H  DW    4269H&lt;br /&gt;
4C32H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Cancel inverse video routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C33H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C34H  DW    426EH&lt;br /&gt;
4C36H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Generate error in E routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C37H  LXI H,045DH          ; Load address of Main ROM&#039;s Generate Error in E routine&lt;br /&gt;
4C3AH  PUSH H               ; Push routine to the stack&lt;br /&gt;
4C3BH  JMP 00A6H            ; Jump to Main ROM&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Print binary number in HL at current position routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C3EH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C3FH  DW    39D4H&lt;br /&gt;
4C41H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Print A to printer, expanding tabs if necessary routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C42H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C43H  DW    4B55H&lt;br /&gt;
4C45H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Input and display (no &amp;quot;?&amp;quot;) line and store routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C46H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C47H  DW    4644H&lt;br /&gt;
4C49H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Check keyboard queue for pending characters routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C4AH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C4BH  DW    13DBH&lt;br /&gt;
4C4DH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Move BC bytes from M to (DE) with decrement routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C4EH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C4FH  DW    6BE6H&lt;br /&gt;
4C51H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s LCOPY statement routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C52H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C53H  DW    1E5EH&lt;br /&gt;
4C55H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Stop automatic scrolling routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C56H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C57H  DW    423FH&lt;br /&gt;
4C59H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Resume Automatic Scrolling routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C5AH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C5BH  DW    4244H&lt;br /&gt;
4C5DH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Get char at M and convert to uppercase routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C5EH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C5FH  DW    0FE8H&lt;br /&gt;
4C61H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Get file descriptor for file in A routine&lt;br /&gt;
; NOT CALLED&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C62H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C63H  DW    4C81H&lt;br /&gt;
4C65H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Update line addresses for current BASIC program routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C66H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C67H  DW    05F0H&lt;br /&gt;
4C69H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Copy CO header bytes (6) from (HL) to &amp;quot;active&amp;quot; CO Header storage area routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C6AH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C6BH  DW    253DH&lt;br /&gt;
4C6DH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s print CO address, length and invocation address to LCD routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C6EH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C6FH  DW    25A4H&lt;br /&gt;
4C71H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Process SAVEM arguments for address, length and entry point routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4C72H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
4C73H  DW    2346H&lt;br /&gt;
4C75H  RET&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Navigate to:&lt;br /&gt;
* [[Dissasembly of RAM and ROM versions of TS-DOS]]&lt;br /&gt;
* [[M100 TS-DOS ROM OptROM Support]]&lt;br /&gt;
* [[M100 TS-DOS ROM UI Code]]&lt;br /&gt;
* [[M100 TS-DOS ROM RST 7 Handlers]]&lt;br /&gt;
* [[M100 TS-DOS ROM Compression]]&lt;br /&gt;
* [[M100 TS-DOS ROM Cold Boot Recovery]]&lt;/div&gt;</summary>
		<author><name>Kpettit</name></author>
	</entry>
	<entry>
		<id>https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_RST_7_Handlers&amp;diff=1382</id>
		<title>M100 TS-DOS ROM RST 7 Handlers</title>
		<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_RST_7_Handlers&amp;diff=1382"/>
		<updated>2009-04-03T08:01:34Z</updated>

		<summary type="html">&lt;p&gt;Kpettit: New page: == TS-DOS Model 100/102 ROM RST 7 Handlers ==  This is the code for the DOS-ON RST 7 Hooks, along with the TPDD1 Rename functionality.  &amp;lt;pre&amp;gt; ; ============================================...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== TS-DOS Model 100/102 ROM RST 7 Handlers ==&lt;br /&gt;
&lt;br /&gt;
This is the code for the DOS-ON RST 7 Hooks, along with the TPDD1 Rename functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Load default RST 7 vector table values&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3FFAH  LXI 7FF3H            ; Address of a RET opcode in ROM &lt;br /&gt;
3FFDH  SHLD FAE6H           ; Save as hook for RST 7,0Ch??  We didn&#039;t modify this one&lt;br /&gt;
4000H  SHLD FB08H           ; Save as hook for RST 7,2Eh - DSKI$ function&lt;br /&gt;
4003H  SHLD FB0AH           ; Save as hook for RST 7,30h - OPEN/CLOSE/PRINT/LINE INPUT &lt;br /&gt;
4006H  SHLD FAF0H           ; Save as hook for RST 7,16h - SAVE&lt;br /&gt;
4009H  SHLD FAF4H           ; Save as hook for RST 7,1Ah - RUN&lt;br /&gt;
400CH  LXI H,08DBH          ; Load address of &amp;quot;Generate FC Error&amp;quot; in Main ROM&lt;br /&gt;
400FH  SHLD FB2CH           ; Save as hook for RST 7,52h - LFILES&lt;br /&gt;
4012H  SHLD FB32H           ; Save as hook for RST 7,58h - KILL&lt;br /&gt;
4015H  SHLD FB34H           ; Save as hook for RST 7,5Ah - NAME&lt;br /&gt;
4018H  SHLD FB36H           ; Save as hook for RST 7,5Ch - SAVEM&lt;br /&gt;
401BH  SHLD FB38H           ; Save as hook for RST 7,5Eh - LOADM and RUNM&lt;br /&gt;
401EH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Install our RST 7 hook for all RST 7 calls we are interested in.  This uses the &amp;quot;ON TIME&amp;quot;&lt;br /&gt;
;      time storage location to copy a 6-byte routine to switch to OptROM and call our &lt;br /&gt;
;      RST 7 &amp;quot;switch&amp;quot; statement in our ROM.  This means ON TIME can&#039;t be used when using&lt;br /&gt;
;      the DOS-ON feature.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
401FH  CALL 3FFAH           ; Load default RST 7 vector table values&lt;br /&gt;
4022H  LXI H,4084H          ; Point to RST 7 RAM hook routine&lt;br /&gt;
4025H  LXI D,F93DH          ; Point Time for ON TIME interrupt to use as our hook routine&lt;br /&gt;
4028H  LXI B,0006H          ; Copy our RST 7 hood to the &amp;quot;ON TIME&amp;quot; time location&lt;br /&gt;
402BH  CALL 4A05H           ; Move BC bytes from HL to DE - copy our hook to RAM&lt;br /&gt;
402EH  LXI H,F93DH          ; Load address of &amp;quot;ON TIM&amp;quot; time where our hook was copied&lt;br /&gt;
4031H  SHLD FAF4H           ; Use our RAM RST 7 Hook for RST 7,1Ah - RUN&lt;br /&gt;
4034H  SHLD FAF0H           ; Use our RAM RST 7 Hook for RST 7,16h - SAVE&lt;br /&gt;
4037H  SHLD FB38H           ; Use our RAM RST 7 Hook for RST 7,5Eh - LOADM and RUNM&lt;br /&gt;
403AH  SHLD FB36H           ; Use our RAM RST 7 Hook for RST 7,5Ch - SAVEM&lt;br /&gt;
403DH  SHLD FB08H           ; Use our RAM RST 7 Hook for RST 7,2Eh - DSKI$&lt;br /&gt;
4040H  SHLD FB0AH           ; Use our RAM RST 7 Hook for RST 7,30h - OPEN/CLOSE/PRINT/INPUT&lt;br /&gt;
4043H  SHLD FB2CH           ; Use our RAM RST 7 Hook for RST 7,52h - LFILES&lt;br /&gt;
4046H  SHLD FB32H           ; Use our RAM RST 7 Hook for RST 7,58h - KILL&lt;br /&gt;
4049H  SHLD FB34H           ; Use our RAM RST 7 Hook for RST 7,5Ah - NAME&lt;br /&gt;
404CH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process jump to custom RST 7 Hook routine from Main ROM&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
404DH  PUSH PSW             ; Preserve PSW&lt;br /&gt;
404EH  LDA FAC9H            ; Get address of last RST 38H call argument&lt;br /&gt;
4051H  CPI 1AH              ; RST 7,1Ah Hook - RUN statement &lt;br /&gt;
4053H  JZ 4451H&lt;br /&gt;
4056H  CPI 16H              ; RST 7,16h Hook - SAVE statement&lt;br /&gt;
4058H  JZ 44E7H&lt;br /&gt;
405BH  CPI 5EH              ; RST 7,5Eh Hook - LOADM and RUNM statement &lt;br /&gt;
405DH  JZ 43C1H&lt;br /&gt;
4060H  CPI 5CH              ; RST 7,5Ch Hook - SAVEM statement &lt;br /&gt;
4062H  JZ 440DH&lt;br /&gt;
4065H  CPI 2EH              ; RST 7,2Eh Hook - DSKI$ function&lt;br /&gt;
4067H  JZ 4324H&lt;br /&gt;
406AH  CPI 30H              ; RST 7,30h Hook - OPEN/CLOSE/PRINT/LINE INPUT satement&lt;br /&gt;
406CH  JZ 451DH&lt;br /&gt;
406FH  CPI 52H              ; RST 7,52h Hook - LFILES &lt;br /&gt;
4071H  JZ 4346H&lt;br /&gt;
4074H  CPI 58H              ; RST 7,58h Hook - KILL&lt;br /&gt;
4076H  JZ 4377H&lt;br /&gt;
4079H  CPI 5AH              ; RST 7,5Ah Hook - NAME statement &lt;br /&gt;
407BH  JZ 4396H&lt;br /&gt;
407EH  POP PSW              ; Restore stack frame&lt;br /&gt;
407FH  MVI E,02H            ; Prepare to generate &amp;quot;SN&amp;quot; error&lt;br /&gt;
4081H  JMP 4C37H            ; Generate error in E&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 7 Handler copied to RAM for DOS-ON&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4084H  CALL FAA4H           ; Call RAM hook to switch to OptROM&lt;br /&gt;
4087H  JMP 404DH            ; Jump to TS-DOS RST 7 handler in OptROM &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Open TPDD file for Read Mode.  File already stored in TX buffer.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
408AH  LXI H,0101H          ; Load &amp;quot;Open file&amp;quot; opcode&lt;br /&gt;
408DH  MVI A,03H            ; Load OPEN_READ mode into A&lt;br /&gt;
408FH  STA FCE8H            ; Save A in TX data storage (mode location)&lt;br /&gt;
4092H  JMP 409BH            ; Send Request in HL and await response - Open File&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Send TPDD Write File opcode using RX buffer with length in A&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4095H  MOV H,A              ; Move length to H&lt;br /&gt;
4096H  MVI L,04H            ; Load TPDD_WRITE opcode to L&lt;br /&gt;
4098H  JMP 40A7H            ; Send TX packet using RX buffer&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Send Request in HL and await response&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
409BH  CALL 4822H           ; Send TPDD Command/Len in HL&lt;br /&gt;
409EH  CALL 49F0H           ; Wait for data to be ready&lt;br /&gt;
40A1H  CALL 47CCH           ; Copy Receive RX packet routine to RAM and execute it&lt;br /&gt;
40A4H  JMP 47F8H            ; Check RX packet for Normal Response &amp;amp; report errors&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Use RX buffer to send a TX packet (used to send data).  Opcode/len in HL&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
40A7H  SHLD FD02H           ; Save Opcode/len to RX buffer &lt;br /&gt;
40AAH  LXI H,FD02H          ; Storage for RX packet&lt;br /&gt;
40ADH  CALL 4828H           ; Send TPDD pointed to by HL&lt;br /&gt;
40B0H  CALL 47CCH           ; Receive a packet&lt;br /&gt;
40B3H  JMP 47F8H            ; Check RX packet for Normal Response &amp;amp; report errors &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Send TPDD_READ data opcode and recieve response&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
40B6H  LXI H,0003H          ; Load TPDD_READ opcode &lt;br /&gt;
40B9H  CALL 4822H           ; Send TPDD Command/Len in HL&lt;br /&gt;
40BCH  CALL 47CCH           ; Receive a packet &lt;br /&gt;
40BFH  LDA FD03H            ; Get length byte from RX buffer &lt;br /&gt;
40C2H  LXI H,FD04H          ; Point to return data addres in RX buffer&lt;br /&gt;
40C5H  CPI 80H              ; Test for maximum read length  &lt;br /&gt;
40C7H  RET		  &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Write HL bytes of data from (DE) to TPDD&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
40C8H  PUSH D               ; Push address of write-data to stack  &lt;br /&gt;
40C9H  PUSH H               ; Push length of data to the stack  &lt;br /&gt;
40CAH  CALL 4101H           ; Test free Disk space and issue TPDD_OPEN request      &lt;br /&gt;
40CDH  POP H                ; Get address of data from stack &lt;br /&gt;
40CEH  SHLD FCD5H           ; Save length as remaining length to write      &lt;br /&gt;
40D1H  POP H                ; Get address of data to write to TPDD from stack &lt;br /&gt;
40D2H  LXI D,FD04H          ; Point to RX buffer to copy write data&lt;br /&gt;
40D5H  LXI B,0080H          ; Prepare to copy 128 bytes of data to the RX buffer  &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Write BC bytes of data from (HL) to (DE) and write to TPDD, DE=RX buffer data pointer&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
40D8H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment       &lt;br /&gt;
40DBH  PUSH H               ; Push the updated address to the stack   &lt;br /&gt;
40DCH  LHLD FCD5H           ; Get the remaining lenth left to write       &lt;br /&gt;
40DFH  LXI B,0080H          ; Prepare to subtract 128 from the length   &lt;br /&gt;
40E2H  DSUB                 ; Subtract 128 bytes from remaining length to write &lt;br /&gt;
40E3H  JC 40F4H             ; Jump out of loop if less than 128 bytes remaining     &lt;br /&gt;
40E6H  JZ 40F4H             ; Jump out of loop if exactly 128 bytes remaining     &lt;br /&gt;
40E9H  SHLD FCD5H           ; Save updated length left to write for next pass       &lt;br /&gt;
40ECH  MVI A,80H            ; Prepare to write 128 bytes to TPDD      &lt;br /&gt;
40EEH  CALL 4095H           ; Send TPDD Write File opcode using RX buffer with length in A       &lt;br /&gt;
40F1H  JMP 40D1H            ; Jump to send next packet of 128 bytes      &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Write remaining bytes (128 or less from above) to TPDD&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
40F4H  POP H                ; Clear stack of unneeded updated source address  &lt;br /&gt;
40F5H  LDA FCD5H            ; Load A with remainder of bytes to be sent&lt;br /&gt;
40F8H  CALL 4095H           ; Send TPDD Write File opcode using RX buffer with length in A &lt;br /&gt;
40FBH  LXI H,0002H          ; Load TPDD_CLOSE opcode in HL&lt;br /&gt;
40FEH  JMP 409BH            ; Send Request in HL and await response&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test if enough space on disk for HL bytes and issue Open request, error if disk full&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4101H  LXI D,0500H          ; Load decimal 1280 to calculate sector number&lt;br /&gt;
4104H  XCHG                 ; Swap HL/DE to perform size/bytes_per_sector &lt;br /&gt;
4105H  CALL 4C1BH           ; Signed integer divide (FAC1=DE/HL)       &lt;br /&gt;
4108H  LDA FD1FH            ; Get number of free sectors on disk      &lt;br /&gt;
410BH  SUB L                ; Compare required sectors with free space to see if enough room  &lt;br /&gt;
410CH  JC 4881H             ; Disk Full Error             &lt;br /&gt;
410FH  JZ 4881H             ; Disk Full Error     &lt;br /&gt;
4112H  LDA FCD6H            ; Load open mode (new, append, etc.)      &lt;br /&gt;
4115H  STA FCE8H            ; Save file open mode to TX buffer      &lt;br /&gt;
4118H  LXI H,0101H          ; Load TPDD_OPEN opcode&lt;br /&gt;
411BH  JMP 409BH            ; Send Request in HL and await response      &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Insert BC spaces at address of RAM file being loaded/run&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
411EH  LHLD FCE2H           ; Load address of file being processed&lt;br /&gt;
4121H  CALL 4C0BH           ; Insert BC spaces at M&lt;br /&gt;
4124H  JC 488AH             ; RAM full error&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Open TPDD file and read data to file address being processed&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4127H  LHLD FCE2H           ; Get address of file being processed&lt;br /&gt;
412AH  PUSH H               ; Save address on stack  &lt;br /&gt;
412BH  CALL 408AH           ; Open TPDD file for Read Mode&lt;br /&gt;
412EH  CALL 40B6H           ; Send TPDD_READ data opcode and recieve response&lt;br /&gt;
4131H  MOV C,A              ; Move read length to C   &lt;br /&gt;
4132H  MVI B,00H            ; Clear MSB of copy length&lt;br /&gt;
4134H  POP D                ; Restore address to write data &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Write BC bytes from M to DE and subtract BC from total file size&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4135H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment&lt;br /&gt;
4138H  PUSH D               ; Save updated address to stack  &lt;br /&gt;
4139H  LDA FD03H            ; Get length byte from RX buffer      &lt;br /&gt;
413CH  LHLD FCDDH           ; Get total file size from storage&lt;br /&gt;
413FH  MOV C,A              ; Load count of bytes transfered this block   &lt;br /&gt;
4140H  MVI B,00H            ; Clear MSB of count     &lt;br /&gt;
4142H  DSUB                 ; Subtract this block from total file length&lt;br /&gt;
4143H  SHLD FCDDH           ; Save remaining bytes to be read back to temp storage&lt;br /&gt;
4146H  JC 414EH             ; Branch if too many bytes read    &lt;br /&gt;
4149H  MOV A,L              ; Load LSB to A to test for zero   &lt;br /&gt;
414AH  ORA H                ; OR MSB to test for zero &lt;br /&gt;
414BH  JNZ 412EH            ; Branch to read more data if not zero     &lt;br /&gt;
414EH  POP D                ; Pop address from stack - cleanup &lt;br /&gt;
414FH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Write data to FDC Emulation mode physical/logical sector&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4150H  LDA FCDDH            ; Get physical sector number        &lt;br /&gt;
4153H  CPI 01H              ; Test if physical sector is #1      &lt;br /&gt;
4155H  RZ                   ; Return if trying to write to sector 1 - reserved!!! &lt;br /&gt;
4156H  CALL 4998H           ; Flush RX queue and discard         &lt;br /&gt;
4159H  MVI A,57H            ; Load FDC opcode for &amp;quot;W&amp;quot;rite sector                 &lt;br /&gt;
415BH  STA FCD3H            ; Save the FDC emulation mode opcode        &lt;br /&gt;
415EH  CALL 42CEH           ; Send FDC emulation mode opcode&lt;br /&gt;
4161H  CALL 4998H           ; Flush RX queue and discard&lt;br /&gt;
4164H  CALL 4176H           ; Increment to next logical/physical sector&lt;br /&gt;
4167H  LHLD FCE4H           ; FDC Emulation data pointer address &lt;br /&gt;
416AH  CALL 48D9H           ; Send BC bytes to RS-232 from (HL) using XON/XOFF&lt;br /&gt;
416DH  SHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
4170H  CALL 42EEH           ; Read FDC Emulation mode response&lt;br /&gt;
4173H  JMP 4150H            ; Jump to write next sector ???        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Increment to next logical/physical sector&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4176H  LDA FD09H            ; Get byte 7 from the RX buffer (logical sector length)        &lt;br /&gt;
4179H  CALL 4191H           ; Get FDC Emulation RAM buffer sector length based on response         &lt;br /&gt;
417CH  CPI 35H              ; Test if RAM Buffer logical sector length is &amp;quot;500&amp;quot; (1280)      &lt;br /&gt;
417EH  JZ 4189H             ; Just update physical sector if RAM length = physical sector len       &lt;br /&gt;
4181H  LXI H,FCDEH          ; Load pointer to logical sector value&lt;br /&gt;
4184H  INR M                ; Increment to next logical sector    &lt;br /&gt;
4185H  MOV A,M              ; Get the next logical sector value      &lt;br /&gt;
4186H  CPI 14H              ; Test if logical sector = 20 (There are 20 64-byte logical sectors)      &lt;br /&gt;
4188H  RNZ                  ; Return if not paat end of physical sector  &lt;br /&gt;
4189H  LXI H,FCDDH          ; Point to physical sector storage          &lt;br /&gt;
418CH  INR M                ; Increment to next physical sector - we &amp;quot;rolled over&amp;quot;    &lt;br /&gt;
418DH  INX H                ; Point to logical sector    &lt;br /&gt;
418EH  MVI M,01H            ; Start with logical sector #1 in new physical sector        &lt;br /&gt;
4190H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get FDC Emulation RAM buffer sector length based on response code in A&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4191H  LXI B,0500H          ; Initialize to 1280 byte sector length&lt;br /&gt;
4194H  CPI 35H              ; Compare response to test for &amp;quot;500&amp;quot; &lt;br /&gt;
4196H  RZ                   ; Return if match  &lt;br /&gt;
4197H  LXI B,0040H          ; Sector lenth not 1280, must be 64 bytes  &lt;br /&gt;
419AH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Send TPDD opcode 0x08 - Go to FDC emulation mode&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
419BH  LXI H,0008H          ; Prepare to send Opcode 0x08 (FDC Emulation Mode)&lt;br /&gt;
419EH  CALL 4822H           ; Send TPDD Command/Len in HL &lt;br /&gt;
41A1H  CALL 49D3H           ; Send 0x0D to RS-232 and Delay 3ms &lt;br /&gt;
41A4H  JMP 4998H            ; Flush RX queue and discard&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Rename the TPDD file whose name is in &amp;quot;current BASIC program&amp;quot;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
41A7H  LXI H,FC93H          ; Filename of current BASIC program    &lt;br /&gt;
41AAH  LXI D,FCE8H          ; Point to data area in TX buffer&lt;br /&gt;
41ADH  LXI B,0006H          ; Move 6 bytes of filename data&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Rename the TPDD file whose name is in (HL)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
41B0H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment          &lt;br /&gt;
41B3H  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag         &lt;br /&gt;
41B6H  ANA A                ; Test for TPDD server     &lt;br /&gt;
41B7H  JNZ 4258H            ; Send TPDD_RENAME opcode and check response     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Rename on a TPDD.  I&#039;m guessing the drive will allow changing a name to something&lt;br /&gt;
; that already exists, or there is no &amp;quot;rename&amp;quot;, so TS-DOS is reading sector 1 and doing&lt;br /&gt;
; the rename opertaion manually, then writing sector 1 back to the disk.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
41BAH  CALL 4A72H           ; Send Dir Reference opcode         &lt;br /&gt;
41BDH  JNZ 487EH            ; File Exists Error        &lt;br /&gt;
41C0H  LXI D,0500H          ; Prepare to test for 1280 bytes of free ram (1 sector)          &lt;br /&gt;
41C3H  CALL 4308H           ; Test if at least DE bytes of RAM free         &lt;br /&gt;
41C6H  LXI H,0100H          ; Load HL with physical sector 1, logical sector 0          &lt;br /&gt;
41C9H  SHLD FCDDH           ; Save in FDC Emulation sector storage         &lt;br /&gt;
41CCH  CALL 419BH           ; Send opcode 0x08 - go to FDC emulation mode         &lt;br /&gt;
41CFH  CALL 427EH           ; Load Physical sector 1 to (HL) (HL=Unused memory pointer)         &lt;br /&gt;
41D2H  LHLD FBB6H           ; Get pointer to data - Unused memory pointer    &lt;br /&gt;
41D5H  PUSH H               ; Push data pointer to the stack       &lt;br /&gt;
41D6H  MVI B,28H            ; Prepare to test up to 40 filenames (max for TPDD)&lt;br /&gt;
41D8H  LXI D,FC9CH          ; Filename of last program loaded from tape    &lt;br /&gt;
41DBH  CALL 4269H           ; Compare &amp;quot;Last program loaded&amp;quot; filename with all files on TPDD    &lt;br /&gt;
41DEH  JC 487BH             ; Printer not ready / FF error         &lt;br /&gt;
41E1H  MOV A,B              ; Get index in TPDD Sector 1 of filename that matches the old filename        &lt;br /&gt;
41E2H  ANA A                ; Test if old filename exists      &lt;br /&gt;
41E3H  JZ 487BH             ; Jump to error if filename not found in sector 1 - FF error         &lt;br /&gt;
41E6H  PUSH H               ; Save address within Sector 1 of matching filename to stack       &lt;br /&gt;
41E7H  LXI D,FCE8H          ; Point to TX buffer data area (payload)            &lt;br /&gt;
41EAH  XCHG                 ; HL &amp;lt;--&amp;gt; DE  Prepare to copy new filename to Sector 1 data                 &lt;br /&gt;
41EBH  LXI B,0009H          ; Prepare to copy 9 bytes of filename            &lt;br /&gt;
41EEH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment - copy new filename to sector 1           &lt;br /&gt;
41F1H  POP H                ; Restore pointer to filename address within sector 1      &lt;br /&gt;
41F2H  PUSH H               ; Save it to the stack again       &lt;br /&gt;
41F3H  LXI D,FD20H          ; Load address of data byte 28 in RX buffer            &lt;br /&gt;
41F6H  LXI B,001FH          ; Prepare to copy 31 bytes to RX buffer from Sector 1 data            &lt;br /&gt;
41F9H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment - Save File data in RX buffer           &lt;br /&gt;
&lt;br /&gt;
	; ==========================================================================================&lt;br /&gt;
	; Now we will &amp;quot;remove&amp;quot; the renamed file from sector 1 by copying over it with the remaining&lt;br /&gt;
	; files in the sector.  Filenames in sector 1 must be in alphabetical order, so we have to&lt;br /&gt;
	; remove it and reinsert it at the new location based on the new name.&lt;br /&gt;
	; ==========================================================================================&lt;br /&gt;
&lt;br /&gt;
41FCH  POP D                ; Restore pointer to filename address within sector 1      &lt;br /&gt;
41FDH  PUSH D               ; Save it to the stack again       &lt;br /&gt;
41FEH  LXI H,001FH          ; Prepare to add 31 bytes to the sector 1 pointer (go to next file)            &lt;br /&gt;
4201H  DAD D                ; Point to next file after rename file within sector 1      &lt;br /&gt;
4202H  PUSH H               ; Save address of next file after rename file to stack       &lt;br /&gt;
4203H  LHLD FBB6H           ; Unused memory pointer    &lt;br /&gt;
4206H  LXI B,0500H          ; Load size of 1 TPDD sector (1280 bytes)            &lt;br /&gt;
4209H  DAD B                ; Point to end of sector 1 data in free memory region      &lt;br /&gt;
420AH  POP B                ; Restore address of next file after rename file from stack      &lt;br /&gt;
420BH  PUSH B               ; Save it back to the stack       &lt;br /&gt;
420CH  DSUB                 ; Calculate number of bytes from next file after rename to end of sector 1      &lt;br /&gt;
420DH  XTHL                 ; HL &amp;lt;--&amp;gt; (SP)  Prepare to move HL to BC, HL now has address of next file     &lt;br /&gt;
420EH  POP B                ; Get byte count to end of sector 1      &lt;br /&gt;
420FH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment - shift bytes &amp;quot;left&amp;quot; in buffer           &lt;br /&gt;
4212H  LHLD FBB6H           ; Unused memory pointer - point to beginning of Sector 1 data    &lt;br /&gt;
4215H  MVI B,27H            ; Prepare to search throuh 39 files (we just deleted one)          &lt;br /&gt;
4217H  LXI D,FD20H          ; Load address of data byte 28 in RX buffer (our saved file)            &lt;br /&gt;
421AH  CALL 4269H           ; Search Sector-1 files at (HL) for filename at (DE)     &lt;br /&gt;
421DH  PUSH H               ; Save address of location where file should be inserted in Sector 1       &lt;br /&gt;
421EH  LHLD FBB6H           ; Unused memory pointer - point to beginning of Sector 1    &lt;br /&gt;
4221H  LXI B,04FFH          ; Prepare to move bytes &amp;quot;right&amp;quot; to end of sector (1280 bytes - 1)            &lt;br /&gt;
4224H  DAD B                ; Point to end of sector 1 data      &lt;br /&gt;
4225H  PUSH H               ; Save end of sector 1 address to stack       &lt;br /&gt;
4226H  LXI B,001FH          ; Prepare to subtract 1 file entry length from end of sector 1 address            &lt;br /&gt;
4229H  DSUB                 ; Shorten the copy operation by 1 file entry so we don&#039;t overflow memory     &lt;br /&gt;
422AH  POP D                ; Get end of sector 1 address from stack as our &amp;quot;copy to&amp;quot; address      &lt;br /&gt;
422BH  POP B                ; Get address where file needs to be inserted from the stack      &lt;br /&gt;
422CH  PUSH B               ; Save it back to the stack for later       &lt;br /&gt;
422DH  PUSH H               ; Save address of end of Sector 1 minus one file entry length to stack       &lt;br /&gt;
422EH  DSUB                 ; Calculate the copy lenght of data from insertion point to end of sector-1 file     &lt;br /&gt;
422FH  PUSH H               ; Save copy length to the stack to copy it to BC       &lt;br /&gt;
4230H  POP B                ; Get copy length into BC      &lt;br /&gt;
4231H  INX B                ; Increment length by 1 so the last byte is inclusive      &lt;br /&gt;
4232H  POP H                ; Get address of file insertion point from stack      &lt;br /&gt;
4233H  CALL 4C4EH           ; Move BC bytes from M to (DE) with decrement - shift files &amp;quot;right&amp;quot; in sector 1           &lt;br /&gt;
4236H  LXI H,FD20H          ; Get address of our saved file info in the RX buffer&lt;br /&gt;
4239H  POP D                ; Get address in Sector 1 of file insertion point      &lt;br /&gt;
423AH  LXI B,001FH          ; Prepare to copy 1 file entry size (31 bytes)            &lt;br /&gt;
423DH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment           &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	; ===============================================================================&lt;br /&gt;
	; Seems like the next two lines don&#039;t do anything. The value being loaded in HL &lt;br /&gt;
	; *appears* to mean &amp;quot;Logical sector 20, physical sector 1&amp;quot;, but only if the SHLD&lt;br /&gt;
	; target address is FCCDH.  Then 5 instructions further down, the value in&lt;br /&gt;
	; ED80h is overwritten with logical sector 0.&lt;br /&gt;
	; ===============================================================================&lt;br /&gt;
4240H  LXI H,1401H          ; Set L = logical sector 1, H=File type 0x14?            &lt;br /&gt;
4243H  SHLD FCDEH           ; Save logical sector &amp;amp; filetype           &lt;br /&gt;
&lt;br /&gt;
4246H  POP H                ; POP stale address within Sector 1 of matching filename from stack      &lt;br /&gt;
4247H  POP H                ; Get address of unused memory (Sector 1 data storage) from stack      &lt;br /&gt;
4248H  SHLD FCE4H           ; Save in FDC Emulation data pointer address            &lt;br /&gt;
424BH  LXI H,0100H          ; Load HL= logical sector 1, physical sector 0            &lt;br /&gt;
424EH  SHLD FCDDH           ; Save in FDC Emulation physical/logical sector storage           &lt;br /&gt;
4251H  CALL 4150H           ; Write data to FDC Emulation mode physical/logical sector           &lt;br /&gt;
4254H  CALL 49CDH           ; Send &amp;quot;M1&amp;quot;,0x0D to RS-232 and delay about 3ms - go to Standard mode           &lt;br /&gt;
4257H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Send TPDD_RENAME opcode and check response for errors&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4258H  LXI H,190DH          ; Load TPDD_RENAME opcode&lt;br /&gt;
425BH  CALL 4822H           ; Send TPDD Command/Len in HL &lt;br /&gt;
425EH  CALL 47CCH           ; Receive a packet &lt;br /&gt;
4261H  LDA FD04H            ; Get response error code &lt;br /&gt;
4264H  ANA A                ; Check for errors &lt;br /&gt;
4265H  JNZ 487EH            ; Report File Exists Error if not zero&lt;br /&gt;
4268H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Search Sector-1 files at (HL) for filename at (DE), maximum of &amp;quot;B&amp;quot; entries searched &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4269H  MVI C,09H            ; Prepare to compare 9 bytes        &lt;br /&gt;
426BH  CALL 4A1CH           ; Compare (HL) with (DE), C bytes long (HL &amp;amp; DE preserved)         &lt;br /&gt;
426EH  RZ                   ; Return if they are the same &lt;br /&gt;
426FH  RC                   ; Return if filename is less (files are sorted on TPDD) &lt;br /&gt;
4270H  MOV A,M              ; Get 1st byte of filename to test for NULL      &lt;br /&gt;
4271H  ORA A                ; Test if A is 0    &lt;br /&gt;
4272H  RZ                   ; Return if string is NULL &lt;br /&gt;
4273H  PUSH B               ; Save BC on stack     &lt;br /&gt;
4274H  LXI B,001FH          ; Prepare to add 31 to HL&lt;br /&gt;
4277H  DAD B                ; Add 31 to HL    &lt;br /&gt;
4278H  POP B                ; Restore original BC    &lt;br /&gt;
4279H  DCR B                ; Decrement loop counter    &lt;br /&gt;
427AH  RZ                   ; Return if no more items to compare &lt;br /&gt;
427BH  JMP 4269H            ; Jump to compare next entry  &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Read FDC sectors to New File Address (Free memory)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
427EH  LHLD FCE2H           ; Get pointer for TPDD read data&lt;br /&gt;
4281H  CALL 4298H           ; Read sector A into (HL)     &lt;br /&gt;
4284H  LDA FCDDH            ; Load current FDC Emulation physical sector number        &lt;br /&gt;
4287H  DCR A                ; Decrement to previous sector    &lt;br /&gt;
4288H  RZ                   ; Return if sector number is zero &lt;br /&gt;
4289H  JMP 4281H            ; Jump to read another sector (what breaks the loop? - A not saved)        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Receive RX bytes to (HL) routine copied to RAM&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
428CH  CALL 6D7EH           ; Get a character from RS232 receive queue&lt;br /&gt;
428FH  MOV M,A              ; Save next byte to (HL)&lt;br /&gt;
4290H  INX H                ; Increment pointer&lt;br /&gt;
4291H  DCX B                ; Decrement counter&lt;br /&gt;
4292H  MOV A,C              ; Prepare to test or zero&lt;br /&gt;
4293H  ORA B                ; OR in MSB of coutner&lt;br /&gt;
4294H  JNZ FD89H            ; Jump back to receive next character (RAM address)&lt;br /&gt;
4297H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Read FDC sector A to (HL), BC has length&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4298H  PUSH H               ; Save target address for RX data stack&lt;br /&gt;
4299H  MVI A,52H            ; Load FDC Emulation opcode for &amp;quot;R&amp;quot;ead&lt;br /&gt;
429BH  STA FCD3H            ; Save as FDC Emulation opcode to send&lt;br /&gt;
429EH  CALL 42CEH           ; Send FDC emulation mode opcode&lt;br /&gt;
42A1H  CALL 4176H           ; Increment to next logical/physical sector&lt;br /&gt;
42A4H  CALL 4862H           ; Test if DSR is set - drive ready, error otherwise&lt;br /&gt;
42A7H  PUSH B               ; Save length of RX to the stack&lt;br /&gt;
42A8H  LXI H,428CH          ; Load address of RX routine to copy to RAM&lt;br /&gt;
42ABH  LXI B,000CH          ; Size of the RX routine to be copied to RAM&lt;br /&gt;
42AEH  LXI D,FD89H          ; Target address of RX routine (in ALTLCD buffer)&lt;br /&gt;
42B1H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment&lt;br /&gt;
42B4H  MVI A,0DH            ; Prepare to send CR to RS-232&lt;br /&gt;
42B6H  CALL 485FH           ; Send A to RS-232 using XON/XOFF          &lt;br /&gt;
42B9H  CALL 4BDBH           ; Call Main ROM&#039;s Set interrupt to 1DH routine.&lt;br /&gt;
42BCH  POP B                ; Restore count of bytes to receive&lt;br /&gt;
42BDH  POP H                ; Restore target address for RX data&lt;br /&gt;
42BEH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
42BFH  DW FD89H             ; Switch to Main ROM and call our RAM based RX routine&lt;br /&gt;
42C1H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Convert decimal value in A to base 10 ASCII value in BC&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
42C2H  MVI B,2FH            ; Start with &#039;0&#039; - 1&lt;br /&gt;
42C4H  SUI 0AH              ; Subtract 10 from A &lt;br /&gt;
42C6H  INR B                ; Increment B (10&#039;s position) &lt;br /&gt;
42C7H  JNC 42C4H            ; Keep looping until A negative&lt;br /&gt;
42CAH  ADI 3AH              ; Convert negative remainder to positive ASCII &#039;0&#039;-&#039;9&#039; &lt;br /&gt;
42CCH  MOV C,A              ; Store LSB ASCII value in C  &lt;br /&gt;
42CDH  RET		&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Send FDC emulation mode opcode&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
42CEH  LDA FCDDH            ; Get physical sector number         &lt;br /&gt;
42D1H  CALL 42C2H           ; Convert A to 10-based ASCII          &lt;br /&gt;
42D4H  LDA FCD3H            ; Load the FDC emulation mode opcode to send         &lt;br /&gt;
42D7H  CALL 485FH           ; Send A to RS-232 using XON/XOFF          &lt;br /&gt;
42DAH  CALL 49DBH           ; Send BC to RS-232 using XON/XOFF - send physical sector #          &lt;br /&gt;
42DDH  LDA FCDEH            ; Get logical sector number         &lt;br /&gt;
42E0H  CALL 42C2H           ; Convert A to 10-based ASCII          &lt;br /&gt;
42E3H  MVI A,2CH            ; Load code for &#039;,&#039;         &lt;br /&gt;
42E5H  CALL 485FH           ; Send A to RS-232 using XON/XOFF          &lt;br /&gt;
42E8H  CALL 49DBH           ; Send BC to RS-232 using XON/XOFF - send logical sector #          &lt;br /&gt;
42EBH  CALL 49D3H           ; Send 0x0D to RS-232 and Delay 3ms          &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Read FDC Emulation mode response&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
42EEH  LXI H,FD04H          ; Point to RX buffer data area          &lt;br /&gt;
42F1H  PUSH H               ; Save RX buffer address on stack     &lt;br /&gt;
42F2H  MVI C,08H            ; Prepare to read 8 bytes from RX - standard FDC response length        &lt;br /&gt;
42F4H  CALL 47E5H           ; Get next byte from RX into HL         &lt;br /&gt;
42F7H  DCR C                ; Decrement loop counter    &lt;br /&gt;
42F8H  JNZ 42F4H            ; Keep looping until 8 bytes read        &lt;br /&gt;
42FBH  POP H                ; Get start of RX buffer address from stack    &lt;br /&gt;
42FCH  MOV A,M              ; Get first response byte      &lt;br /&gt;
42FDH  CPI 30H              ; Test if response error code is &#039;0&#039; - no error      &lt;br /&gt;
42FFH  RZ                   ; Return if no error &lt;br /&gt;
4300H  CPI 42H              ; Test for FDC Emulation mode &amp;quot;write protect&amp;quot; error code      &lt;br /&gt;
4302H  JZ 486DH             ; Write Protect Error       &lt;br /&gt;
4305H  JMP 4867H            ; Drive Not Ready Error        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test if at least DE bytes of RAM left&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4308H  LHLD FBB6H           ; Unused memory pointer  &lt;br /&gt;
430BH  PUSH H               ; Push unused memory location on stack    &lt;br /&gt;
430CH  SHLD FCE2H           ; Save unused memory location locally        &lt;br /&gt;
430FH  LXI H,FFC0H          ; Prepare to subtract 64 from stack pointer &lt;br /&gt;
4312H  DAD SP               ; Add SP to HL (-64) (need some call space to run program)    &lt;br /&gt;
4313H  POP B                ; Restore unused memory location in BC            &lt;br /&gt;
4314H  DSUB                 ; Subtract stack from unused memory pointer  &lt;br /&gt;
4315H  RST 3                ; Compare DE and HL - check if enough free RAM &lt;br /&gt;
4316H  JC 488AH             ; RAM full error      &lt;br /&gt;
4319H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Issue TPDD Delete file Opcode&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
431AH  XRA A                ; Prepare to indicate we can&#039;t use Next Dir feature&lt;br /&gt;
431BH  STA FD01H            ; Save in dir reference location in TX buffer&lt;br /&gt;
431EH  LXI H,0005H          ; Load Delete File opcode into HL&lt;br /&gt;
4321H  JMP 409BH            ; Send Request in HL and await response&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 7,2Eh Hook - DSKI$ function&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4324H  POP PSW              ; Pop return address - we will return manually to Main ROM&lt;br /&gt;
4325H  CPI 30H              ; Test A against &#039;0&#039; to check for bounds (only allow &#039;0&#039; and &#039;1&#039;)       &lt;br /&gt;
4327H  JC 00A6H             ; Return to Main ROM if less than &#039;0&#039; - not our&#039;s        &lt;br /&gt;
432AH  CPI 32H              ; Test A against &#039;2&#039; to check for bounds       &lt;br /&gt;
432CH  JNC 00A6H            ; Return to Main ROM if &amp;gt;= &#039;2&#039;         &lt;br /&gt;
432FH  SUI 30H              ; Convert ASCII bank number to binary       &lt;br /&gt;
4331H  STA FCCAH            ; Save the target bank number in TPDD2 Bank number space         &lt;br /&gt;
4334H  INX H                ; Point to next byte to ensure it is &#039;:&#039;     &lt;br /&gt;
4335H  DCR E                ; ? Maybe length     &lt;br /&gt;
4336H  MOV A,M              ; Get next byte of filename       &lt;br /&gt;
4337H  CPI 3AH              ; Test if it is &#039;:&#039;       &lt;br /&gt;
4339H  JNZ 00A6H            ; Return if not &#039;:&#039;         &lt;br /&gt;
433CH  INX H                ; Increment to filename portion     &lt;br /&gt;
433DH  DCR E                ; ? Maybe length     &lt;br /&gt;
433EH  XTHL                 ; Put pointer to filename on stack so we don&#039;t lose it when we pop             &lt;br /&gt;
433FH  POP H                ; Pop so we return to our caller&#039;s return address     &lt;br /&gt;
4340H  MVI A,09H            ; Load A with a value we will test for later to see if it&#039;s our file         &lt;br /&gt;
4342H  ORA A                ; Set return flags     &lt;br /&gt;
4343H  JMP 00A6H            ; Return to Main ROM&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 7,52h Hook - LFILES function&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4346H  POP PSW              ; POP return address from stack...we will return manually&lt;br /&gt;
4347H  PUSH D               ; Preserve DE on STACK     &lt;br /&gt;
4348H  PUSH H               ; Preserve HL on STACK     &lt;br /&gt;
4349H  PUSH PSW             ; Preserve A on STACK       &lt;br /&gt;
434AH  XRA A                ; Flag to generate system errors vs. printing    &lt;br /&gt;
434BH  CALL 4A85H           ; Save OS&#039;s baud rate string to storage area         &lt;br /&gt;
434EH  LDES 02H             ; DE = SP + 2       &lt;br /&gt;
4350H  LHLX                 ; Get value of HL pushed to stack above - LFILES argument pointer   &lt;br /&gt;
4351H  MOV A,M              ; Get 1st byte of argument      &lt;br /&gt;
4352H  ANA A                ; Test if arguement is zero             &lt;br /&gt;
4353H  JZ 436AH             ; Jump to display files from current TPDD bank number if zero       &lt;br /&gt;
4356H  CPI 3AH              ; Test if 1st byte is &#039;:&#039;      &lt;br /&gt;
4358H  JZ 436AH             ; Jump to display files from current TPDD bank number if &#039;:&amp;quot;       &lt;br /&gt;
435BH  CALL 4BCFH           ; Evaluate expression at M-1 - Convert &amp;quot;0:&amp;quot; or &amp;quot;1:&amp;quot; to decimal         &lt;br /&gt;
435EH  MOV A,E              ; Get result of evaluation      &lt;br /&gt;
435FH  CPI 02H              ; Compare result for bounds      &lt;br /&gt;
4361H  JNC 4370H            ; Jump to exit routine if not 0 or 1        &lt;br /&gt;
4364H  STA FCCAH            ; Save as TPDD2 Bank number        &lt;br /&gt;
4367H  LDES 02H             ; DE = SP + 2       &lt;br /&gt;
4369H  SHLX                 ; Save updated expression pointer to stack location prior to RST 7   &lt;br /&gt;
436AH  CALL 4704H           ; Display / print all files and free space         &lt;br /&gt;
436DH  CALL 4AC4H           ; Restore original baud settings         &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 7 Hook exit routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4370H  POP PSW              ; Get preserved A from stack    &lt;br /&gt;
4371H  POP H                ; Get preserved HL from stack  &lt;br /&gt;
4372H  POP D                ; Get preserved DE from stack  &lt;br /&gt;
4373H  POP B                ; B isn&#039;t PUSHed in the Hook routines, POP the return address  &lt;br /&gt;
4374H  JMP 00A6             ; Return to the Main ROM&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 7,58h Hook - KILL statement&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4377H  POP PSW              ; POP the return address - we will return manually&lt;br /&gt;
4378H  CPI 09H              ; Test if we found &amp;quot;0:&amp;quot; or &amp;quot;1:&amp;quot; in the DSKI$ function    &lt;br /&gt;
437AH  JNZ 4516H            ; Generate FC error      &lt;br /&gt;
437DH  PUSH D               ; Preserve DE on the stack   &lt;br /&gt;
437EH  PUSH H               ; Preserve HL on the stack   &lt;br /&gt;
437FH  PUSH PSW             ; Preserve A on the stack     &lt;br /&gt;
4380H  XRA A                ; Flag to generate system errors vs. printing  &lt;br /&gt;
4381H  CALL 4A85H           ; Save OS&#039;s baud rate string to storage area       &lt;br /&gt;
4384H  LXI H,FC93H          ; Filename of current BASIC program            &lt;br /&gt;
4387H  CALL 4A57H           ; Send Dir Reference for filename at (HL)       &lt;br /&gt;
438AH  JZ 487BH             ; &amp;quot;FF&amp;quot; error if attribute byte is zero     &lt;br /&gt;
438DH  CALL 431AH           ; Issue TPDD Delete file Opcode       &lt;br /&gt;
4390H  CALL 4AC4H           ; Restore original baud settings       &lt;br /&gt;
4393H  JMP 4370H            ; RST 7 Hook exit routine      &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 7,5Ah Hook - NAME statement&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4396H  POP PSW              ; POP the return address - we will return manually&lt;br /&gt;
4397H  CPI 09H              ; Test if we found &amp;quot;0:&amp;quot; or &amp;quot;1:&amp;quot; in the DSKI$ function    &lt;br /&gt;
4399H  JNZ 4516H            ; Generate FC error      &lt;br /&gt;
439CH  PUSH D               ; Preserve DE on the stack   &lt;br /&gt;
439DH  PUSH H               ; Preserve HL on the stack   &lt;br /&gt;
439EH  PUSH PSW             ; Preserve A on the stack     &lt;br /&gt;
439FH  XRA A                ; Flag to generate system errors vs. printing          &lt;br /&gt;
43A0H  CALL 4A85H           ; Save OS&#039;s baud rate string to storage area       &lt;br /&gt;
43A3H  LXI H,FC9CH          ; Filename of last program loaded from tape            &lt;br /&gt;
43A6H  CALL 4A57H           ; Send Dir Reference for filename at (HL)       &lt;br /&gt;
43A9H  JZ 487BH             ; &amp;quot;FF&amp;quot; error if attribut byte is zero     &lt;br /&gt;
43ACH  LXI H,FCE8H          ; Point to TX buffer data area (payload)        &lt;br /&gt;
43AFH  LXI D,FC9CH          ; Filename of last program loaded from tape            &lt;br /&gt;
43B2H  LXI B,0009H          ; Prepare to copy 9 bytes of filename        &lt;br /&gt;
43B5H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment       &lt;br /&gt;
43B8H  CALL 41A7H           ; Rename the TPDD file whose name is in &amp;quot;current BASIC program&amp;quot;       &lt;br /&gt;
43BBH  CALL 4AC4H           ; Restore original baud settings       &lt;br /&gt;
43BEH  JMP 4370H            ; RST 7 Hook exit routine      &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 7,5Eh Hook - LOADM and RUNM statement&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
43C1H  POP PSW        &lt;br /&gt;
43C2H  CPI 09H              ; Test if we found &amp;quot;0:&amp;quot; or &amp;quot;1:&amp;quot; in the DSKI$ function    &lt;br /&gt;
43C4H  JNZ 00A6H            ; Return if not a TPDD file      &lt;br /&gt;
43C7H  POP B                ; Pop return address from stack - we will jump manually to exit  &lt;br /&gt;
43C8H  PUSH H               ; Preserve HL on the stack   &lt;br /&gt;
43C9H  LXI B,4F43H          ; Load code for &amp;quot;CO&amp;quot; filename extension        &lt;br /&gt;
43CCH  CALL 44BAH           ; Compare extension in current BASIC program filename with value in BC    &lt;br /&gt;
43CFH  JZ 487BH             ; &amp;quot;FF&amp;quot; Printer not ready error     &lt;br /&gt;
43D2H  CALL 408AH           ; Open TPDD file for Read Mode       &lt;br /&gt;
43D5H  LHLD FD1DH           ; Get file size parameter from RX buffer       &lt;br /&gt;
43D8H  MOV A,L              ; Swap endianness of file size    &lt;br /&gt;
43D9H  MOV L,H              ; Move MSB to LSB    &lt;br /&gt;
43DAH  MOV H,A              ; Move LSB to MSB    &lt;br /&gt;
43DBH  SHLD FCDDH           ; Save endian modified length back to storage       &lt;br /&gt;
43DEH  CALL 40B6H           ; Send TPDD_READ data opcode and recieve response, HL=RX buf upon return       &lt;br /&gt;
43E1H  CALL 4C6AH           ; Copy CO header bytes (6) from (HL) to &amp;quot;active&amp;quot; CO Header storage area       &lt;br /&gt;
43E4H  PUSH H               ; Push updated (+6) RX data pointer to stack   &lt;br /&gt;
43E5H  CALL 4C6EH           ; Go print CO address, length and invocation address to LCD       &lt;br /&gt;
43E8H  LHLD FACEH           ; Address of CO Header - get CO load address       &lt;br /&gt;
43EBH  PUSH H               ; Push CO load address to stack   &lt;br /&gt;
43ECH  PUSH H               ; Push another copy to the stack to preserve value during XTHL/POP   &lt;br /&gt;
43EDH  LHLD F5F4H           ; RST 5.5 RAM Vector   &lt;br /&gt;
43F0H  XTHL                 ; HL &amp;lt;--&amp;gt; (SP)  Load RST 5.5 RAM vector as return address &lt;br /&gt;
43F1H  POP B                ; BC now has RST 5.5 RAM Vector, HL= CO load address  &lt;br /&gt;
43F2H  DSUB                 ; Test if CO load address is less that RST 5.5 RAM address &lt;br /&gt;
43F3H  JC 488AH             ; Trying to clober RST5.5 RAM vectors - generate RAM full error     &lt;br /&gt;
43F6H  POP D                ; Get CO load address saved on stack   &lt;br /&gt;
43F7H  POP H                ; Get Updated (+6) RX data pointer from stack   &lt;br /&gt;
43F8H  LDA FD03H            ; Load RX Length byte from RX data buffer       &lt;br /&gt;
43FBH  SUI 06H              ; Subtract CO header length from packet data length     &lt;br /&gt;
43FDH  MOV C,A              ; Save packet data length in BC     &lt;br /&gt;
43FEH  MVI B,00H            ; Make MSB of BC zero       &lt;br /&gt;
4400H  CALL 4135H           ; Write BC bytes from M to DE and subtract BC from total file size        &lt;br /&gt;
4403H  CALL 4AC4H           ; Restore original baud settings        &lt;br /&gt;
4406H  LXI H,251AH          ; Load new return address in Main ROM&lt;br /&gt;
4409H  PUSH H               ; Push new return address to stack&lt;br /&gt;
440AH  JMP 00A6H            ; Jump to Main ROM&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 7,5Ch Hook - SAVEM statement&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
440DH  POP PSW              ; POP the return address - we will return elsewhere&lt;br /&gt;
440EH  CPI 09H              ; Test if we found &amp;quot;0:&amp;quot; or &amp;quot;1:&amp;quot; in the DSKI$ function    &lt;br /&gt;
4410H  JNZ 00A6H            ; Return if not a TPDD file      &lt;br /&gt;
4413H  CALL 4C72H           ; Process SAVEM arguments for address, length and entry point       &lt;br /&gt;
4416H  LXI B,4F43H          ; Load code for &amp;quot;CO&amp;quot; file extension        &lt;br /&gt;
4419H  CALL 44BAH           ; Compare ext. in current BASIC program with BC, send dir ref. if match            &lt;br /&gt;
441CH  JNZ 487EH            ; Jump to generate File Exists Error if found      &lt;br /&gt;
441FH  MVI A,01H            ; Set open mode for new file      &lt;br /&gt;
4421H  STA FCD6H            ; Save open mode to input variable      &lt;br /&gt;
4424H  LHLD FAD0H           ; Length of last program loaded/saved to tape            &lt;br /&gt;
4427H  LXI B,0006H          ; Prepare to add CO header size (6 bytes) to required length        &lt;br /&gt;
442AH  PUSH B               ; Push CO header length to stack   &lt;br /&gt;
442BH  DAD B                ; Add CO header size to required length  &lt;br /&gt;
442CH  PUSH H               ; Push updated file length to stack   &lt;br /&gt;
442DH  CALL 4101H           ; Test free Disk space and issue TPDD_OPEN request       &lt;br /&gt;
4430H  POP H                ; Get updated file length from stack  &lt;br /&gt;
4431H  SHLD FCD5H           ; Save as lenght of file being saved / loaded       &lt;br /&gt;
4434H  POP B                ; Get CO header length from stack          &lt;br /&gt;
4435H  LXI H,FACEH          ; Load address of &amp;quot;active&amp;quot; CO header block        &lt;br /&gt;
4438H  LXI D,FD04H          ; DE points to the data area in RX buffer        &lt;br /&gt;
443BH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment       &lt;br /&gt;
443EH  LHLD FD04H           ; DE points to the data area in RX buffer       &lt;br /&gt;
4441H  LXI B,007AH          ; Prepare to write 122 bytes of data to next location in RX buffer        &lt;br /&gt;
4444H  CALL 40D8H           ; Write 122 bytes from (HL) and send TPDD_WRITE to TPDD       &lt;br /&gt;
4447H  CALL 4AC4H           ; Restore original baud settings       &lt;br /&gt;
444AH  LXI H,0501H          ; Load return address in Main ROM - vector to BASIC ready&lt;br /&gt;
444DH  PUSH H               ; Push return address to stack&lt;br /&gt;
444EH  JMP 00A6H            ; Return to Main ROM&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 7,1Ah Hook - RUN statement&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4451H  POP PSW       &lt;br /&gt;
4452H  CPI 09H              ; Test if we found &amp;quot;0:&amp;quot; or &amp;quot;1:&amp;quot; in the DSKI$ function   &lt;br /&gt;
4454H  JNZ 00A6H            ; Return if not TPDD file     &lt;br /&gt;
4457H  POP B                ; Get return address from stack  &lt;br /&gt;
4458H  POP PSW              ; Get 1st byte of RUN statement argument   &lt;br /&gt;
4459H  PUSH PSW             ; Put back the data we stole    &lt;br /&gt;
445AH  PUSH B               ; Put back the return address  &lt;br /&gt;
445BH  JZ 00A6H             ; Return if there were no arguments to the RUN statement    &lt;br /&gt;
445EH  SBB A                ; Clear zero flag (C is set and A=0xFF) &lt;br /&gt;
445FH  STA FC92H            ; Save in flag to execute BASIC program (non-zero = execute)     &lt;br /&gt;
4462H  LXI B,4142H          ; Load code for &amp;quot;BA&amp;quot; BASIC file extension       &lt;br /&gt;
4465H  CALL 44BAH           ; Compare ext. in current BASIC program with BC, send dir ref. if match           &lt;br /&gt;
4468H  JZ 487BH             ; Jump to error if not &amp;quot;BA&amp;quot; or &amp;quot;  &amp;quot; - generate &amp;quot;FF&amp;quot; error    &lt;br /&gt;
446BH  LHLD FD1DH           ; Get file size parameter from RX buffer      &lt;br /&gt;
446EH  MOV C,H              ; Swap endianness of file size   &lt;br /&gt;
446FH  MOV B,L              ; Swap LSB to MSB   &lt;br /&gt;
4470H  MOV H,B              ; Copy file size parameter back to HL   &lt;br /&gt;
4471H  MOV L,C              ; Copy LSB of file size to HL   &lt;br /&gt;
4472H  SHLD FCDDH           ; Store length of file       &lt;br /&gt;
4475H  CALL 44ABH           ; Call NEW statement, upon return HL=address of last variable assigned      &lt;br /&gt;
4478H  INX H                ; Increment to free memory space &lt;br /&gt;
4479H  SHLD FCE2H           ; Save as address of file being loaded/saved/etc.      &lt;br /&gt;
447CH  LHLD FCDDH           ; Get disk file length      &lt;br /&gt;
447FH  PUSH H               ; Save file length on stack  &lt;br /&gt;
4480H  PUSH H               ; Push file length to stack to copy to BC  &lt;br /&gt;
4481H  POP B                ; Pop file length to BC &lt;br /&gt;
4482H  CALL 411EH           ; Insert BC spaces at address of RAM file being loaded/run      &lt;br /&gt;
4485H  POP D                ; Get length of disk file from stack &lt;br /&gt;
4486H  LHLD FBAEH           ; Load Start of DO files pointer    &lt;br /&gt;
4489H  DAD D                ; Increment Start of DO files pointer by disk file length    &lt;br /&gt;
448AH  SHLD FBAEH           ; Save updated Start of DO files pointer    &lt;br /&gt;
448DH  LHLD FAD8H           ; Load pointer to address used for RAM Input processing         &lt;br /&gt;
4490H  DAD D                ; Increment pointer by disk file length    &lt;br /&gt;
4491H  SHLD FAD8H           ; Save updated RAM Input processing pointer         &lt;br /&gt;
4494H  CALL 4AC4H           ; Restore original baud settings         &lt;br /&gt;
4497H  XRA A                ; Clear zero flag and A    &lt;br /&gt;
4498H  LXI H,23F5           ; Load address in Main ROM to configure and execute current BASIC programH         &lt;br /&gt;
449BH  PUSH H               ; Push return address to stack&lt;br /&gt;
449CH  JMP 00A6H            ; Return to Main ROM&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call &amp;quot;BASIC NEW&amp;quot; helper routine.  This get&#039;s copied to RAM below.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
449FH  XRA A                ; Prepare to switch to Main ROM&lt;br /&gt;
44A0H  OUT E0H              ; Switch to Main ROM&lt;br /&gt;
44A2H  CALL 20FFH           ; Call BASIC NEW statement&lt;br /&gt;
44A5H  CALL FAA4H           ; Switch back to OptROM&lt;br /&gt;
44A8H  JMP 4478H            ; Jump back into RST 7,1Ch Hook - RUN statement&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Copy &amp;quot;BASIC NEW&amp;quot; helper routine to RAM and Jump to it --- Call Main ROM&#039;s NEW statement&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
44ABH  LXI H,449FH          ; Point to helper function to copy to RAM&lt;br /&gt;
44AEH  LXI D,FD89H          ; RAM destination&lt;br /&gt;
44B1H  LXI B,000CH          ; Length of helper funciton&lt;br /&gt;
44B4H  CALL 4A05H           ; Copy helper to RAM&lt;br /&gt;
44B7H  JMP FD89H            ; Branch to helper function&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Compare current BASIC program file extension with value in BC or &amp;quot;  &amp;quot;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
44BAH  PUSH PSW             ; Preserve A on Stack     &lt;br /&gt;
44BBH  PUSH H               ; Preserve HL on Stack   &lt;br /&gt;
44BCH  PUSH D               ; Preserve DE on Stack   &lt;br /&gt;
44BDH  PUSH B               ; Preserve comparison file extension on Stack   &lt;br /&gt;
44BEH  LHLD FC99H           ; Load 2 extension field bytes of current BASIC program name       &lt;br /&gt;
44C1H  LXI D,2020H          ; Load 2 spaces (0x20) into DE&lt;br /&gt;
44C4H  RST 3                ; Test if filename extension in current BASIC program is &amp;quot;  &amp;quot;            &lt;br /&gt;
44C5H  JZ 44D6H             ; Jump if current BASIC program filename extension is &amp;quot;  &amp;quot;     &lt;br /&gt;
44C8H  POP D                ; Get comparison file extension from stack into DE  &lt;br /&gt;
44C9H  PUSH D               ; Push file extension back to stack for storage   &lt;br /&gt;
44CAH  RST 3                ; Test if current BASIC program filename extension matches BC                    &lt;br /&gt;
44CBH  JZ 44D6H             ; Jump if current BASIC program filename extension matches BC     &lt;br /&gt;
44CEH  POP B                ; Get BC back off stack  &lt;br /&gt;
44CFH  POP D                ; Recover DE from stack  &lt;br /&gt;
44D0H  POP H                ; Recover HL from stack  &lt;br /&gt;
44D1H  POP PSW              ; Recover A &amp;amp; flags from stack    &lt;br /&gt;
44D2H  POP B                ; Pop return address - File extension doesn&#039;t match so don&#039;t run  &lt;br /&gt;
44D3H  JMP 00A6H            ; Return to Main ROM&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Store expected extension (on stack) to current BASIC program and send dir reference for &lt;br /&gt;
;    the disk file&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
44D6H  POP H                ; Get expected file extension &amp;quot;BA&amp;quot; or &amp;quot;CO&amp;quot; from stack  &lt;br /&gt;
44D7H  SHLD FC99H           ; Save to 2 extension field bytes of current BASIC program name       &lt;br /&gt;
44DAH  POP D                ; Restore DE from stack  &lt;br /&gt;
44DBH  POP H                ; Restore HL from stack  &lt;br /&gt;
44DCH  POP PSW              ; Restore A from stack    &lt;br /&gt;
44DDH  XRA A                ; Flag to generate system errors vs. printing  &lt;br /&gt;
44DEH  CALL 4A85H           ; Save OS&#039;s baud rate string to storage area       &lt;br /&gt;
44E1H  LXI H,FC93H          ; Filename of current BASIC program            &lt;br /&gt;
44E4H  JMP 4A57H            ; Send Dir Reference for filename at (HL)      &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 7,16h Hook - SAVE statement&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
44E7H  POP PSW              ; POP return address, we will return manually&lt;br /&gt;
44E8H  CPI 09H              ; Test if we found &amp;quot;0:&amp;quot; or &amp;quot;1:&amp;quot; in the DSKI$ function    &lt;br /&gt;
44EAH  JNZ 00A6H            ; Return if not a TPDD file      &lt;br /&gt;
44EDH  LXI B,4142H          ; Load code for &amp;quot;BA&amp;quot; basic extension        &lt;br /&gt;
44F0H  CALL 44BAH           ; Compare extension in current BASIC program filename with value in BC            &lt;br /&gt;
44F3H  JNZ 487EH            ; File Exists Error      &lt;br /&gt;
44F6H  CALL 4C66H           ; Update line addresses for current BASIC program       &lt;br /&gt;
44F9H  LHLD F67CH           ; Start of BASIC program pointer            &lt;br /&gt;
44FCH  XCHG                 ; HL &amp;lt;--&amp;gt; DE  DE=BASIC program strt, HL=BASIC program end &lt;br /&gt;
44FDH  RST 3                ; Compare DE and HL    &lt;br /&gt;
44FEH  JZ 450FH             ; Vector to BASIC ready - print Ok if BASIC start=BASIC end     &lt;br /&gt;
4501H  PUSH D               ; Save start of BASIC program to stack   &lt;br /&gt;
4502H  POP B                ; POP start of BASIC program from stack  &lt;br /&gt;
4503H  DSUB                 ; Subtract BASIC start address from BASIC end address &lt;br /&gt;
4504H  MVI A,01H            ; Set file open mode for new file      &lt;br /&gt;
4506H  STA FCD6H            ; Save open mode to pass to function      &lt;br /&gt;
4509H  CALL 40C8H           ; Write HL bytes of data from (DE) to TPDD       &lt;br /&gt;
450CH  CALL 4AC4H           ; Restore original baud settings       &lt;br /&gt;
450FH  LXI H,0502H          ; Load address in Main ROM of Vector to BASIC ready - print Ok        &lt;br /&gt;
4512H  PUSH H               ; Push new return address to stack&lt;br /&gt;
4513H  JMP 00A6H            ; Return to Main ROM&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Return to Main ROM&#039;s Generate FC Error routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4516H  LXI H,08DBH          ; Load address of Generate FC error routine&lt;br /&gt;
4519H  PUSH H               ; Push return address to the stack&lt;br /&gt;
451AH  JMP 00A6H            ; Return to Main ROM&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 7,30h Hook - OPEN/CLOSE/READ/WRITE/LINE INPUT statement&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
451DH  XRA A                ; Clear A to set print error flag                  &lt;br /&gt;
451EH  STA FCD2H            ; Set flag to generate system errors vs. print&lt;br /&gt;
4521H  POP PSW              ; POP return address ... returning manually&lt;br /&gt;
4522H  SHLD FCCEH           ; Save HL in Stack pointer upon entry location     &lt;br /&gt;
4525H  PUSH D               ; Preserve DE on stack     &lt;br /&gt;
4526H  PUSH H               ; Preserve HL on stack       &lt;br /&gt;
4527H  PUSH PSW             ; Preserve A on stack          &lt;br /&gt;
4528H  LXI D,0004H          ; Offset of the file descriptor address MSB    &lt;br /&gt;
452BH  DAD D                ; Point to the file descriptor address MSB      &lt;br /&gt;
452CH  MOV A,M              ; Get MSB address of FD      &lt;br /&gt;
452DH  CPI 09H              ; Test if we found &amp;quot;0:&amp;quot; or &amp;quot;1:&amp;quot; in the DSKI$ function       &lt;br /&gt;
452FH  JZ 4538H             ; Jump to process the sub-operation code if it&#039;s a TPDD file&lt;br /&gt;
				  &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 7,30h Hook exit routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4532H  POP PSW              ; Restore A from stack          &lt;br /&gt;
4533H  POP H                ; Restore HL from stack        &lt;br /&gt;
4534H  POP D                ; Restore DE from stack        &lt;br /&gt;
4535H  JMP 00A6H            ; Return to Main ROM &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test the RST 7,30h sub-operation code and vector to the proper handler function&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4538H  POP PSW              ; Retrieve A from the stack - contains sub-operation code   &lt;br /&gt;
4539H  PUSH PSW             ; Restore to stack    &lt;br /&gt;
453AH  CPI 00H              ; Test for OPEN sub-operation   &lt;br /&gt;
453CH  JZ 455CH       &lt;br /&gt;
453FH  CPI 02H              ; Test for CLOSE sub-operation   &lt;br /&gt;
4541H  JZ 45E8H       &lt;br /&gt;
4544H  CPI 04H              ; Test for PRINT # sub-operation   &lt;br /&gt;
4546H  JZ 46B0H       &lt;br /&gt;
4549H  CPI 06H              ; Test for EOF sub-operation   &lt;br /&gt;
454BH  JZ 4607H       &lt;br /&gt;
454EH  CPI 08H              ; Test for LINE INPUT sub-operation   &lt;br /&gt;
4550H  JNZ 4532H       &lt;br /&gt;
4553H  LDES 06H             ; Get stack location upon entry (we pushed 3 times = 6 bytes) in DE    &lt;br /&gt;
4555H  LXI H,161BH          ; Not an operation we care about, load address for &amp;quot;Special RAM IO&amp;quot; routine&lt;br /&gt;
4558H  SHLX                 ; Replace our return address so we return to &amp;quot;Special RAM IO&amp;quot; routine instead&lt;br /&gt;
4559H  JMP 4532H            ; Jump to RST 7,32h exit routine     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 7,30h OPEN sub-operation&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
455CH  XRA A                ; Generate system errors vs. printing &lt;br /&gt;
455DH  CALL 4A85H           ; Save OS&#039;s baud rate string to storage area      &lt;br /&gt;
4560H  LXI H,FC99H          ; Load address of 1st extension byte of current BASIC program filename       &lt;br /&gt;
4563H  MOV A,M              ; Get 1st byte of file extension from current BASIC program   &lt;br /&gt;
4564H  CPI 20H              ; Test if opening a file with no extension   &lt;br /&gt;
4566H  JZ 456EH             ; Branch to proivde &amp;quot;DO&amp;quot; default extension if non provided    &lt;br /&gt;
4569H  CPI 44H              ; Test if A is &#039;D&#039; - opening a &amp;quot;DO&amp;quot; file   &lt;br /&gt;
456BH  JNZ 488DH            ; Generate system error 0x0C - ID Error     &lt;br /&gt;
456EH  MVI M,44H            ; Change 1st extension byte to &#039;D&#039;     &lt;br /&gt;
4570H  INX H                ; Increment to 2nd extension byte &lt;br /&gt;
4571H  MVI M,4FH            ; Change 2nd extension byte to &#039;O&#039;     &lt;br /&gt;
4573H  LXI H,FC93H          ; Filename of current BASIC program       &lt;br /&gt;
4576H  CALL 4A57H           ; Send Dir Reference for filename at (HL)      &lt;br /&gt;
4579H  MOV C,A              ; Move attribute byte to C   &lt;br /&gt;
457AH  CALL 465BH           ; Calculate offset of BASIC instruction file # EOF marker      &lt;br /&gt;
457DH  MVI M,00H            ; Set EOF marker to zero - not EOF     &lt;br /&gt;
457FH  POP H                ; POP PSW and discard &lt;br /&gt;
4580H  POP H                ; Restore address of FD control &lt;br /&gt;
4581H  POP D                ; Restore DE &lt;br /&gt;
4582H  PUSH D               ; Save DE back to stack  &lt;br /&gt;
4583H  PUSH H               ; Save FD control address back to stack  &lt;br /&gt;
4584H  MOV D,C              ; Save TPDD file attribute byte to D               &lt;br /&gt;
4585H  MOV A,E              ; Move open mode to A (8=Append,1=Read,2=Write)   &lt;br /&gt;
4586H  ANI 07H              ; Mask all but lower 3 bits so we get 0, 1, or 2   &lt;br /&gt;
4588H  LXI H,4AE4H          ; Get address of RST 7,32h open mode to TPDD Open mode mapping       &lt;br /&gt;
458BH  MOV C,A              ; Save mapping mode table offset to C   &lt;br /&gt;
458CH  MVI B,00H            ; Clear MSB of offset for 16-bit add     &lt;br /&gt;
458EH  DAD B                ; Calculate index address into mapping table        &lt;br /&gt;
458FH  MOV A,M              ; Load TPDD open mode from mapping   &lt;br /&gt;
4590H  DCR A                ; Test if TPDD open mode is Write     &lt;br /&gt;
4591H  JZ 45CDH             ; Jump if opening for write mode        &lt;br /&gt;
4594H  DCR A                ; Test if TPDD open mode is Append     &lt;br /&gt;
4595H  JNZ 45E0H            ; Jump to open TPDD for Read mode if not zero         &lt;br /&gt;
4598H  LDA FD1CH            ; Load attribute byte from RX buffer         &lt;br /&gt;
459BH  ANA A                ; Opening for Append, test if file already exists     &lt;br /&gt;
459CH  JNZ 45A1H            ; Jump to perform open for append if file already exists         &lt;br /&gt;
459FH  INX H                ; Opening for append but file doesn&#039;t exist, increment mapping to Write     &lt;br /&gt;
45A0H  INX H                ; Increment again to skip &amp;quot;read&amp;quot; mapping in table     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Open TPDD file with open mode as specified by RST 7,32h mapping table&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
45A1H  MOV A,M              ; Reload the TPDD open mode from the mapping table     &lt;br /&gt;
45A2H  STA FCE8H            ; Point to TX buffer data area (payload)       &lt;br /&gt;
45A5H  LXI H,0101H          ; Load TPDD_OPEN opcode in HL         &lt;br /&gt;
45A8H  CALL 409BH           ; Send Request in HL and await response        &lt;br /&gt;
45ABH  LHLD FCCEH           ; Get address of FD control        &lt;br /&gt;
45AEH  LXI D,0007H          ; Load offset of write buffer length within FD control         &lt;br /&gt;
45B1H  DAD D                ; Point to write buffer length within FD control   &lt;br /&gt;
45B2H  XRA A                ; Clear A   &lt;br /&gt;
45B3H  MOV M,A              ; Set the write buffer length to zero - just opened the file     &lt;br /&gt;
45B4H  INX H                ; Increment to write buffer output pointer address   &lt;br /&gt;
45B5H  MOV D,H              ; Save HL to DE to update write buffer output pointer     &lt;br /&gt;
45B6H  MOV E,L              ; Save LSB of HL to DE     &lt;br /&gt;
45B7H  INX H                ; Increment to MSB of write buffer output pointer   &lt;br /&gt;
45B8H  INX H                ; Increment to write buffer location   &lt;br /&gt;
45B9H  SHLX                 ; Reset write buffer output poiner to beginning of buffer  &lt;br /&gt;
45BAH  POP H                ; Restore address of FD control   &lt;br /&gt;
45BBH  POP D                ; Restore DE from stack   &lt;br /&gt;
45BCH  MOV A,E              ; Load RST 7,32h open mode into A     &lt;br /&gt;
45BDH  CPI 08H              ; Test if open mode is Append     &lt;br /&gt;
45BFH  JNZ 45C4H            ; Jump to retain open mode if not append       &lt;br /&gt;
45C2H  MVI E,02H            ; Change Append open mode value to &amp;quot;Write&amp;quot;       &lt;br /&gt;
45C4H  MOV M,E              ; Save open status to FD control     &lt;br /&gt;
45C5H  XTHL                 ; HL &amp;lt;--&amp;gt; (SP)  Prepare to change our return address, saving HL  &lt;br /&gt;
45C6H  LXI H,14DEH          ; Load new return address in ROM &amp;quot;LCD and PRT file open&amp;quot; routine         &lt;br /&gt;
45C9H  XTHL                 ; Put return address back to stack, restoring HL           &lt;br /&gt;
45CAH  JMP 00A6H            ; Return to the new address in LCD and PRT file open routine in Main ROM&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 7,30h open file for write mode.  The Attribute byte from the Dir Ref opcode is in D&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
45CDH  MOV A,D              ; Get the File attribute byte from the Dir Reference operation    &lt;br /&gt;
45CEH  ORA A                ; Test if the file exists (will be &#039;F&#039; if the file exists)  &lt;br /&gt;
45CFH  JZ 45A1H             ; Jump to create the file if it doesn&#039;t already exist     &lt;br /&gt;
45D2H  PUSH H               ; Save HL to the stack for restoration   &lt;br /&gt;
45D3H  CALL 431AH           ; Issue TPDD Delete file Opcode - Overwriting existing file       &lt;br /&gt;
45D6H  LXI H,FC93H          ; Filename of current BASIC program    &lt;br /&gt;
45D9H  CALL 4A57H           ; Send Dir Reference for filename at (HL) - Need new Dir Ref       &lt;br /&gt;
45DCH  POP H                ; Restore HL from stack  &lt;br /&gt;
45DDH  JMP 45A1H            ; Open TPDD file with open mode as specified by RST 7,32h mapping table      &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 7,30h open file for read mode.  Ensure the file exists via the attribute byte in D&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
45E0H  MOV A,D              ; Load the file attribute byte from the Dir Ref opcode  &lt;br /&gt;
45E1H  ORA A                ; Test if attribute byte is zero&lt;br /&gt;
45E2H  JZ 487BH             ; Generate &amp;quot;FF&amp;quot; error if file doesn&#039;t exist &lt;br /&gt;
45E5H  JMP 45A1H            ; Jump to open the file&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 7,30h Sub command - CLOSE FILE&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
45E8H  POP PSW              ; Retrieve A PUSHed by RST 7,32a entry    &lt;br /&gt;
45E9H  POP H                ; Retrieve HL  &lt;br /&gt;
45EAH  POP D                ; Retrieve DE  &lt;br /&gt;
45EBH  PUSH H               ; Save FD control pointer to stack   &lt;br /&gt;
45ECH  MOV A,M              ; Get FD control status byte    &lt;br /&gt;
45EDH  MVI M,00H            ; Change FD control status to &amp;quot;closed&amp;quot;      &lt;br /&gt;
45EFH  CPI 02H              ; Test if status     &lt;br /&gt;
45F1H  CZ 46DDH             ; Call flush output buffer routine if opened for write mode     &lt;br /&gt;
45F4H  LXI H,0002H          ; Load TPDD_CLOSE opcode into HL        &lt;br /&gt;
45F7H  CALL 409BH           ; Send Request in HL and await response       &lt;br /&gt;
45FAH  CALL 4AC4H           ; Restore original baud settings       &lt;br /&gt;
45FDH  POP H                ; Restore FD control pointer  &lt;br /&gt;
45FEH  XTHL                 ; HL &amp;lt;--&amp;gt; (SP) so we can preserve HL through POP         &lt;br /&gt;
45FFH  POP H                ; Pop return address (actually FD control address) from stack  &lt;br /&gt;
4600H  LXI H,4D59H          ; Load new reuturn address - LCD, CRT, and LPT file close routine        &lt;br /&gt;
4603H  PUSH H               ; Push new return address to stack - not returning to caller   &lt;br /&gt;
4604H  JMP 00A6H            ; Return to Main ROM&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 7,30h Sub command - EOF&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4607H  CALL 465BH           ; Calculate offset of BASIC instruction file # EOF marker        &lt;br /&gt;
460AH  MOV A,M              ; Get the current EOF marker     &lt;br /&gt;
460BH  MVI M,00H            ; Set the EOF marker to zero to reset it       &lt;br /&gt;
460DH  ANA A                ; Test if at EOF for this file   &lt;br /&gt;
460EH  JNZ 4627H            ; Jump if EOF marker for this file not zero       &lt;br /&gt;
4611H  LHLD FCCEH           ; Get address of FD control        &lt;br /&gt;
4614H  LXI B,0007H          ; Offset of write buffer length within FD control         &lt;br /&gt;
4617H  DAD B                ; Point to write buffer length   &lt;br /&gt;
4618H  MOV A,M              ; Get current write buffer length     &lt;br /&gt;
4619H  INX H                ; Point to LSB of read/write buffer output pointer within FD control   &lt;br /&gt;
461AH  PUSH H               ; Save address of read/write buffer output pointer to stack    &lt;br /&gt;
461BH  ANA A                ; Test if data left in the buffer   &lt;br /&gt;
461CH  CZ 4663H             ; Call to read more data from TPDD if buffer empty      &lt;br /&gt;
461FH  POP D                ; Restore address of read/write output buffer within FD control   &lt;br /&gt;
4620H  LHLX                 ; Get current read/write pointer location from FD control  &lt;br /&gt;
4621H  MOV A,M              ; Read the next byte from the buffer     &lt;br /&gt;
4622H  INX H                ; Increment buffer pointer to the next byte   &lt;br /&gt;
4623H  SHLX                 ; Save read/write buffer pointer back to FD control  &lt;br /&gt;
4624H  DCX D                ; Decrement back to read/write buffer length within FD control   &lt;br /&gt;
4625H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  Prepare to update buffer length  &lt;br /&gt;
4626H  DCR M	            ; Decrement length since we just read a byte&lt;br /&gt;
      &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test if EOF for BASIC file #&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4627H  CPI 1AH              ; Test if byte is EOF marker      &lt;br /&gt;
4629H  STC                  ; Ensure the Carry flag is set  &lt;br /&gt;
462AH  CMC                  ; And now clear it to indicate not EOF  &lt;br /&gt;
462BH  JNZ 4633H            ; Jump if not at end of file        &lt;br /&gt;
462EH  CALL 465BH           ; Calculate offset of BASIC instruction file # EOF marker         &lt;br /&gt;
4631H  MOV M,A              ; Save EOF marker for this file #      &lt;br /&gt;
4632H  STC                  ; Set Carry to indicate EOF  &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Save EOF status&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4633H  PUSH PSW             ; Save EOF indication in Carry flag and marker value to stack      &lt;br /&gt;
4634H  LDES 10H             ; Load offset to our return address (we PUSHed a bunch to the stack)      &lt;br /&gt;
4636H  LHLX                 ; Load HL with our return address from the stack  &lt;br /&gt;
4637H  LXI B,189AH          ; Load address of return within EOF function         &lt;br /&gt;
463AH  DSUB                 ; Test if we were called from the EOF function  &lt;br /&gt;
463BH  JNZ 464FH            ; Jump if not called from ROM EOF function - don&#039;t to EOF logical testing       &lt;br /&gt;
463EH  CALL 465BH           ; Calculate offset of BASIC instruction file # EOF marker        &lt;br /&gt;
4641H  POP PSW              ; Retreive EOF and marker value from stack     &lt;br /&gt;
4642H  MOV M,A              ; Save the marker value to the file # marker storage location     &lt;br /&gt;
4643H  MOV C,A              ; Save marker value in C     &lt;br /&gt;
4644H  SBB A                ; Subtract with borrow (C was set if EOF)   &lt;br /&gt;
4645H  CALL 4BCBH           ; Call into SGN function to set FAC1 with sign of A (EOF test)        &lt;br /&gt;
4648H  LDES 12H             ; Prepare to &amp;quot;POP&amp;quot; 6 register pairs from the stack all at once      &lt;br /&gt;
464AH  XCHG                 ; HL &amp;lt;--&amp;gt; DE  HL now has new stack value  &lt;br /&gt;
464BH  SPHL                 ; HL &amp;lt;--&amp;gt; SP  &amp;quot;POP&amp;quot; 6 values from the stack           &lt;br /&gt;
464CH  JMP 00A6H            ; Return to Main ROM&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Non-EOF function call return&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
464FH  POP PSW              ; Restore PSW with EOF indication (C flag)   &lt;br /&gt;
4650H  POP H                ; Pop old PSW - we don&#039;t want it &lt;br /&gt;
4651H  POP H                ; Resore HL from stack &lt;br /&gt;
4652H  POP D                ; Restore DE from stack &lt;br /&gt;
4653H  XTHL                 ; Push HL to stack to set new return address       &lt;br /&gt;
4654H  LXI H,4E8AH          ; Load address of a &amp;quot;Stack frame retrun&amp;quot; routine&lt;br /&gt;
4657H  XTHL                 ; Stack gets new return address, restore HL&lt;br /&gt;
4658H  JMP 00A6H            ; Return to the new address (not returning to parent)     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Calculate offset of BASIC instruction file # EOF marker&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
465BH  LHLD FAA2H           ; Get file # of active BASIC instruction (EOF, LINE INPUT, etc.) &lt;br /&gt;
465EH  LXI D,FA91H          ; Load base address of file status array &lt;br /&gt;
4661H  DAD D                ; Add offset to base of file status byte array&lt;br /&gt;
4662H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 7,30A Read data from server (TPDD) into FD file buffer&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
4663H  LXI H,0003H          ; Load TPDD_READ opcode in HL         &lt;br /&gt;
4666H  CALL 4822H           ; Send TPDD Command/Len in HL        &lt;br /&gt;
4669H  CALL 47CCH           ; Receive a packet        &lt;br /&gt;
466CH  LDA FD02H            ; Get response byte from storage for RX packet       &lt;br /&gt;
466FH  CPI 10H              ; Test for valid read file response     &lt;br /&gt;
4671H  JNZ 469EH            ; Branch if not valid read from file response       &lt;br /&gt;
4674H  LDA FD03H            ; Get length of read from RX buffer       &lt;br /&gt;
4677H  LHLD FCCEH           ; Get pointer to FD control        &lt;br /&gt;
467AH  LXI D,0008H          ; Offset of address of read/write buffer relative to FD control         &lt;br /&gt;
467DH  DAD D                ; Point to address of read/write buffer within FD control            &lt;br /&gt;
467EH  PUSH H               ; Save address of read/write buffer to stack    &lt;br /&gt;
467FH  MOV D,H              ; Move address of read/write buffer to DE for update     &lt;br /&gt;
4680H  MOV E,L              ; Move LSB     &lt;br /&gt;
4681H  INX H                ; Increment to MSB of read/write buffer address in FD control   &lt;br /&gt;
4682H  INX H                ; Increment to read/write buffer   &lt;br /&gt;
4683H  SHLX                 ; Reset pointer to read/write buffer - we just read more data  &lt;br /&gt;
4684H  LXI D,FD04H          ; DE points to the RX data in the buffer         &lt;br /&gt;
4687H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  Prepare to move data from RX buffer to FD buffer  &lt;br /&gt;
4688H  MOV C,A              ; Move the RX data length to C     &lt;br /&gt;
4689H  MVI B,00H            ; Clear MSB of BC count       &lt;br /&gt;
468BH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment - copy to FD buffer        &lt;br /&gt;
468EH  LDA FD03H            ; Get length of RX read data again       &lt;br /&gt;
4691H  CPI 80H              ; Test for maximum read length     &lt;br /&gt;
4693H  JZ 469AH             ; If maximum read, skip writing EOF marker to read/write buffer      &lt;br /&gt;
4696H  XCHG                 ; HL = destination address in FD buffer  &lt;br /&gt;
4697H  MVI M,1AH            ; Terminate .DO file in FD read/write buffer with EOF marker       &lt;br /&gt;
4699H  INR A                ; Increment length to reflect EOF marker &lt;br /&gt;
  &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 7,32A Read - not max read size&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
469AH  POP H                ; Get address of read/write buffer in FD control from stack       &lt;br /&gt;
469BH  DCX H                ; Decrement to FD control read/write buffer length location       &lt;br /&gt;
469CH  MOV M,A              ; Save length of data in read/write buffer to FD control                  &lt;br /&gt;
469DH  RET         &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 7,32A Read - unsuccessful TPDD read&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
469EH  LHLD FCCEH           ; Get address of FD control      &lt;br /&gt;
46A1H  LXI D,0007H          ; Load offset of output buffer count in FD control       &lt;br /&gt;
46A4H  DAD D                ; Point to output buffer length in FD control &lt;br /&gt;
46A5H  MVI M,01H            ; Set read/write buffer length to 1 to indicate EOF marker     &lt;br /&gt;
46A7H  INX H                ; Increment to LSB of read/write buffer output address in FD control &lt;br /&gt;
46A8H  MOV D,H              ; Save HL in DE for update of read/write buffer output in FD control   &lt;br /&gt;
46A9H  MOV E,L              ; Save LSB of HL to DE   &lt;br /&gt;
46AAH  INX H                ; Increment to MSB of read/write buffer in FD control &lt;br /&gt;
46ABH  INX H                ; Increment to the FD read/write buffer &lt;br /&gt;
46ACH  SHLX                 ; Reset the FD control read/write buffer pointer to begining of buffer&lt;br /&gt;
46ADH  MVI M,1AH            ; Write an EOF marker to the buffer&lt;br /&gt;
46AFH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 7,32h PRINT # sub-operation&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
46B0H  LHLD FCCEH           ; Pointer to FD control       &lt;br /&gt;
46B3H  LXI D,0007H          ; ?Offset to output byte count        &lt;br /&gt;
46B6H  DAD D                ; Get pointer to file&#039;s output byte count  &lt;br /&gt;
46B7H  MOV A,M              ; Load byte count of pending bytes to write    &lt;br /&gt;
46B8H  CPI 80H              ; Test if 128 bytes to write    &lt;br /&gt;
46BAH  CZ 46DDH             ; Call routine to flush output buffer to file     &lt;br /&gt;
46BDH  POP PSW              ; Restore A from stack (from RST 7,32h entry)    &lt;br /&gt;
46BEH  POP H                ; Restore HL from stack  &lt;br /&gt;
46BFH  POP D                ; Restore DE from stack  &lt;br /&gt;
46C0H  POP H                ; Pop the return address - we will return via JMP  &lt;br /&gt;
46C1H  POP PSW              ; Get the caller&#039;s A so we know what byte is being written    &lt;br /&gt;
46C2H  PUSH PSW             ; Put it back on the stack...it isn&#039;t ours     &lt;br /&gt;
46C3H  CPI 1AH              ; Test if writing an EOF marker to the file    &lt;br /&gt;
46C5H  JZ 46D6H             ; Jump if writing EOF marder to the file - don&#039;t actually write it     &lt;br /&gt;
46C8H  LHLD FCCEH           ; Get address of FD control       &lt;br /&gt;
46CBH  LXI D,0007H          ; Get offset of output buffer length within FD control        &lt;br /&gt;
46CEH  DAD D                ; Point to output buffer length address  &lt;br /&gt;
46CFH  INR M                ; Increment the output buffer length - writing 1 byte  &lt;br /&gt;
46D0H  INX H                ; Point to current file location pointer in FD control  &lt;br /&gt;
46D1H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  Move address of file location pointer to DE &lt;br /&gt;
46D2H  LHLX                 ; Load current file location address to HL &lt;br /&gt;
46D3H  MOV M,A              ; Save the byte in the buffer (RX buffer for subsequent write)    &lt;br /&gt;
46D4H  INX H                ; Increment the curent file location pointer (we will flush later)  &lt;br /&gt;
46D5H  SHLX                 ; Save the update current file location pointer to FD control         &lt;br /&gt;
46D6H  LXI H,14EAH          ; Load address to update automatic timer and POP regs from the stack        &lt;br /&gt;
46D9H  PUSH H               ; Push new return address.  We will return to the parent&#039;s caller   &lt;br /&gt;
46DAH  JMP 00A6H            ; Return to Main ROM      &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Navigate to:&lt;br /&gt;
* [[Dissasembly of RAM and ROM versions of TS-DOS]]&lt;br /&gt;
* [[M100 TS-DOS ROM OptROM Support]]&lt;br /&gt;
* [[M100 TS-DOS ROM UI Code]]&lt;br /&gt;
* [[M100 TS-DOS ROM TPDD Protocol]]&lt;br /&gt;
* [[M100 TS-DOS ROM Compression]]&lt;br /&gt;
* [[M100 TS-DOS ROM Cold Boot Recovery]]&lt;/div&gt;</summary>
		<author><name>Kpettit</name></author>
	</entry>
	<entry>
		<id>https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_UI_Code&amp;diff=1381</id>
		<title>M100 TS-DOS ROM UI Code</title>
		<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_UI_Code&amp;diff=1381"/>
		<updated>2009-04-03T07:57:22Z</updated>

		<summary type="html">&lt;p&gt;Kpettit: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== TS-DOS Model 100/102 User Interface Code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; TS-DOS UI Entry location&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
 &lt;br /&gt;
    .org  3535H&lt;br /&gt;
&lt;br /&gt;
3535H  LXI H,FCC0H          ; Start of Alt LCD character buffer&lt;br /&gt;
3538H  MVI B,B4H            ; Prepare to clear 180 bytes from the ALTLCD buffer &lt;br /&gt;
353AH  XRA A                ; Prepare to clear the ALTLCD buffer&lt;br /&gt;
353BH  CALL 4A34H           ; Fill (HL) with B bytes of A        &lt;br /&gt;
353EH  LXI H,0000H          ; Prepare to get current stack pointer&lt;br /&gt;
3541H  DAD SP               ; Copy SP into HL&lt;br /&gt;
3542H  SHLD FCCEH           ; Stack pointer upon entry - pointer to arguments&lt;br /&gt;
3545H  MVI A,01H            ; Set flag to print error message to LCD - GUI mode&lt;br /&gt;
3547H  CALL 4A85H           ; Save the currently selected baud rate settings&lt;br /&gt;
354AH  XRA A                ; Zero A to clear our vars&lt;br /&gt;
354BH  STA FCD4H            ; Current Page of files being displayed&lt;br /&gt;
354EH  STA FCDAH            ; TPDD &amp;quot;skip page&amp;quot; count&lt;br /&gt;
3551H  STA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
3554H  STA FCCAH            ; TPDD2 Bank number&lt;br /&gt;
3557H  INR A                ; A = 1 to select 1st file on page&lt;br /&gt;
3558H  STA FCCDH            ; Currently selected file index&lt;br /&gt;
355BH  LXI H,3564H          ; Get pointer to main loop routine&lt;br /&gt;
355EH  SHLD FCD0H           ; Return vector after error&lt;br /&gt;
3561H  CALL 4C27H           ; CLS statement&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; UI Main loop&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3564H  CALL 4C5AH           ; Resume automatic scrolling&lt;br /&gt;
3567H  CALL 3611H           ; Print Copyright and files&lt;br /&gt;
356AH  LDA FCD5H            ; Load currently selected index from temp storage&lt;br /&gt;
356DH  STA FCCDH            ; Currently selected file index&lt;br /&gt;
3570H  CALL 362FH           ; Print length of selected file using inverse video&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Code will return here when a funtion key is pressed (except F4 &amp;amp; F6)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3573H  LXI H,48B5H          ; Get address of &amp;quot;Long jump&amp;quot;&lt;br /&gt;
3576H  PUSH H               ; Push &amp;quot;Long jump&amp;quot; address to stack&lt;br /&gt;
3577H  PUSH PSW             ; Save function key press to stack&lt;br /&gt;
3578H  CPI 02H              ; Test if function key is F5-F8 (Non file operation F Keys)&lt;br /&gt;
357AH  JNC 35B9H            ; Jump to Function key handler if F5-F8 (No tagging to process)&lt;br /&gt;
357DH  LDA FCCCH            ; Last Tag/Untag operation code&lt;br /&gt;
3580H  ANA A                ; Test if a tag operation was performed&lt;br /&gt;
3581H  JZ 35B9H             ; Jump to Function key handler if no tag operation performed&lt;br /&gt;
3584H  LDA FCD6H            ; Count of files on screen&lt;br /&gt;
3587H  MOV C,A              ; Save count of files for loop decrementing &lt;br /&gt;
3588H  INR C                ; Increment by 1 for loop bounding&lt;br /&gt;
3589H  MVI B,00H            ; Start with index zero on the LCD&lt;br /&gt;
358BH  PUSH B               ; Save the current index on the stack&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display next file&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
358CH  LDA FCCDH            ; Currently selected file index&lt;br /&gt;
358FH  STA FCD5H            ; Currently selected file index - temp&lt;br /&gt;
3592H  CALL 3AC4H           ; Print selected file using normal video&lt;br /&gt;
3595H  POP B                ; Restore index from stack&lt;br /&gt;
3596H  INR B                ; Increment to the next file index to display&lt;br /&gt;
3597H  DCR C                ; Decrement the loop control&lt;br /&gt;
3598H  JZ 48B5H             ; Branch to perform &amp;quot;Long Jump&amp;quot; if all files printed to LCD&lt;br /&gt;
359BH  MOV A,B              ; Get the index of the current file&lt;br /&gt;
359CH  STA FCD5H            ; Save in temporary &amp;quot;current file&amp;quot; area&lt;br /&gt;
359FH  STA FCCDH            ; Currently selected file index&lt;br /&gt;
35A2H  PUSH B               ; Push the value on the stack for the next iteration&lt;br /&gt;
35A3H  CALL 3AB2H           ; Print currently selected file using inverse video&lt;br /&gt;
35A6H  LHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
35A9H  DCX H                ; Decrement to the Tag area for the file&lt;br /&gt;
35AAH  MOV A,M              ; Get the file&#039;s Tag code&lt;br /&gt;
35ABH  CPI 3EH              ; Compare with &#039;&amp;gt;&#039;&lt;br /&gt;
35ADH  JNZ 358CH            ; Jump to process next file if not tagged&lt;br /&gt;
35B0H  POP B                ; Pop currently selected file value from stack&lt;br /&gt;
35B1H  POP PSW    &lt;br /&gt;
35B2H  LXI H,358CH          ; Return address to display the next file&lt;br /&gt;
35B5H  PUSH PSW             ; ? Stack trickery&lt;br /&gt;
35B6H  PUSH B               ; Save current file index to stack for use after a RET operation&lt;br /&gt;
35B7H  PUSH H               ; Setup &amp;quot;Display next file&amp;quot; as a return address for RET&lt;br /&gt;
35B8H  PUSH PSW             ; ? More stack trickery&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Function key handler - Disk mode and dispatch to RAM mode&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
35B9H  CALL 4C56H           ; Stop automatic scrolling&lt;br /&gt;
35BCH  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
35BFH  ORA A     &lt;br /&gt;
35C0H  JZ 35E2H             ; Branch if in RAM mode&lt;br /&gt;
35C3H  POP PSW   &lt;br /&gt;
35C4H  ANA A                ; Test for F1&lt;br /&gt;
35C5H  JZ 3B2EH             ; Branch to F1 handler for disk&lt;br /&gt;
35C8H  DCR A                ; Test for F2&lt;br /&gt;
35C9H  JZ 3D73H  &lt;br /&gt;
35CCH  DCR A                ; Test for F3&lt;br /&gt;
35CDH  JZ 3D9FH  &lt;br /&gt;
35D0H  DCR A                ; Skip F4 - handled at lower level&lt;br /&gt;
35D1H  DCR A                ; Test for F5&lt;br /&gt;
35D2H  JZ 3D53H  &lt;br /&gt;
35D5H  DCR A                ; Skip F6 - handled at lower level&lt;br /&gt;
35D6H  DCR A                ; Test for F7&lt;br /&gt;
35D7H  JZ 3D00H  &lt;br /&gt;
35DAH  DCR A                ; Test for F8&lt;br /&gt;
35DBH  POP H     &lt;br /&gt;
35DCH  JZ 35FEH             ; Jump to exit if F8&lt;br /&gt;
35DFH  JMP 3564H            ; Jump to main loop&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Function key handler - RAM mode&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
35E2H  POP PSW  &lt;br /&gt;
35E3H  ANA A                ; Test for F1 &lt;br /&gt;
35E4H  JZ 3C4BH &lt;br /&gt;
35E7H  DCR A                ; Test for F2&lt;br /&gt;
35E8H  JZ 3C2BH &lt;br /&gt;
35EBH  DCR A                ; Test for F3&lt;br /&gt;
35ECH  JZ 3AF8H &lt;br /&gt;
35EFH  DCR A                ; Skip F4 - handled at lower level&lt;br /&gt;
35F0H  DCR A                ; Test for F5&lt;br /&gt;
35F1H  JZ 3E5CH &lt;br /&gt;
35F4H  DCR A                ; Skip F6 - handled at lower level&lt;br /&gt;
35F5H  DCR A                ; Skip F7 - not defined for RAM&lt;br /&gt;
35F6H  DCR A                ; Test for F8&lt;br /&gt;
35F7H  POP H    &lt;br /&gt;
35F8H  JZ 35FEH             ; Jump to exit if F8&lt;br /&gt;
35FBH  JMP 3564H            ; Jump back to main loop&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; This is the UI exit routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
35FEH  CALL 4AC4H           ; Restore original baud settings&lt;br /&gt;
3601H  CALL 4BD7H           ; Wait for TX empty and Reset UART to accept mode bits&lt;br /&gt;
3604H  CALL 4C27H           ; CLS statement&lt;br /&gt;
3607H  CALL 4C5AH           ; Resume automatic scrolling&lt;br /&gt;
360AH  LXI H,0000H&lt;br /&gt;
360DH  PUSH H&lt;br /&gt;
360EH  JMP 00A6H            ; Exit TS-DOS&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print Copyright string and files&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3611H  LXI H,0101H          ; Goto top left corner&lt;br /&gt;
3614H  SHLD F639H           ; Cursor row (1-8)&lt;br /&gt;
3617H  LXI H,3E69H          ; Point to &amp;quot;TS-DOS&amp;quot; copyright string&lt;br /&gt;
361AH  CALL 4A2CH           ; Send buffer at M to screen&lt;br /&gt;
361DH  XRA A                ; Indicate no previous Tag/Untag operation&lt;br /&gt;
361EH  STA FCCCH            ; Last Tag/Untag operation code&lt;br /&gt;
3621H  MVI A,01H            ; Start with 1st file in list&lt;br /&gt;
3623H  STA FCD5H            ; Currently selected file index - temp&lt;br /&gt;
3626H  LXI H,0202H          ; Goto first file entry location&lt;br /&gt;
3629H  SHLD F639H           ; Cursor row (1-8)&lt;br /&gt;
362CH  JMP 383BH            ; Draw the display&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print length of selected file using inverse video&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
362FH  LDA FCCDH            ; Currently selected file index      &lt;br /&gt;
3632H  STA FCD5H            ; Currently selected file index - temp      &lt;br /&gt;
3635H  CALL 3AB2H           ; Print currently seleted file using inverse video       &lt;br /&gt;
3638H  LDA FCD5H            ; Currently selected file index - temp      &lt;br /&gt;
363BH  DCR A                ; Make index zero based for multiply x2  &lt;br /&gt;
363CH  STC                  ; Set Carry flag&lt;br /&gt;
363DH  CMC                  ; Compliment (clear) carry flag&lt;br /&gt;
363EH  RLC                  ; Rotate left circular &lt;br /&gt;
363FH  MOV E,A              ; E = File index * 2 to point to file length value    &lt;br /&gt;
3640H  MVI D,00H            ; Clear MSB of file length offset      &lt;br /&gt;
3642H  LXI H,F685H          ; Keyboard buffer - store file lengths        &lt;br /&gt;
3645H  DAD D                ; Add file lenght offset from beginning of keyboard buffer  &lt;br /&gt;
3646H  XCHG                 ; HL &amp;lt;--&amp;gt; DE Save file length address pointer in DE &lt;br /&gt;
3647H  LXI H,2307H          ; Load position of File Size area on LCD&lt;br /&gt;
364AH  SHLD F639H           ; Cursor row (1-8) &lt;br /&gt;
364DH  CALL 4C2BH           ; Erase from cursor to end of line&lt;br /&gt;
3650H  LHLX                 ; Load HL with file length &lt;br /&gt;
3651H  CALL 4C2FH           ; Start inverse character mode       &lt;br /&gt;
3654H  CALL 4C3EH           ; Print binary number in HL at current position       &lt;br /&gt;
3657H  CALL 4C33H           ; Cancel inverse character mode         &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Keyboard scan loop&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
365AH  CALL 3DFEH           ; Process automatic power off logic&lt;br /&gt;
365DH  CALL 4BEFH           ; Scan keyboard for character (CTRL-BREAK ==&amp;gt; CTRL-C)&lt;br /&gt;
3660H  JZ 365AH             ; Jump to scan keyboard again if no key pressed &lt;br /&gt;
3663H  JC 380CH             ; Jump to Function Key Handler if FKey &lt;br /&gt;
3666H  CPI 0DH              ; Test for CR&lt;br /&gt;
3668H  JZ 3722H   &lt;br /&gt;
366BH  CPI 17H              ; Test for Ctrl-Up key&lt;br /&gt;
366DH  JZ 37AAH   &lt;br /&gt;
3670H  CPI 14H              ; Test for Shift-Up key&lt;br /&gt;
3672H  JZ 3798H   &lt;br /&gt;
3675H  CPI 5DH              ; Test for &amp;quot;]&amp;quot; key&lt;br /&gt;
3677H  JZ 3798H   &lt;br /&gt;
367AH  CPI 3FH              ; Test for &amp;quot;?&amp;quot; key&lt;br /&gt;
367CH  JZ 3777H   &lt;br /&gt;
367FH  CPI 02H              ; Test for Shift-Down arrow key&lt;br /&gt;
3681H  JZ 3777H   &lt;br /&gt;
3684H  CPI 1EH              ; Test for up key&lt;br /&gt;
3686H  JZ 36EEH   &lt;br /&gt;
3689H  CPI 1FH              ; Test for down key&lt;br /&gt;
368BH  JZ 36FCH   &lt;br /&gt;
368EH  CPI 1DH              ; Test for &amp;quot;left arrow&amp;quot; key&lt;br /&gt;
3690H  JZ 36DDH   &lt;br /&gt;
3693H  CPI 1CH              ; Test for &amp;quot;Right arrow&amp;quot; key&lt;br /&gt;
3695H  JZ 36CAH   &lt;br /&gt;
3698H  CPI 20H              ; Test for space key &lt;br /&gt;
369AH  JZ 36CAH             ; Treat space the same as right arrow  &lt;br /&gt;
369DH  ANI DFH              ; Convert to Upper case &lt;br /&gt;
369FH  CPI 52H              ; Test for &#039;R&#039; character  &lt;br /&gt;
36A1H  JZ 3759H   &lt;br /&gt;
36A4H  CPI 54H              ; Test for &#039;T&#039; character &lt;br /&gt;
36A6H  JZ 37EEH   &lt;br /&gt;
36A9H  CPI 41H              ; Test for &amp;quot;A&amp;quot; key &lt;br /&gt;
36ABH  JZ 3715H   &lt;br /&gt;
36AEH  CPI 47H              ; Test for &amp;quot;G&amp;quot; key &lt;br /&gt;
36B0H  JZ 3715H   &lt;br /&gt;
36B3H  CPI 55H              ; Test for &amp;quot;U&amp;quot; key &lt;br /&gt;
36B5H  JZ 37AEH   &lt;br /&gt;
36B8H  CPI 44H              ; Test for &amp;quot;D&amp;quot; key &lt;br /&gt;
36BAH  JZ 39B9H   &lt;br /&gt;
36BDH  CPI 4CH              ; Test for &amp;quot;L&amp;quot; key &lt;br /&gt;
36BFH  JZ 39C2H   &lt;br /&gt;
36C2H  CPI 50H              ; Test for &amp;quot;P&amp;quot; key &lt;br /&gt;
36C4H  JZ 39C2H   &lt;br /&gt;
36C7H  JMP 365AH            ; Go scan keyboard again   &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Right Arrow key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
36CAH  MVI A,01H            ; Prepare to add 1 to selected file    &lt;br /&gt;
36CCH  LXI H,FCD5H          ; Currently selected file index - temp storage&lt;br /&gt;
36CFH  ADD M                ; Add 1 to the selected file index&lt;br /&gt;
36D0H  INX H                ; Point to file count on screen&lt;br /&gt;
36D1H  CMP M                ; Compare new index with screen file count&lt;br /&gt;
36D2H  JC 370AH             ; Jump to process new file if we didn&#039;t wrap   &lt;br /&gt;
36D5H  JZ 370AH             ; Jump to process new file if = file count   &lt;br /&gt;
36D8H  MVI A,01H            ; Wrap to the first file    &lt;br /&gt;
36DAH  JMP 370AH            ; Go process file 1 as the new selection    &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Left Arrow key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
36DDH  LDA FCD5H            ; Currently selected file index - temp storage&lt;br /&gt;
36E0H  DCR A                ; Move to next lowest file index&lt;br /&gt;
36E1H  JNZ 370AH            ; If no wrap, jump to process new selection&lt;br /&gt;
36E4H  LDA FCD6H            ; Count of files on screen&lt;br /&gt;
36E7H  ANA A                ; Ensure there is at least 1 file on the screen &lt;br /&gt;
36E8H  JZ 365AH             ; Jump to keyboard scan loop if no files on LCD&lt;br /&gt;
36EBH  JMP 370AH            ; Go process new selection as the max (wrap-around)&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Up Arrow key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
36EEH  LDA FCD5H            ; Currently selected file index - temp storage&lt;br /&gt;
36F1H  SUI 04H              ; Subtract 4 from file count (4 files per line)&lt;br /&gt;
36F3H  JC 365AH             ; Jump to keysacn loop if negative&lt;br /&gt;
36F6H  JZ 365AH             ; Jump to keysacn loop if zero&lt;br /&gt;
36F9H  JMP 370AH            ; Go process the new file index setting&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Down Arrow key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
36FCH  MVI A,04H            ; There are 4 files per line &lt;br /&gt;
36FEH  LXI H,FCD5H          ; Currently selected file index - temp storage&lt;br /&gt;
3701H  ADD M                ; Add 4 to the index number&lt;br /&gt;
3702H  MOV C,A              ; Save new index for comparison and further processing  &lt;br /&gt;
3703H  INX H                ; Maximum file index count&lt;br /&gt;
3704H  MOV A,M              ; Load maximum index for bounds  &lt;br /&gt;
3705H  CMP C                ; Compare new index with maximum&lt;br /&gt;
3706H  JC 365AH             ; Jump to keyboard scan if moving past last file   &lt;br /&gt;
3709H  MOV A,C              ; Restore new current file index  &lt;br /&gt;
370AH  PUSH PSW             ; Save new file index for storage after the call   &lt;br /&gt;
370BH  CALL 3AC4H           ; Print selected file using normal video     &lt;br /&gt;
370EH  POP PSW              ; Restore new file index from stack  &lt;br /&gt;
370FH  STA FCCDH            ; Save the new file index    &lt;br /&gt;
3712H  JMP 362FH            ; Print length of selected file using inverse video.    &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;A&amp;quot; or &amp;quot;G&amp;quot; key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3715H  MVI A,3EH            ; Load &amp;quot;&amp;gt;&amp;quot; for the tag symbol&lt;br /&gt;
3717H  CALL 37CAH           ; Go tag all files on the LCD&lt;br /&gt;
371AH  MVI A,01H            ; Indicate last operation as &amp;quot;Tag All&amp;quot;&lt;br /&gt;
371CH  STA FCCCH            ; Last Tag/Untag operation code&lt;br /&gt;
371FH  JMP 362FH            ; Print length of selected file using inverse video.&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Enter key from TS-DOS key scan - Change Directory&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3722H  LDA FCCBH            ; Get NADSBox/Desklink/TPDD2 flag     &lt;br /&gt;
3725H  CPI 02H              ; Test if NADSBox current directory valid   &lt;br /&gt;
3727H  JNZ 365AH            ; Back to keyscan if no &amp;quot;current directory&amp;quot; - Enter is meaningless     &lt;br /&gt;
372AH  LHLD FCE4H           ; LCD Buffer address of current file selection      &lt;br /&gt;
372DH  LXI B,0007H          ; Load offset of file extension       &lt;br /&gt;
3730H  DAD B                ; Point to file extension of selected file &lt;br /&gt;
3731H  MOV A,M              ; Load the 1st byte of the file extension   &lt;br /&gt;
3732H  CPI 3CH              ; Test if 1st byte of extension is &amp;quot;&amp;lt;&amp;quot;   &lt;br /&gt;
3734H  JNZ 365AH            ; Jump to keyscan if current selection not directory entry     &lt;br /&gt;
3737H  CALL 4A3BH           ; Initialize blank filename and attribute byte      &lt;br /&gt;
373AH  LHLD FCE4H           ; LCD Buffer address of current file selection      &lt;br /&gt;
373DH  CALL 3D95H           ; Copy filename at (HL) to TX buffer      &lt;br /&gt;
3740H  CALL 408AH           ; Open TPDD file for Read Mode      &lt;br /&gt;
3743H  LXI H,0002H          ; Load opcode to close currently opened file       &lt;br /&gt;
3746H  CALL 409BH           ; Send Request in HL and await response      &lt;br /&gt;
3749H  LHLD FCE4H           ; LCD Buffer address of current file selection      &lt;br /&gt;
374CH  LXI D,FCC0H          ; NADSBox current directory storage    &lt;br /&gt;
374FH  LXI B,0009H          ; Copy 9 bytes of NADSBox directory to the LCD       &lt;br /&gt;
3752H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
3755H  XRA A                ; Clear A to show 1st page of files &lt;br /&gt;
3756H  JMP 378AH            ; Branch to show the page of files in A     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;R&amp;quot; key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3759H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
375CH  ANA A                ; Test if in Disk mode&lt;br /&gt;
375DH  JNZ 362FH            ; Jump to keyscan if in Disk mode&lt;br /&gt;
3760H  LHLD FCE4H           ; LCD Buffer address of current file selection       &lt;br /&gt;
3763H  CALL 4902H           ; Copy filename at (HL) to current BASIC program&lt;br /&gt;
3766H  CALL 4A51H           ; Get RAM directory address of current BASIC program          &lt;br /&gt;
3769H  CPI C0H              ; Test if filetype is .DO&lt;br /&gt;
376BH  CZ 5000H             ; Call routine to Compress / Decompress .DO files&lt;br /&gt;
376EH  CALL 4C0FH           ; Update system pointers       &lt;br /&gt;
3771H  CALL 3611H           ; Print Copyright and files&lt;br /&gt;
3774H  JMP 362FH            ; Jump to keyscan &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;?&amp;quot; and Shift-Down key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3777H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
377AH  ANA A                ; Test if RAM mode &lt;br /&gt;
377BH  JZ 365AH             ; Branch to keyscan if in RAM mode    &lt;br /&gt;
377EH  LDA FCD6H            ; Count of files on screen     &lt;br /&gt;
3781H  CPI 14H              ; Maximum number of files that fit on the screen   &lt;br /&gt;
3783H  JC 365AH             ; Branch to keyscan if on last page    &lt;br /&gt;
3786H  LDA FCD4H            ; Current Page of files being displayed     &lt;br /&gt;
3789H  INR A                ; Increment to next page of files &lt;br /&gt;
				 &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Show the page of files indicated by A&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
378AH  STA FCD4H            ; Current Page of files being displayed     &lt;br /&gt;
378DH  MVI A,01H            ; Go to 1st file on the new page     &lt;br /&gt;
378FH  STA FCCDH            ; Currently selected file index     &lt;br /&gt;
3792H  CALL 3611H           ; Print copyright and files      &lt;br /&gt;
3795H  JMP 362FH            ; Print length of selected file using inverse video     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;]&amp;quot; and Shift-Up key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3798H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
379BH  ANA A                ; Test if RAM mode &lt;br /&gt;
379CH  JZ 365AH             ; Branch to keyscan if in RAM mode    &lt;br /&gt;
379FH  LDA FCD4H            ; Current Page of files being displayed     &lt;br /&gt;
37A2H  ANA A                ; Test if current page is zero &lt;br /&gt;
37A3H  JZ 365AH             ; Branch to keyscan if already on page 0    &lt;br /&gt;
37A6H  DCR A                ; Decrement the page number &lt;br /&gt;
37A7H  JMP 378AH            ; Show the page of files indicated by A&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Ctrl-Up key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
37AAH  XRA A                ; Go to page zero&lt;br /&gt;
37ABH  JMP 378AH            ; Show the page of files indicated by A&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;U&amp;quot; key from TS-DOS key scan - Remove all tags&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
37AEH  MVI A,20H            ; Display &#039; &#039; as the tag marker&lt;br /&gt;
37B0H  CALL 37CAH           ; Go process tag for all files&lt;br /&gt;
37B3H  XRA A                ; Indicate last tag operation was untag&lt;br /&gt;
37B4H  STA FCCCH            ; Store as &amp;quot;last tag&amp;quot; operation&lt;br /&gt;
37B7H  JMP 362FH            ; Print length of selected file using inverse video&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Swap TPDD2 Bank number&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
37BAH  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag&lt;br /&gt;
37BDH  DCR A                ; Test if the flag = 1 (TPDD2)&lt;br /&gt;
37BEH  JNZ 365AH            ; Jump to keyscan if not 1&lt;br /&gt;
37C1H  LDA FCCAH            ; Get TPDD Bank Number&lt;br /&gt;
37C4H  XRI 01H              ; Switch to the other bank&lt;br /&gt;
37C6H  STA FCCAH            ; Save TPDD bank number&lt;br /&gt;
37C9H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process Tag or Untag for all files on screen&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
37CAH  STA FCCCH            ; Store tag/untag code for later      &lt;br /&gt;
37CDH  LDA FCD6H            ; Get Maximum file count on screen      &lt;br /&gt;
37D0H  ANA A                ; Test for zero  &lt;br /&gt;
37D1H  RZ		            ; Return if no files on screen&lt;br /&gt;
37D2H  XRA A                ; Clear A  &lt;br /&gt;
37D3H  INR A                ; A=1 to selet 1st file  &lt;br /&gt;
37D4H  STA FCD5H            ; Currently selected file index      &lt;br /&gt;
37D7H  CALL 3ACDH           ; Calculate Row and Column of soon-to-be (newly) selected file       &lt;br /&gt;
37DAH  LHLD FCE4H           ; LCD Buffer address of current file selection       &lt;br /&gt;
37DDH  DCX H                ; Point to Tag location for the file  &lt;br /&gt;
37DEH  LDA FCCCH            ; Get the tag/untag code      &lt;br /&gt;
37E1H  RST 4                ; Display A to the LCD    &lt;br /&gt;
37E2H  LDA FCD5H            ; Get currently selected file index      &lt;br /&gt;
37E5H  LXI H,FCD6H          ; Point to count of files on screen        &lt;br /&gt;
37E8H  CMP M                ; Compare current selection with count of files on LCD  &lt;br /&gt;
37E9H  JC 37D3H             ; Jump to process next file if more files left     &lt;br /&gt;
37ECH  ANA A                ; Set zero flag to indicate files were tagged/untagged  &lt;br /&gt;
37EDH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;T&amp;quot; key key from TS-DOS key scan - TAG&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
37EEH  CALL 3ACDH           ; Calculate Row and Column of soon-to-be (newly) selected file    &lt;br /&gt;
37F1H  CALL 4C2FH           ; Start inverse character mode    &lt;br /&gt;
37F4H  LHLD FCE4H           ; LCD Buffer address of current file selection    &lt;br /&gt;
37F7H  DCX H	            ; Point to the &amp;quot;Tag&amp;quot; area for the file&lt;br /&gt;
37F8H  MVI A,3EH            ; Load the code for &amp;quot;&amp;gt;&amp;quot;   &lt;br /&gt;
37FAH  CMP M                ; Compare if file is already tagged     &lt;br /&gt;
37FBH  JNZ 3800H            ; Skip ahead if already tagged   &lt;br /&gt;
37FEH  MVI A,20H            ; Need to untag - load the untag code   &lt;br /&gt;
3800H  RST 4                ; Display the tag code on the LCD   &lt;br /&gt;
3801H  CALL 4C33H           ; Cancel inverse character mode    &lt;br /&gt;
3804H  LXI H,FCCCH          ; Point to &amp;quot;last tag&amp;quot; operation code     &lt;br /&gt;
3807H  MVI M,01H            ; Indicate last operation was &amp;quot;tag&amp;quot;   &lt;br /&gt;
3809H  JMP 36CAH            ; Move to next file - jump to Right Arrow key handler   &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; 1st level Function Key Handler (handles F4 and F6)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
380CH  CPI 08H              ; Test for valid function key code     &lt;br /&gt;
380EH  JNC 365AH            ; Branch back to scan loop if invalid       &lt;br /&gt;
3811H  CPI 05H              ; Test for F6     &lt;br /&gt;
3813H  JZ 3833H             ; Jump if F6 pressed      &lt;br /&gt;
3816H  CPI 03H              ; Test for F4     &lt;br /&gt;
3818H  RNZ                  ; Return to &amp;quot;Main Loop&amp;quot; if not F4 pressed &lt;br /&gt;
3819H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)       &lt;br /&gt;
381CH  XRI 01H              ; Swap RAM/DISK mode     &lt;br /&gt;
381EH  STA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)       &lt;br /&gt;
3821H  XRA A                ; Clear A to go to 1st page of files   &lt;br /&gt;
3822H  STA FCD4H            ; Current Page of files being displayed       &lt;br /&gt;
3825H  MVI A,01H            ; Select the 1st file in the page       &lt;br /&gt;
3827H  STA FCCDH            ; Currently selected file index       &lt;br /&gt;
382AH  CALL 4C27H           ; CLS statement     &lt;br /&gt;
382DH  CALL 3611H           ; Print the title bar and files        &lt;br /&gt;
3830H  JMP 362FH            ; Print length of selected file using inverse video.       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F6 Function Key Handler&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3833H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
3836H  ANA A                ; Test if in RAM or DISK mode&lt;br /&gt;
3837H  RZ                   ; Return if RAM mode&lt;br /&gt;
3838H  JMP 37AAH            ; Jump to Ctrl-Up key handler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Draw the display.  This takes care of RAM and Disk mode displays, handles&lt;br /&gt;
;    skipping page number to the proper &amp;quot;Disk&amp;quot; page, displaying the Bank# or&lt;br /&gt;
;    current directory for NADSBox/Desklink, showing free space, filling in&lt;br /&gt;
;    empty slots with &amp;quot;-.-&amp;quot;, etc.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
383BH  LXI H,F685H          ; Keyboard buffer  &lt;br /&gt;
383EH  SHLD FCDBH           ; Initialize pointer to file length table (in keyboard buffer)     &lt;br /&gt;
3841H  XRA A                ; Prepare to set 1st file lenght to zero&lt;br /&gt;
3842H  MOV M,A              ; Set LSB of length of 1st file to zero  &lt;br /&gt;
3843H  INX H                ; Increment to MSB of length&lt;br /&gt;
3844H  MOV M,A              ; Set MSB of length of file to zero  &lt;br /&gt;
3845H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)    &lt;br /&gt;
3848H  ANA A                ; Test if RAM or DISK&lt;br /&gt;
3849H  JZ 395DH             ; Jump to show RAM files if in RAM mode   &lt;br /&gt;
384CH  XRA A                ; Prepare to initialize the &amp;quot;page being processed&amp;quot; variable&lt;br /&gt;
384DH  STA FCDAH            ; Clear the &amp;quot;page being processed&amp;quot; variable    &lt;br /&gt;
3850H  CALL 4735H           ; Clear #files displayed, init TPDD and send 1st file dir referene opcode     &lt;br /&gt;
3853H  JNZ 390FH            ; Process unformated disk (empty slots and error message)    &lt;br /&gt;
3856H  LDA FCD4H            ; Current Page of files being displayed    &lt;br /&gt;
3859H  ANA A                ; Test if displaying page 0&lt;br /&gt;
385AH  JZ 3871H             ; Jump if showing page 0 - don&#039;t need to skikp any pages   &lt;br /&gt;
385DH  STA FCDAH            ; Initialize the number of pages left to skip count    &lt;br /&gt;
3860H  CALL 4742H           ; Read next page of files from server     &lt;br /&gt;
3863H  LDA FCDAH            ; Get the &amp;quot;Pages left to skip&amp;quot; count    &lt;br /&gt;
3866H  DCR A                ; Decrement the remaining skip page count &lt;br /&gt;
3867H  JNZ 385DH            ; Keep reading pages until we have skipped enough pages     &lt;br /&gt;
386AH  XRA A                ; Prepare to clear the remaining skip page count &lt;br /&gt;
386BH  STA FCDAH            ; Clear the remaining skip page count     &lt;br /&gt;
386EH  STA FCD6H            ; Count of files on screen     &lt;br /&gt;
3871H  CALL 4742H           ; Read next page of files from server      &lt;br /&gt;
3874H  LDA FCD6H            ; Count of files on screen     &lt;br /&gt;
3877H  CPI 14H              ; Test if all file slots are full   &lt;br /&gt;
3879H  CC 39AAH             ; Print &amp;quot;-.-&amp;quot; for all empty file slots (if any)    &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print NADSBox directory or TPDD Bank number to LCD&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
387CH  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag    &lt;br /&gt;
387FH  ANA A                ; Test if server is TPDD&lt;br /&gt;
3880H  JZ 389FH             ; Skip processing Bank # or Current Dir if TPDD   &lt;br /&gt;
3883H  DCR A                ; Test if server is TPDD2&lt;br /&gt;
3884H  JZ 388DH             ; Jump to print bank number if TPDD2   &lt;br /&gt;
3887H  LXI H,FCC0H          ; Load pointer to NADSBox current directory storage    &lt;br /&gt;
388AH  JMP 38A5H            ; Jump to print the NADSBox / Desklink directory    &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print the TPDD Bank number to LCD&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
388DH  LXI H,2401H          ; Go to Row 1, column 24&lt;br /&gt;
3890H  SHLD F639H           ; Cursor row (1-8) &lt;br /&gt;
3893H  CALL 4C2FH           ; Start inverse character mode &lt;br /&gt;
3896H  MVI A,23H            ; ASCII code for &#039;#&#039; &lt;br /&gt;
3898H  RST 4                ; Send character in A to the LCD&lt;br /&gt;
3899H  LDA FCCAH            ; Load TPDD Bank number &lt;br /&gt;
389CH  ADI 30H              ; Convert to ASCII digit   &lt;br /&gt;
389EH  RST 4                ; Send it to the LCD  &lt;br /&gt;
389FH  CALL 4C33H           ; Cancel inverse character mode&lt;br /&gt;
38A2H  JMP 38B8H            ; Branch to print the function menu, RAM/Disk free, etc.&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print the NADSBox / Desklink current directory in title bar&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
38A5H  PUSH H               ; Save address of the directory string     &lt;br /&gt;
38A6H  LXI H,2101H          ; Prepare to position the cursor in the title bar          &lt;br /&gt;
38A9H  SHLD F639H           ; Cursor row (1-8)         &lt;br /&gt;
38ACH  CALL 4C2FH           ; Start inverse character mode         &lt;br /&gt;
38AFH  POP H                ; Retrieve the directory string from the stack    &lt;br /&gt;
38B0H  MVI C,06H            ; Prepare to redraw 6 chars with inverse video        &lt;br /&gt;
38B2H  CALL 48E5H           ; Redraw C characters from buffer at HL using current video mode         &lt;br /&gt;
38B5H  CALL 4C33H           ; Cancel inverse character mode         &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print funtion menu, RAM/Disk free &amp;amp; selected file length&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
38B8H  LXI H,3E97H          ; Point to Disk function menu          &lt;br /&gt;
38BBH  LXI B,3936H          ; Routine to print free disk space          &lt;br /&gt;
38BEH  LDA FCD9H            ; RAM/Disk mode        &lt;br /&gt;
38C1H  ANA A                ; Test if in Disk mode and skip ahead to print Disk FKeys    &lt;br /&gt;
38C2H  JNZ 38CBH            ; Skip ahead if in disk mode to keep vectors        &lt;br /&gt;
38C5H  LXI H,3ED9H          ; Point to RAM function menu          &lt;br /&gt;
38C8H  LXI B,3922H          ; Routine to print free RAM space          &lt;br /&gt;
38CBH  PUSH B               ; Save routine address to stack     &lt;br /&gt;
38CCH  PUSH H               ; Save pointer to function text to stack     &lt;br /&gt;
38CDH  LDA FCCDH            ; Currently selected file index        &lt;br /&gt;
38D0H  LXI H,FCD6H          ; Count of files on screen          &lt;br /&gt;
38D3H  CMP M                ; Compare selected file with count of files on screen    &lt;br /&gt;
38D4H  JC 38DDH             ; Branch if within bounds       &lt;br /&gt;
38D7H  MOV A,M              ; Get the file count      &lt;br /&gt;
38D8H  ANA A                ; Test if #files = 0    &lt;br /&gt;
38D9H  JNZ 38DDH            ; Skip ahead if not zero        &lt;br /&gt;
38DCH  INR A                ; Don&#039;t allow a count of zero - must be 1    &lt;br /&gt;
38DDH  STA FCD5H            ; Currently selected file index - temp       &lt;br /&gt;
38E0H  LXI H,0B07H          ; Row &amp;amp; column of start of text          &lt;br /&gt;
38E3H  SHLD F639H           ; Cursor row (1-8)          &lt;br /&gt;
38E6H  POP H                ; Get address of text from the stack and display it   &lt;br /&gt;
38E7H  CALL 4A2CH           ; Send buffer at M to screen        &lt;br /&gt;
38EAH  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)       &lt;br /&gt;
38EDH  ANA A                ; Test if in RAM mode   &lt;br /&gt;
38EEH  JZ 3905H             ; Jump if in RAM mode (0 = RAM)       &lt;br /&gt;
38F1H  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag   &lt;br /&gt;
38F4H  ANA A                ; Test if server is TPDD      &lt;br /&gt;
38F5H  JZ 3905H             ; Skip printing of &amp;quot;Bank&amp;quot; or &amp;quot;Mkdr&amp;quot; if TPDD       &lt;br /&gt;
38F8H  LXI H,3FE9H          ; Point to text for &amp;quot;Bank&amp;quot;     &lt;br /&gt;
38FBH  DCR A                ; Test if server is TPDD2      &lt;br /&gt;
38FCH  JZ 3902H             ; Jump to print &amp;quot;Bank&amp;quot; if TPDD2         &lt;br /&gt;
38FFH  LXI H,3FD8H          ; Point to text for &amp;quot;Mkdr&amp;quot;        &lt;br /&gt;
3902H  CALL 4A2CH           ; Send buffer at M to screen                  &lt;br /&gt;
3905H  CALL 3940H           ; Display DISK ON/OFF status on LCD         &lt;br /&gt;
3908H  LXI H,1507H          ; Point to location for &amp;quot;Free&amp;quot; space (RAM or DISK)&lt;br /&gt;
390BH  SHLD F639H           ; Cursor row (1-8)          &lt;br /&gt;
390EH  RET                  &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle unformatted disks.  Print message and show empty slots.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
390FH  XRA A                ; Starting with slot zero...&lt;br /&gt;
3910H  CALL 39AAH           ; Print &amp;quot;-.-&amp;quot; for all empty file slots&lt;br /&gt;
3913H  LXI H,3E97H          ; Point to Disk Function menu string&lt;br /&gt;
3916H  LXI B,391CH          ; Print NOT FORMATTED to the display&lt;br /&gt;
3919H  JMP 38CBH            ; Go process the print and jump to error handler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print &amp;quot;NOT FORMATTED&amp;quot; on the LCD and return&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
391CH  LXI H,`H             ; Point to &amp;quot;NOT FORMATTED&amp;quot; string&lt;br /&gt;
391FH  JMP 4A2CH            ; Send buffer at M to screen&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print RAM free space at current posiiton&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3922H  LHLD FBB2H           ; Start of variable data pointer  &lt;br /&gt;
3925H  XCHG                 ; HL &amp;lt;--&amp;gt; DE&lt;br /&gt;
3926H  LHLD F678H           ; BASIC string buffer pointer  &lt;br /&gt;
3929H  MOV A,L              ; Prepare for 16 bit subtract   &lt;br /&gt;
392AH  SUB E                ; Subtract LSB &lt;br /&gt;
392BH  MOV L,A              ; Save LSB of difference for printing   &lt;br /&gt;
392CH  MOV A,H              ; Prepare for subtrating MSB   &lt;br /&gt;
392DH  SBB D                ; Subtract MSB &lt;br /&gt;
392EH  MOV H,A              ; Save in H for printing   &lt;br /&gt;
392FH  LXI B,FFF2H          ; Load signed number -14       &lt;br /&gt;
3932H  DAD B                ; Subtract 14 from free memory &lt;br /&gt;
3933H  JMP 4C3EH            ; Print binary number in HL at current position     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display free space on disk&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3936H  CALL 4A10H           ; Calculate free space on disk&lt;br /&gt;
3939H  CALL 4C3EH           ; Print binary number in HL at current position&lt;br /&gt;
393CH  MVI A,30H            ; Prepare to add an extra &#039;0&#039; since calc is /10&lt;br /&gt;
393EH  RST 4                ; Send A to the LCD      &lt;br /&gt;
393FH  RET       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display DISK ON/OFF status on LCD&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3940H  LDA FCD9H            ; DISK/RAM mode (0=RAM, 1=DISK)       &lt;br /&gt;
3943H  ANA A                ; Test if in RAM mode   &lt;br /&gt;
3944H  RNZ                  ; Return if not in RAM mode  &lt;br /&gt;
3945H  LDA FB2CH            ; DISK-OFF/ON status   &lt;br /&gt;
3948H  LXI D,3FF2H          ; Load pointer to &amp;quot;OFF&amp;quot; text         &lt;br /&gt;
394BH  CPI DBH              ; Test if DISK mode (vector LSB) indicates ON or OFF     &lt;br /&gt;
394DH  JZ 3953H             ; Branch if in DISK-OFF mode      &lt;br /&gt;
3950H  LXI D,3FF6H          ; Load pointer to &amp;quot;ON&amp;quot; text         &lt;br /&gt;
3953H  LXI H,1908H          ; Location of DISK-OFF/ON indication on LCD         &lt;br /&gt;
3956H  SHLD F639H           ; Cursor row (1-8)   &lt;br /&gt;
3959H  XCHG                 ; HL = pointer to text in DE  &lt;br /&gt;
395AH  JMP 4A2CH            ; Send buffer at M to screen       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display RAM files to LCD and calculate file lengths&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
395DH  LXI H,F9BAH          ; Load pointer to 1st available file slot in catalog&lt;br /&gt;
3960H  XRA A                ; Set count of RAM files on screen to zero &lt;br /&gt;
3961H  STA FCD6H            ; Count of files on screen     &lt;br /&gt;
3964H  MVI A,14H            ; Get max # files that will fit on LCD     &lt;br /&gt;
3966H  DCR A                ; Decrement the max file count &lt;br /&gt;
3967H  PUSH PSW             ; Save count to the stack    &lt;br /&gt;
3968H  MOV A,M              ; Get file type   &lt;br /&gt;
3969H  XRI 80H              ; Compliment ?active bit   &lt;br /&gt;
396BH  ANI 9FH              ; Test if file is active and should be displayed   &lt;br /&gt;
396DH  JNZ 3996H            ; Branch to test next file if not displayed     &lt;br /&gt;
3970H  PUSH H               ; Save address of current catalog file  &lt;br /&gt;
3971H  INX H                ; Point to file address &lt;br /&gt;
3972H  MOV E,M              ; Get LSB of file address   &lt;br /&gt;
3973H  INX H                ; Point to MSB of address &lt;br /&gt;
3974H  MOV D,M              ; Get MSB of file address   &lt;br /&gt;
3975H  XTHL                 ; HL &amp;lt;--&amp;gt; (SP)  Get address of file within catalog&lt;br /&gt;
3976H  PUSH H               ; Push pointer to MSB of address on stack  &lt;br /&gt;
3977H  CALL 3CD3H           ; Calculate length of RAM file      &lt;br /&gt;
397AH  XCHG                 ; HL &amp;lt;--&amp;gt; DE DE has the length&lt;br /&gt;
397BH  CALL 4791H           ; Store next file length to keyboard buffer      &lt;br /&gt;
397EH  POP H                ; Get catalog address of current file from stack &lt;br /&gt;
397FH  XTHL                 ; HL &amp;lt;--&amp;gt; (SP) swap catalog address with pointer to MSB of file address&lt;br /&gt;
3980H  INX H                ; Increment to filename &lt;br /&gt;
3981H  MVI C,06H            ; Prepare to print 6 characters of filename     &lt;br /&gt;
3983H  CALL 48E5H           ; Redraw C characters from buffer at HL using current video mode       &lt;br /&gt;
3986H  MVI A,2EH            ; Load code for &#039;.&#039;      &lt;br /&gt;
3988H  RST 4                ; Send A to the LCD                &lt;br /&gt;
3989H  MVI C,02H            ; Prepare to print 2 ext bytes to LCD      &lt;br /&gt;
398BH  CALL 48E5H           ; Redraw C characters from buffer at HL using current video mode       &lt;br /&gt;
398EH  MVI A,20H            ; Load code for space      &lt;br /&gt;
3990H  RST 4                ; Send A to the LCD           &lt;br /&gt;
3991H  LXI H,FCD6H          ; Count of files on screen        &lt;br /&gt;
3994H  INR M                ; Increment number of files displayed on LCD  &lt;br /&gt;
3995H  POP H                ; Get catalog address of file from stack  &lt;br /&gt;
3996H  LXI D,000BH          ; Load offset to next file locaion in catalog        &lt;br /&gt;
3999H  DAD D                ; Offset HL to next file  &lt;br /&gt;
399AH  POP PSW              ; Restore the file count from the stack    &lt;br /&gt;
399BH  DCR A                ; Decrement the max file count on the LCD  &lt;br /&gt;
399CH  JNZ 3967H            ; Branch to test and display next file until zero      &lt;br /&gt;
399FH  LDA FCD6H            ; Get the count of files actually displayed on screen              &lt;br /&gt;
39A2H  CPI 14H              ; Test if max number of files displayed    &lt;br /&gt;
39A4H  CC 39AAH             ; Branch to display &amp;quot;-.-&amp;quot; for remaining empty slots if not max     &lt;br /&gt;
39A7H  JMP 387CH            ; Print NADSBox directory or TPDD Bank number to LCD      &lt;br /&gt;
				  &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print &amp;quot;-.-&amp;quot; for all empty file slots&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
39AAH  PUSH PSW             ; Save current file index count on stack &lt;br /&gt;
39ABH  LXI H,3FCDH          ; Point to &amp;quot;-.-&amp;quot; text&lt;br /&gt;
39AEH  CALL 4A2CH           ; Send buffer at M to screen &lt;br /&gt;
39B1H  POP PSW              ; Restore current count &lt;br /&gt;
39B2H  INR A                ; Increment file index number&lt;br /&gt;
39B3H  CPI 14H              ; Compare A with max files that fit on LCD&lt;br /&gt;
39B5H  JNZ 39AAH            ; Jump to print next &amp;quot;-.-&amp;quot; if not done&lt;br /&gt;
39B8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;D&amp;quot; key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
39B9H  CALL 3AA8H           ; Test if printer busy.  Return if not busy or error&lt;br /&gt;
39BCH  CALL 4C52H           ; LCOPY statement&lt;br /&gt;
39BFH  JMP 362FH            ; Print length of selected file using inverse video.&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;L&amp;quot;, &amp;quot;P&amp;quot; and &amp;quot;O&amp;quot; keys from TS-DOS key scan - list or print .DO file contents&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
39C2H  STA FCDFH            ; Save key pressed       &lt;br /&gt;
39C5H  LXI D,0007H          ; Load offset of Extension bytes         &lt;br /&gt;
39C8H  LHLD FCE4H           ; LCD Buffer address of current file selection        &lt;br /&gt;
39CBH  DAD D                ; Point to extension bytes in LCD buffer   &lt;br /&gt;
39CCH  MOV A,M              ; Get 1st extension byte     &lt;br /&gt;
39CDH  CPI 44H              ; Compare byte with &amp;quot;D&amp;quot;     &lt;br /&gt;
39CFH  JNZ 362FH            ; Print length of selected file using inverse video if not &amp;quot;D&amp;quot;       &lt;br /&gt;
39D2H  INX H                ; Point to 2nd extension byte  &lt;br /&gt;
39D3H  MOV A,M              ; Load 2nd extension byte for comparison&lt;br /&gt;
39D4H  CPI 4FH              ; Compare with &amp;quot;0&amp;quot;&lt;br /&gt;
39D6H  JNZ 3A06H            ; Jump to print compressed file&lt;br /&gt;
39D9H  CALL 3A49H           ; Prepare file for reading (open disk file, address of RAM file)        &lt;br /&gt;
39DCH  LDA FCDFH            ; Restore key pressed       &lt;br /&gt;
39DFH  CPI 4CH              ; Test if key was &amp;quot;L&amp;quot; - List to LCD     &lt;br /&gt;
39E1H  CZ 4C27H             ; CLS statement if LCD      &lt;br /&gt;
39E4H  CNZ 3AA8H            ; Test if printer busy.  Return if not busy or error       &lt;br /&gt;
39E7H  CALL 3A24H           ; Get next block of data to display/print (HL=address)        &lt;br /&gt;
39EAH  PUSH PSW             ; Push Z flag indicating if a full 128 bytes was read      &lt;br /&gt;
39EBH  CALL 3A6BH           ; Display / print file data bytes at HL, A has length                 &lt;br /&gt;
39EEH  POP PSW              ; Get Z flag indicating if 128 bytes read     &lt;br /&gt;
39EFH  JZ 39E7H             ; Jump to process more if 128 bytes were read last time      &lt;br /&gt;
39F2H  LDA FCDFH            ; Restore key pressed       &lt;br /&gt;
39F5H  CPI 4CH              ; Test if key was &amp;quot;L&amp;quot;              &lt;br /&gt;
39F7H  JNZ 3A00H            ; Skip beep if printing       &lt;br /&gt;
39FAH  MVI A,07H            ; Load code for BELL       &lt;br /&gt;
39FCH  RST 4                ; Go print a BELL (beep)    &lt;br /&gt;
39FDH  CALL 3DF8H           ; Process power-off logic and wait for a key from keyboard        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Clear screen and perform Long Jump&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3A00H  CALL 4C27H           ; CLS statement         &lt;br /&gt;
3A03H  JMP 48B5H            ; Branch to &amp;quot;Long Jump&amp;quot; operation        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handler for the &amp;quot;O&amp;quot; key - print a compressed file?? &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3A06H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
3A09H  ANA A                ; Test if in Disk mode &lt;br /&gt;
3A0AH  JNZ 362FH            ; Jump to keyscan if in Disk mode&lt;br /&gt;
3A0DH  LHLD FCE4H           ; LCD Buffer address of current file selection      &lt;br /&gt;
3A10H  CALL 4902H           ; Copy filename at (HL) to current BASIC program&lt;br /&gt;
3A13H  CALL 4A51H           ; Get RAM directory address of current BASIC program&lt;br /&gt;
3A16H  CPI C0H              ; Test if filetype is .DO&lt;br /&gt;
3A18H  CZ 5004H             ; Call routine to Compress / Decompress .DO files&lt;br /&gt;
3A1BH  CALL 4C0FH           ; Update system pointers       &lt;br /&gt;
3A1EH  CALL 3611H           ; Print Copyright and files&lt;br /&gt;
3A21H  JMP 362FH            ; Jump to keyscan &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get next 128 bytes (or less) of data from RAM or disk file for display&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3A24H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)      &lt;br /&gt;
3A27H  ANA A                ; Test if RAM mode  &lt;br /&gt;
3A28H  JNZ 40B6H            ; If not RAM mode, go send TPDD_READ data opcode and recieve response      &lt;br /&gt;
3A2BH  LHLD FCDDH           ; Get length of file to be displayed / printed       &lt;br /&gt;
3A2EH  LXI B,0080H          ; Prepare to subtract 128 from length&lt;br /&gt;
3A31H  MOV A,C              ; Save 128 to A    &lt;br /&gt;
3A32H  DSUB                 ; Subtract 128 from file length &lt;br /&gt;
3A33H  JNC 3A3AH            ; Branch if length &amp;gt;= 128      &lt;br /&gt;
3A36H  DAD B                ; Add 128 back to length to print &amp;quot;partial&amp;quot; buffer  &lt;br /&gt;
3A37H  MOV A,L              ; Move remainder of bytes to display/print    &lt;br /&gt;
3A38H  MOV L,H              ; Clear LSB of remainder    &lt;br /&gt;
3A39H  MOV C,A              ; Move LSB of remainder to C    &lt;br /&gt;
3A3AH  SHLD FCDDH           ; Save new remaining file length       &lt;br /&gt;
3A3DH  LHLD FCE0H           ; Load the address to be printed / saved       &lt;br /&gt;
3A40H  PUSH H               ; Save on stack    &lt;br /&gt;
3A41H  DAD B                ; Update address to be used for display/printing next time  &lt;br /&gt;
3A42H  SHLD FCE0H           ; Save address to be displayed / printed       &lt;br /&gt;
3A45H  POP H                ; Retrieve address to be printed this loop from stack  &lt;br /&gt;
3A46H  CPI 80H              ; Compare length with maximum    &lt;br /&gt;
3A48H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Initialize Selected file for display (RAM or Disk)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3A49H  CALL 4A3BH           ; Initialize blank filename and attribute byte&lt;br /&gt;
3A4CH  LHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
3A4FH  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)     &lt;br /&gt;
3A52H  ANA A                ; Test if in RAM mode &lt;br /&gt;
3A53H  JNZ 3A65H            ; Branch to process Disk files if in Disk mode     &lt;br /&gt;
3A56H  CALL 4A4BH           ; Get RAM directory address of selected file&lt;br /&gt;
3A59H  PUSH D               ; Push file address to stack  &lt;br /&gt;
3A5AH  CALL 3CD3H           ; Calculate length of RAM file, HL=address of catalog entry, DE=file address&lt;br /&gt;
3A5DH  SHLD FCDDH           ; Save length to FDC emulation sector storage area&lt;br /&gt;
3A60H  POP H                ; Pop address of file into H &lt;br /&gt;
3A61H  SHLD FCE0H           ; Save file address&lt;br /&gt;
3A64H  RET		 &lt;br /&gt;
				 &lt;br /&gt;
; =====================================================================================&lt;br /&gt;
; Send TPDD Open command to open selected file&lt;br /&gt;
; =====================================================================================&lt;br /&gt;
3A65H  CALL 3D95H           ; Copy filename at (HL) to TX buffer&lt;br /&gt;
3A68H  JMP 408AH            ; Open TPDD file for Read Mode&lt;br /&gt;
&lt;br /&gt;
; =====================================================================================&lt;br /&gt;
; Display / print file data bytes at HL, A has length&lt;br /&gt;
; =====================================================================================&lt;br /&gt;
3A6BH  XCHG                 ; HL &amp;lt;--&amp;gt; DE  &lt;br /&gt;
3A6CH  ORA A                ; Test if length = 0   &lt;br /&gt;
3A6DH  RZ                   ; Return if length = 0&lt;br /&gt;
3A6EH  MOV C,A              ; Save length count in C     &lt;br /&gt;
3A6FH  LDA FCDFH            ; Load key press value       &lt;br /&gt;
3A72H  CPI 4CH              ; Test if key was &amp;quot;L&amp;quot;     &lt;br /&gt;
3A74H  JNZ 3A82H            ; Jump to print contents if not &amp;quot;L&amp;quot;       &lt;br /&gt;
3A77H  CALL 3A8FH           ; Check for CTRL-C&lt;br /&gt;
3A7AH  LDAX D               ; Load next byte from src pointer    &lt;br /&gt;
3A7BH  RST 4                ; Send A to LCD           &lt;br /&gt;
3A7CH  INX D                ; Increment the pointer   &lt;br /&gt;
3A7DH  DCR C                ; Decrement the length count   &lt;br /&gt;
3A7EH  JNZ 3A77H            ; Keep looping until all data displayed       &lt;br /&gt;
3A81H  RET        &lt;br /&gt;
&lt;br /&gt;
; =====================================================================================&lt;br /&gt;
; Print file data bytes at HL, A has length&lt;br /&gt;
; =====================================================================================&lt;br /&gt;
3A82H  CALL 3A8FH           ; Test for CTRL-C, etc.&lt;br /&gt;
3A85H  LDAX D               ; Load next file byte from source poiner &lt;br /&gt;
3A86H  CALL 4C42H           ; Print A to printer, expanding tabs if necessary&lt;br /&gt;
3A89H  INX D                ; Increment pointer&lt;br /&gt;
3A8AH  DCR C                ; Decrement length count&lt;br /&gt;
3A8BH  JNZ 3A82H            ; Keep looping until all data printed    &lt;br /&gt;
3A8EH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test for ESC, CTRL-C or Space&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3A8FH  CALL 4C4AH           ; Check keyboard queue for pending characters&lt;br /&gt;
3A92H  RZ                   ; Return if no pending characters&lt;br /&gt;
3A93H  CALL 4BEBH           ; Wait for key from keyboard&lt;br /&gt;
3A96H  CPI 03H              ; Test for F4 maybe?  &lt;br /&gt;
3A98H  JZ 3A00H             ; Clear screen and perform Long Jump if F4 maybe?   &lt;br /&gt;
3A9BH  CPI 1BH              ; Test for ESC key  &lt;br /&gt;
3A9DH  JZ 3A00H             ; Clear screen and perform Long Jump if ESC   &lt;br /&gt;
3AA0H  CPI 20H              ; Test for space key  &lt;br /&gt;
3AA2H  JNZ 3A8FH            ; Branch back to wait for ESC, CTRL-C or space if not space    &lt;br /&gt;
3AA5H  JMP 4BEBH            ; Wait for key from keyboard    &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test if printer busy.  Return if not busy, print error if it is&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3AA8H  IN BBH               ; Get printer port input     &lt;br /&gt;
3AAAH  ANI 06H              ; Mask all but BUSY and /BUSY      &lt;br /&gt;
3AACH  XRI 02H              ; Compliment /BUSY      &lt;br /&gt;
3AAEH  JNZ 487BH            ; Printer not ready / FF error        &lt;br /&gt;
3AB1H  RET        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print currently selected file using inverse video&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3AB2H  CALL 3ACDH           ; Calculate Row and Column of newly selected file&lt;br /&gt;
3AB5H  SHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
3AB8H  CALL 4C2FH           ; Start inverse character mode&lt;br /&gt;
3ABBH  DCX H                ; Start drawing from left edge of selection (include space)   &lt;br /&gt;
3ABCH  MVI C,0AH            ; Draw 10 characters       &lt;br /&gt;
3ABEH  CALL 48E5H           ; Redraw C characters from buffer at HL using current video mode&lt;br /&gt;
3AC1H  JMP 4C33H            ; Cancel inverse character mode       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print selected file using normal video to &amp;quot;unselect&amp;quot; it&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3AC4H  CALL 4C33H           ; Cancel inverse character mode&lt;br /&gt;
3AC7H  CALL 3ACDH           ; Calculate row and column of newly selected file&lt;br /&gt;
3ACAH  JMP 3ABBH            ; Print the file to the LCD       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Calculate Row and Column of soon-to-be (newly) selected file&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3ACDH  LDA FCD5H            ; Currently selected file index       &lt;br /&gt;
3AD0H  DCR A                ; Make selected file zero based   &lt;br /&gt;
3AD1H  MOV L,A              ; Save index to 16-bit HL&lt;br /&gt;
3AD2H  MVI H,00H            ; Make MSB zero&lt;br /&gt;
3AD4H  LXI D,000AH          ; Prepare to multiply index * 10 cols      &lt;br /&gt;
3AD7H  CALL 4C1FH           ; Signed integer muliply (FAC1=HL*DE)&lt;br /&gt;
3ADAH  LXI D,FE28H          ; Load address of line 2 in the LCD buffer&lt;br /&gt;
3ADDH  DAD D                ; Calculate starting LCD buffer address for this file&lt;br /&gt;
3ADEH  INX H                ; Skip the &amp;quot;tag&amp;quot; space on the LCD&lt;br /&gt;
3ADFH  PUSH H               ; Save address on the stack&lt;br /&gt;
3AE0H  LXI B,FE00H          ; Load starting address of LCD character buffer&lt;br /&gt;
3AE3H  DSUB                 ; Calculate file start offset from start of LCD buffer&lt;br /&gt;
3AE4H  LXI D,0028H          ; Load 1 LCD line width&lt;br /&gt;
3AE7H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  Prepare for divide&lt;br /&gt;
3AE8H  CALL 4C1BH           ; Signed integer divide (FAC1=DE/HL)&lt;br /&gt;
3AEBH  MOV A,L              ; Save selected file&#039;s row number to A&lt;br /&gt;
3AECH  INR A                ; Make row 1-based&lt;br /&gt;
3AEDH  STA F639H            ; Cursor row (1-8)&lt;br /&gt;
3AF0H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  DE had remainder*2 from divide&lt;br /&gt;
3AF1H  ASHR                 ; Divide HL by 2&lt;br /&gt;
3AF2H  MOV A,L              ; Prepare to save remainder as the column&lt;br /&gt;
3AF3H  STA F63AH            ; Cursor column (1-40)&lt;br /&gt;
3AF6H  POP H                ; Restore address of LCD buffer location from stack&lt;br /&gt;
3AF7H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F3 Function key handler for RAM mode - Rename&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3AF8H  CALL 4A4BH           ; Get RAM directory address of selected file          &lt;br /&gt;
3AFBH  SHLD FCE0H           ; Save address of file being processed          &lt;br /&gt;
3AFEH  LXI H,3F4AH          ; Address of &amp;quot;New name&amp;quot; string           &lt;br /&gt;
3B01H  CALL 3E1AH           ; Get 6-byte input filename from keyboard          &lt;br /&gt;
3B04H  RZ                   ; Return if no input provided  &lt;br /&gt;
3B05H  CALL 4902H           ; Copy filename at (HL) to current BASIC program          &lt;br /&gt;
3B08H  LHLD FCE0H           ; Load RAM directory address of file being renamed          &lt;br /&gt;
3B0BH  LXI B,0009H          ; Load offset of extension within catalog entry           &lt;br /&gt;
3B0EH  DAD B                ; Point to extension bytes     &lt;br /&gt;
3B0FH  LXI D,FC99H          ; Load address of extension field of current BASIC program name           &lt;br /&gt;
3B12H  MOV A,M              ; Get 1st byte of extension of catalog file being renamed       &lt;br /&gt;
3B13H  STAX D               ; Save extension byte in current BASIC program filename - preserve EXT      &lt;br /&gt;
3B14H  INX D                ; Point to 2nd ext byte of BASIC program name     &lt;br /&gt;
3B15H  INX H                ; Point to 2nd ext byte of catalog filename     &lt;br /&gt;
3B16H  MOV A,M              ; Get 2nd extension byte from catalog filename       &lt;br /&gt;
3B17H  STAX D               ; Save byte in current BASIC program filename area      &lt;br /&gt;
3B18H  CALL 4A51H           ; Get RAM directory address of current BASIC program          &lt;br /&gt;
3B1BH  JNZ 487EH            ; If found, jump to File Exists Error         &lt;br /&gt;
3B1EH  LHLD FCE0H           ; Load catalog address of file being renamed          &lt;br /&gt;
3B21H  INX H                ; Point to LSB of file address     &lt;br /&gt;
3B22H  INX H                ; Point to MSB of file address     &lt;br /&gt;
3B23H  INX H                ; Point to name     &lt;br /&gt;
3B24H  LXI D,FC93H          ; Load address of filename of current BASIC program    &lt;br /&gt;
3B27H  LXI B,0006H          ; Prepare to copy 6 bytes of filename (ext doesn&#039;t change)           &lt;br /&gt;
3B2AH  XCHG                 ; HL &amp;lt;--&amp;gt; DE    &lt;br /&gt;
3B2BH  JMP 4A05H            ; Move BC bytes from M to (DE) with increment         &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F1 Function key handler for DISK mode - Load&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3B2EH  CALL 4A3BH           ; Initialize blank filename and attribute byte      &lt;br /&gt;
3B31H  LHLD FCE4H           ; LCD Buffer address of current file selection      &lt;br /&gt;
3B34H  CALL 3D95H           ; Copy filename at (HL) to TX buffer      &lt;br /&gt;
3B37H  LDA FCCCH            ; Last Tag/Untag operation code     &lt;br /&gt;
3B3AH  ANA A                ; Test if a tag operation is pending &lt;br /&gt;
3B3BH  JNZ 3B56H            ; Branch if doing tag load operation     &lt;br /&gt;
3B3EH  LXI H,3F7AH          ; Point to &amp;quot;Load as:&amp;quot; text       &lt;br /&gt;
3B41H  CALL 3E1AH           ; Get 6-byte filename input from keyboard      &lt;br /&gt;
3B44H  JZ 3B56H             ; Jump to use existing disk name as filename    &lt;br /&gt;
3B47H  CALL 4902H           ; Copy filename at (HL) to current BASIC program      &lt;br /&gt;
3B4AH  LXI B,0002H          ; Prepare to copy 2 extension bytes to current BASIC program space       &lt;br /&gt;
3B4DH  LXI H,FCEFH          ; Point to disk file extension in TX buffer       &lt;br /&gt;
3B50H  LXI D,FC99H          ; Point to current BASIC program extension address       &lt;br /&gt;
3B53H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
3B56H  CALL 4A51H           ; Get RAM directory address of current BASIC program      &lt;br /&gt;
3B59H  JZ 3B69H             ; Branch to load if file doesn&#039;t already exist    &lt;br /&gt;
3B5CH  LXI H,3FB0H          ; Point to &amp;quot;File Exists, Replace?&amp;quot; text       &lt;br /&gt;
3B5FH  CALL 48F4H           ; Print string at HL to col 1 on the bottom line      &lt;br /&gt;
3B62H  CALL 3DEEH           ; Get key from keyboard and test for &#039;Y&#039; or &#039;y&#039;      &lt;br /&gt;
3B65H  RNZ                  ; Return if isn&#039;t &#039;y&#039; or &#039;Y&#039; &lt;br /&gt;
3B66H  CALL 3C38H           ; Kill file in current BASIC program space      &lt;br /&gt;
3B69H  LHLD FD1DH           ; Get file size from RX buffer      &lt;br /&gt;
3B6CH  MOV A,H              ; Swap bytes (big endian in RX buffer)   &lt;br /&gt;
3B6DH  MOV H,L              ; Move LSB to MSB   &lt;br /&gt;
3B6EH  MOV L,A              ; Move MSB to LSB   &lt;br /&gt;
3B6FH  SHLD FD1DH           ; Save with little endian to RX buffer      &lt;br /&gt;
3B72H  LDA FCEFH            ; Get 1st byte of extension from TX buffer     &lt;br /&gt;
3B75H  CPI 44H              ; Test if 1st extension byte is &amp;quot;D&amp;quot;   &lt;br /&gt;
3B77H  JNZ 3B82H            ; Jump if not &amp;quot;D&amp;quot; to check for &amp;quot;C&amp;quot; or &amp;quot;B&amp;quot;     &lt;br /&gt;
3B7AH  LHLD FBAEH           ; Get start of DO files pointer for location of new file       &lt;br /&gt;
3B7DH  MVI A,C0H            ; Load file type code for .DO files     &lt;br /&gt;
3B7FH  JMP 3BA3H            ; Process the file load      &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test file exension type in A for .CO files&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3B82H  CPI 43H              ; Test if A contains &amp;quot;C&amp;quot; &lt;br /&gt;
3B84H  JNZ 3B95H            ; Branch if not .CO file&lt;br /&gt;
3B87H  LHLD FBB0H           ; Start of CO files pointer&lt;br /&gt;
3B8AH  SHLD FCD5H           ; Save in currently selected file index storage area&lt;br /&gt;
3B8DH  LHLD FBB2H           ; Get Start of variable data pointer as location for new file&lt;br /&gt;
3B90H  MVI A,A0H            ; Load file type code for .CO files&lt;br /&gt;
3B92H  JMP 3BA3H            ; Process the file load&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process load of .BA file&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3B95H  LHLD FD1DH           ; Get file size from RX buffer&lt;br /&gt;
3B98H  SHLD FCD5H           ; Save in Currently selected file index storage&lt;br /&gt;
3B9BH  LHLD F99AH           ; Get BASIC program not saved pointer     &lt;br /&gt;
3B9EH  SHLD FCE0H           ; Save as address of file being processed&lt;br /&gt;
3BA1H  MVI A,80H            ; Load file type code for .BA files     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process file load operation&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3BA3H  STA FCDFH            ; Save file type code for later     &lt;br /&gt;
3BA6H  SHLD FCE2H           ; Save address for new file &lt;br /&gt;
3BA9H  LHLD FD1DH           ; Get file size from RX buffer&lt;br /&gt;
3BACH  SHLD FCDDH           ; Save in FDC emulation physical/logical sector storage area&lt;br /&gt;
3BAFH  PUSH H               ; Save file size on stack  &lt;br /&gt;
3BB0H  POP B                ; Copy file size to BC &lt;br /&gt;
3BB1H  LDA FCDFH            ; Get file type code     &lt;br /&gt;
3BB4H  CPI A0H              ; Test for .CO file   &lt;br /&gt;
3BB6H  JZ 3BC0H             ; Skip increment if .CO file (.BA has trailing 0x0000, .DO a 0x1A)    &lt;br /&gt;
3BB9H  INX B                ; Increment file length for .BA and .DO files &lt;br /&gt;
3BBAH  CPI 80H              ; Test if file is .BA   &lt;br /&gt;
3BBCH  JNZ 3BC0H            ; Skip additional increment if .BA     &lt;br /&gt;
3BBFH  INX B                ; Add 1 more to length for .BA files to account for both trailing 0&#039;s &lt;br /&gt;
3BC0H  PUSH B               ; Save updated length on stack  &lt;br /&gt;
3BC1H  CALL 3E48H           ; Find empty catalog entry      &lt;br /&gt;
3BC4H  JC 4887H             ; Generate system error 0x0A (&amp;quot;DD&amp;quot;) if full&lt;br /&gt;
3BC7H  POP B                ; Get length from stack &lt;br /&gt;
3BC8H  PUSH H               ; Save new file catalog address on stack  &lt;br /&gt;
3BC9H  PUSH B               ; Save new file length on stack  &lt;br /&gt;
3BCAH  LHLD FCE2H           ; Get address for new contents of new file      &lt;br /&gt;
3BCDH  CALL 4C0BH           ; Insert BC spaces at M - make room      &lt;br /&gt;
3BD0H  JC 488AH	            ; Branch if error - RAM full error&lt;br /&gt;
3BD3H  LHLD FCE2H           ; Restore address of new file contents&lt;br /&gt;
3BD6H  POP B                ; Get file length from stack   &lt;br /&gt;
3BD7H  MVI M,00H            ; Fill newly created file space with zero&#039;s       &lt;br /&gt;
3BD9H  INX H                ; Increment pointer   &lt;br /&gt;
3BDAH  DCX B                ; Decrement count   &lt;br /&gt;
3BDBH  MOV A,C              ; Move LSB to A to check for zero - could use JNX here!     &lt;br /&gt;
3BDCH  ORA B                ; Or in MSB to check for zero   &lt;br /&gt;
3BDDH  JNZ 3BD7H            ; Keep looping until all are zero       &lt;br /&gt;
3BE0H  DCX H                ; Decrement pointer to last byte in new file   &lt;br /&gt;
3BE1H  POP D                ; Get File catalog address from stack   &lt;br /&gt;
3BE2H  LDA FCDFH            ; Load file type code byte       &lt;br /&gt;
3BE5H  CPI C0H              ; Test for .DO file     &lt;br /&gt;
3BE7H  JNZ 3BF3H            ; Branch if not .DO file       &lt;br /&gt;
3BEAH  MVI M,1AH            ; Terminate .DO file with EOF marker       &lt;br /&gt;
3BECH  LHLD FCE2H           ; Reload address of new file contents        &lt;br /&gt;
3BEFH  DCX H                ; Decrement pointer to jump into middle of loop   &lt;br /&gt;
3BF0H  JMP 3C1BH            ; Write file entry to catalog       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process end-of-file / file length for .CO and .BA files&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3BF3H  CPI A0H              ; Test if new file is .CO  &lt;br /&gt;
3BF5H  JNZ 3C04H            ; Branch if not .CO - must be .BA &lt;br /&gt;
3BF8H  LHLD FCD5H           ; Get old start of CO files pointer&lt;br /&gt;
3BFBH  SHLD FBB0H           ; Save as current start of CO files pointer     &lt;br /&gt;
3BFEH  LHLD FCE2H           ; Reload address of new file contents&lt;br /&gt;
3C01H  JMP 3C1BH            ; Write file entry to catalog &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process end-of-file for .BA files&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3C04H  PUSH D               ; Push file catalog address to stack    &lt;br /&gt;
3C05H  LHLD FBAEH           ; Get start of DO files pointer          &lt;br /&gt;
3C08H  DCX H                ; Decrement address by 1   &lt;br /&gt;
3C09H  SHLD F99AH           ; Save as new BASIC program not saved pointer          &lt;br /&gt;
3C0CH  INX H                ; Increment back to start of .DO files   &lt;br /&gt;
3C0DH  XCHG                 ; HL &amp;lt;--&amp;gt; DE  DE has start of DO files  &lt;br /&gt;
3C0EH  LHLD FCD5H           ; Get BA file size        &lt;br /&gt;
3C11H  INX H                ; Increment file size to account for trailing 0&#039;s   &lt;br /&gt;
3C12H  INX H                ; Increment file size to account for trailing 0&#039;s   &lt;br /&gt;
3C13H  DAD D                ; Add new length to start of DO files pointer   &lt;br /&gt;
3C14H  SHLD FBAEH           ; Save new start of DO files pointer          &lt;br /&gt;
3C17H  POP D                ; Retrieve file catalog address from stack   &lt;br /&gt;
3C18H  LHLD FCE0H           ; Reload address of new file contents        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Write file entry to catalog&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3C1BH  XCHG                 ; HL &amp;lt;--&amp;gt; DE  DE has file address, HL has catalog address         &lt;br /&gt;
3C1CH  CALL 4C17H           ; Write new entry to catalog (A=type, DE=file address,HL=catalog address)       &lt;br /&gt;
3C1FH  CALL 4127H           ; Open TPDD file and read data to file address being processed       &lt;br /&gt;
3C22H  CALL 4C0FH           ; Update system pointers       &lt;br /&gt;
3C25H  LXI H,0002H          ; Load TPDD_READ opcode in HL        &lt;br /&gt;
3C28H  JMP 409BH            ; Send Request in HL and await response      &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F2 Function key handler for RAM mode - Kill&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3C2BH  LDA FCCCH            ; Get last Tag/Untag operation code       &lt;br /&gt;
3C2EH  ANA A                ; Test if there is a pending tag operation&lt;br /&gt;
3C2FH  CZ 3DE1H             ; Display &amp;quot;Sure ?&amp;quot;, validate and return if validated if no tag&lt;br /&gt;
3C32H  LHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
3C35H  CALL 4902H           ; Copy filename at (HL) to current BASIC program&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Kill file in current BASIC program space&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3C38H  CALL 4A51H           ; Get RAM directory address of current BASIC program&lt;br /&gt;
3C3BH  CPI C0H              ; Test if file is .DO &lt;br /&gt;
3C3DH  JZ 4BFFH             ; Kill .DO file  &lt;br /&gt;
3C40H  CPI A0H              ; Test if file is .CO &lt;br /&gt;
3C42H  JZ 4C07H             ; Kill .CO file &lt;br /&gt;
3C45H  CPI 80H              ; Test if file is .BA&lt;br /&gt;
3C47H  JZ 4C03H             ; Kill .BA file&lt;br /&gt;
3C4AH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F1 Function key handler for RAM mode - Save&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3C4BH  CALL 4A3BH           ; Initialize blank filename and attribute byte      &lt;br /&gt;
3C4EH  CALL 4A4BH           ; Get RAM directory address of selected file      &lt;br /&gt;
3C51H  PUSH D               ; Push file address to stack  &lt;br /&gt;
3C52H  PUSH H               ; Push file catalog address to stack  &lt;br /&gt;
3C53H  INX H                ; Point to LSB of file address &lt;br /&gt;
3C54H  INX H                ; Point to MSB of file address &lt;br /&gt;
3C55H  INX H                ; Point to filename in catalog &lt;br /&gt;
3C56H  LXI D,FCE8H          ; Point to TX buffer data area (payload)&lt;br /&gt;
3C59H  LXI B,0006H          ; Prepare to copy 6 filename bytes to TX packet data&lt;br /&gt;
3C5CH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
3C5FH  MVI A,2EH            ; Load code for &#039;.&#039;     &lt;br /&gt;
3C61H  STAX D               ; Store &#039;.&#039; separator in TX packet data  &lt;br /&gt;
3C62H  INX D                ; Increment TX packet data pointer &lt;br /&gt;
3C63H  LXI B,0002H          ; Prepare to copy 2 extention bytes from catalog&lt;br /&gt;
3C66H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
3C69H  LDA FCCCH            ; Last Tag/Untag operation code     &lt;br /&gt;
3C6CH  ANA A                ; Test if a tag save operation is being performed &lt;br /&gt;
3C6DH  JNZ 3C88H            ; Jump ahead if doing a tag save - skip filename questioning     &lt;br /&gt;
3C70H  LXI H,3F71H          ; Point to &amp;quot;Save as:&amp;quot; text&lt;br /&gt;
3C73H  CALL 3E1AH           ; Get 6-byte input filename from keyboard      &lt;br /&gt;
3C76H  JZ 3C88H             ; Skip ahead to use catalog name if no input given    &lt;br /&gt;
3C79H  CALL 4902H           ; Copy filename at (HL) to current BASIC program             &lt;br /&gt;
3C7CH  LXI B,0006H          ; Prepare to copy 6 filename bytes from input string       &lt;br /&gt;
3C7FH  LXI D,FCE8H          ; Point to filename area in TX buffer       &lt;br /&gt;
3C82H  LXI H,FC93H          ; Filename of current BASIC program         &lt;br /&gt;
3C85H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
3C88H  POP H                ; Restore file catalog address from stack &lt;br /&gt;
3C89H  POP D                ; Restore file address from stack &lt;br /&gt;
3C8AH  PUSH D               ; Save file address on stack  &lt;br /&gt;
3C8BH  CALL 3CD3H           ; Calculate length of RAM file, HL=address of catalog entry, DE=file address&lt;br /&gt;
3C8EH  MOV A,H              ; Test for zero length file - move H to A    &lt;br /&gt;
3C8FH  ORA L                ; OR LSB to test for zero  &lt;br /&gt;
3C90H  JZ 4884H             ; Branch if empty - File Empty Error     &lt;br /&gt;
3C93H  PUSH H               ; Save file address to stack   &lt;br /&gt;
3C94H  MVI A,01H            ; Set file open mode to new file      &lt;br /&gt;
3C96H  STA FCD6H            ; Save open mode to pass to open routine      &lt;br /&gt;
3C99H  CALL 4943H           ; Configure baud, test for NADSBox, get NADSBox dir       &lt;br /&gt;
3C9CH  CALL 4A72H           ; Send Dir Reference opcode       &lt;br /&gt;
3C9FH  JZ 3CCEH             ; Jump to write data if file doesn&#039;t exist (size = 0)     &lt;br /&gt;
3CA2H  LXI H,3F8BH          ; Point to &amp;quot;File Exists, A)ppend R)eplace Q)uit&amp;quot; text        &lt;br /&gt;
3CA5H  CALL 48F4H           ; Print string at HL to col 1 on the bottom line       &lt;br /&gt;
3CA8H  CALL 3DF8H           ; Process power-off logic and wait for a key from keyboard       &lt;br /&gt;
3CABH  ANI DFH              ; Make key uppercase    &lt;br /&gt;
3CADH  RST 4                ; Display key on LCD            &lt;br /&gt;
3CAEH  CPI 52H              ; Test if key is &#039;R&#039;    &lt;br /&gt;
3CB0H  JNZ 3CBCH            ; Jump if not &#039;R&#039;eplace                      &lt;br /&gt;
3CB3H  CALL 431AH           ; Issue TPDD Delete file Opcode       &lt;br /&gt;
3CB6H  CALL 4A72H           ; Send Dir Reference opcode       &lt;br /&gt;
3CB9H  JMP 3CCEH            ; Go write data to the file      &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F1-Save: Test for &#039;A&#039;ppend&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3CBCH  POP H                ; Get file length from stack    &lt;br /&gt;
3CBDH  POP D                ; Get file address from stack    &lt;br /&gt;
3CBEH  CPI 41H              ; Test if response is &#039;A&#039;ppend      &lt;br /&gt;
3CC0H  RNZ                  ; Return if not &#039;A&#039;  &lt;br /&gt;
3CC1H  LDA FCEFH            ; Load 1st byte of extension from TX buffer        &lt;br /&gt;
3CC4H  CPI 44H              ; Test if file is &amp;quot;D&amp;quot;O file      &lt;br /&gt;
3CC6H  RNZ                  ; Don&#039;t allow appending non DO files  &lt;br /&gt;
3CC7H  MVI A,02H            ; Set open mode to open existing (append)        &lt;br /&gt;
3CC9H  STA FCD6H            ; Save mode to pass to open routine        &lt;br /&gt;
3CCCH  PUSH D               ; Save file address on stack     &lt;br /&gt;
3CCDH  PUSH H               ; Save file length on stack     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Save function - Replace or new file, write data to file&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3CCEH  POP H                ; Retrieve file length from stack    &lt;br /&gt;
3CCFH  POP D                ; Retrieve file address from stack    &lt;br /&gt;
3CD0H  JMP 40C8H            ; Write HL bytes of data from (DE) to TPDD        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Calculate length of RAM file, HL=address of catalog entry, DE=file address&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3CD3H  MOV A,M              ; Get RAM file type from catalog   &lt;br /&gt;
3CD4H  CPI C0H              ; Test for .DO file   &lt;br /&gt;
3CD6H  JZ 3CE6H             ; Jump to calculate length if .DO file    &lt;br /&gt;
3CD9H  CPI A0H              ; Test for .CO file         &lt;br /&gt;
3CDBH  JZ 3CF5H             ; Jump to calculate length if .CO file    &lt;br /&gt;
3CDEH  PUSH D               ; Save address of start of BASIC program to stack  &lt;br /&gt;
3CDFH  CALL 4C13H           ; Call ROM routine to find BASIC end of program&lt;br /&gt;
3CE2H  POP B                ; Get BASIC program start address from stack &lt;br /&gt;
3CE3H  DSUB                 ; Subtract starting address from end address&lt;br /&gt;
3CE4H  DCX H                ; Don&#039;t count trailing 0x00 as part of BASIC program length &lt;br /&gt;
3CE5H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Calculate length of .DO file, HL=Catalog address, DE=file address&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3CE6H  XCHG                 ; HL &amp;lt;--&amp;gt; DE Get file address in HL &lt;br /&gt;
3CE7H  LXI D,0000H          ; Clear file length&lt;br /&gt;
3CEAH  MOV A,M              ; Get next byte from .DO file    &lt;br /&gt;
3CEBH  INX H                ; Increment pointer  &lt;br /&gt;
3CECH  INX D                ; Increment length  &lt;br /&gt;
3CEDH  CPI 1AH              ; Test for EOF marker    &lt;br /&gt;
3CEFH  JNZ 3CEAH            ; Branch to next byte if not EOF      &lt;br /&gt;
3CF2H  DCX D                ; Subtract EOF marker from file length  &lt;br /&gt;
3CF3H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  HL=length &lt;br /&gt;
3CF4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Calculate length of .CO file, HL=Catalog address, DE=file address&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3CF5H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  Get file address in HL &lt;br /&gt;
3CF6H  INX H                ; Increment past .CO load address &lt;br /&gt;
3CF7H  INX H                ; Increment past MSB of load address&lt;br /&gt;
3CF8H  MOV C,M              ; Get LSB of length  &lt;br /&gt;
3CF9H  INX H                ; Increment to MSB of length&lt;br /&gt;
3CFAH  MOV B,M              ; Get MSB of length&lt;br /&gt;
3CFBH  LXI H,0006H          ; Prepare to add 6-byte header to length&lt;br /&gt;
3CFEH  DAD B                ; Add 6-byte header to length&lt;br /&gt;
3CFFH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F7 Function key handler for DISK mode - Mkdir&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D00H  LDA FCCBH            ; NADSBox / TPDD2 / Desklink flag        &lt;br /&gt;
3D03H  ANA A                ; Test if server is TPDD    &lt;br /&gt;
3D04H  RZ                   ; Return if not NADSBox or TPDD2 &lt;br /&gt;
3D05H  DCR A                ; Test if TPDD2    &lt;br /&gt;
3D06H  JZ 37BAH             ; Go Swap TPDD Bank Number if TPDD2       &lt;br /&gt;
3D09H  CALL 4A3BH           ; Must be NADSBOx Initialize blank filename         &lt;br /&gt;
3D0CH  LXI H,3F61H          ; Load pointer to &amp;quot;Directory name:&amp;quot; text          &lt;br /&gt;
3D0FH  CALL 3E1AH           ; Get 6-byte input filename from keyboard         &lt;br /&gt;
3D12H  RZ                   ; Return if no input given &lt;br /&gt;
3D13H  CALL 4902H           ; Copy filename at (HL) to current BASIC program         &lt;br /&gt;
3D16H  LXI H,FC93H          ; Filename of current BASIC program              &lt;br /&gt;
3D19H  LXI D,FCE8H          ; Point to TX buffer data area (payload)          &lt;br /&gt;
3D1CH  LXI B,0006H          ; Prepare to copy 6 filename bytes to TX buffer          &lt;br /&gt;
3D1FH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment         &lt;br /&gt;
3D22H  LXI H,3E3CH          ; Load code for &amp;quot;&amp;lt;&amp;gt;&amp;quot;          &lt;br /&gt;
3D25H  SHLD FCEFH           ; Save &amp;quot;&amp;lt;&amp;gt;&amp;quot; extension bytes in TX buffer - NADSBox Mkdir                   &lt;br /&gt;
3D28H  MVI A,2EH            ; Load code for &#039;.&#039; extension separator        &lt;br /&gt;
3D2AH  STA FCEEH            ; Save &amp;quot;.&amp;quot; to TX buffer        &lt;br /&gt;
3D2DH  CALL 4943H           ; Configure baud, test for NADSBox, get NADSBox dir         &lt;br /&gt;
3D30H  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag        &lt;br /&gt;
3D33H  CPI 02H              ; Test if we have NADSBox current directory      &lt;br /&gt;
3D35H  RNZ                  ; Return if we don&#039;t have current directory  &lt;br /&gt;
3D36H  CALL 4A72H           ; Send Directory Reference opcode         &lt;br /&gt;
3D39H  JNZ 3D4DH            ; If the file exists, branch to open it for READ mode        &lt;br /&gt;
3D3CH  MVI A,01H            ; Load OPEN_WRITE mode into A to create the directory        &lt;br /&gt;
3D3EH  STA FCE8H            ; Save A in TX data storage mode field        &lt;br /&gt;
3D41H  LXI H,0101H          ; Load opcode to open a file          &lt;br /&gt;
3D44H  CALL 409BH           ; Send Request in HL and await response         &lt;br /&gt;
3D47H  LXI H,0002H          ; Load opcode to close the file          &lt;br /&gt;
3D4AH  JMP 409BH            ; Send Request in HL and await response        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Open and close a directory file (from above)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D4DH  CALL 408AH           ; Open TPDD file for Read Mode&lt;br /&gt;
3D50H  JMP 3D47H            ; Branch to close the directory open request&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F5 Function key handler for DISK mode - Format&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D53H  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag       &lt;br /&gt;
3D56H  CPI 02H              ; Test if we have &amp;quot;current directory&amp;quot; name     &lt;br /&gt;
3D58H  RZ                   ; Return if server is NADSBox / Desklink - No format supported&lt;br /&gt;
3D59H  LXI H,3F1BH          ; Load pointer to &amp;quot;Insert Disk&amp;quot; string&lt;br /&gt;
3D5CH  CALL 48F4H           ; Print string at HL to col 1 on the bottom line        &lt;br /&gt;
3D5FH  CALL 3DEEH           ; Get key from keyboard and test for &#039;Y&#039; or &#039;y&#039;        &lt;br /&gt;
3D62H  RNZ                  ; Return if response not &#039;Y&#039; &lt;br /&gt;
3D63H  CALL 4943H           ; Configure baud, test for NADSBox, get NADSBox dir        &lt;br /&gt;
3D66H  CALL 49E3H           ; Delay routine - about 3ms        &lt;br /&gt;
3D69H  LXI H,0006H          ; Load TPDD_FORMAT opcode in HL&lt;br /&gt;
3D6CH  CALL 409BH           ; Send Request in HL and await response        &lt;br /&gt;
3D6FH  MVI A,07H            ; Load code for BELL       &lt;br /&gt;
3D72H  RET		            ; Go beep to indicate format&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F2 Function key handler for DISK mode - Kill&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D73H  LDA FCCCH            ; Last Tag/Untag operation code      &lt;br /&gt;
3D76H  ANA A                ; Test if there&#039;s an active tag group&lt;br /&gt;
3D77H  CZ 3DE1H             ; Display &amp;quot;Sure ?&amp;quot;, validate and return if validated if no tag&lt;br /&gt;
3D7AH  CALL 4A3BH           ; Initialize blank filename and attribute byte&lt;br /&gt;
3D7DH  CALL 3D83H           ; Copy selected filename to TX buffer and init TPDD/NADSBox&lt;br /&gt;
3D80H  JMP 431AH            ; Issue TPDD Delete file Opcode            &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Copy selected filename to TX buffer and init TPDD/NADSBox&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D83H  LXI B,0009H          ; Prepare to copy 9 filename bytes&lt;br /&gt;
3D86H  LHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
3D89H  LXI D,FCE8H          ; Address of TX packet data&lt;br /&gt;
3D8CH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment&lt;br /&gt;
3D8FH  CALL 4943H           ; Configure baud, test for NADSBox, get NADSBox dir&lt;br /&gt;
3D92H  JMP 4A72H            ; Send Dir Reference opcode&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Copy filename at (HL) to TX buffer&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D95H  CALL 4902H           ; Copy filename at (HL) to current BASIC program&lt;br /&gt;
3D98H  LXI H,FC93H          ; Filename of current BASIC program&lt;br /&gt;
3D9BH  CALL 4A57H           ; Send Dir Reference for filename at (HL)&lt;br /&gt;
3D9EH  RET        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F3 Function key handler for DISK mode - Name&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D9FH  CALL 4A3BH           ; Initialize blank filename and attribute byte          &lt;br /&gt;
3DA2H  CALL 3D83H           ; Copy selected filename to TX buffer and init TPDD/NADSBox          &lt;br /&gt;
3DA5H  LXI H,FCE8H          ; Point to TX buffer data area (payload)&lt;br /&gt;
3DA8H  LXI D,FC9CH          ; Filename of last program loaded from tape  &lt;br /&gt;
3DABH  LXI B,0009H          ; Prepare to copy 9 bytes to &amp;quot;last program loaded&amp;quot; filename&lt;br /&gt;
3DAEH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment          &lt;br /&gt;
3DB1H  LHLD FD1DH           ; Get file size from RX buffer          &lt;br /&gt;
3DB4H  MOV C,H              ; Save file size MSB to C (swap endian)       &lt;br /&gt;
3DB5H  MOV B,L              ; Save file size LSB to B (swap endian)       &lt;br /&gt;
3DB6H  LXI H,7CC0H          ; ? Load HL with 31936&lt;br /&gt;
3DB9H  DSUB                 ; ? Compare file length with 31936    &lt;br /&gt;
3DBAH  LXI H,3F4AH          ; Address of &amp;quot;New name&amp;quot; string&lt;br /&gt;
3DBDH  JNZ 3DD7H            ; Branch to change filename if not 30656         &lt;br /&gt;
3DC0H  LXI B,0009H          ; Allow a 9-byte filename input string&lt;br /&gt;
3DC3H  CALL 3E1DH           ; Get max BC length input for filename and convert to uppercase          &lt;br /&gt;
3DC6H  RZ                   ; Return if no input provided  &lt;br /&gt;
3DC7H  PUSH H               ; Save pointer to input string to stack      &lt;br /&gt;
3DC8H  PUSH PSW             ; Save string length to stack        &lt;br /&gt;
3DC9H  CALL 4A3BH           ; Initialize blank filename and attribute byte          &lt;br /&gt;
3DCCH  POP PSW              ; Get string length from stack       &lt;br /&gt;
3DCDH  POP H                ; Get string address from stack     &lt;br /&gt;
3DCEH  LXI D,FCE8H          ; Point to TX buffer data area (payload)           &lt;br /&gt;
3DD1H  MOV C,A              ; Copy length to BC       &lt;br /&gt;
3DD2H  MVI B,00H            ; Make MSB of length = 0         &lt;br /&gt;
3DD4H  JMP 41B0H            ; Rename the TPDD file whose name is in (HL)         &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get filename from keyboard and rename Disk file, filename in &amp;quot;current BASIC program&amp;quot;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3DD7H  CALL 3E1AH           ; Get 6-byte input filename from keyboard&lt;br /&gt;
3DDAH  RZ                   ; Return if no input provided &lt;br /&gt;
3DDBH  CALL 4902H           ; Copy filename at (HL) to current BASIC program&lt;br /&gt;
3DDEH  JMP 41A7H            ; Rename the TPDD file whose name is in &amp;quot;current BASIC program&amp;quot; &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display &amp;quot;Sure ?&amp;quot;, validate and return if validated&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3DE1H  LXI H,3F83H          ; Load pointer to &amp;quot;Sure ?&amp;quot; string&lt;br /&gt;
3DE4H  CALL 48F4H           ; Print string at HL to col 1 on the bottom line &lt;br /&gt;
3DE7H  CALL 3DEEH           ; Get key and test for &#039;Y&#039; or &#039;y&#039; &lt;br /&gt;
3DEAH  JNZ 48B5H            ; Branch to &amp;quot;Long jump&amp;quot; operation to abort if not &#039;y&#039; &lt;br /&gt;
3DEDH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get key from keyboard and test for &#039;Y&#039; or &#039;y&#039;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3DEEH  CALL 3DF8H           ; Process power-off logic and wait for a key from keyboard&lt;br /&gt;
3DF1H  RST 4                ; Display the key on the LCD &lt;br /&gt;
3DF2H  CPI 59H              ; Test if key pressed was &#039;Y&#039;      &lt;br /&gt;
3DF4H  RZ                   ; Return if key pressed was &#039;Y&#039; &lt;br /&gt;
3DF5H  CPI 79H              ; Test if key pressed was &#039;y&#039;      &lt;br /&gt;
3DF7H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process power-off logic and wait for a key from keyboard&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3DF8H  CALL 3DFEH           ; Process automatic poweroff logic&lt;br /&gt;
3DFBH  JMP 4BEBH            ; Wait for key from keyboard&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process automatic power-off logic during key scan loop&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3DFEH  XRA A                ; Clear A  &lt;br /&gt;
3DFFH  DCR A                ; Set A to 0xFF   &lt;br /&gt;
3E00H  STA F656H            ; Power off exit condition switch  &lt;br /&gt;
3E03H  CALL 4C4AH           ; Check keyboard queue for pending characters&lt;br /&gt;
3E06H  JZ 3DFEH             ; Branch back if no keyboard characters in queue - wait for key&lt;br /&gt;
3E09H  XRA A                ; Clear A  &lt;br /&gt;
3E0AH  STA F656H            ; Power off exit condition switch  &lt;br /&gt;
3E0DH  LXI H,F932H          ; Load address of &amp;quot;Renew Automatic Poweroff Counter Flag&amp;quot;&lt;br /&gt;
3E10H  ORA M                ; Test if auto poweroff counter should be renewed&lt;br /&gt;
3E11H  JZ 4BF7H             ; Renew automatic power-off counter if enabled&lt;br /&gt;
3E14H  CALL 4BF3H           ; Turn off the computer&lt;br /&gt;
3E17H  JMP 3DFEH            ; Branch back to continue processing power off logic&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get max 6-byte input for filename and convert to uppercase&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E1AH  LXI B,0006H          ; Get maximum 6 characters of input&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get max BC length input for filename and convert to uppercase&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E1DH  CALL 3E2FH           ; Get max BC length input string from keyboard&lt;br /&gt;
3E20H  RZ                   ; Return if no input provided &lt;br /&gt;
3E21H  PUSH H               ; Preserve pointer to input string     &lt;br /&gt;
3E22H  PUSH PSW             ; Preserve flags from input       &lt;br /&gt;
3E23H  CALL 4C5EH           ; Get char at M and convert to uppercase&lt;br /&gt;
3E26H  MOV M,A              ; Save uppercase char back to string      &lt;br /&gt;
3E27H  INX H                ; Point to next byte in input     &lt;br /&gt;
3E28H  ANA A                ; Test for NULL - end of string    &lt;br /&gt;
3E29H  JNZ 3E23H            ; Keep looping until end of string        &lt;br /&gt;
3E2CH  POP PSW              ; Restore flags from input routine      &lt;br /&gt;
3E2DH  POP H                ; Restore pointer to input string    &lt;br /&gt;
3E2EH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get maximum BC length input character string from keyboard&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E2FH  PUSH B               ; Save maximum input length to stack     &lt;br /&gt;
3E30H  CALL 48F4H           ; Print string at HL to col 1 on the bottom line&lt;br /&gt;
3E33H  CALL 4C46H           ; Input and display (no &amp;quot;?&amp;quot;) line and store&lt;br /&gt;
3E36H  JC 48B5H             ; Branch to &amp;quot;Long jump&amp;quot; if CTRL-C       &lt;br /&gt;
3E39H  INX H                ; Point to start of input string    &lt;br /&gt;
3E3AH  MOV A,B              ; Get string length (counting NULL)      &lt;br /&gt;
3E3BH  DCR A                ; Remove NULL from count    &lt;br /&gt;
3E3CH  POP D                ; Restore maximum input length    &lt;br /&gt;
3E3DH  RZ                   ; Return if string length is zero &lt;br /&gt;
3E3EH  CMP E                ; Compare expected length with actual length    &lt;br /&gt;
3E3FH  RC                   ; Return if string is shorter than expected          &lt;br /&gt;
3E40H  PUSH H               ; Save pointer to start of string on stack     &lt;br /&gt;
3E41H  DAD D                ; Add Expected length to pointer    &lt;br /&gt;
3E42H  MVI M,00H            ; Truncate the string to the max length        &lt;br /&gt;
3E44H  POP H                ; Restore pointer to input string    &lt;br /&gt;
3E45H  MOV A,E              ; Update length to reflect maximum      &lt;br /&gt;
3E46H  ORA A                ; Clear zero flag to indicate input provided    &lt;br /&gt;
3E47H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Find Empty catalog entry (only 9 instructions...Don&#039;t bother with Main ROM)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E48H  LXI H,F9AFH         ; Point to the &amp;quot;RickY&amp;quot; catalog entry (start of valid entries)&lt;br /&gt;
3E4BH  LXI B,000BH         ; Load length of each catalog entry&lt;br /&gt;
3E4EH  DAD B               ; Point to next catalog entry to test if empty&lt;br /&gt;
3E4FH  MOV A,M             ; Get file attribute byte from catalog entry&lt;br /&gt;
3E50H  CPI FFH             ; Test if at end of catalog&lt;br /&gt;
3E52H  JZ 3E5AH            ; Jump to report directory full if at end&lt;br /&gt;
3E55H  ADD A               ; Test if MSB is set (entry being used)&lt;br /&gt;
3E56H  JC 3E4EH            ; Jump to test next enry if MSB set&lt;br /&gt;
3E59H  RET                 ; Entry found...return with Carry clear&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Empty catalog entry not found...set Carry and exit&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E5AH  STC                 ; Indicate empty entry not found&lt;br /&gt;
3E5BH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F5 Function key handler for RAM mode - DOS ON/OF&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E5CH  LHLD FB2CH          ; Get LFILES statement hook address&lt;br /&gt;
3E5FH  LXI B,08DBH         ; Load address of default (DOS-OFF) hook for LFILES&lt;br /&gt;
3E62H  DSUB                ; Test if in DOS-OFF mode&lt;br /&gt;
3E63H  JZ 401FH            ; Jump to add our custom RST 7 hooks if in DOS-OFF mode&lt;br /&gt;
3E66H  JMP 3FFAH           ; Must be in DOS-ON mode, jump to turn it off&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Strings&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E69H  DB	0x1B, &amp;quot;p TS-DOS (100 v4.00) (c)87,TSI.          &amp;quot;,0x1B,&#039;q&#039;,0x00&lt;br /&gt;
3E97H  DB   &amp;quot;DISK Free:         File:&amp;quot;,0DH,0AH,&amp;quot;Load Kill Name Ram  Frmt Log       Menu&amp;quot;,00H&lt;br /&gt;
3ED9H  DB   &amp;quot; RAM Free:         File:&amp;quot;,0DH,0AH,&amp;quot;Save Kill Name Disk DOS-           Menu&amp;quot;,00H&lt;br /&gt;
3F1BH  DB   &amp;quot;Insert Disk, Press \&amp;quot;Y\&amp;quot; to begin &amp;quot;,00H&lt;br /&gt;
3F3CH  DB   &amp;quot;NOT FORMATTED&amp;quot;,00H&lt;br /&gt;
3F4AH  DB   &amp;quot;New Name:&amp;quot;,00H&lt;br /&gt;
3F54H  DB   &amp;quot;System name:&amp;quot;,00H&lt;br /&gt;
3F61H  DB   &amp;quot;Directory name:&amp;quot;,00H&lt;br /&gt;
3F71H  DB   &amp;quot;Save as:&amp;quot;,00H&lt;br /&gt;
3F7AH  DB   &amp;quot;Load as:&amp;quot;,00H&lt;br /&gt;
3F83H  DB   &amp;quot;Sure ? &amp;quot;,00H&lt;br /&gt;
3F8BH  DB   &amp;quot;File exists, A)ppend R)eplace Q)uit:&amp;quot;,00H&lt;br /&gt;
3FB0H  DB   &amp;quot;File exists, Replace? (Y/N):&amp;quot;,00H&lt;br /&gt;
3FCDH  DB   &amp;quot;-.-       &amp;quot;,00H&lt;br /&gt;
3FD8H  DB   0x1B,&amp;quot;Y74    &amp;quot;,1BH,&amp;quot;Y7&amp;gt;MkDr&amp;quot;,00H     ;  TODO: Check this&lt;br /&gt;
3FE9H  DB   0x1B,&amp;quot;Y7&amp;gt;Bank&amp;quot;,00H                   ;  TODO: Check this&lt;br /&gt;
3FF2H  DB   &amp;quot;OFF&amp;quot;,00H&lt;br /&gt;
3FF6H  DB   &amp;quot;ON &amp;quot;,00H&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Navigate to:&lt;br /&gt;
* [[Dissasembly of RAM and ROM versions of TS-DOS]]&lt;br /&gt;
* [[M100 TS-DOS ROM OptROM Support]]&lt;br /&gt;
* [[M100 TS-DOS ROM RST 7 Handlers]]&lt;br /&gt;
* [[M100 TS-DOS ROM TPDD Protocol]]&lt;br /&gt;
* [[M100 TS-DOS ROM Compression]]&lt;br /&gt;
* [[M100 TS-DOS ROM Cold Boot Recovery]]&lt;/div&gt;</summary>
		<author><name>Kpettit</name></author>
	</entry>
	<entry>
		<id>https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_OptROM_Support&amp;diff=1380</id>
		<title>M100 TS-DOS ROM OptROM Support</title>
		<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_OptROM_Support&amp;diff=1380"/>
		<updated>2009-04-03T07:55:16Z</updated>

		<summary type="html">&lt;p&gt;Kpettit: /* TS-DOS Model 100/102 ROM OptROM Support */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== TS-DOS Model 100/102 ROM OptROM Support ==&lt;br /&gt;
&lt;br /&gt;
This code defines the variables used throughout the TS-DOS application as well as the support routines needed to navigate between the Main ROM and the Option ROM (most of them).  Also included is the TS-DOS startup code.  The assembly labels defined are open for discussion and have not been applied to any of the disassembled code yet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 =========================================================================================&lt;br /&gt;
; TS-DOS M100 ROM version Disassembly&lt;br /&gt;
;&lt;br /&gt;
; Initial Disassembly By Kenneth D. Pettit&lt;br /&gt;
; March, 2009&lt;br /&gt;
;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Variables in ALTLCD buffer&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
NB_CUR_DIR    equ FCC0H              ; NADSBox current directory (&amp;quot;MYFILE.&amp;lt;&amp;gt; &amp;quot;)&lt;br /&gt;
TPDD_BANK     equ FCCAH              ; TPDD2 Bank (side)&lt;br /&gt;
NB_TPDD_FLG   equ FCCBH              ; NADSBox/Desklink/TPDD2 flag (0=TPDD, 1=TPDD2, 2=NADSBox)&lt;br /&gt;
LAST_TAG      equ FCCCH              ; Tag/Untag last operation code&lt;br /&gt;
CUR_FILE      equ FCCDH              ; Currently selected file index on UI (1 based)&lt;br /&gt;
LJ_SP         equ FCCEH              ; Stack pointer upon entry for Long Jump&lt;br /&gt;
LJ_RET        equ FCD0H              ; Return vector for Long Jump &amp;quot;RETURN&amp;quot;&lt;br /&gt;
ERR_MODE      equ FCD2H              ; Print Error Messages flag, 1=Print, 0=Generate System Error&lt;br /&gt;
FDC_OPCODE    equ FCD3H              ; FDC Emulation mode opcode&lt;br /&gt;
CUR_PAGE      equ FCD4H              ; Current page of files being displayed (0 based)&lt;br /&gt;
TMP_FILE_IDX  equ FCD5H              ; Currently selected file index on UI - temp&lt;br /&gt;
FILE_COUNT    equ FCD6H              ; Count of files currently displayed on LCD&lt;br /&gt;
MAX_FILES     equ FCD7H              ; Maximum files that fit on the LCD&lt;br /&gt;
DISP_MODE     equ FCD9H              ; RAM / Disk Display mode (0=RAM,  1=DISK)&lt;br /&gt;
SKIP_PAGE     equ FCDAH              ; TPDD &amp;quot;skip page&amp;quot; count (number of pages to read and discard)&lt;br /&gt;
FILE_LEN      equ FCDBH              ; Pointer to &amp;quot;Current file&amp;quot; length bytes (in keyboard buffer)&lt;br /&gt;
PHYS_SCTR     equ FCDDH              ; FDC Emulation Physical Sector Number / Active File Length LSB&lt;br /&gt;
LOG_SCTR      equ FCDEH              ; FDC Emulation Logical Sector Number / Active File Length MSB&lt;br /&gt;
KEY_TYPE      equ FCDFH              ; Storage for FDC emulation / New file type code / Keypress storage&lt;br /&gt;
FILE_ADDR     equ FCE0H              ; Address of file being displayed/printed/loaded/saved&lt;br /&gt;
FILE_BUFF     equ FCE2H              ; Pointer for TPDD direct read data / address of file being read/written&lt;br /&gt;
TX_PKT_BUF    equ FCE6H              ; Storage for TX packets (28 bytes)&lt;br /&gt;
RX_PKT_BUF    equ FD02H              ; Storage for RX packets (130 bytes ??)&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Main Entry point when called from &amp;quot;CALL 63013,1&amp;quot;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
   &lt;br /&gt;
   .org 0000H&lt;br /&gt;
&lt;br /&gt;
0000H  JMP 00B2H            ; Jump to entry point handler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Pop registers after we power back up from a powerdown (I think)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0003H  POP H&lt;br /&gt;
0004H  POP D&lt;br /&gt;
0005H  POP B&lt;br /&gt;
0006H  POP PSW&lt;br /&gt;
0007H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 1 - Call Main ROM at location whose address follows RST 1 opcode&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0008H  (C3H) JMP 0080H      ; BASIC statement keyword table END to NEW&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 2 - Call Main ROM&#039;s RST 2 routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0010H  (CFH) RST 1          ; Call main ROM at address in following 2 bytes&lt;br /&gt;
0011H  DW    0010H          ; Call the Main ROM&#039;s RST 2 function&lt;br /&gt;
0013H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 3 routine - Compare HL and DE&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0018H  JMP 006CH            ; Jump to comparison routine&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Return to Main ROM.  After issuing the OUT E0H, we will be in Main ROM.  The next opcode&lt;br /&gt;
; in Main ROM after this OUT statement occurs will be a RET (part of RST 1).  We have &lt;br /&gt;
; PUSHed a return address to the stack, so the main ROM&#039;s RET instruction will get us &lt;br /&gt;
; where to intend to go.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
001BH  OUT E0H              ; Send A to the ROM bank port to switch to Main ROM&lt;br /&gt;
001DH  RET                  ; Should never execute this instruction, but just in case&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Send a space to the screen/printer - Not called from anywhere.  Copy of Main ROM.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
001EH  (3EH) MVI A,20H      ; Prepare to print a SPACE&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 3 routine - Send character in A to the screen / printer&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0020H  (CFH) RST 1          ; Call main ROM at address in following 2 bytes&lt;br /&gt;
0021H  DW    0020H          ; Main ROM&#039;s RST 3 routine&lt;br /&gt;
0023H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Power down TRAP.  Let Main ROM deal with it.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0024H  DI                   ; Disable interrupts while we jump   &lt;br /&gt;
0025H  CALL 0097H           ; Jump to Main ROM&#039;s RST handler for this vector &lt;br /&gt;
0028H  POP H      &lt;br /&gt;
0029H  JMP 0003H            ; Pop regs after we power back up from a power-down? &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Hardware Interrupt - Let Main ROM deal with it - Bar Code Reader&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
002CH  DI                   ; Disable interrupts while we jump  &lt;br /&gt;
002DH  CALL 0097H           ; Jump to Main ROM&#039;s RST handler for this vector&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Return from Main ROM hook in RAM returns here via RST 6&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0030H  POP PSW              ; Cleanup stack&lt;br /&gt;
0031H  POP PSW              ; Cleanup stack&lt;br /&gt;
0032H  RET                  ; Return to OptROM execution point        &lt;br /&gt;
&lt;br /&gt;
0033H  NOP                  ; Filler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Hardware Interrupt - Let Main ROM deal with it - RS232 character pending&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0034H  DI                   ; Disable interrupts while we jump&lt;br /&gt;
0035H  CALL 0097H           ; Jump to Main ROM&#039;s RST handler for this vector&lt;br /&gt;
0038H  JMP 00A6H            ; Stack cleanup&lt;br /&gt;
&lt;br /&gt;
003BH  NOP                  ; UNUSED - filler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Hardware Interrupt - Let Main ROM deal with it - Timer background task&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
003CH  DI                   ; Disable interrupts&lt;br /&gt;
003DH  CALL 0097H           ; Jump to Main ROM&#039;s RST handler for this vector&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; This routine gets copied to RAM to be used for switching back to the TS-DOS ROM after&lt;br /&gt;
;      calling a routine in the Main ROM.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0040H  PUSH PSW             ; Preserve the PSW&lt;br /&gt;
0041H  LDA FF45H            ; Contents of port E8H&lt;br /&gt;
0044H  INR A                ; Prepare to switch to OptRom&lt;br /&gt;
0045H  OUT E0H              ; Switch to OptRom&lt;br /&gt;
0047H  RST 6                ; Get sign of FAC1&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; This routine gets copied to RAM and appears to detect the presence of the TS-DOS ROM&lt;br /&gt;
;       after power-up and copies the original &amp;quot;External ROM&amp;quot; detection routine to RAM&lt;br /&gt;
;       if the TS-DOS ROM is no longer present.  At least I think that&#039;s what it&#039;s doing.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0048H  LXI D,F605H          ; Copy address for &amp;quot;Ext ROM detect&amp;quot; routine&lt;br /&gt;
004BH  INR A                ; Set bit to enable OptROM&lt;br /&gt;
004CH  OUT E0H              ; Switch to OptROM&lt;br /&gt;
004EH  XRA A                ; Prepare to switch back to Main ROM&lt;br /&gt;
004FH  LHLD 0049H           ; Load target address of the LXI D instruction above&lt;br /&gt;
0052H  OUT E0H              ; Switch back to Main ROM&lt;br /&gt;
0054H  RST 3                ; Compare DE and HL - Test if OptROM is TS-DOS&lt;br /&gt;
0055H  CPI 01H              ; Test for TS-DOS ROM&lt;br /&gt;
0057H  RC                   ; Return if TS-DOS ROM&lt;br /&gt;
0058H  LXI H,111DH          ; Load &amp;quot;Return&amp;quot; address to the CALL below&lt;br /&gt;
005BH  SHLD FAE0H&lt;br /&gt;
005EH  SHLD F5F2H           ; Save a &amp;quot;Restart signature&amp;quot; ???&lt;br /&gt;
0061H  CALL 2905H           ; Copy the DB number of bytes from the DW address to (DE)&lt;br /&gt;
0064H  DB   24H             ; ....copy 24H bytes&lt;br /&gt;
0065H  DW   036FH           ; ....from ROM addres 036F (external ROM detect)&lt;br /&gt;
0067H  RST 0                ; I&#039;m not sure it it every actually returns here or not&lt;br /&gt;
0068H  NOP&lt;br /&gt;
0069H  CALL FAA4H           ; Call our installed RAM hook to return to TS-DOS&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Compare HL and DE - called by the RST 3 routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
006CH  MOV A,H              ; Move H into A for comparison&lt;br /&gt;
006DH  SUB D                ; Compare MSB first&lt;br /&gt;
006EH  RNZ                  ; Return if no match&lt;br /&gt;
006FH  MOV A,L              ; Now move L into A&lt;br /&gt;
0070H  SUB E                ; Compare LSB&lt;br /&gt;
0071H  RET                  ; Return with flags set&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Copy 8 bytes from DE to HL &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0072H  LXI B,0008H          ; Prepare to copy 8 bytes &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Copy BC bytes from DE to HL &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0075H  LDAX D               ; Load value from (DE)&lt;br /&gt;
0076H  MOV M,A              ; Save value to (HL)&lt;br /&gt;
0077H  INX D                ; Increment DE&lt;br /&gt;
0078H  INX H                ; Increment HL&lt;br /&gt;
0079H  DCX B                ; Decrement counter&lt;br /&gt;
007AH  MOV A,B              ; Prepare to test counter for zero&lt;br /&gt;
007BH  ORA C                ; Test counter for zero&lt;br /&gt;
007CH  JNZ 0075H            ; Keep looping until 8 bytes copied&lt;br /&gt;
007FH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle the RST 1 routine.  Read the Main ROM address from the 2 bytes after the RST 1&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0080H  SHLD F9B2H           ; Save HL off in &amp;quot;RickY&amp;quot; Cat entry so we don&#039;t clobber it&lt;br /&gt;
0083H  POP H                ; Get out return address (location of the ROM address to call&lt;br /&gt;
0084H  PUSH D               ; Push the return address back to the stack as storage &lt;br /&gt;
0085H  MOV E,M              ; Get LSB of the ROM address to call&lt;br /&gt;
0086H  INX H                ; Point to MSB of ROM address to call&lt;br /&gt;
0087H  MOV D,M              ; Get MSB of the ROM address to call&lt;br /&gt;
0088H  INX H                ; Point to return address after the RST 1 DB address&lt;br /&gt;
0089H  XTHL                 ; Put the return address on the stack so we return after the RST 1&lt;br /&gt;
008AH  XCHG                 ; Now get the address within ROM to call&lt;br /&gt;
008BH  PUSH H               ; Push the target ROM address to the stack so we &amp;quot;RETurn&amp;quot; there&lt;br /&gt;
008CH  LXI H,FAA4H          ; Load address of our RAM hook to switch back to our ROM bank and RET&lt;br /&gt;
008FH  XTHL                 ; Push that address on the stack for after the ROM call is complete&lt;br /&gt;
0090H  PUSH H               ; Now put the ROM address back on the stack so we will RET there&lt;br /&gt;
0091H  LHLD F9B2H           ; Restore HL from temp storage in &amp;quot;RickY&amp;quot;&lt;br /&gt;
0094H  JMP 00A6H            ; Branch to switch to Main ROM and &amp;quot;RET&amp;quot; to the address we pushed&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST handler for calling the Main ROM&#039;s RST handlers.  This routine restores the original&lt;br /&gt;
;      RST vector address to the stack, and jumps to the Main ROM&#039;s RST routine while &lt;br /&gt;
;      preserving all register values.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0097H  SHLD F9B4H           ; Save HL temporarily (somewhere in RickY&#039;s name)&lt;br /&gt;
009AH  LXI H,FAA4H          ; Point to our RAM hook for returning to TS-DOS&lt;br /&gt;
009DH  XTHL                 ; Put the hook address as the return address on the stack&lt;br /&gt;
009EH  DCX H                ; Decrement the return address by 4&lt;br /&gt;
009FH  DCX H                ; ...this will result in the starting address of the RST&lt;br /&gt;
00A0H  DCX H                ; ...that brought us here&lt;br /&gt;
00A1H  DCX H&lt;br /&gt;
00A2H  PUSH H               ; Push the RST vector address to the stack&lt;br /&gt;
00A3H  LHLD F9B4H           ; Restore HL upon entry&lt;br /&gt;
00A6H  PUSH PSW             ; Save A to the stack&lt;br /&gt;
00A7H  PUSH H               ; Save the HL to the stack so we can preserve through XTHL&lt;br /&gt;
00A8H  LXI H,1488H          ; Load a RETurn address in the Main ROM (a POP PSW &amp;amp; RET) &lt;br /&gt;
00ABH  XTHL                 ; Push the address and get HL back&lt;br /&gt;
00ACH  LDA FF45H            ; Contents of port E8H - prepare for jump to Main ROM&lt;br /&gt;
00AFH  JMP 001BH            ; Jump to Main ROM &amp;amp; our custom &amp;quot;RET&amp;quot; address in the ROM&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Manual invocation entry point.  This is where we jump when &amp;quot;CALL 63013,1&amp;quot; is invoked&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
00B2H  DI                   ; Disable interrupts so nobody bugs us yet&lt;br /&gt;
00B3H  CPI 08H              ; Check the invocation parameter to test for recovery request&lt;br /&gt;
00B5H  JNC 0100H            ; Jump to test for recovery mode&lt;br /&gt;
00B8H  MOV B,A              ; Save the calling paramter to B&lt;br /&gt;
00B9H  PUSH B               ; Save BC to the stack&lt;br /&gt;
00BAH  PUSH D               ; Save DE to the stack&lt;br /&gt;
00BBH  PUSH H               ; Save HL to the stack&lt;br /&gt;
00BCH  LXI D,0040H          ; Load address of our &amp;quot;Change to OptROM&amp;quot; routine&lt;br /&gt;
00BFH  LXI H,FAA4H          ; Load pointer to somewhere in RAM to hold our routine&lt;br /&gt;
00C2H  CALL 0072H           ; Copy 8 bytes from DE to HL &lt;br /&gt;
00C5H  LXI B,0024H          ; Now prepare to copy 36 bytes worth of &amp;quot;routine&amp;quot;&lt;br /&gt;
00C8H  LXI H,F605H          ; Point to another RAM location&lt;br /&gt;
00CBH  CALL 0075H           ; Copy the next &amp;quot;ROM Bank Switching&amp;quot; routine from our ROM&lt;br /&gt;
00CEH  POP H                ; Restore HL&lt;br /&gt;
00CFH  POP D                ; Restore DE&lt;br /&gt;
00D0H  POP PSW              ; Restore A&lt;br /&gt;
00D1H  EI                   ; Allow interrupts again&lt;br /&gt;
00D2H  JMP 0100H            ; Go test if a &amp;quot;Cold Start&amp;quot; recovery is being requested&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    .org 100H&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test if cold-start recovery requested&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0100H  MOV A,H              ; Move H to A to test HL for zero&lt;br /&gt;
0101H  ORA L                ; Test for zero&lt;br /&gt;
0102H  JZ 7000H             ; Call recovery routine if requested&lt;br /&gt;
0105H  POP H                ; Pop the return address.  We will exit manually&lt;br /&gt;
0106H  CALL 0117H           ; Ensure the TS-DOS progam is installed in the MENU&lt;br /&gt;
0109H  JMP 3535H            ; Jump to the TS-DOS UI&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Move BC bytes from (HL) to (DE) with increment&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
010CH  MOV A,M              ; Get next byte from (HL)&lt;br /&gt;
010DH  STAX D               ; Save byte in (DE)&lt;br /&gt;
010EH  INX H                ; Increment source pointer&lt;br /&gt;
010FH  INX D                ; Increment destination pointer&lt;br /&gt;
0110H  DCX B                ; Decrement loop control&lt;br /&gt;
0111H  MOV A,B              ; Move MSB to A to test for zero&lt;br /&gt;
0112H  ORA C                ; OR in LSB to test for zero&lt;br /&gt;
0113H  JNZ 010CH            ; Branch to copy next byte until done&lt;br /&gt;
0116H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Insert the &amp;quot;TS-DOS&amp;quot; invocation program (BASIC program) into the Catalog / MENU.&lt;br /&gt;
;    we always insert ourselves at the lowest RAM address.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0117H  LXI H,01E1H          ; Point to &amp;quot;TS-DOS&amp;quot; catalog entry in our ROM&lt;br /&gt;
011AH  PUSH H               ; Save the address on the stack for later&lt;br /&gt;
011BH  INX H                ; Point to the text portion of the catalog entry&lt;br /&gt;
011CH  LXI B,0008H          ; Prepare to copy 8 filename byte&lt;br /&gt;
011FH  LXI D,FC93H          ; Filename of current BASIC program&lt;br /&gt;
0122H  CALL 010CH           ; Copy BC bytes from HL to DE - put &amp;quot;TS-DOS  &amp;quot; in cur. BASIC prog.&lt;br /&gt;
0125H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  DE now has the address of the invocation program&lt;br /&gt;
0126H  LHLX                 ; Get the length of the BASIC program into HL&lt;br /&gt;
0127H  SHLD FCC4H           ; Save the BASIC program length in the ALTLCD buffer for now&lt;br /&gt;
012AH  INX D                ; Point to MSB of the length&lt;br /&gt;
012BH  INX D                ; Point to LSB of the pointer to the &amp;quot;Next&amp;quot; BASIC instruction&lt;br /&gt;
012CH  XCHG                 ; HL &amp;lt;--&amp;gt; DE HL has the pointer to the &amp;quot;Next&amp;quot; BASIC inst address&lt;br /&gt;
012DH  SHLD FCC8H           ; Save the &amp;quot;Next&amp;quot; BASIC inst pointer to ALTLCD (start of program)&lt;br /&gt;
0130H  CALL 01D1H           ; Update the System pointers&lt;br /&gt;
0133H  CALL 01CDH           ; Search Catalog for entry matching current BASIC program&lt;br /&gt;
0136H  POP B                ; Pop address in case we return&lt;br /&gt;
0137H  RNZ                  ; Return if &amp;quot;TS-DOS&amp;quot; is already in the catalog&lt;br /&gt;
0138H  LHLD F99AH           ; Get the BASIC program not saved pointer - insert before that&lt;br /&gt;
013BH  SHLD FCC2H           ; Save storage location for the TS-DOS invocation progam&lt;br /&gt;
013EH  LDAX B               ; Load the file type byte from our ROM (B has the address from above)&lt;br /&gt;
013FH  STA FCC6H            ; Store the Type byte in the ALTLCD &lt;br /&gt;
0142H  CALL 0185H           ; Find empty entry in Catalog&lt;br /&gt;
0145H  RC                   ; Return if catalog full&lt;br /&gt;
0146H  PUSH H               ; Save the address of the empty catalog entry to the stack&lt;br /&gt;
0147H  LHLD FCC4H           ; Restore the BASIC program length from ALTLCD&lt;br /&gt;
014AH  MOV B,H              ; Move BASIC program length to BC for copy&lt;br /&gt;
014BH  MOV C,L              ; Move LSB of length&lt;br /&gt;
014CH  PUSH B               ; Save Length to the stack&lt;br /&gt;
014DH  LHLD FCC2H           ; Get address of insertion for TS-DOS just before the unsaved BASIC prog.&lt;br /&gt;
0150H  CALL 01DDH           ; Call Main ROM&#039;s Insert BC spaces at M routine&lt;br /&gt;
0153H  JC 0182H             ; Abort if RAM full&lt;br /&gt;
0156H  LHLD FCC2H           ; Get address of insertion point again&lt;br /&gt;
0159H  XCHG                 ; DE now has insertion point for BASIC program&lt;br /&gt;
015AH  LHLD FCC8H           ; Get the address of the BASIC program (in our ROM) from ALTLCD&lt;br /&gt;
015DH  POP B                ; Restore copy length of the BASIC program&lt;br /&gt;
015EH  CALL 010CH           ; Move BC bytes from (HL) to (DE) with increment&lt;br /&gt;
0161H  POP D                ; Get the address of the empty catalog entry we will use for TS-DOS&lt;br /&gt;
0162H  PUSH D               ; Save it back to the stack&lt;br /&gt;
0163H  LHLD FBAEH           ; Load the start of DO files pointer&lt;br /&gt;
0166H  DCX H                ; Derement the start of DO files pointer&lt;br /&gt;
0167H  SHLD F99AH           ; Save it as the new BASIC program not saved pointer&lt;br /&gt;
016AH  INX H                ; Point to start of DO files again&lt;br /&gt;
016BH  XCHG                 ; Move it to DE&lt;br /&gt;
016CH  LHLD FCC4H           ; Load the TS-DOS BASIC progam length from ALTLCD&lt;br /&gt;
016FH  DAD D                ; Offset the start of DO files by the insertion amount&lt;br /&gt;
0170H  SHLD FBAEH           ; Save the new start of DO files pointer&lt;br /&gt;
0173H  POP D                ; Restore the address of the empty catalog entry&lt;br /&gt;
0174H  LHLD FCC2H           ; Get the starting address of the newly inserted TS-DOS program&lt;br /&gt;
0177H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  Swap for the call to the catalog insertion routine &lt;br /&gt;
0178H  LDA FCC6H            ; Load A with the file type byte&lt;br /&gt;
017BH  CALL 01D5H           ; Save current BASIC program to the Catalog entry at HL&lt;br /&gt;
017EH  CALL 01D1H           ; Update system pointers&lt;br /&gt;
0181H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Insert &amp;quot;TS-DOS&amp;quot; RAM full abort routine ... stack cleanup.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0182H  POP H                ; Pop the BASIC program length from the stack&lt;br /&gt;
0183H  POP H                ; Pop the catalog entry address from the stack&lt;br /&gt;
0184H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Find an empty entry in the Catalog.  HL points to start of new entry&lt;br /&gt;
;     This routine appears again at address 3E48H&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0185H  LXI H,F9AFH          ; Point to &amp;quot;RickY&amp;quot; to start search at beginning of catalog&lt;br /&gt;
0188H  LXI B,000BH          ; Get length of each entry in the Catalog&lt;br /&gt;
018BH  DAD B                ; Point to next entry in the catalog&lt;br /&gt;
018CH  MOV A,M              ; Get the File Attribute byte from the catalog for this file&lt;br /&gt;
018DH  CPI FFH              ; Test if at end of the catalog&lt;br /&gt;
018FH  JZ 0197H             ; Jump to set Carry flag and exit if at end&lt;br /&gt;
0192H  ADD A                ; Test if MSB set (test if entry available)&lt;br /&gt;
0193H  JC 018BH             ; Branch to get next entry if this one is used&lt;br /&gt;
0196H  RET                  ; Return with Carry clear to indicate entry found&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Empty catalog entry not found in Catalog, set Carry and return&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0197H  STC                  ; Set the Carry flag - not found&lt;br /&gt;
0198H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Display function key line routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0199H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
019AH  DW    42A8H&lt;br /&gt;
019CH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Erase function key display routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
019DH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
019EH  DW    428AH&lt;br /&gt;
01A0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Set new function key table routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01A1H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01A2H  DW    5A7CH&lt;br /&gt;
01A4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Wait for key from keyboard routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01A5H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01A6H  DW    12CBH&lt;br /&gt;
01A8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Scan keyboard for character (CTRL-BREAK ==&amp;gt; CTRL-C) routine&lt;br /&gt;
;      This appears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01A9H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01AAH  DW    7242H&lt;br /&gt;
01ACH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Power Down routine&lt;br /&gt;
;      This appears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01ADH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01AEH  DW    13B5H&lt;br /&gt;
01B0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Renew automatic power-off counter routine&lt;br /&gt;
;      This apears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01B1H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01B2H  DW    1BB1H&lt;br /&gt;
01B4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s CLS statement routine&lt;br /&gt;
;      This apears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01B5H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01B6H  DW    4231H&lt;br /&gt;
01B8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Start inverse character mode routine&lt;br /&gt;
;      This appears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01B9H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01BAH  DW    4269H&lt;br /&gt;
01BCH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Cancel inverse video routine&lt;br /&gt;
;      This appears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01BDH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01BEH  DW    426EH&lt;br /&gt;
01C0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Check keyboard queue for pending characters routine&lt;br /&gt;
;      This appers later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01C1H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01C2H  DW    13DBH&lt;br /&gt;
01C4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Stop automatic scrolling routine&lt;br /&gt;
;      This appers later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01C5H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01C6H  DW    423FH&lt;br /&gt;
01C8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Reset vector routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01C9H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01CAH  DW    0000H&lt;br /&gt;
01CCH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Search Catalog for entry matching current BASIC program&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01CDH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01CEH  DW    20AFH&lt;br /&gt;
01D0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Update system pointers routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01D1H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01D2H  DW    2146H&lt;br /&gt;
01D4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s routine to save current BASIC program to the Catalog entry at HL&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01D5H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01D6H  DW    2239H&lt;br /&gt;
01D8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Not a valid entry into ROM and not called anywhere&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01D9H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01DAH  DW    5825H&lt;br /&gt;
01DCH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Insert BC spaces at M routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01DDH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01DEH  DB    6B6DH&lt;br /&gt;
01E0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; TS-DOS entry that will be inserted into the catalog for invoking TS-DOS&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01E1H  DB   80H             ; TS-DOS file type for catalog entry&lt;br /&gt;
01E2H  DB   &amp;quot;TS-DOS  &amp;quot;      ; TS-DOS Catalog name entry&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; BASIC program that will be inserted into RAM to launch TS-DOS from the MENU/Catalog entry&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01EAH  DB   0FH,00H,0EH,80H ; BASIC program length and pointer to &amp;quot;Next&amp;quot; BASIC instruction&lt;br /&gt;
01EDH  DB   0AH,00H,B9H     ; BASIC Line number &amp;quot;10&amp;quot; and BASIC token for CALL&lt;br /&gt;
01EFH  DB   &amp;quot;63013,1&amp;quot;       ; CALL argument &lt;br /&gt;
01F5H  DB   00H,00H         ; BASIC terminating zeros&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
End of disassembly for OptROM Support.&lt;br /&gt;
&lt;br /&gt;
Navigate to:&lt;br /&gt;
* [[Dissasembly of RAM and ROM versions of TS-DOS]]&lt;br /&gt;
* [[M100 TS-DOS ROM UI Code]]&lt;br /&gt;
* [[M100 TS-DOS ROM RST 7 Handlers]]&lt;br /&gt;
* [[M100 TS-DOS ROM TPDD Protocol]]&lt;br /&gt;
* [[M100 TS-DOS ROM Compression]]&lt;br /&gt;
* [[M100 TS-DOS ROM Cold Boot Recovery]]&lt;/div&gt;</summary>
		<author><name>Kpettit</name></author>
	</entry>
	<entry>
		<id>https://bitchin100.com/wiki/index.php?title=Disassembly_of_RAM_and_ROM_versions_of_TS-DOS&amp;diff=1379</id>
		<title>Disassembly of RAM and ROM versions of TS-DOS</title>
		<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=Disassembly_of_RAM_and_ROM_versions_of_TS-DOS&amp;diff=1379"/>
		<updated>2009-04-03T07:50:49Z</updated>

		<summary type="html">&lt;p&gt;Kpettit: /* Model 100/102 ROM Version */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== TS-DOS Dissassembly ==&lt;br /&gt;
&lt;br /&gt;
There are various version of TS-DOS for The Model 100/102, for T200 and for the PC-8201a.  Additionally each of these versions has a ROM and a RAM.  While the majority of the code is equivalent across the various incarnations of TS-DOS, there are some differences due to varying RS-232 hardware and to accomodate execution from OptROM vs. RAM.&lt;br /&gt;
&lt;br /&gt;
The goal of the disassembly is to create a fully commented source file that can be assembled and subsequently modified / enhanced for new functionality.  The disassembly is split into several sections to keep each page &amp;quot;relatively&amp;quot; short.  The disassembly currently will not assemble as it contains absolute addresses that must be converted into assembly labels, or deleted where not needed.&lt;br /&gt;
&lt;br /&gt;
== Model 100/102 ROM Version ==&lt;br /&gt;
* [[M100 TS-DOS ROM OptROM Support]]&lt;br /&gt;
* [[M100 TS-DOS ROM UI Code]]&lt;br /&gt;
* [[M100 TS-DOS ROM RST 7 Handlers]]&lt;br /&gt;
* [[M100 TS-DOS ROM TPDD Protocol]]&lt;br /&gt;
&lt;br /&gt;
Not Completed Yet&lt;br /&gt;
* [[M100 TS-DOS ROM Compression]]&lt;br /&gt;
* [[M100 TS-DOS ROM Cold Boot Recovery]]&lt;br /&gt;
&lt;br /&gt;
== Model 200 RAM Version ==&lt;br /&gt;
[[UI Code]]  [[FKey Handlers]]  [[RST 7 Handlers]]  [[TPDD Protocol]]&lt;/div&gt;</summary>
		<author><name>Kpettit</name></author>
	</entry>
	<entry>
		<id>https://bitchin100.com/wiki/index.php?title=Disassembly_of_RAM_and_ROM_versions_of_TS-DOS&amp;diff=1378</id>
		<title>Disassembly of RAM and ROM versions of TS-DOS</title>
		<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=Disassembly_of_RAM_and_ROM_versions_of_TS-DOS&amp;diff=1378"/>
		<updated>2009-04-03T07:49:59Z</updated>

		<summary type="html">&lt;p&gt;Kpettit: /* Model 100/102 ROM Version */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== TS-DOS Dissassembly ==&lt;br /&gt;
&lt;br /&gt;
There are various version of TS-DOS for The Model 100/102, for T200 and for the PC-8201a.  Additionally each of these versions has a ROM and a RAM.  While the majority of the code is equivalent across the various incarnations of TS-DOS, there are some differences due to varying RS-232 hardware and to accomodate execution from OptROM vs. RAM.&lt;br /&gt;
&lt;br /&gt;
The goal of the disassembly is to create a fully commented source file that can be assembled and subsequently modified / enhanced for new functionality.  The disassembly is split into several sections to keep each page &amp;quot;relatively&amp;quot; short.  The disassembly currently will not assemble as it contains absolute addresses that must be converted into assembly labels, or deleted where not needed.&lt;br /&gt;
&lt;br /&gt;
== Model 100/102 ROM Version ==&lt;br /&gt;
* [[M100 TS-DOS ROM OptROM Support]]&lt;br /&gt;
* [[M100 TS-DOS ROM UI Code]]&lt;br /&gt;
* [[M100 TS-DOS ROM FKey Handlers]]&lt;br /&gt;
* [[M100 TS-DOS ROM RST 7 Handlers]]&lt;br /&gt;
* [[M100 TS-DOS ROM TPDD Protocol]]&lt;br /&gt;
&lt;br /&gt;
Not Completed Yet&lt;br /&gt;
* [[M100 TS-DOS ROM Compression]]&lt;br /&gt;
* [[M100 TS-DOS ROM Cold Boot Recovery]]&lt;br /&gt;
&lt;br /&gt;
== Model 200 RAM Version ==&lt;br /&gt;
[[UI Code]]  [[FKey Handlers]]  [[RST 7 Handlers]]  [[TPDD Protocol]]&lt;/div&gt;</summary>
		<author><name>Kpettit</name></author>
	</entry>
	<entry>
		<id>https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_UI_Code&amp;diff=1377</id>
		<title>M100 TS-DOS ROM UI Code</title>
		<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_UI_Code&amp;diff=1377"/>
		<updated>2009-04-03T07:43:49Z</updated>

		<summary type="html">&lt;p&gt;Kpettit: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== TS-DOS Model 100/102 User Interface Code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; TS-DOS UI Entry location&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
 &lt;br /&gt;
    .org  3535H&lt;br /&gt;
&lt;br /&gt;
3535H  LXI H,FCC0H          ; Start of Alt LCD character buffer&lt;br /&gt;
3538H  MVI B,B4H            ; Prepare to clear 180 bytes from the ALTLCD buffer &lt;br /&gt;
353AH  XRA A                ; Prepare to clear the ALTLCD buffer&lt;br /&gt;
353BH  CALL 4A34H           ; Fill (HL) with B bytes of A        &lt;br /&gt;
353EH  LXI H,0000H          ; Prepare to get current stack pointer&lt;br /&gt;
3541H  DAD SP               ; Copy SP into HL&lt;br /&gt;
3542H  SHLD FCCEH           ; Stack pointer upon entry - pointer to arguments&lt;br /&gt;
3545H  MVI A,01H            ; Set flag to print error message to LCD - GUI mode&lt;br /&gt;
3547H  CALL 4A85H           ; Save the currently selected baud rate settings&lt;br /&gt;
354AH  XRA A                ; Zero A to clear our vars&lt;br /&gt;
354BH  STA FCD4H            ; Current Page of files being displayed&lt;br /&gt;
354EH  STA FCDAH            ; TPDD &amp;quot;skip page&amp;quot; count&lt;br /&gt;
3551H  STA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
3554H  STA FCCAH            ; TPDD2 Bank number&lt;br /&gt;
3557H  INR A                ; A = 1 to select 1st file on page&lt;br /&gt;
3558H  STA FCCDH            ; Currently selected file index&lt;br /&gt;
355BH  LXI H,3564H          ; Get pointer to main loop routine&lt;br /&gt;
355EH  SHLD FCD0H           ; Return vector after error&lt;br /&gt;
3561H  CALL 4C27H           ; CLS statement&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; UI Main loop&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3564H  CALL 4C5AH           ; Resume automatic scrolling&lt;br /&gt;
3567H  CALL 3611H           ; Print Copyright and files&lt;br /&gt;
356AH  LDA FCD5H            ; Load currently selected index from temp storage&lt;br /&gt;
356DH  STA FCCDH            ; Currently selected file index&lt;br /&gt;
3570H  CALL 362FH           ; Print length of selected file using inverse video&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Code will return here when a funtion key is pressed (except F4 &amp;amp; F6)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3573H  LXI H,48B5H          ; Get address of &amp;quot;Long jump&amp;quot;&lt;br /&gt;
3576H  PUSH H               ; Push &amp;quot;Long jump&amp;quot; address to stack&lt;br /&gt;
3577H  PUSH PSW             ; Save function key press to stack&lt;br /&gt;
3578H  CPI 02H              ; Test if function key is F5-F8 (Non file operation F Keys)&lt;br /&gt;
357AH  JNC 35B9H            ; Jump to Function key handler if F5-F8 (No tagging to process)&lt;br /&gt;
357DH  LDA FCCCH            ; Last Tag/Untag operation code&lt;br /&gt;
3580H  ANA A                ; Test if a tag operation was performed&lt;br /&gt;
3581H  JZ 35B9H             ; Jump to Function key handler if no tag operation performed&lt;br /&gt;
3584H  LDA FCD6H            ; Count of files on screen&lt;br /&gt;
3587H  MOV C,A              ; Save count of files for loop decrementing &lt;br /&gt;
3588H  INR C                ; Increment by 1 for loop bounding&lt;br /&gt;
3589H  MVI B,00H            ; Start with index zero on the LCD&lt;br /&gt;
358BH  PUSH B               ; Save the current index on the stack&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display next file&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
358CH  LDA FCCDH            ; Currently selected file index&lt;br /&gt;
358FH  STA FCD5H            ; Currently selected file index - temp&lt;br /&gt;
3592H  CALL 3AC4H           ; Print selected file using normal video&lt;br /&gt;
3595H  POP B                ; Restore index from stack&lt;br /&gt;
3596H  INR B                ; Increment to the next file index to display&lt;br /&gt;
3597H  DCR C                ; Decrement the loop control&lt;br /&gt;
3598H  JZ 48B5H             ; Branch to perform &amp;quot;Long Jump&amp;quot; if all files printed to LCD&lt;br /&gt;
359BH  MOV A,B              ; Get the index of the current file&lt;br /&gt;
359CH  STA FCD5H            ; Save in temporary &amp;quot;current file&amp;quot; area&lt;br /&gt;
359FH  STA FCCDH            ; Currently selected file index&lt;br /&gt;
35A2H  PUSH B               ; Push the value on the stack for the next iteration&lt;br /&gt;
35A3H  CALL 3AB2H           ; Print currently selected file using inverse video&lt;br /&gt;
35A6H  LHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
35A9H  DCX H                ; Decrement to the Tag area for the file&lt;br /&gt;
35AAH  MOV A,M              ; Get the file&#039;s Tag code&lt;br /&gt;
35ABH  CPI 3EH              ; Compare with &#039;&amp;gt;&#039;&lt;br /&gt;
35ADH  JNZ 358CH            ; Jump to process next file if not tagged&lt;br /&gt;
35B0H  POP B                ; Pop currently selected file value from stack&lt;br /&gt;
35B1H  POP PSW    &lt;br /&gt;
35B2H  LXI H,358CH          ; Return address to display the next file&lt;br /&gt;
35B5H  PUSH PSW             ; ? Stack trickery&lt;br /&gt;
35B6H  PUSH B               ; Save current file index to stack for use after a RET operation&lt;br /&gt;
35B7H  PUSH H               ; Setup &amp;quot;Display next file&amp;quot; as a return address for RET&lt;br /&gt;
35B8H  PUSH PSW             ; ? More stack trickery&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Function key handler - Disk mode and dispatch to RAM mode&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
35B9H  CALL 4C56H           ; Stop automatic scrolling&lt;br /&gt;
35BCH  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
35BFH  ORA A     &lt;br /&gt;
35C0H  JZ 35E2H             ; Branch if in RAM mode&lt;br /&gt;
35C3H  POP PSW   &lt;br /&gt;
35C4H  ANA A                ; Test for F1&lt;br /&gt;
35C5H  JZ 3B2EH             ; Branch to F1 handler for disk&lt;br /&gt;
35C8H  DCR A                ; Test for F2&lt;br /&gt;
35C9H  JZ 3D73H  &lt;br /&gt;
35CCH  DCR A                ; Test for F3&lt;br /&gt;
35CDH  JZ 3D9FH  &lt;br /&gt;
35D0H  DCR A                ; Skip F4 - handled at lower level&lt;br /&gt;
35D1H  DCR A                ; Test for F5&lt;br /&gt;
35D2H  JZ 3D53H  &lt;br /&gt;
35D5H  DCR A                ; Skip F6 - handled at lower level&lt;br /&gt;
35D6H  DCR A                ; Test for F7&lt;br /&gt;
35D7H  JZ 3D00H  &lt;br /&gt;
35DAH  DCR A                ; Test for F8&lt;br /&gt;
35DBH  POP H     &lt;br /&gt;
35DCH  JZ 35FEH             ; Jump to exit if F8&lt;br /&gt;
35DFH  JMP 3564H            ; Jump to main loop&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Function key handler - RAM mode&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
35E2H  POP PSW  &lt;br /&gt;
35E3H  ANA A                ; Test for F1 &lt;br /&gt;
35E4H  JZ 3C4BH &lt;br /&gt;
35E7H  DCR A                ; Test for F2&lt;br /&gt;
35E8H  JZ 3C2BH &lt;br /&gt;
35EBH  DCR A                ; Test for F3&lt;br /&gt;
35ECH  JZ 3AF8H &lt;br /&gt;
35EFH  DCR A                ; Skip F4 - handled at lower level&lt;br /&gt;
35F0H  DCR A                ; Test for F5&lt;br /&gt;
35F1H  JZ 3E5CH &lt;br /&gt;
35F4H  DCR A                ; Skip F6 - handled at lower level&lt;br /&gt;
35F5H  DCR A                ; Skip F7 - not defined for RAM&lt;br /&gt;
35F6H  DCR A                ; Test for F8&lt;br /&gt;
35F7H  POP H    &lt;br /&gt;
35F8H  JZ 35FEH             ; Jump to exit if F8&lt;br /&gt;
35FBH  JMP 3564H            ; Jump back to main loop&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; This is the UI exit routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
35FEH  CALL 4AC4H           ; Restore original baud settings&lt;br /&gt;
3601H  CALL 4BD7H           ; Wait for TX empty and Reset UART to accept mode bits&lt;br /&gt;
3604H  CALL 4C27H           ; CLS statement&lt;br /&gt;
3607H  CALL 4C5AH           ; Resume automatic scrolling&lt;br /&gt;
360AH  LXI H,0000H&lt;br /&gt;
360DH  PUSH H&lt;br /&gt;
360EH  JMP 00A6H            ; Exit TS-DOS&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print Copyright string and files&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3611H  LXI H,0101H          ; Goto top left corner&lt;br /&gt;
3614H  SHLD F639H           ; Cursor row (1-8)&lt;br /&gt;
3617H  LXI H,3E69H          ; Point to &amp;quot;TS-DOS&amp;quot; copyright string&lt;br /&gt;
361AH  CALL 4A2CH           ; Send buffer at M to screen&lt;br /&gt;
361DH  XRA A                ; Indicate no previous Tag/Untag operation&lt;br /&gt;
361EH  STA FCCCH            ; Last Tag/Untag operation code&lt;br /&gt;
3621H  MVI A,01H            ; Start with 1st file in list&lt;br /&gt;
3623H  STA FCD5H            ; Currently selected file index - temp&lt;br /&gt;
3626H  LXI H,0202H          ; Goto first file entry location&lt;br /&gt;
3629H  SHLD F639H           ; Cursor row (1-8)&lt;br /&gt;
362CH  JMP 383BH            ; Draw the display&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print length of selected file using inverse video&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
362FH  LDA FCCDH            ; Currently selected file index      &lt;br /&gt;
3632H  STA FCD5H            ; Currently selected file index - temp      &lt;br /&gt;
3635H  CALL 3AB2H           ; Print currently seleted file using inverse video       &lt;br /&gt;
3638H  LDA FCD5H            ; Currently selected file index - temp      &lt;br /&gt;
363BH  DCR A                ; Make index zero based for multiply x2  &lt;br /&gt;
363CH  STC                  ; Set Carry flag&lt;br /&gt;
363DH  CMC                  ; Compliment (clear) carry flag&lt;br /&gt;
363EH  RLC                  ; Rotate left circular &lt;br /&gt;
363FH  MOV E,A              ; E = File index * 2 to point to file length value    &lt;br /&gt;
3640H  MVI D,00H            ; Clear MSB of file length offset      &lt;br /&gt;
3642H  LXI H,F685H          ; Keyboard buffer - store file lengths        &lt;br /&gt;
3645H  DAD D                ; Add file lenght offset from beginning of keyboard buffer  &lt;br /&gt;
3646H  XCHG                 ; HL &amp;lt;--&amp;gt; DE Save file length address pointer in DE &lt;br /&gt;
3647H  LXI H,2307H          ; Load position of File Size area on LCD&lt;br /&gt;
364AH  SHLD F639H           ; Cursor row (1-8) &lt;br /&gt;
364DH  CALL 4C2BH           ; Erase from cursor to end of line&lt;br /&gt;
3650H  LHLX                 ; Load HL with file length &lt;br /&gt;
3651H  CALL 4C2FH           ; Start inverse character mode       &lt;br /&gt;
3654H  CALL 4C3EH           ; Print binary number in HL at current position       &lt;br /&gt;
3657H  CALL 4C33H           ; Cancel inverse character mode         &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Keyboard scan loop&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
365AH  CALL 3DFEH           ; Process automatic power off logic&lt;br /&gt;
365DH  CALL 4BEFH           ; Scan keyboard for character (CTRL-BREAK ==&amp;gt; CTRL-C)&lt;br /&gt;
3660H  JZ 365AH             ; Jump to scan keyboard again if no key pressed &lt;br /&gt;
3663H  JC 380CH             ; Jump to Function Key Handler if FKey &lt;br /&gt;
3666H  CPI 0DH              ; Test for CR&lt;br /&gt;
3668H  JZ 3722H   &lt;br /&gt;
366BH  CPI 17H              ; Test for Ctrl-Up key&lt;br /&gt;
366DH  JZ 37AAH   &lt;br /&gt;
3670H  CPI 14H              ; Test for Shift-Up key&lt;br /&gt;
3672H  JZ 3798H   &lt;br /&gt;
3675H  CPI 5DH              ; Test for &amp;quot;]&amp;quot; key&lt;br /&gt;
3677H  JZ 3798H   &lt;br /&gt;
367AH  CPI 3FH              ; Test for &amp;quot;?&amp;quot; key&lt;br /&gt;
367CH  JZ 3777H   &lt;br /&gt;
367FH  CPI 02H              ; Test for Shift-Down arrow key&lt;br /&gt;
3681H  JZ 3777H   &lt;br /&gt;
3684H  CPI 1EH              ; Test for up key&lt;br /&gt;
3686H  JZ 36EEH   &lt;br /&gt;
3689H  CPI 1FH              ; Test for down key&lt;br /&gt;
368BH  JZ 36FCH   &lt;br /&gt;
368EH  CPI 1DH              ; Test for &amp;quot;left arrow&amp;quot; key&lt;br /&gt;
3690H  JZ 36DDH   &lt;br /&gt;
3693H  CPI 1CH              ; Test for &amp;quot;Right arrow&amp;quot; key&lt;br /&gt;
3695H  JZ 36CAH   &lt;br /&gt;
3698H  CPI 20H              ; Test for space key &lt;br /&gt;
369AH  JZ 36CAH             ; Treat space the same as right arrow  &lt;br /&gt;
369DH  ANI DFH              ; Convert to Upper case &lt;br /&gt;
369FH  CPI 52H              ; Test for &#039;R&#039; character  &lt;br /&gt;
36A1H  JZ 3759H   &lt;br /&gt;
36A4H  CPI 54H              ; Test for &#039;T&#039; character &lt;br /&gt;
36A6H  JZ 37EEH   &lt;br /&gt;
36A9H  CPI 41H              ; Test for &amp;quot;A&amp;quot; key &lt;br /&gt;
36ABH  JZ 3715H   &lt;br /&gt;
36AEH  CPI 47H              ; Test for &amp;quot;G&amp;quot; key &lt;br /&gt;
36B0H  JZ 3715H   &lt;br /&gt;
36B3H  CPI 55H              ; Test for &amp;quot;U&amp;quot; key &lt;br /&gt;
36B5H  JZ 37AEH   &lt;br /&gt;
36B8H  CPI 44H              ; Test for &amp;quot;D&amp;quot; key &lt;br /&gt;
36BAH  JZ 39B9H   &lt;br /&gt;
36BDH  CPI 4CH              ; Test for &amp;quot;L&amp;quot; key &lt;br /&gt;
36BFH  JZ 39C2H   &lt;br /&gt;
36C2H  CPI 50H              ; Test for &amp;quot;P&amp;quot; key &lt;br /&gt;
36C4H  JZ 39C2H   &lt;br /&gt;
36C7H  JMP 365AH            ; Go scan keyboard again   &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Right Arrow key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
36CAH  MVI A,01H            ; Prepare to add 1 to selected file    &lt;br /&gt;
36CCH  LXI H,FCD5H          ; Currently selected file index - temp storage&lt;br /&gt;
36CFH  ADD M                ; Add 1 to the selected file index&lt;br /&gt;
36D0H  INX H                ; Point to file count on screen&lt;br /&gt;
36D1H  CMP M                ; Compare new index with screen file count&lt;br /&gt;
36D2H  JC 370AH             ; Jump to process new file if we didn&#039;t wrap   &lt;br /&gt;
36D5H  JZ 370AH             ; Jump to process new file if = file count   &lt;br /&gt;
36D8H  MVI A,01H            ; Wrap to the first file    &lt;br /&gt;
36DAH  JMP 370AH            ; Go process file 1 as the new selection    &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Left Arrow key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
36DDH  LDA FCD5H            ; Currently selected file index - temp storage&lt;br /&gt;
36E0H  DCR A                ; Move to next lowest file index&lt;br /&gt;
36E1H  JNZ 370AH            ; If no wrap, jump to process new selection&lt;br /&gt;
36E4H  LDA FCD6H            ; Count of files on screen&lt;br /&gt;
36E7H  ANA A                ; Ensure there is at least 1 file on the screen &lt;br /&gt;
36E8H  JZ 365AH             ; Jump to keyboard scan loop if no files on LCD&lt;br /&gt;
36EBH  JMP 370AH            ; Go process new selection as the max (wrap-around)&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Up Arrow key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
36EEH  LDA FCD5H            ; Currently selected file index - temp storage&lt;br /&gt;
36F1H  SUI 04H              ; Subtract 4 from file count (4 files per line)&lt;br /&gt;
36F3H  JC 365AH             ; Jump to keysacn loop if negative&lt;br /&gt;
36F6H  JZ 365AH             ; Jump to keysacn loop if zero&lt;br /&gt;
36F9H  JMP 370AH            ; Go process the new file index setting&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Down Arrow key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
36FCH  MVI A,04H            ; There are 4 files per line &lt;br /&gt;
36FEH  LXI H,FCD5H          ; Currently selected file index - temp storage&lt;br /&gt;
3701H  ADD M                ; Add 4 to the index number&lt;br /&gt;
3702H  MOV C,A              ; Save new index for comparison and further processing  &lt;br /&gt;
3703H  INX H                ; Maximum file index count&lt;br /&gt;
3704H  MOV A,M              ; Load maximum index for bounds  &lt;br /&gt;
3705H  CMP C                ; Compare new index with maximum&lt;br /&gt;
3706H  JC 365AH             ; Jump to keyboard scan if moving past last file   &lt;br /&gt;
3709H  MOV A,C              ; Restore new current file index  &lt;br /&gt;
370AH  PUSH PSW             ; Save new file index for storage after the call   &lt;br /&gt;
370BH  CALL 3AC4H           ; Print selected file using normal video     &lt;br /&gt;
370EH  POP PSW              ; Restore new file index from stack  &lt;br /&gt;
370FH  STA FCCDH            ; Save the new file index    &lt;br /&gt;
3712H  JMP 362FH            ; Print length of selected file using inverse video.    &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;A&amp;quot; or &amp;quot;G&amp;quot; key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3715H  MVI A,3EH            ; Load &amp;quot;&amp;gt;&amp;quot; for the tag symbol&lt;br /&gt;
3717H  CALL 37CAH           ; Go tag all files on the LCD&lt;br /&gt;
371AH  MVI A,01H            ; Indicate last operation as &amp;quot;Tag All&amp;quot;&lt;br /&gt;
371CH  STA FCCCH            ; Last Tag/Untag operation code&lt;br /&gt;
371FH  JMP 362FH            ; Print length of selected file using inverse video.&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Enter key from TS-DOS key scan - Change Directory&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3722H  LDA FCCBH            ; Get NADSBox/Desklink/TPDD2 flag     &lt;br /&gt;
3725H  CPI 02H              ; Test if NADSBox current directory valid   &lt;br /&gt;
3727H  JNZ 365AH            ; Back to keyscan if no &amp;quot;current directory&amp;quot; - Enter is meaningless     &lt;br /&gt;
372AH  LHLD FCE4H           ; LCD Buffer address of current file selection      &lt;br /&gt;
372DH  LXI B,0007H          ; Load offset of file extension       &lt;br /&gt;
3730H  DAD B                ; Point to file extension of selected file &lt;br /&gt;
3731H  MOV A,M              ; Load the 1st byte of the file extension   &lt;br /&gt;
3732H  CPI 3CH              ; Test if 1st byte of extension is &amp;quot;&amp;lt;&amp;quot;   &lt;br /&gt;
3734H  JNZ 365AH            ; Jump to keyscan if current selection not directory entry     &lt;br /&gt;
3737H  CALL 4A3BH           ; Initialize blank filename and attribute byte      &lt;br /&gt;
373AH  LHLD FCE4H           ; LCD Buffer address of current file selection      &lt;br /&gt;
373DH  CALL 3D95H           ; Copy filename at (HL) to TX buffer      &lt;br /&gt;
3740H  CALL 408AH           ; Open TPDD file for Read Mode      &lt;br /&gt;
3743H  LXI H,0002H          ; Load opcode to close currently opened file       &lt;br /&gt;
3746H  CALL 409BH           ; Send Request in HL and await response      &lt;br /&gt;
3749H  LHLD FCE4H           ; LCD Buffer address of current file selection      &lt;br /&gt;
374CH  LXI D,FCC0H          ; NADSBox current directory storage    &lt;br /&gt;
374FH  LXI B,0009H          ; Copy 9 bytes of NADSBox directory to the LCD       &lt;br /&gt;
3752H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
3755H  XRA A                ; Clear A to show 1st page of files &lt;br /&gt;
3756H  JMP 378AH            ; Branch to show the page of files in A     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;R&amp;quot; key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3759H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
375CH  ANA A                ; Test if in Disk mode&lt;br /&gt;
375DH  JNZ 362FH            ; Jump to keyscan if in Disk mode&lt;br /&gt;
3760H  LHLD FCE4H           ; LCD Buffer address of current file selection       &lt;br /&gt;
3763H  CALL 4902H           ; Copy filename at (HL) to current BASIC program&lt;br /&gt;
3766H  CALL 4A51H           ; Get RAM directory address of current BASIC program          &lt;br /&gt;
3769H  CPI C0H              ; Test if filetype is .DO&lt;br /&gt;
376BH  CZ 5000H             ; Call routine to Compress / Decompress .DO files&lt;br /&gt;
376EH  CALL 4C0FH           ; Update system pointers       &lt;br /&gt;
3771H  CALL 3611H           ; Print Copyright and files&lt;br /&gt;
3774H  JMP 362FH            ; Jump to keyscan &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;?&amp;quot; and Shift-Down key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3777H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
377AH  ANA A                ; Test if RAM mode &lt;br /&gt;
377BH  JZ 365AH             ; Branch to keyscan if in RAM mode    &lt;br /&gt;
377EH  LDA FCD6H            ; Count of files on screen     &lt;br /&gt;
3781H  CPI 14H              ; Maximum number of files that fit on the screen   &lt;br /&gt;
3783H  JC 365AH             ; Branch to keyscan if on last page    &lt;br /&gt;
3786H  LDA FCD4H            ; Current Page of files being displayed     &lt;br /&gt;
3789H  INR A                ; Increment to next page of files &lt;br /&gt;
				 &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Show the page of files indicated by A&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
378AH  STA FCD4H            ; Current Page of files being displayed     &lt;br /&gt;
378DH  MVI A,01H            ; Go to 1st file on the new page     &lt;br /&gt;
378FH  STA FCCDH            ; Currently selected file index     &lt;br /&gt;
3792H  CALL 3611H           ; Print copyright and files      &lt;br /&gt;
3795H  JMP 362FH            ; Print length of selected file using inverse video     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;]&amp;quot; and Shift-Up key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3798H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
379BH  ANA A                ; Test if RAM mode &lt;br /&gt;
379CH  JZ 365AH             ; Branch to keyscan if in RAM mode    &lt;br /&gt;
379FH  LDA FCD4H            ; Current Page of files being displayed     &lt;br /&gt;
37A2H  ANA A                ; Test if current page is zero &lt;br /&gt;
37A3H  JZ 365AH             ; Branch to keyscan if already on page 0    &lt;br /&gt;
37A6H  DCR A                ; Decrement the page number &lt;br /&gt;
37A7H  JMP 378AH            ; Show the page of files indicated by A&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Ctrl-Up key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
37AAH  XRA A                ; Go to page zero&lt;br /&gt;
37ABH  JMP 378AH            ; Show the page of files indicated by A&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;U&amp;quot; key from TS-DOS key scan - Remove all tags&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
37AEH  MVI A,20H            ; Display &#039; &#039; as the tag marker&lt;br /&gt;
37B0H  CALL 37CAH           ; Go process tag for all files&lt;br /&gt;
37B3H  XRA A                ; Indicate last tag operation was untag&lt;br /&gt;
37B4H  STA FCCCH            ; Store as &amp;quot;last tag&amp;quot; operation&lt;br /&gt;
37B7H  JMP 362FH            ; Print length of selected file using inverse video&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Swap TPDD2 Bank number&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
37BAH  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag&lt;br /&gt;
37BDH  DCR A                ; Test if the flag = 1 (TPDD2)&lt;br /&gt;
37BEH  JNZ 365AH            ; Jump to keyscan if not 1&lt;br /&gt;
37C1H  LDA FCCAH            ; Get TPDD Bank Number&lt;br /&gt;
37C4H  XRI 01H              ; Switch to the other bank&lt;br /&gt;
37C6H  STA FCCAH            ; Save TPDD bank number&lt;br /&gt;
37C9H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process Tag or Untag for all files on screen&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
37CAH  STA FCCCH            ; Store tag/untag code for later      &lt;br /&gt;
37CDH  LDA FCD6H            ; Get Maximum file count on screen      &lt;br /&gt;
37D0H  ANA A                ; Test for zero  &lt;br /&gt;
37D1H  RZ		            ; Return if no files on screen&lt;br /&gt;
37D2H  XRA A                ; Clear A  &lt;br /&gt;
37D3H  INR A                ; A=1 to selet 1st file  &lt;br /&gt;
37D4H  STA FCD5H            ; Currently selected file index      &lt;br /&gt;
37D7H  CALL 3ACDH           ; Calculate Row and Column of soon-to-be (newly) selected file       &lt;br /&gt;
37DAH  LHLD FCE4H           ; LCD Buffer address of current file selection       &lt;br /&gt;
37DDH  DCX H                ; Point to Tag location for the file  &lt;br /&gt;
37DEH  LDA FCCCH            ; Get the tag/untag code      &lt;br /&gt;
37E1H  RST 4                ; Display A to the LCD    &lt;br /&gt;
37E2H  LDA FCD5H            ; Get currently selected file index      &lt;br /&gt;
37E5H  LXI H,FCD6H          ; Point to count of files on screen        &lt;br /&gt;
37E8H  CMP M                ; Compare current selection with count of files on LCD  &lt;br /&gt;
37E9H  JC 37D3H             ; Jump to process next file if more files left     &lt;br /&gt;
37ECH  ANA A                ; Set zero flag to indicate files were tagged/untagged  &lt;br /&gt;
37EDH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;T&amp;quot; key key from TS-DOS key scan - TAG&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
37EEH  CALL 3ACDH           ; Calculate Row and Column of soon-to-be (newly) selected file    &lt;br /&gt;
37F1H  CALL 4C2FH           ; Start inverse character mode    &lt;br /&gt;
37F4H  LHLD FCE4H           ; LCD Buffer address of current file selection    &lt;br /&gt;
37F7H  DCX H	            ; Point to the &amp;quot;Tag&amp;quot; area for the file&lt;br /&gt;
37F8H  MVI A,3EH            ; Load the code for &amp;quot;&amp;gt;&amp;quot;   &lt;br /&gt;
37FAH  CMP M                ; Compare if file is already tagged     &lt;br /&gt;
37FBH  JNZ 3800H            ; Skip ahead if already tagged   &lt;br /&gt;
37FEH  MVI A,20H            ; Need to untag - load the untag code   &lt;br /&gt;
3800H  RST 4                ; Display the tag code on the LCD   &lt;br /&gt;
3801H  CALL 4C33H           ; Cancel inverse character mode    &lt;br /&gt;
3804H  LXI H,FCCCH          ; Point to &amp;quot;last tag&amp;quot; operation code     &lt;br /&gt;
3807H  MVI M,01H            ; Indicate last operation was &amp;quot;tag&amp;quot;   &lt;br /&gt;
3809H  JMP 36CAH            ; Move to next file - jump to Right Arrow key handler   &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; 1st level Function Key Handler (handles F4 and F6)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
380CH  CPI 08H              ; Test for valid function key code     &lt;br /&gt;
380EH  JNC 365AH            ; Branch back to scan loop if invalid       &lt;br /&gt;
3811H  CPI 05H              ; Test for F6     &lt;br /&gt;
3813H  JZ 3833H             ; Jump if F6 pressed      &lt;br /&gt;
3816H  CPI 03H              ; Test for F4     &lt;br /&gt;
3818H  RNZ                  ; Return to &amp;quot;Main Loop&amp;quot; if not F4 pressed &lt;br /&gt;
3819H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)       &lt;br /&gt;
381CH  XRI 01H              ; Swap RAM/DISK mode     &lt;br /&gt;
381EH  STA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)       &lt;br /&gt;
3821H  XRA A                ; Clear A to go to 1st page of files   &lt;br /&gt;
3822H  STA FCD4H            ; Current Page of files being displayed       &lt;br /&gt;
3825H  MVI A,01H            ; Select the 1st file in the page       &lt;br /&gt;
3827H  STA FCCDH            ; Currently selected file index       &lt;br /&gt;
382AH  CALL 4C27H           ; CLS statement     &lt;br /&gt;
382DH  CALL 3611H           ; Print the title bar and files        &lt;br /&gt;
3830H  JMP 362FH            ; Print length of selected file using inverse video.       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F6 Function Key Handler&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3833H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
3836H  ANA A                ; Test if in RAM or DISK mode&lt;br /&gt;
3837H  RZ                   ; Return if RAM mode&lt;br /&gt;
3838H  JMP 37AAH            ; Jump to Ctrl-Up key handler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Draw the display.  This takes care of RAM and Disk mode displays, handles&lt;br /&gt;
;    skipping page number to the proper &amp;quot;Disk&amp;quot; page, displaying the Bank# or&lt;br /&gt;
;    current directory for NADSBox/Desklink, showing free space, filling in&lt;br /&gt;
;    empty slots with &amp;quot;-.-&amp;quot;, etc.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
383BH  LXI H,F685H          ; Keyboard buffer  &lt;br /&gt;
383EH  SHLD FCDBH           ; Initialize pointer to file length table (in keyboard buffer)     &lt;br /&gt;
3841H  XRA A                ; Prepare to set 1st file lenght to zero&lt;br /&gt;
3842H  MOV M,A              ; Set LSB of length of 1st file to zero  &lt;br /&gt;
3843H  INX H                ; Increment to MSB of length&lt;br /&gt;
3844H  MOV M,A              ; Set MSB of length of file to zero  &lt;br /&gt;
3845H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)    &lt;br /&gt;
3848H  ANA A                ; Test if RAM or DISK&lt;br /&gt;
3849H  JZ 395DH             ; Jump to show RAM files if in RAM mode   &lt;br /&gt;
384CH  XRA A                ; Prepare to initialize the &amp;quot;page being processed&amp;quot; variable&lt;br /&gt;
384DH  STA FCDAH            ; Clear the &amp;quot;page being processed&amp;quot; variable    &lt;br /&gt;
3850H  CALL 4735H           ; Clear #files displayed, init TPDD and send 1st file dir referene opcode     &lt;br /&gt;
3853H  JNZ 390FH            ; Process unformated disk (empty slots and error message)    &lt;br /&gt;
3856H  LDA FCD4H            ; Current Page of files being displayed    &lt;br /&gt;
3859H  ANA A                ; Test if displaying page 0&lt;br /&gt;
385AH  JZ 3871H             ; Jump if showing page 0 - don&#039;t need to skikp any pages   &lt;br /&gt;
385DH  STA FCDAH            ; Initialize the number of pages left to skip count    &lt;br /&gt;
3860H  CALL 4742H           ; Read next page of files from server     &lt;br /&gt;
3863H  LDA FCDAH            ; Get the &amp;quot;Pages left to skip&amp;quot; count    &lt;br /&gt;
3866H  DCR A                ; Decrement the remaining skip page count &lt;br /&gt;
3867H  JNZ 385DH            ; Keep reading pages until we have skipped enough pages     &lt;br /&gt;
386AH  XRA A                ; Prepare to clear the remaining skip page count &lt;br /&gt;
386BH  STA FCDAH            ; Clear the remaining skip page count     &lt;br /&gt;
386EH  STA FCD6H            ; Count of files on screen     &lt;br /&gt;
3871H  CALL 4742H           ; Read next page of files from server      &lt;br /&gt;
3874H  LDA FCD6H            ; Count of files on screen     &lt;br /&gt;
3877H  CPI 14H              ; Test if all file slots are full   &lt;br /&gt;
3879H  CC 39AAH             ; Print &amp;quot;-.-&amp;quot; for all empty file slots (if any)    &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print NADSBox directory or TPDD Bank number to LCD&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
387CH  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag    &lt;br /&gt;
387FH  ANA A                ; Test if server is TPDD&lt;br /&gt;
3880H  JZ 389FH             ; Skip processing Bank # or Current Dir if TPDD   &lt;br /&gt;
3883H  DCR A                ; Test if server is TPDD2&lt;br /&gt;
3884H  JZ 388DH             ; Jump to print bank number if TPDD2   &lt;br /&gt;
3887H  LXI H,FCC0H          ; Load pointer to NADSBox current directory storage    &lt;br /&gt;
388AH  JMP 38A5H            ; Jump to print the NADSBox / Desklink directory    &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print the TPDD Bank number to LCD&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
388DH  LXI H,2401H          ; Go to Row 1, column 24&lt;br /&gt;
3890H  SHLD F639H           ; Cursor row (1-8) &lt;br /&gt;
3893H  CALL 4C2FH           ; Start inverse character mode &lt;br /&gt;
3896H  MVI A,23H            ; ASCII code for &#039;#&#039; &lt;br /&gt;
3898H  RST 4                ; Send character in A to the LCD&lt;br /&gt;
3899H  LDA FCCAH            ; Load TPDD Bank number &lt;br /&gt;
389CH  ADI 30H              ; Convert to ASCII digit   &lt;br /&gt;
389EH  RST 4                ; Send it to the LCD  &lt;br /&gt;
389FH  CALL 4C33H           ; Cancel inverse character mode&lt;br /&gt;
38A2H  JMP 38B8H            ; Branch to print the function menu, RAM/Disk free, etc.&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print the NADSBox / Desklink current directory in title bar&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
38A5H  PUSH H               ; Save address of the directory string     &lt;br /&gt;
38A6H  LXI H,2101H          ; Prepare to position the cursor in the title bar          &lt;br /&gt;
38A9H  SHLD F639H           ; Cursor row (1-8)         &lt;br /&gt;
38ACH  CALL 4C2FH           ; Start inverse character mode         &lt;br /&gt;
38AFH  POP H                ; Retrieve the directory string from the stack    &lt;br /&gt;
38B0H  MVI C,06H            ; Prepare to redraw 6 chars with inverse video        &lt;br /&gt;
38B2H  CALL 48E5H           ; Redraw C characters from buffer at HL using current video mode         &lt;br /&gt;
38B5H  CALL 4C33H           ; Cancel inverse character mode         &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print funtion menu, RAM/Disk free &amp;amp; selected file length&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
38B8H  LXI H,3E97H          ; Point to Disk function menu          &lt;br /&gt;
38BBH  LXI B,3936H          ; Routine to print free disk space          &lt;br /&gt;
38BEH  LDA FCD9H            ; RAM/Disk mode        &lt;br /&gt;
38C1H  ANA A                ; Test if in Disk mode and skip ahead to print Disk FKeys    &lt;br /&gt;
38C2H  JNZ 38CBH            ; Skip ahead if in disk mode to keep vectors        &lt;br /&gt;
38C5H  LXI H,3ED9H          ; Point to RAM function menu          &lt;br /&gt;
38C8H  LXI B,3922H          ; Routine to print free RAM space          &lt;br /&gt;
38CBH  PUSH B               ; Save routine address to stack     &lt;br /&gt;
38CCH  PUSH H               ; Save pointer to function text to stack     &lt;br /&gt;
38CDH  LDA FCCDH            ; Currently selected file index        &lt;br /&gt;
38D0H  LXI H,FCD6H          ; Count of files on screen          &lt;br /&gt;
38D3H  CMP M                ; Compare selected file with count of files on screen    &lt;br /&gt;
38D4H  JC 38DDH             ; Branch if within bounds       &lt;br /&gt;
38D7H  MOV A,M              ; Get the file count      &lt;br /&gt;
38D8H  ANA A                ; Test if #files = 0    &lt;br /&gt;
38D9H  JNZ 38DDH            ; Skip ahead if not zero        &lt;br /&gt;
38DCH  INR A                ; Don&#039;t allow a count of zero - must be 1    &lt;br /&gt;
38DDH  STA FCD5H            ; Currently selected file index - temp       &lt;br /&gt;
38E0H  LXI H,0B07H          ; Row &amp;amp; column of start of text          &lt;br /&gt;
38E3H  SHLD F639H           ; Cursor row (1-8)          &lt;br /&gt;
38E6H  POP H                ; Get address of text from the stack and display it   &lt;br /&gt;
38E7H  CALL 4A2CH           ; Send buffer at M to screen        &lt;br /&gt;
38EAH  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)       &lt;br /&gt;
38EDH  ANA A                ; Test if in RAM mode   &lt;br /&gt;
38EEH  JZ 3905H             ; Jump if in RAM mode (0 = RAM)       &lt;br /&gt;
38F1H  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag   &lt;br /&gt;
38F4H  ANA A                ; Test if server is TPDD      &lt;br /&gt;
38F5H  JZ 3905H             ; Skip printing of &amp;quot;Bank&amp;quot; or &amp;quot;Mkdr&amp;quot; if TPDD       &lt;br /&gt;
38F8H  LXI H,3FE9H          ; Point to text for &amp;quot;Bank&amp;quot;     &lt;br /&gt;
38FBH  DCR A                ; Test if server is TPDD2      &lt;br /&gt;
38FCH  JZ 3902H             ; Jump to print &amp;quot;Bank&amp;quot; if TPDD2         &lt;br /&gt;
38FFH  LXI H,3FD8H          ; Point to text for &amp;quot;Mkdr&amp;quot;        &lt;br /&gt;
3902H  CALL 4A2CH           ; Send buffer at M to screen                  &lt;br /&gt;
3905H  CALL 3940H           ; Display DISK ON/OFF status on LCD         &lt;br /&gt;
3908H  LXI H,1507H          ; Point to location for &amp;quot;Free&amp;quot; space (RAM or DISK)&lt;br /&gt;
390BH  SHLD F639H           ; Cursor row (1-8)          &lt;br /&gt;
390EH  RET                  &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle unformatted disks.  Print message and show empty slots.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
390FH  XRA A                ; Starting with slot zero...&lt;br /&gt;
3910H  CALL 39AAH           ; Print &amp;quot;-.-&amp;quot; for all empty file slots&lt;br /&gt;
3913H  LXI H,3E97H          ; Point to Disk Function menu string&lt;br /&gt;
3916H  LXI B,391CH          ; Print NOT FORMATTED to the display&lt;br /&gt;
3919H  JMP 38CBH            ; Go process the print and jump to error handler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print &amp;quot;NOT FORMATTED&amp;quot; on the LCD and return&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
391CH  LXI H,`H             ; Point to &amp;quot;NOT FORMATTED&amp;quot; string&lt;br /&gt;
391FH  JMP 4A2CH            ; Send buffer at M to screen&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print RAM free space at current posiiton&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3922H  LHLD FBB2H           ; Start of variable data pointer  &lt;br /&gt;
3925H  XCHG                 ; HL &amp;lt;--&amp;gt; DE&lt;br /&gt;
3926H  LHLD F678H           ; BASIC string buffer pointer  &lt;br /&gt;
3929H  MOV A,L              ; Prepare for 16 bit subtract   &lt;br /&gt;
392AH  SUB E                ; Subtract LSB &lt;br /&gt;
392BH  MOV L,A              ; Save LSB of difference for printing   &lt;br /&gt;
392CH  MOV A,H              ; Prepare for subtrating MSB   &lt;br /&gt;
392DH  SBB D                ; Subtract MSB &lt;br /&gt;
392EH  MOV H,A              ; Save in H for printing   &lt;br /&gt;
392FH  LXI B,FFF2H          ; Load signed number -14       &lt;br /&gt;
3932H  DAD B                ; Subtract 14 from free memory &lt;br /&gt;
3933H  JMP 4C3EH            ; Print binary number in HL at current position     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display free space on disk&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3936H  CALL 4A10H           ; Calculate free space on disk&lt;br /&gt;
3939H  CALL 4C3EH           ; Print binary number in HL at current position&lt;br /&gt;
393CH  MVI A,30H            ; Prepare to add an extra &#039;0&#039; since calc is /10&lt;br /&gt;
393EH  RST 4                ; Send A to the LCD      &lt;br /&gt;
393FH  RET       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display DISK ON/OFF status on LCD&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3940H  LDA FCD9H            ; DISK/RAM mode (0=RAM, 1=DISK)       &lt;br /&gt;
3943H  ANA A                ; Test if in RAM mode   &lt;br /&gt;
3944H  RNZ                  ; Return if not in RAM mode  &lt;br /&gt;
3945H  LDA FB2CH            ; DISK-OFF/ON status   &lt;br /&gt;
3948H  LXI D,3FF2H          ; Load pointer to &amp;quot;OFF&amp;quot; text         &lt;br /&gt;
394BH  CPI DBH              ; Test if DISK mode (vector LSB) indicates ON or OFF     &lt;br /&gt;
394DH  JZ 3953H             ; Branch if in DISK-OFF mode      &lt;br /&gt;
3950H  LXI D,3FF6H          ; Load pointer to &amp;quot;ON&amp;quot; text         &lt;br /&gt;
3953H  LXI H,1908H          ; Location of DISK-OFF/ON indication on LCD         &lt;br /&gt;
3956H  SHLD F639H           ; Cursor row (1-8)   &lt;br /&gt;
3959H  XCHG                 ; HL = pointer to text in DE  &lt;br /&gt;
395AH  JMP 4A2CH            ; Send buffer at M to screen       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display RAM files to LCD and calculate file lengths&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
395DH  LXI H,F9BAH          ; Load pointer to 1st available file slot in catalog&lt;br /&gt;
3960H  XRA A                ; Set count of RAM files on screen to zero &lt;br /&gt;
3961H  STA FCD6H            ; Count of files on screen     &lt;br /&gt;
3964H  MVI A,14H            ; Get max # files that will fit on LCD     &lt;br /&gt;
3966H  DCR A                ; Decrement the max file count &lt;br /&gt;
3967H  PUSH PSW             ; Save count to the stack    &lt;br /&gt;
3968H  MOV A,M              ; Get file type   &lt;br /&gt;
3969H  XRI 80H              ; Compliment ?active bit   &lt;br /&gt;
396BH  ANI 9FH              ; Test if file is active and should be displayed   &lt;br /&gt;
396DH  JNZ 3996H            ; Branch to test next file if not displayed     &lt;br /&gt;
3970H  PUSH H               ; Save address of current catalog file  &lt;br /&gt;
3971H  INX H                ; Point to file address &lt;br /&gt;
3972H  MOV E,M              ; Get LSB of file address   &lt;br /&gt;
3973H  INX H                ; Point to MSB of address &lt;br /&gt;
3974H  MOV D,M              ; Get MSB of file address   &lt;br /&gt;
3975H  XTHL                 ; HL &amp;lt;--&amp;gt; (SP)  Get address of file within catalog&lt;br /&gt;
3976H  PUSH H               ; Push pointer to MSB of address on stack  &lt;br /&gt;
3977H  CALL 3CD3H           ; Calculate length of RAM file      &lt;br /&gt;
397AH  XCHG                 ; HL &amp;lt;--&amp;gt; DE DE has the length&lt;br /&gt;
397BH  CALL 4791H           ; Store next file length to keyboard buffer      &lt;br /&gt;
397EH  POP H                ; Get catalog address of current file from stack &lt;br /&gt;
397FH  XTHL                 ; HL &amp;lt;--&amp;gt; (SP) swap catalog address with pointer to MSB of file address&lt;br /&gt;
3980H  INX H                ; Increment to filename &lt;br /&gt;
3981H  MVI C,06H            ; Prepare to print 6 characters of filename     &lt;br /&gt;
3983H  CALL 48E5H           ; Redraw C characters from buffer at HL using current video mode       &lt;br /&gt;
3986H  MVI A,2EH            ; Load code for &#039;.&#039;      &lt;br /&gt;
3988H  RST 4                ; Send A to the LCD                &lt;br /&gt;
3989H  MVI C,02H            ; Prepare to print 2 ext bytes to LCD      &lt;br /&gt;
398BH  CALL 48E5H           ; Redraw C characters from buffer at HL using current video mode       &lt;br /&gt;
398EH  MVI A,20H            ; Load code for space      &lt;br /&gt;
3990H  RST 4                ; Send A to the LCD           &lt;br /&gt;
3991H  LXI H,FCD6H          ; Count of files on screen        &lt;br /&gt;
3994H  INR M                ; Increment number of files displayed on LCD  &lt;br /&gt;
3995H  POP H                ; Get catalog address of file from stack  &lt;br /&gt;
3996H  LXI D,000BH          ; Load offset to next file locaion in catalog        &lt;br /&gt;
3999H  DAD D                ; Offset HL to next file  &lt;br /&gt;
399AH  POP PSW              ; Restore the file count from the stack    &lt;br /&gt;
399BH  DCR A                ; Decrement the max file count on the LCD  &lt;br /&gt;
399CH  JNZ 3967H            ; Branch to test and display next file until zero      &lt;br /&gt;
399FH  LDA FCD6H            ; Get the count of files actually displayed on screen              &lt;br /&gt;
39A2H  CPI 14H              ; Test if max number of files displayed    &lt;br /&gt;
39A4H  CC 39AAH             ; Branch to display &amp;quot;-.-&amp;quot; for remaining empty slots if not max     &lt;br /&gt;
39A7H  JMP 387CH            ; Print NADSBox directory or TPDD Bank number to LCD      &lt;br /&gt;
				  &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print &amp;quot;-.-&amp;quot; for all empty file slots&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
39AAH  PUSH PSW             ; Save current file index count on stack &lt;br /&gt;
39ABH  LXI H,3FCDH          ; Point to &amp;quot;-.-&amp;quot; text&lt;br /&gt;
39AEH  CALL 4A2CH           ; Send buffer at M to screen &lt;br /&gt;
39B1H  POP PSW              ; Restore current count &lt;br /&gt;
39B2H  INR A                ; Increment file index number&lt;br /&gt;
39B3H  CPI 14H              ; Compare A with max files that fit on LCD&lt;br /&gt;
39B5H  JNZ 39AAH            ; Jump to print next &amp;quot;-.-&amp;quot; if not done&lt;br /&gt;
39B8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;D&amp;quot; key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
39B9H  CALL 3AA8H           ; Test if printer busy.  Return if not busy or error&lt;br /&gt;
39BCH  CALL 4C52H           ; LCOPY statement&lt;br /&gt;
39BFH  JMP 362FH            ; Print length of selected file using inverse video.&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;L&amp;quot;, &amp;quot;P&amp;quot; and &amp;quot;O&amp;quot; keys from TS-DOS key scan - list or print .DO file contents&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
39C2H  STA FCDFH            ; Save key pressed       &lt;br /&gt;
39C5H  LXI D,0007H          ; Load offset of Extension bytes         &lt;br /&gt;
39C8H  LHLD FCE4H           ; LCD Buffer address of current file selection        &lt;br /&gt;
39CBH  DAD D                ; Point to extension bytes in LCD buffer   &lt;br /&gt;
39CCH  MOV A,M              ; Get 1st extension byte     &lt;br /&gt;
39CDH  CPI 44H              ; Compare byte with &amp;quot;D&amp;quot;     &lt;br /&gt;
39CFH  JNZ 362FH            ; Print length of selected file using inverse video if not &amp;quot;D&amp;quot;       &lt;br /&gt;
39D2H  INX H                ; Point to 2nd extension byte  &lt;br /&gt;
39D3H  MOV A,M              ; Load 2nd extension byte for comparison&lt;br /&gt;
39D4H  CPI 4FH              ; Compare with &amp;quot;0&amp;quot;&lt;br /&gt;
39D6H  JNZ 3A06H            ; Jump to print compressed file&lt;br /&gt;
39D9H  CALL 3A49H           ; Prepare file for reading (open disk file, address of RAM file)        &lt;br /&gt;
39DCH  LDA FCDFH            ; Restore key pressed       &lt;br /&gt;
39DFH  CPI 4CH              ; Test if key was &amp;quot;L&amp;quot; - List to LCD     &lt;br /&gt;
39E1H  CZ 4C27H             ; CLS statement if LCD      &lt;br /&gt;
39E4H  CNZ 3AA8H            ; Test if printer busy.  Return if not busy or error       &lt;br /&gt;
39E7H  CALL 3A24H           ; Get next block of data to display/print (HL=address)        &lt;br /&gt;
39EAH  PUSH PSW             ; Push Z flag indicating if a full 128 bytes was read      &lt;br /&gt;
39EBH  CALL 3A6BH           ; Display / print file data bytes at HL, A has length                 &lt;br /&gt;
39EEH  POP PSW              ; Get Z flag indicating if 128 bytes read     &lt;br /&gt;
39EFH  JZ 39E7H             ; Jump to process more if 128 bytes were read last time      &lt;br /&gt;
39F2H  LDA FCDFH            ; Restore key pressed       &lt;br /&gt;
39F5H  CPI 4CH              ; Test if key was &amp;quot;L&amp;quot;              &lt;br /&gt;
39F7H  JNZ 3A00H            ; Skip beep if printing       &lt;br /&gt;
39FAH  MVI A,07H            ; Load code for BELL       &lt;br /&gt;
39FCH  RST 4                ; Go print a BELL (beep)    &lt;br /&gt;
39FDH  CALL 3DF8H           ; Process power-off logic and wait for a key from keyboard        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Clear screen and perform Long Jump&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3A00H  CALL 4C27H           ; CLS statement         &lt;br /&gt;
3A03H  JMP 48B5H            ; Branch to &amp;quot;Long Jump&amp;quot; operation        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handler for the &amp;quot;O&amp;quot; key - print a compressed file?? &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3A06H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
3A09H  ANA A                ; Test if in Disk mode &lt;br /&gt;
3A0AH  JNZ 362FH            ; Jump to keyscan if in Disk mode&lt;br /&gt;
3A0DH  LHLD FCE4H           ; LCD Buffer address of current file selection      &lt;br /&gt;
3A10H  CALL 4902H           ; Copy filename at (HL) to current BASIC program&lt;br /&gt;
3A13H  CALL 4A51H           ; Get RAM directory address of current BASIC program&lt;br /&gt;
3A16H  CPI C0H              ; Test if filetype is .DO&lt;br /&gt;
3A18H  CZ 5004H             ; Call routine to Compress / Decompress .DO files&lt;br /&gt;
3A1BH  CALL 4C0FH           ; Update system pointers       &lt;br /&gt;
3A1EH  CALL 3611H           ; Print Copyright and files&lt;br /&gt;
3A21H  JMP 362FH            ; Jump to keyscan &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get next 128 bytes (or less) of data from RAM or disk file for display&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3A24H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)      &lt;br /&gt;
3A27H  ANA A                ; Test if RAM mode  &lt;br /&gt;
3A28H  JNZ 40B6H            ; If not RAM mode, go send TPDD_READ data opcode and recieve response      &lt;br /&gt;
3A2BH  LHLD FCDDH           ; Get length of file to be displayed / printed       &lt;br /&gt;
3A2EH  LXI B,0080H          ; Prepare to subtract 128 from length&lt;br /&gt;
3A31H  MOV A,C              ; Save 128 to A    &lt;br /&gt;
3A32H  DSUB                 ; Subtract 128 from file length &lt;br /&gt;
3A33H  JNC 3A3AH            ; Branch if length &amp;gt;= 128      &lt;br /&gt;
3A36H  DAD B                ; Add 128 back to length to print &amp;quot;partial&amp;quot; buffer  &lt;br /&gt;
3A37H  MOV A,L              ; Move remainder of bytes to display/print    &lt;br /&gt;
3A38H  MOV L,H              ; Clear LSB of remainder    &lt;br /&gt;
3A39H  MOV C,A              ; Move LSB of remainder to C    &lt;br /&gt;
3A3AH  SHLD FCDDH           ; Save new remaining file length       &lt;br /&gt;
3A3DH  LHLD FCE0H           ; Load the address to be printed / saved       &lt;br /&gt;
3A40H  PUSH H               ; Save on stack    &lt;br /&gt;
3A41H  DAD B                ; Update address to be used for display/printing next time  &lt;br /&gt;
3A42H  SHLD FCE0H           ; Save address to be displayed / printed       &lt;br /&gt;
3A45H  POP H                ; Retrieve address to be printed this loop from stack  &lt;br /&gt;
3A46H  CPI 80H              ; Compare length with maximum    &lt;br /&gt;
3A48H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Initialize Selected file for display (RAM or Disk)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3A49H  CALL 4A3BH           ; Initialize blank filename and attribute byte&lt;br /&gt;
3A4CH  LHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
3A4FH  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)     &lt;br /&gt;
3A52H  ANA A                ; Test if in RAM mode &lt;br /&gt;
3A53H  JNZ 3A65H            ; Branch to process Disk files if in Disk mode     &lt;br /&gt;
3A56H  CALL 4A4BH           ; Get RAM directory address of selected file&lt;br /&gt;
3A59H  PUSH D               ; Push file address to stack  &lt;br /&gt;
3A5AH  CALL 3CD3H           ; Calculate length of RAM file, HL=address of catalog entry, DE=file address&lt;br /&gt;
3A5DH  SHLD FCDDH           ; Save length to FDC emulation sector storage area&lt;br /&gt;
3A60H  POP H                ; Pop address of file into H &lt;br /&gt;
3A61H  SHLD FCE0H           ; Save file address&lt;br /&gt;
3A64H  RET		 &lt;br /&gt;
				 &lt;br /&gt;
; =====================================================================================&lt;br /&gt;
; Send TPDD Open command to open selected file&lt;br /&gt;
; =====================================================================================&lt;br /&gt;
3A65H  CALL 3D95H           ; Copy filename at (HL) to TX buffer&lt;br /&gt;
3A68H  JMP 408AH            ; Open TPDD file for Read Mode&lt;br /&gt;
&lt;br /&gt;
; =====================================================================================&lt;br /&gt;
; Display / print file data bytes at HL, A has length&lt;br /&gt;
; =====================================================================================&lt;br /&gt;
3A6BH  XCHG                 ; HL &amp;lt;--&amp;gt; DE  &lt;br /&gt;
3A6CH  ORA A                ; Test if length = 0   &lt;br /&gt;
3A6DH  RZ                   ; Return if length = 0&lt;br /&gt;
3A6EH  MOV C,A              ; Save length count in C     &lt;br /&gt;
3A6FH  LDA FCDFH            ; Load key press value       &lt;br /&gt;
3A72H  CPI 4CH              ; Test if key was &amp;quot;L&amp;quot;     &lt;br /&gt;
3A74H  JNZ 3A82H            ; Jump to print contents if not &amp;quot;L&amp;quot;       &lt;br /&gt;
3A77H  CALL 3A8FH           ; Check for CTRL-C&lt;br /&gt;
3A7AH  LDAX D               ; Load next byte from src pointer    &lt;br /&gt;
3A7BH  RST 4                ; Send A to LCD           &lt;br /&gt;
3A7CH  INX D                ; Increment the pointer   &lt;br /&gt;
3A7DH  DCR C                ; Decrement the length count   &lt;br /&gt;
3A7EH  JNZ 3A77H            ; Keep looping until all data displayed       &lt;br /&gt;
3A81H  RET        &lt;br /&gt;
&lt;br /&gt;
; =====================================================================================&lt;br /&gt;
; Print file data bytes at HL, A has length&lt;br /&gt;
; =====================================================================================&lt;br /&gt;
3A82H  CALL 3A8FH           ; Test for CTRL-C, etc.&lt;br /&gt;
3A85H  LDAX D               ; Load next file byte from source poiner &lt;br /&gt;
3A86H  CALL 4C42H           ; Print A to printer, expanding tabs if necessary&lt;br /&gt;
3A89H  INX D                ; Increment pointer&lt;br /&gt;
3A8AH  DCR C                ; Decrement length count&lt;br /&gt;
3A8BH  JNZ 3A82H            ; Keep looping until all data printed    &lt;br /&gt;
3A8EH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test for ESC, CTRL-C or Space&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3A8FH  CALL 4C4AH           ; Check keyboard queue for pending characters&lt;br /&gt;
3A92H  RZ                   ; Return if no pending characters&lt;br /&gt;
3A93H  CALL 4BEBH           ; Wait for key from keyboard&lt;br /&gt;
3A96H  CPI 03H              ; Test for F4 maybe?  &lt;br /&gt;
3A98H  JZ 3A00H             ; Clear screen and perform Long Jump if F4 maybe?   &lt;br /&gt;
3A9BH  CPI 1BH              ; Test for ESC key  &lt;br /&gt;
3A9DH  JZ 3A00H             ; Clear screen and perform Long Jump if ESC   &lt;br /&gt;
3AA0H  CPI 20H              ; Test for space key  &lt;br /&gt;
3AA2H  JNZ 3A8FH            ; Branch back to wait for ESC, CTRL-C or space if not space    &lt;br /&gt;
3AA5H  JMP 4BEBH            ; Wait for key from keyboard    &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test if printer busy.  Return if not busy, print error if it is&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3AA8H  IN BBH               ; Get printer port input     &lt;br /&gt;
3AAAH  ANI 06H              ; Mask all but BUSY and /BUSY      &lt;br /&gt;
3AACH  XRI 02H              ; Compliment /BUSY      &lt;br /&gt;
3AAEH  JNZ 487BH            ; Printer not ready / FF error        &lt;br /&gt;
3AB1H  RET        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print currently selected file using inverse video&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3AB2H  CALL 3ACDH           ; Calculate Row and Column of newly selected file&lt;br /&gt;
3AB5H  SHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
3AB8H  CALL 4C2FH           ; Start inverse character mode&lt;br /&gt;
3ABBH  DCX H                ; Start drawing from left edge of selection (include space)   &lt;br /&gt;
3ABCH  MVI C,0AH            ; Draw 10 characters       &lt;br /&gt;
3ABEH  CALL 48E5H           ; Redraw C characters from buffer at HL using current video mode&lt;br /&gt;
3AC1H  JMP 4C33H            ; Cancel inverse character mode       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print selected file using normal video to &amp;quot;unselect&amp;quot; it&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3AC4H  CALL 4C33H           ; Cancel inverse character mode&lt;br /&gt;
3AC7H  CALL 3ACDH           ; Calculate row and column of newly selected file&lt;br /&gt;
3ACAH  JMP 3ABBH            ; Print the file to the LCD       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Calculate Row and Column of soon-to-be (newly) selected file&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3ACDH  LDA FCD5H            ; Currently selected file index       &lt;br /&gt;
3AD0H  DCR A                ; Make selected file zero based   &lt;br /&gt;
3AD1H  MOV L,A              ; Save index to 16-bit HL&lt;br /&gt;
3AD2H  MVI H,00H            ; Make MSB zero&lt;br /&gt;
3AD4H  LXI D,000AH          ; Prepare to multiply index * 10 cols      &lt;br /&gt;
3AD7H  CALL 4C1FH           ; Signed integer muliply (FAC1=HL*DE)&lt;br /&gt;
3ADAH  LXI D,FE28H          ; Load address of line 2 in the LCD buffer&lt;br /&gt;
3ADDH  DAD D                ; Calculate starting LCD buffer address for this file&lt;br /&gt;
3ADEH  INX H                ; Skip the &amp;quot;tag&amp;quot; space on the LCD&lt;br /&gt;
3ADFH  PUSH H               ; Save address on the stack&lt;br /&gt;
3AE0H  LXI B,FE00H          ; Load starting address of LCD character buffer&lt;br /&gt;
3AE3H  DSUB                 ; Calculate file start offset from start of LCD buffer&lt;br /&gt;
3AE4H  LXI D,0028H          ; Load 1 LCD line width&lt;br /&gt;
3AE7H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  Prepare for divide&lt;br /&gt;
3AE8H  CALL 4C1BH           ; Signed integer divide (FAC1=DE/HL)&lt;br /&gt;
3AEBH  MOV A,L              ; Save selected file&#039;s row number to A&lt;br /&gt;
3AECH  INR A                ; Make row 1-based&lt;br /&gt;
3AEDH  STA F639H            ; Cursor row (1-8)&lt;br /&gt;
3AF0H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  DE had remainder*2 from divide&lt;br /&gt;
3AF1H  ASHR                 ; Divide HL by 2&lt;br /&gt;
3AF2H  MOV A,L              ; Prepare to save remainder as the column&lt;br /&gt;
3AF3H  STA F63AH            ; Cursor column (1-40)&lt;br /&gt;
3AF6H  POP H                ; Restore address of LCD buffer location from stack&lt;br /&gt;
3AF7H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F3 Function key handler for RAM mode - Rename&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3AF8H  CALL 4A4BH           ; Get RAM directory address of selected file          &lt;br /&gt;
3AFBH  SHLD FCE0H           ; Save address of file being processed          &lt;br /&gt;
3AFEH  LXI H,3F4AH          ; Address of &amp;quot;New name&amp;quot; string           &lt;br /&gt;
3B01H  CALL 3E1AH           ; Get 6-byte input filename from keyboard          &lt;br /&gt;
3B04H  RZ                   ; Return if no input provided  &lt;br /&gt;
3B05H  CALL 4902H           ; Copy filename at (HL) to current BASIC program          &lt;br /&gt;
3B08H  LHLD FCE0H           ; Load RAM directory address of file being renamed          &lt;br /&gt;
3B0BH  LXI B,0009H          ; Load offset of extension within catalog entry           &lt;br /&gt;
3B0EH  DAD B                ; Point to extension bytes     &lt;br /&gt;
3B0FH  LXI D,FC99H          ; Load address of extension field of current BASIC program name           &lt;br /&gt;
3B12H  MOV A,M              ; Get 1st byte of extension of catalog file being renamed       &lt;br /&gt;
3B13H  STAX D               ; Save extension byte in current BASIC program filename - preserve EXT      &lt;br /&gt;
3B14H  INX D                ; Point to 2nd ext byte of BASIC program name     &lt;br /&gt;
3B15H  INX H                ; Point to 2nd ext byte of catalog filename     &lt;br /&gt;
3B16H  MOV A,M              ; Get 2nd extension byte from catalog filename       &lt;br /&gt;
3B17H  STAX D               ; Save byte in current BASIC program filename area      &lt;br /&gt;
3B18H  CALL 4A51H           ; Get RAM directory address of current BASIC program          &lt;br /&gt;
3B1BH  JNZ 487EH            ; If found, jump to File Exists Error         &lt;br /&gt;
3B1EH  LHLD FCE0H           ; Load catalog address of file being renamed          &lt;br /&gt;
3B21H  INX H                ; Point to LSB of file address     &lt;br /&gt;
3B22H  INX H                ; Point to MSB of file address     &lt;br /&gt;
3B23H  INX H                ; Point to name     &lt;br /&gt;
3B24H  LXI D,FC93H          ; Load address of filename of current BASIC program    &lt;br /&gt;
3B27H  LXI B,0006H          ; Prepare to copy 6 bytes of filename (ext doesn&#039;t change)           &lt;br /&gt;
3B2AH  XCHG                 ; HL &amp;lt;--&amp;gt; DE    &lt;br /&gt;
3B2BH  JMP 4A05H            ; Move BC bytes from M to (DE) with increment         &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F1 Function key handler for DISK mode - Load&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3B2EH  CALL 4A3BH           ; Initialize blank filename and attribute byte      &lt;br /&gt;
3B31H  LHLD FCE4H           ; LCD Buffer address of current file selection      &lt;br /&gt;
3B34H  CALL 3D95H           ; Copy filename at (HL) to TX buffer      &lt;br /&gt;
3B37H  LDA FCCCH            ; Last Tag/Untag operation code     &lt;br /&gt;
3B3AH  ANA A                ; Test if a tag operation is pending &lt;br /&gt;
3B3BH  JNZ 3B56H            ; Branch if doing tag load operation     &lt;br /&gt;
3B3EH  LXI H,3F7AH          ; Point to &amp;quot;Load as:&amp;quot; text       &lt;br /&gt;
3B41H  CALL 3E1AH           ; Get 6-byte filename input from keyboard      &lt;br /&gt;
3B44H  JZ 3B56H             ; Jump to use existing disk name as filename    &lt;br /&gt;
3B47H  CALL 4902H           ; Copy filename at (HL) to current BASIC program      &lt;br /&gt;
3B4AH  LXI B,0002H          ; Prepare to copy 2 extension bytes to current BASIC program space       &lt;br /&gt;
3B4DH  LXI H,FCEFH          ; Point to disk file extension in TX buffer       &lt;br /&gt;
3B50H  LXI D,FC99H          ; Point to current BASIC program extension address       &lt;br /&gt;
3B53H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
3B56H  CALL 4A51H           ; Get RAM directory address of current BASIC program      &lt;br /&gt;
3B59H  JZ 3B69H             ; Branch to load if file doesn&#039;t already exist    &lt;br /&gt;
3B5CH  LXI H,3FB0H          ; Point to &amp;quot;File Exists, Replace?&amp;quot; text       &lt;br /&gt;
3B5FH  CALL 48F4H           ; Print string at HL to col 1 on the bottom line      &lt;br /&gt;
3B62H  CALL 3DEEH           ; Get key from keyboard and test for &#039;Y&#039; or &#039;y&#039;      &lt;br /&gt;
3B65H  RNZ                  ; Return if isn&#039;t &#039;y&#039; or &#039;Y&#039; &lt;br /&gt;
3B66H  CALL 3C38H           ; Kill file in current BASIC program space      &lt;br /&gt;
3B69H  LHLD FD1DH           ; Get file size from RX buffer      &lt;br /&gt;
3B6CH  MOV A,H              ; Swap bytes (big endian in RX buffer)   &lt;br /&gt;
3B6DH  MOV H,L              ; Move LSB to MSB   &lt;br /&gt;
3B6EH  MOV L,A              ; Move MSB to LSB   &lt;br /&gt;
3B6FH  SHLD FD1DH           ; Save with little endian to RX buffer      &lt;br /&gt;
3B72H  LDA FCEFH            ; Get 1st byte of extension from TX buffer     &lt;br /&gt;
3B75H  CPI 44H              ; Test if 1st extension byte is &amp;quot;D&amp;quot;   &lt;br /&gt;
3B77H  JNZ 3B82H            ; Jump if not &amp;quot;D&amp;quot; to check for &amp;quot;C&amp;quot; or &amp;quot;B&amp;quot;     &lt;br /&gt;
3B7AH  LHLD FBAEH           ; Get start of DO files pointer for location of new file       &lt;br /&gt;
3B7DH  MVI A,C0H            ; Load file type code for .DO files     &lt;br /&gt;
3B7FH  JMP 3BA3H            ; Process the file load      &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test file exension type in A for .CO files&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3B82H  CPI 43H              ; Test if A contains &amp;quot;C&amp;quot; &lt;br /&gt;
3B84H  JNZ 3B95H            ; Branch if not .CO file&lt;br /&gt;
3B87H  LHLD FBB0H           ; Start of CO files pointer&lt;br /&gt;
3B8AH  SHLD FCD5H           ; Save in currently selected file index storage area&lt;br /&gt;
3B8DH  LHLD FBB2H           ; Get Start of variable data pointer as location for new file&lt;br /&gt;
3B90H  MVI A,A0H            ; Load file type code for .CO files&lt;br /&gt;
3B92H  JMP 3BA3H            ; Process the file load&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process load of .BA file&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3B95H  LHLD FD1DH           ; Get file size from RX buffer&lt;br /&gt;
3B98H  SHLD FCD5H           ; Save in Currently selected file index storage&lt;br /&gt;
3B9BH  LHLD F99AH           ; Get BASIC program not saved pointer     &lt;br /&gt;
3B9EH  SHLD FCE0H           ; Save as address of file being processed&lt;br /&gt;
3BA1H  MVI A,80H            ; Load file type code for .BA files     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process file load operation&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3BA3H  STA FCDFH            ; Save file type code for later     &lt;br /&gt;
3BA6H  SHLD FCE2H           ; Save address for new file &lt;br /&gt;
3BA9H  LHLD FD1DH           ; Get file size from RX buffer&lt;br /&gt;
3BACH  SHLD FCDDH           ; Save in FDC emulation physical/logical sector storage area&lt;br /&gt;
3BAFH  PUSH H               ; Save file size on stack  &lt;br /&gt;
3BB0H  POP B                ; Copy file size to BC &lt;br /&gt;
3BB1H  LDA FCDFH            ; Get file type code     &lt;br /&gt;
3BB4H  CPI A0H              ; Test for .CO file   &lt;br /&gt;
3BB6H  JZ 3BC0H             ; Skip increment if .CO file (.BA has trailing 0x0000, .DO a 0x1A)    &lt;br /&gt;
3BB9H  INX B                ; Increment file length for .BA and .DO files &lt;br /&gt;
3BBAH  CPI 80H              ; Test if file is .BA   &lt;br /&gt;
3BBCH  JNZ 3BC0H            ; Skip additional increment if .BA     &lt;br /&gt;
3BBFH  INX B                ; Add 1 more to length for .BA files to account for both trailing 0&#039;s &lt;br /&gt;
3BC0H  PUSH B               ; Save updated length on stack  &lt;br /&gt;
3BC1H  CALL 3E48H           ; Find empty catalog entry      &lt;br /&gt;
3BC4H  JC 4887H             ; Generate system error 0x0A (&amp;quot;DD&amp;quot;) if full&lt;br /&gt;
3BC7H  POP B                ; Get length from stack &lt;br /&gt;
3BC8H  PUSH H               ; Save new file catalog address on stack  &lt;br /&gt;
3BC9H  PUSH B               ; Save new file length on stack  &lt;br /&gt;
3BCAH  LHLD FCE2H           ; Get address for new contents of new file      &lt;br /&gt;
3BCDH  CALL 4C0BH           ; Insert BC spaces at M - make room      &lt;br /&gt;
3BD0H  JC 488AH	            ; Branch if error - RAM full error&lt;br /&gt;
3BD3H  LHLD FCE2H           ; Restore address of new file contents&lt;br /&gt;
3BD6H  POP B                ; Get file length from stack   &lt;br /&gt;
3BD7H  MVI M,00H            ; Fill newly created file space with zero&#039;s       &lt;br /&gt;
3BD9H  INX H                ; Increment pointer   &lt;br /&gt;
3BDAH  DCX B                ; Decrement count   &lt;br /&gt;
3BDBH  MOV A,C              ; Move LSB to A to check for zero - could use JNX here!     &lt;br /&gt;
3BDCH  ORA B                ; Or in MSB to check for zero   &lt;br /&gt;
3BDDH  JNZ 3BD7H            ; Keep looping until all are zero       &lt;br /&gt;
3BE0H  DCX H                ; Decrement pointer to last byte in new file   &lt;br /&gt;
3BE1H  POP D                ; Get File catalog address from stack   &lt;br /&gt;
3BE2H  LDA FCDFH            ; Load file type code byte       &lt;br /&gt;
3BE5H  CPI C0H              ; Test for .DO file     &lt;br /&gt;
3BE7H  JNZ 3BF3H            ; Branch if not .DO file       &lt;br /&gt;
3BEAH  MVI M,1AH            ; Terminate .DO file with EOF marker       &lt;br /&gt;
3BECH  LHLD FCE2H           ; Reload address of new file contents        &lt;br /&gt;
3BEFH  DCX H                ; Decrement pointer to jump into middle of loop   &lt;br /&gt;
3BF0H  JMP 3C1BH            ; Write file entry to catalog       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process end-of-file / file length for .CO and .BA files&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3BF3H  CPI A0H              ; Test if new file is .CO  &lt;br /&gt;
3BF5H  JNZ 3C04H            ; Branch if not .CO - must be .BA &lt;br /&gt;
3BF8H  LHLD FCD5H           ; Get old start of CO files pointer&lt;br /&gt;
3BFBH  SHLD FBB0H           ; Save as current start of CO files pointer     &lt;br /&gt;
3BFEH  LHLD FCE2H           ; Reload address of new file contents&lt;br /&gt;
3C01H  JMP 3C1BH            ; Write file entry to catalog &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process end-of-file for .BA files&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3C04H  PUSH D               ; Push file catalog address to stack    &lt;br /&gt;
3C05H  LHLD FBAEH           ; Get start of DO files pointer          &lt;br /&gt;
3C08H  DCX H                ; Decrement address by 1   &lt;br /&gt;
3C09H  SHLD F99AH           ; Save as new BASIC program not saved pointer          &lt;br /&gt;
3C0CH  INX H                ; Increment back to start of .DO files   &lt;br /&gt;
3C0DH  XCHG                 ; HL &amp;lt;--&amp;gt; DE  DE has start of DO files  &lt;br /&gt;
3C0EH  LHLD FCD5H           ; Get BA file size        &lt;br /&gt;
3C11H  INX H                ; Increment file size to account for trailing 0&#039;s   &lt;br /&gt;
3C12H  INX H                ; Increment file size to account for trailing 0&#039;s   &lt;br /&gt;
3C13H  DAD D                ; Add new length to start of DO files pointer   &lt;br /&gt;
3C14H  SHLD FBAEH           ; Save new start of DO files pointer          &lt;br /&gt;
3C17H  POP D                ; Retrieve file catalog address from stack   &lt;br /&gt;
3C18H  LHLD FCE0H           ; Reload address of new file contents        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Write file entry to catalog&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3C1BH  XCHG                 ; HL &amp;lt;--&amp;gt; DE  DE has file address, HL has catalog address         &lt;br /&gt;
3C1CH  CALL 4C17H           ; Write new entry to catalog (A=type, DE=file address,HL=catalog address)       &lt;br /&gt;
3C1FH  CALL 4127H           ; Open TPDD file and read data to file address being processed       &lt;br /&gt;
3C22H  CALL 4C0FH           ; Update system pointers       &lt;br /&gt;
3C25H  LXI H,0002H          ; Load TPDD_READ opcode in HL        &lt;br /&gt;
3C28H  JMP 409BH            ; Send Request in HL and await response      &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F2 Function key handler for RAM mode - Kill&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3C2BH  LDA FCCCH            ; Get last Tag/Untag operation code       &lt;br /&gt;
3C2EH  ANA A                ; Test if there is a pending tag operation&lt;br /&gt;
3C2FH  CZ 3DE1H             ; Display &amp;quot;Sure ?&amp;quot;, validate and return if validated if no tag&lt;br /&gt;
3C32H  LHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
3C35H  CALL 4902H           ; Copy filename at (HL) to current BASIC program&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Kill file in current BASIC program space&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3C38H  CALL 4A51H           ; Get RAM directory address of current BASIC program&lt;br /&gt;
3C3BH  CPI C0H              ; Test if file is .DO &lt;br /&gt;
3C3DH  JZ 4BFFH             ; Kill .DO file  &lt;br /&gt;
3C40H  CPI A0H              ; Test if file is .CO &lt;br /&gt;
3C42H  JZ 4C07H             ; Kill .CO file &lt;br /&gt;
3C45H  CPI 80H              ; Test if file is .BA&lt;br /&gt;
3C47H  JZ 4C03H             ; Kill .BA file&lt;br /&gt;
3C4AH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F1 Function key handler for RAM mode - Save&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3C4BH  CALL 4A3BH           ; Initialize blank filename and attribute byte      &lt;br /&gt;
3C4EH  CALL 4A4BH           ; Get RAM directory address of selected file      &lt;br /&gt;
3C51H  PUSH D               ; Push file address to stack  &lt;br /&gt;
3C52H  PUSH H               ; Push file catalog address to stack  &lt;br /&gt;
3C53H  INX H                ; Point to LSB of file address &lt;br /&gt;
3C54H  INX H                ; Point to MSB of file address &lt;br /&gt;
3C55H  INX H                ; Point to filename in catalog &lt;br /&gt;
3C56H  LXI D,FCE8H          ; Point to TX buffer data area (payload)&lt;br /&gt;
3C59H  LXI B,0006H          ; Prepare to copy 6 filename bytes to TX packet data&lt;br /&gt;
3C5CH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
3C5FH  MVI A,2EH            ; Load code for &#039;.&#039;     &lt;br /&gt;
3C61H  STAX D               ; Store &#039;.&#039; separator in TX packet data  &lt;br /&gt;
3C62H  INX D                ; Increment TX packet data pointer &lt;br /&gt;
3C63H  LXI B,0002H          ; Prepare to copy 2 extention bytes from catalog&lt;br /&gt;
3C66H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
3C69H  LDA FCCCH            ; Last Tag/Untag operation code     &lt;br /&gt;
3C6CH  ANA A                ; Test if a tag save operation is being performed &lt;br /&gt;
3C6DH  JNZ 3C88H            ; Jump ahead if doing a tag save - skip filename questioning     &lt;br /&gt;
3C70H  LXI H,3F71H          ; Point to &amp;quot;Save as:&amp;quot; text&lt;br /&gt;
3C73H  CALL 3E1AH           ; Get 6-byte input filename from keyboard      &lt;br /&gt;
3C76H  JZ 3C88H             ; Skip ahead to use catalog name if no input given    &lt;br /&gt;
3C79H  CALL 4902H           ; Copy filename at (HL) to current BASIC program             &lt;br /&gt;
3C7CH  LXI B,0006H          ; Prepare to copy 6 filename bytes from input string       &lt;br /&gt;
3C7FH  LXI D,FCE8H          ; Point to filename area in TX buffer       &lt;br /&gt;
3C82H  LXI H,FC93H          ; Filename of current BASIC program         &lt;br /&gt;
3C85H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
3C88H  POP H                ; Restore file catalog address from stack &lt;br /&gt;
3C89H  POP D                ; Restore file address from stack &lt;br /&gt;
3C8AH  PUSH D               ; Save file address on stack  &lt;br /&gt;
3C8BH  CALL 3CD3H           ; Calculate length of RAM file, HL=address of catalog entry, DE=file address&lt;br /&gt;
3C8EH  MOV A,H              ; Test for zero length file - move H to A    &lt;br /&gt;
3C8FH  ORA L                ; OR LSB to test for zero  &lt;br /&gt;
3C90H  JZ 4884H             ; Branch if empty - File Empty Error     &lt;br /&gt;
3C93H  PUSH H               ; Save file address to stack   &lt;br /&gt;
3C94H  MVI A,01H            ; Set file open mode to new file      &lt;br /&gt;
3C96H  STA FCD6H            ; Save open mode to pass to open routine      &lt;br /&gt;
3C99H  CALL 4943H           ; Configure baud, test for NADSBox, get NADSBox dir       &lt;br /&gt;
3C9CH  CALL 4A72H           ; Send Dir Reference opcode       &lt;br /&gt;
3C9FH  JZ 3CCEH             ; Jump to write data if file doesn&#039;t exist (size = 0)     &lt;br /&gt;
3CA2H  LXI H,3F8BH          ; Point to &amp;quot;File Exists, A)ppend R)eplace Q)uit&amp;quot; text        &lt;br /&gt;
3CA5H  CALL 48F4H           ; Print string at HL to col 1 on the bottom line       &lt;br /&gt;
3CA8H  CALL 3DF8H           ; Process power-off logic and wait for a key from keyboard       &lt;br /&gt;
3CABH  ANI DFH              ; Make key uppercase    &lt;br /&gt;
3CADH  RST 4                ; Display key on LCD            &lt;br /&gt;
3CAEH  CPI 52H              ; Test if key is &#039;R&#039;    &lt;br /&gt;
3CB0H  JNZ 3CBCH            ; Jump if not &#039;R&#039;eplace                      &lt;br /&gt;
3CB3H  CALL 431AH           ; Issue TPDD Delete file Opcode       &lt;br /&gt;
3CB6H  CALL 4A72H           ; Send Dir Reference opcode       &lt;br /&gt;
3CB9H  JMP 3CCEH            ; Go write data to the file      &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F1-Save: Test for &#039;A&#039;ppend&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3CBCH  POP H                ; Get file length from stack    &lt;br /&gt;
3CBDH  POP D                ; Get file address from stack    &lt;br /&gt;
3CBEH  CPI 41H              ; Test if response is &#039;A&#039;ppend      &lt;br /&gt;
3CC0H  RNZ                  ; Return if not &#039;A&#039;  &lt;br /&gt;
3CC1H  LDA FCEFH            ; Load 1st byte of extension from TX buffer        &lt;br /&gt;
3CC4H  CPI 44H              ; Test if file is &amp;quot;D&amp;quot;O file      &lt;br /&gt;
3CC6H  RNZ                  ; Don&#039;t allow appending non DO files  &lt;br /&gt;
3CC7H  MVI A,02H            ; Set open mode to open existing (append)        &lt;br /&gt;
3CC9H  STA FCD6H            ; Save mode to pass to open routine        &lt;br /&gt;
3CCCH  PUSH D               ; Save file address on stack     &lt;br /&gt;
3CCDH  PUSH H               ; Save file length on stack     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Save function - Replace or new file, write data to file&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3CCEH  POP H                ; Retrieve file length from stack    &lt;br /&gt;
3CCFH  POP D                ; Retrieve file address from stack    &lt;br /&gt;
3CD0H  JMP 40C8H            ; Write HL bytes of data from (DE) to TPDD        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Calculate length of RAM file, HL=address of catalog entry, DE=file address&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3CD3H  MOV A,M              ; Get RAM file type from catalog   &lt;br /&gt;
3CD4H  CPI C0H              ; Test for .DO file   &lt;br /&gt;
3CD6H  JZ 3CE6H             ; Jump to calculate length if .DO file    &lt;br /&gt;
3CD9H  CPI A0H              ; Test for .CO file         &lt;br /&gt;
3CDBH  JZ 3CF5H             ; Jump to calculate length if .CO file    &lt;br /&gt;
3CDEH  PUSH D               ; Save address of start of BASIC program to stack  &lt;br /&gt;
3CDFH  CALL 4C13H           ; Call ROM routine to find BASIC end of program&lt;br /&gt;
3CE2H  POP B                ; Get BASIC program start address from stack &lt;br /&gt;
3CE3H  DSUB                 ; Subtract starting address from end address&lt;br /&gt;
3CE4H  DCX H                ; Don&#039;t count trailing 0x00 as part of BASIC program length &lt;br /&gt;
3CE5H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Calculate length of .DO file, HL=Catalog address, DE=file address&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3CE6H  XCHG                 ; HL &amp;lt;--&amp;gt; DE Get file address in HL &lt;br /&gt;
3CE7H  LXI D,0000H          ; Clear file length&lt;br /&gt;
3CEAH  MOV A,M              ; Get next byte from .DO file    &lt;br /&gt;
3CEBH  INX H                ; Increment pointer  &lt;br /&gt;
3CECH  INX D                ; Increment length  &lt;br /&gt;
3CEDH  CPI 1AH              ; Test for EOF marker    &lt;br /&gt;
3CEFH  JNZ 3CEAH            ; Branch to next byte if not EOF      &lt;br /&gt;
3CF2H  DCX D                ; Subtract EOF marker from file length  &lt;br /&gt;
3CF3H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  HL=length &lt;br /&gt;
3CF4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Calculate length of .CO file, HL=Catalog address, DE=file address&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3CF5H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  Get file address in HL &lt;br /&gt;
3CF6H  INX H                ; Increment past .CO load address &lt;br /&gt;
3CF7H  INX H                ; Increment past MSB of load address&lt;br /&gt;
3CF8H  MOV C,M              ; Get LSB of length  &lt;br /&gt;
3CF9H  INX H                ; Increment to MSB of length&lt;br /&gt;
3CFAH  MOV B,M              ; Get MSB of length&lt;br /&gt;
3CFBH  LXI H,0006H          ; Prepare to add 6-byte header to length&lt;br /&gt;
3CFEH  DAD B                ; Add 6-byte header to length&lt;br /&gt;
3CFFH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F7 Function key handler for DISK mode - Mkdir&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D00H  LDA FCCBH            ; NADSBox / TPDD2 / Desklink flag        &lt;br /&gt;
3D03H  ANA A                ; Test if server is TPDD    &lt;br /&gt;
3D04H  RZ                   ; Return if not NADSBox or TPDD2 &lt;br /&gt;
3D05H  DCR A                ; Test if TPDD2    &lt;br /&gt;
3D06H  JZ 37BAH             ; Go Swap TPDD Bank Number if TPDD2       &lt;br /&gt;
3D09H  CALL 4A3BH           ; Must be NADSBOx Initialize blank filename         &lt;br /&gt;
3D0CH  LXI H,3F61H          ; Load pointer to &amp;quot;Directory name:&amp;quot; text          &lt;br /&gt;
3D0FH  CALL 3E1AH           ; Get 6-byte input filename from keyboard         &lt;br /&gt;
3D12H  RZ                   ; Return if no input given &lt;br /&gt;
3D13H  CALL 4902H           ; Copy filename at (HL) to current BASIC program         &lt;br /&gt;
3D16H  LXI H,FC93H          ; Filename of current BASIC program              &lt;br /&gt;
3D19H  LXI D,FCE8H          ; Point to TX buffer data area (payload)          &lt;br /&gt;
3D1CH  LXI B,0006H          ; Prepare to copy 6 filename bytes to TX buffer          &lt;br /&gt;
3D1FH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment         &lt;br /&gt;
3D22H  LXI H,3E3CH          ; Load code for &amp;quot;&amp;lt;&amp;gt;&amp;quot;          &lt;br /&gt;
3D25H  SHLD FCEFH           ; Save &amp;quot;&amp;lt;&amp;gt;&amp;quot; extension bytes in TX buffer - NADSBox Mkdir                   &lt;br /&gt;
3D28H  MVI A,2EH            ; Load code for &#039;.&#039; extension separator        &lt;br /&gt;
3D2AH  STA FCEEH            ; Save &amp;quot;.&amp;quot; to TX buffer        &lt;br /&gt;
3D2DH  CALL 4943H           ; Configure baud, test for NADSBox, get NADSBox dir         &lt;br /&gt;
3D30H  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag        &lt;br /&gt;
3D33H  CPI 02H              ; Test if we have NADSBox current directory      &lt;br /&gt;
3D35H  RNZ                  ; Return if we don&#039;t have current directory  &lt;br /&gt;
3D36H  CALL 4A72H           ; Send Directory Reference opcode         &lt;br /&gt;
3D39H  JNZ 3D4DH            ; If the file exists, branch to open it for READ mode        &lt;br /&gt;
3D3CH  MVI A,01H            ; Load OPEN_WRITE mode into A to create the directory        &lt;br /&gt;
3D3EH  STA FCE8H            ; Save A in TX data storage mode field        &lt;br /&gt;
3D41H  LXI H,0101H          ; Load opcode to open a file          &lt;br /&gt;
3D44H  CALL 409BH           ; Send Request in HL and await response         &lt;br /&gt;
3D47H  LXI H,0002H          ; Load opcode to close the file          &lt;br /&gt;
3D4AH  JMP 409BH            ; Send Request in HL and await response        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Open and close a directory file (from above)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D4DH  CALL 408AH           ; Open TPDD file for Read Mode&lt;br /&gt;
3D50H  JMP 3D47H            ; Branch to close the directory open request&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F5 Function key handler for DISK mode - Format&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D53H  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag       &lt;br /&gt;
3D56H  CPI 02H              ; Test if we have &amp;quot;current directory&amp;quot; name     &lt;br /&gt;
3D58H  RZ                   ; Return if server is NADSBox / Desklink - No format supported&lt;br /&gt;
3D59H  LXI H,3F1BH          ; Load pointer to &amp;quot;Insert Disk&amp;quot; string&lt;br /&gt;
3D5CH  CALL 48F4H           ; Print string at HL to col 1 on the bottom line        &lt;br /&gt;
3D5FH  CALL 3DEEH           ; Get key from keyboard and test for &#039;Y&#039; or &#039;y&#039;        &lt;br /&gt;
3D62H  RNZ                  ; Return if response not &#039;Y&#039; &lt;br /&gt;
3D63H  CALL 4943H           ; Configure baud, test for NADSBox, get NADSBox dir        &lt;br /&gt;
3D66H  CALL 49E3H           ; Delay routine - about 3ms        &lt;br /&gt;
3D69H  LXI H,0006H          ; Load TPDD_FORMAT opcode in HL&lt;br /&gt;
3D6CH  CALL 409BH           ; Send Request in HL and await response        &lt;br /&gt;
3D6FH  MVI A,07H            ; Load code for BELL       &lt;br /&gt;
3D72H  RET		            ; Go beep to indicate format&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F2 Function key handler for DISK mode - Kill&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D73H  LDA FCCCH            ; Last Tag/Untag operation code      &lt;br /&gt;
3D76H  ANA A                ; Test if there&#039;s an active tag group&lt;br /&gt;
3D77H  CZ 3DE1H             ; Display &amp;quot;Sure ?&amp;quot;, validate and return if validated if no tag&lt;br /&gt;
3D7AH  CALL 4A3BH           ; Initialize blank filename and attribute byte&lt;br /&gt;
3D7DH  CALL 3D83H           ; Copy selected filename to TX buffer and init TPDD/NADSBox&lt;br /&gt;
3D80H  JMP 431AH            ; Issue TPDD Delete file Opcode            &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Copy selected filename to TX buffer and init TPDD/NADSBox&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D83H  LXI B,0009H          ; Prepare to copy 9 filename bytes&lt;br /&gt;
3D86H  LHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
3D89H  LXI D,FCE8H          ; Address of TX packet data&lt;br /&gt;
3D8CH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment&lt;br /&gt;
3D8FH  CALL 4943H           ; Configure baud, test for NADSBox, get NADSBox dir&lt;br /&gt;
3D92H  JMP 4A72H            ; Send Dir Reference opcode&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Copy filename at (HL) to TX buffer&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D95H  CALL 4902H           ; Copy filename at (HL) to current BASIC program&lt;br /&gt;
3D98H  LXI H,FC93H          ; Filename of current BASIC program&lt;br /&gt;
3D9BH  CALL 4A57H           ; Send Dir Reference for filename at (HL)&lt;br /&gt;
3D9EH  RET        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F3 Function key handler for DISK mode - Name&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D9FH  CALL 4A3BH           ; Initialize blank filename and attribute byte          &lt;br /&gt;
3DA2H  CALL 3D83H           ; Copy selected filename to TX buffer and init TPDD/NADSBox          &lt;br /&gt;
3DA5H  LXI H,FCE8H          ; Point to TX buffer data area (payload)&lt;br /&gt;
3DA8H  LXI D,FC9CH          ; Filename of last program loaded from tape  &lt;br /&gt;
3DABH  LXI B,0009H          ; Prepare to copy 9 bytes to &amp;quot;last program loaded&amp;quot; filename&lt;br /&gt;
3DAEH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment          &lt;br /&gt;
3DB1H  LHLD FD1DH           ; Get file size from RX buffer          &lt;br /&gt;
3DB4H  MOV C,H              ; Save file size MSB to C (swap endian)       &lt;br /&gt;
3DB5H  MOV B,L              ; Save file size LSB to B (swap endian)       &lt;br /&gt;
3DB6H  LXI H,7CC0H          ; ? Load HL with 31936&lt;br /&gt;
3DB9H  DSUB                 ; ? Compare file length with 31936    &lt;br /&gt;
3DBAH  LXI H,3F4AH          ; Address of &amp;quot;New name&amp;quot; string&lt;br /&gt;
3DBDH  JNZ 3DD7H            ; Branch to change filename if not 30656         &lt;br /&gt;
3DC0H  LXI B,0009H          ; Allow a 9-byte filename input string&lt;br /&gt;
3DC3H  CALL 3E1DH           ; Get max BC length input for filename and convert to uppercase          &lt;br /&gt;
3DC6H  RZ                   ; Return if no input provided  &lt;br /&gt;
3DC7H  PUSH H               ; Save pointer to input string to stack      &lt;br /&gt;
3DC8H  PUSH PSW             ; Save string length to stack        &lt;br /&gt;
3DC9H  CALL 4A3BH           ; Initialize blank filename and attribute byte          &lt;br /&gt;
3DCCH  POP PSW              ; Get string length from stack       &lt;br /&gt;
3DCDH  POP H                ; Get string address from stack     &lt;br /&gt;
3DCEH  LXI D,FCE8H          ; Point to TX buffer data area (payload)           &lt;br /&gt;
3DD1H  MOV C,A              ; Copy length to BC       &lt;br /&gt;
3DD2H  MVI B,00H            ; Make MSB of length = 0         &lt;br /&gt;
3DD4H  JMP 41B0H            ; Rename the TPDD file whose name is in (HL)         &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get filename from keyboard and rename Disk file, filename in &amp;quot;current BASIC program&amp;quot;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3DD7H  CALL 3E1AH           ; Get 6-byte input filename from keyboard&lt;br /&gt;
3DDAH  RZ                   ; Return if no input provided &lt;br /&gt;
3DDBH  CALL 4902H           ; Copy filename at (HL) to current BASIC program&lt;br /&gt;
3DDEH  JMP 41A7H            ; Rename the TPDD file whose name is in &amp;quot;current BASIC program&amp;quot; &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display &amp;quot;Sure ?&amp;quot;, validate and return if validated&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3DE1H  LXI H,3F83H          ; Load pointer to &amp;quot;Sure ?&amp;quot; string&lt;br /&gt;
3DE4H  CALL 48F4H           ; Print string at HL to col 1 on the bottom line &lt;br /&gt;
3DE7H  CALL 3DEEH           ; Get key and test for &#039;Y&#039; or &#039;y&#039; &lt;br /&gt;
3DEAH  JNZ 48B5H            ; Branch to &amp;quot;Long jump&amp;quot; operation to abort if not &#039;y&#039; &lt;br /&gt;
3DEDH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get key from keyboard and test for &#039;Y&#039; or &#039;y&#039;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3DEEH  CALL 3DF8H           ; Process power-off logic and wait for a key from keyboard&lt;br /&gt;
3DF1H  RST 4                ; Display the key on the LCD &lt;br /&gt;
3DF2H  CPI 59H              ; Test if key pressed was &#039;Y&#039;      &lt;br /&gt;
3DF4H  RZ                   ; Return if key pressed was &#039;Y&#039; &lt;br /&gt;
3DF5H  CPI 79H              ; Test if key pressed was &#039;y&#039;      &lt;br /&gt;
3DF7H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process power-off logic and wait for a key from keyboard&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3DF8H  CALL 3DFEH           ; Process automatic poweroff logic&lt;br /&gt;
3DFBH  JMP 4BEBH            ; Wait for key from keyboard&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process automatic power-off logic during key scan loop&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3DFEH  XRA A                ; Clear A  &lt;br /&gt;
3DFFH  DCR A                ; Set A to 0xFF   &lt;br /&gt;
3E00H  STA F656H            ; Power off exit condition switch  &lt;br /&gt;
3E03H  CALL 4C4AH           ; Check keyboard queue for pending characters&lt;br /&gt;
3E06H  JZ 3DFEH             ; Branch back if no keyboard characters in queue - wait for key&lt;br /&gt;
3E09H  XRA A                ; Clear A  &lt;br /&gt;
3E0AH  STA F656H            ; Power off exit condition switch  &lt;br /&gt;
3E0DH  LXI H,F932H          ; Load address of &amp;quot;Renew Automatic Poweroff Counter Flag&amp;quot;&lt;br /&gt;
3E10H  ORA M                ; Test if auto poweroff counter should be renewed&lt;br /&gt;
3E11H  JZ 4BF7H             ; Renew automatic power-off counter if enabled&lt;br /&gt;
3E14H  CALL 4BF3H           ; Turn off the computer&lt;br /&gt;
3E17H  JMP 3DFEH            ; Branch back to continue processing power off logic&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get max 6-byte input for filename and convert to uppercase&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E1AH  LXI B,0006H          ; Get maximum 6 characters of input&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get max BC length input for filename and convert to uppercase&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E1DH  CALL 3E2FH           ; Get max BC length input string from keyboard&lt;br /&gt;
3E20H  RZ                   ; Return if no input provided &lt;br /&gt;
3E21H  PUSH H               ; Preserve pointer to input string     &lt;br /&gt;
3E22H  PUSH PSW             ; Preserve flags from input       &lt;br /&gt;
3E23H  CALL 4C5EH           ; Get char at M and convert to uppercase&lt;br /&gt;
3E26H  MOV M,A              ; Save uppercase char back to string      &lt;br /&gt;
3E27H  INX H                ; Point to next byte in input     &lt;br /&gt;
3E28H  ANA A                ; Test for NULL - end of string    &lt;br /&gt;
3E29H  JNZ 3E23H            ; Keep looping until end of string        &lt;br /&gt;
3E2CH  POP PSW              ; Restore flags from input routine      &lt;br /&gt;
3E2DH  POP H                ; Restore pointer to input string    &lt;br /&gt;
3E2EH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get maximum BC length input character string from keyboard&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E2FH  PUSH B               ; Save maximum input length to stack     &lt;br /&gt;
3E30H  CALL 48F4H           ; Print string at HL to col 1 on the bottom line&lt;br /&gt;
3E33H  CALL 4C46H           ; Input and display (no &amp;quot;?&amp;quot;) line and store&lt;br /&gt;
3E36H  JC 48B5H             ; Branch to &amp;quot;Long jump&amp;quot; if CTRL-C       &lt;br /&gt;
3E39H  INX H                ; Point to start of input string    &lt;br /&gt;
3E3AH  MOV A,B              ; Get string length (counting NULL)      &lt;br /&gt;
3E3BH  DCR A                ; Remove NULL from count    &lt;br /&gt;
3E3CH  POP D                ; Restore maximum input length    &lt;br /&gt;
3E3DH  RZ                   ; Return if string length is zero &lt;br /&gt;
3E3EH  CMP E                ; Compare expected length with actual length    &lt;br /&gt;
3E3FH  RC                   ; Return if string is shorter than expected          &lt;br /&gt;
3E40H  PUSH H               ; Save pointer to start of string on stack     &lt;br /&gt;
3E41H  DAD D                ; Add Expected length to pointer    &lt;br /&gt;
3E42H  MVI M,00H            ; Truncate the string to the max length        &lt;br /&gt;
3E44H  POP H                ; Restore pointer to input string    &lt;br /&gt;
3E45H  MOV A,E              ; Update length to reflect maximum      &lt;br /&gt;
3E46H  ORA A                ; Clear zero flag to indicate input provided    &lt;br /&gt;
3E47H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Find Empty catalog entry (only 9 instructions...Don&#039;t bother with Main ROM)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E48H  LXI H,F9AFH         ; Point to the &amp;quot;RickY&amp;quot; catalog entry (start of valid entries)&lt;br /&gt;
3E4BH  LXI B,000BH         ; Load length of each catalog entry&lt;br /&gt;
3E4EH  DAD B               ; Point to next catalog entry to test if empty&lt;br /&gt;
3E4FH  MOV A,M             ; Get file attribute byte from catalog entry&lt;br /&gt;
3E50H  CPI FFH             ; Test if at end of catalog&lt;br /&gt;
3E52H  JZ 3E5AH            ; Jump to report directory full if at end&lt;br /&gt;
3E55H  ADD A               ; Test if MSB is set (entry being used)&lt;br /&gt;
3E56H  JC 3E4EH            ; Jump to test next enry if MSB set&lt;br /&gt;
3E59H  RET                 ; Entry found...return with Carry clear&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Empty catalog entry not found...set Carry and exit&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E5AH  STC                 ; Indicate empty entry not found&lt;br /&gt;
3E5BH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F5 Function key handler for RAM mode - DOS ON/OF&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E5CH  LHLD FB2CH          ; Get LFILES statement hook address&lt;br /&gt;
3E5FH  LXI B,08DBH         ; Load address of default (DOS-OFF) hook for LFILES&lt;br /&gt;
3E62H  DSUB                ; Test if in DOS-OFF mode&lt;br /&gt;
3E63H  JZ 401FH            ; Jump to add our custom RST 7 hooks if in DOS-OFF mode&lt;br /&gt;
3E66H  JMP 3FFAH           ; Must be in DOS-ON mode, jump to turn it off&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Strings&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E69H  DB	0x1B, &amp;quot;p TS-DOS (100 v4.00) (c)87,TSI.          &amp;quot;,0x1B,&#039;q&#039;,0x00&lt;br /&gt;
3E97H  DB   &amp;quot;DISK Free:         File:&amp;quot;,0DH,0AH,&amp;quot;Load Kill Name Ram  Frmt Log       Menu&amp;quot;,00H&lt;br /&gt;
3ED9H  DB   &amp;quot; RAM Free:         File:&amp;quot;,0DH,0AH,&amp;quot;Save Kill Name Disk DOS-           Menu&amp;quot;,00H&lt;br /&gt;
3F1BH  DB   &amp;quot;Insert Disk, Press \&amp;quot;Y\&amp;quot; to begin &amp;quot;,00H&lt;br /&gt;
3F3CH  DB   &amp;quot;NOT FORMATTED&amp;quot;,00H&lt;br /&gt;
3F4AH  DB   &amp;quot;New Name:&amp;quot;,00H&lt;br /&gt;
3F54H  DB   &amp;quot;System name:&amp;quot;,00H&lt;br /&gt;
3F61H  DB   &amp;quot;Directory name:&amp;quot;,00H&lt;br /&gt;
3F71H  DB   &amp;quot;Save as:&amp;quot;,00H&lt;br /&gt;
3F7AH  DB   &amp;quot;Load as:&amp;quot;,00H&lt;br /&gt;
3F83H  DB   &amp;quot;Sure ? &amp;quot;,00H&lt;br /&gt;
3F8BH  DB   &amp;quot;File exists, A)ppend R)eplace Q)uit:&amp;quot;,00H&lt;br /&gt;
3FB0H  DB   &amp;quot;File exists, Replace? (Y/N):&amp;quot;,00H&lt;br /&gt;
3FCDH  DB   &amp;quot;-.-       &amp;quot;,00H&lt;br /&gt;
3FD8H  DB   0x1B,&amp;quot;Y74    &amp;quot;,1BH,&amp;quot;Y7&amp;gt;MkDr&amp;quot;,00H     ;  TODO: Check this&lt;br /&gt;
3FE9H  DB   0x1B,&amp;quot;Y7&amp;gt;Bank&amp;quot;,00H                   ;  TODO: Check this&lt;br /&gt;
3FF2H  DB   &amp;quot;OFF&amp;quot;,00H&lt;br /&gt;
3FF6H  DB   &amp;quot;ON &amp;quot;,00H&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Navigate to:&lt;br /&gt;
 - [[Dissasembly of RAM and ROM versions of TS-DOS]]&lt;br /&gt;
 - [[M100 TS-DOS ROM OptROM Support]]&lt;br /&gt;
 - [[M100 TS-DOS ROM RST 7 Handlers]]&lt;br /&gt;
 - [[M100 TS-DOS ROM TPDD Protocol]]&lt;br /&gt;
 - [[M100 TS-DOS ROM Compression]]&lt;br /&gt;
 - [[M100 TS-DOS ROM Cold Boot Recovery]]&lt;/div&gt;</summary>
		<author><name>Kpettit</name></author>
	</entry>
	<entry>
		<id>https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_UI_Code&amp;diff=1376</id>
		<title>M100 TS-DOS ROM UI Code</title>
		<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_UI_Code&amp;diff=1376"/>
		<updated>2009-04-03T07:37:39Z</updated>

		<summary type="html">&lt;p&gt;Kpettit: New page: == TS-DOS Model 100/102 User Interface Code  &amp;lt;pre&amp;gt; ; ========================================================================================= ; TS-DOS UI Entry location ; ================...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== TS-DOS Model 100/102 User Interface Code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; TS-DOS UI Entry location&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
 &lt;br /&gt;
    .org  3535H&lt;br /&gt;
&lt;br /&gt;
3535H  LXI H,FCC0H          ; Start of Alt LCD character buffer&lt;br /&gt;
3538H  MVI B,B4H            ; Prepare to clear 180 bytes from the ALTLCD buffer &lt;br /&gt;
353AH  XRA A                ; Prepare to clear the ALTLCD buffer&lt;br /&gt;
353BH  CALL 4A34H           ; Fill (HL) with B bytes of A        &lt;br /&gt;
353EH  LXI H,0000H          ; Prepare to get current stack pointer&lt;br /&gt;
3541H  DAD SP               ; Copy SP into HL&lt;br /&gt;
3542H  SHLD FCCEH           ; Stack pointer upon entry - pointer to arguments&lt;br /&gt;
3545H  MVI A,01H            ; Set flag to print error message to LCD - GUI mode&lt;br /&gt;
3547H  CALL 4A85H           ; Save the currently selected baud rate settings&lt;br /&gt;
354AH  XRA A                ; Zero A to clear our vars&lt;br /&gt;
354BH  STA FCD4H            ; Current Page of files being displayed&lt;br /&gt;
354EH  STA FCDAH            ; TPDD &amp;quot;skip page&amp;quot; count&lt;br /&gt;
3551H  STA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
3554H  STA FCCAH            ; TPDD2 Bank number&lt;br /&gt;
3557H  INR A                ; A = 1 to select 1st file on page&lt;br /&gt;
3558H  STA FCCDH            ; Currently selected file index&lt;br /&gt;
355BH  LXI H,3564H          ; Get pointer to main loop routine&lt;br /&gt;
355EH  SHLD FCD0H           ; Return vector after error&lt;br /&gt;
3561H  CALL 4C27H           ; CLS statement&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; UI Main loop&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3564H  CALL 4C5AH           ; Resume automatic scrolling&lt;br /&gt;
3567H  CALL 3611H           ; Print Copyright and files&lt;br /&gt;
356AH  LDA FCD5H            ; Load currently selected index from temp storage&lt;br /&gt;
356DH  STA FCCDH            ; Currently selected file index&lt;br /&gt;
3570H  CALL 362FH           ; Print length of selected file using inverse video&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Code will return here when a funtion key is pressed (except F4 &amp;amp; F6)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3573H  LXI H,48B5H          ; Get address of &amp;quot;Long jump&amp;quot;&lt;br /&gt;
3576H  PUSH H               ; Push &amp;quot;Long jump&amp;quot; address to stack&lt;br /&gt;
3577H  PUSH PSW             ; Save function key press to stack&lt;br /&gt;
3578H  CPI 02H              ; Test if function key is F5-F8 (Non file operation F Keys)&lt;br /&gt;
357AH  JNC 35B9H            ; Jump to Function key handler if F5-F8 (No tagging to process)&lt;br /&gt;
357DH  LDA FCCCH            ; Last Tag/Untag operation code&lt;br /&gt;
3580H  ANA A                ; Test if a tag operation was performed&lt;br /&gt;
3581H  JZ 35B9H             ; Jump to Function key handler if no tag operation performed&lt;br /&gt;
3584H  LDA FCD6H            ; Count of files on screen&lt;br /&gt;
3587H  MOV C,A              ; Save count of files for loop decrementing &lt;br /&gt;
3588H  INR C                ; Increment by 1 for loop bounding&lt;br /&gt;
3589H  MVI B,00H            ; Start with index zero on the LCD&lt;br /&gt;
358BH  PUSH B               ; Save the current index on the stack&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display next file&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
358CH  LDA FCCDH            ; Currently selected file index&lt;br /&gt;
358FH  STA FCD5H            ; Currently selected file index - temp&lt;br /&gt;
3592H  CALL 3AC4H           ; Print selected file using normal video&lt;br /&gt;
3595H  POP B                ; Restore index from stack&lt;br /&gt;
3596H  INR B                ; Increment to the next file index to display&lt;br /&gt;
3597H  DCR C	            ; Decrement the loop control&lt;br /&gt;
3598H  JZ 48B5H             ; Branch to perform &amp;quot;Long Jump&amp;quot; if all files printed to LCD&lt;br /&gt;
359BH  MOV A,B              ; Get the index of the current file&lt;br /&gt;
359CH  STA FCD5H            ; Save in temporary &amp;quot;current file&amp;quot; area&lt;br /&gt;
359FH  STA FCCDH            ; Currently selected file index&lt;br /&gt;
35A2H  PUSH B               ; Push the value on the stack for the next iteration&lt;br /&gt;
35A3H  CALL 3AB2H           ; Print currently selected file using inverse video&lt;br /&gt;
35A6H  LHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
35A9H  DCX H                ; Decrement to the Tag area for the file&lt;br /&gt;
35AAH  MOV A,M              ; Get the file&#039;s Tag code&lt;br /&gt;
35ABH  CPI 3EH              ; Compare with &#039;&amp;gt;&#039;&lt;br /&gt;
35ADH  JNZ 358CH            ; Jump to process next file if not tagged&lt;br /&gt;
35B0H  POP B                ; Pop currently selected file value from stack&lt;br /&gt;
35B1H  POP PSW    &lt;br /&gt;
35B2H  LXI H,358CH          ; Return address to display the next file&lt;br /&gt;
35B5H  PUSH PSW             ; ? Stack trickery&lt;br /&gt;
35B6H  PUSH B               ; Save current file index to stack for use after a RET operation&lt;br /&gt;
35B7H  PUSH H               ; Setup &amp;quot;Display next file&amp;quot; as a return address for RET&lt;br /&gt;
35B8H  PUSH PSW             ; ? More stack trickery&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Function key handler - Disk mode and dispatch to RAM mode&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
35B9H  CALL 4C56H           ; Stop automatic scrolling&lt;br /&gt;
35BCH  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
35BFH  ORA A     &lt;br /&gt;
35C0H  JZ 35E2H             ; Branch if in RAM mode&lt;br /&gt;
35C3H  POP PSW   &lt;br /&gt;
35C4H  ANA A                ; Test for F1&lt;br /&gt;
35C5H  JZ 3B2EH             ; Branch to F1 handler for disk&lt;br /&gt;
35C8H  DCR A                ; Test for F2&lt;br /&gt;
35C9H  JZ 3D73H  &lt;br /&gt;
35CCH  DCR A                ; Test for F3&lt;br /&gt;
35CDH  JZ 3D9FH  &lt;br /&gt;
35D0H  DCR A                ; Skip F4 - handled at lower level&lt;br /&gt;
35D1H  DCR A                ; Test for F5&lt;br /&gt;
35D2H  JZ 3D53H  &lt;br /&gt;
35D5H  DCR A                ; Skip F6 - handled at lower level&lt;br /&gt;
35D6H  DCR A                ; Test for F7&lt;br /&gt;
35D7H  JZ 3D00H  &lt;br /&gt;
35DAH  DCR A                ; Test for F8&lt;br /&gt;
35DBH  POP H     &lt;br /&gt;
35DCH  JZ 35FEH             ; Jump to exit if F8&lt;br /&gt;
35DFH  JMP 3564H            ; Jump to main loop&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Function key handler - RAM mode&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
35E2H  POP PSW  &lt;br /&gt;
35E3H  ANA A                ; Test for F1 &lt;br /&gt;
35E4H  JZ 3C4BH &lt;br /&gt;
35E7H  DCR A                ; Test for F2&lt;br /&gt;
35E8H  JZ 3C2BH &lt;br /&gt;
35EBH  DCR A                ; Test for F3&lt;br /&gt;
35ECH  JZ 3AF8H &lt;br /&gt;
35EFH  DCR A                ; Skip F4 - handled at lower level&lt;br /&gt;
35F0H  DCR A                ; Test for F5&lt;br /&gt;
35F1H  JZ 3E5CH &lt;br /&gt;
35F4H  DCR A                ; Skip F6 - handled at lower level&lt;br /&gt;
35F5H  DCR A                ; Skip F7 - not defined for RAM&lt;br /&gt;
35F6H  DCR A                ; Test for F8&lt;br /&gt;
35F7H  POP H    &lt;br /&gt;
35F8H  JZ 35FEH             ; Jump to exit if F8&lt;br /&gt;
35FBH  JMP 3564H            ; Jump back to main loop&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; This is the UI exit routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
35FEH  CALL 4AC4H           ; Restore original baud settings&lt;br /&gt;
3601H  CALL 4BD7H           ; Wait for TX empty and Reset UART to accept mode bits&lt;br /&gt;
3604H  CALL 4C27H           ; CLS statement&lt;br /&gt;
3607H  CALL 4C5AH           ; Resume automatic scrolling&lt;br /&gt;
360AH  LXI H,0000H&lt;br /&gt;
360DH  PUSH H&lt;br /&gt;
360EH  JMP 00A6H            ; Exit TS-DOS&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print Copyright string and files&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3611H  LXI H,0101H          ; Goto top left corner&lt;br /&gt;
3614H  SHLD F639H           ; Cursor row (1-8)&lt;br /&gt;
3617H  LXI H,3E69H          ; Point to &amp;quot;TS-DOS&amp;quot; copyright string&lt;br /&gt;
361AH  CALL 4A2CH           ; Send buffer at M to screen&lt;br /&gt;
361DH  XRA A                ; Indicate no previous Tag/Untag operation&lt;br /&gt;
361EH  STA FCCCH            ; Last Tag/Untag operation code&lt;br /&gt;
3621H  MVI A,01H            ; Start with 1st file in list&lt;br /&gt;
3623H  STA FCD5H            ; Currently selected file index - temp&lt;br /&gt;
3626H  LXI H,0202H          ; Goto first file entry location&lt;br /&gt;
3629H  SHLD F639H           ; Cursor row (1-8)&lt;br /&gt;
362CH  JMP 383BH            ; Draw the display&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print length of selected file using inverse video&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
362FH  LDA FCCDH            ; Currently selected file index      &lt;br /&gt;
3632H  STA FCD5H            ; Currently selected file index - temp      &lt;br /&gt;
3635H  CALL 3AB2H           ; Print currently seleted file using inverse video       &lt;br /&gt;
3638H  LDA FCD5H            ; Currently selected file index - temp      &lt;br /&gt;
363BH  DCR A                ; Make index zero based for multiply x2  &lt;br /&gt;
363CH  STC                  ; Set Carry flag&lt;br /&gt;
363DH  CMC                  ; Compliment (clear) carry flag&lt;br /&gt;
363EH  RLC		            ; Rotate left circular &lt;br /&gt;
363FH  MOV E,A              ; E = File index * 2 to point to file length value    &lt;br /&gt;
3640H  MVI D,00H            ; Clear MSB of file length offset      &lt;br /&gt;
3642H  LXI H,F685H          ; Keyboard buffer - store file lengths        &lt;br /&gt;
3645H  DAD D                ; Add file lenght offset from beginning of keyboard buffer  &lt;br /&gt;
3646H  XCHG                 ; HL &amp;lt;--&amp;gt; DE Save file length address pointer in DE &lt;br /&gt;
3647H  LXI H,2307H          ; Load position of File Size area on LCD&lt;br /&gt;
364AH  SHLD F639H           ; Cursor row (1-8) &lt;br /&gt;
364DH  CALL 4C2BH           ; Erase from cursor to end of line&lt;br /&gt;
3650H  LHLX                 ; Load HL with file length &lt;br /&gt;
3651H  CALL 4C2FH           ; Start inverse character mode       &lt;br /&gt;
3654H  CALL 4C3EH           ; Print binary number in HL at current position       &lt;br /&gt;
3657H  CALL 4C33H           ; Cancel inverse character mode         &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Keyboard scan loop&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
365AH  CALL 3DFEH           ; Process automatic power off logic&lt;br /&gt;
365DH  CALL 4BEFH           ; Scan keyboard for character (CTRL-BREAK ==&amp;gt; CTRL-C)&lt;br /&gt;
3660H  JZ 365AH             ; Jump to scan keyboard again if no key pressed &lt;br /&gt;
3663H  JC 380CH             ; Jump to Function Key Handler if FKey &lt;br /&gt;
3666H  CPI 0DH              ; Test for CR&lt;br /&gt;
3668H  JZ 3722H   &lt;br /&gt;
366BH  CPI 17H              ; Test for Ctrl-Up key&lt;br /&gt;
366DH  JZ 37AAH   &lt;br /&gt;
3670H  CPI 14H              ; Test for Shift-Up key&lt;br /&gt;
3672H  JZ 3798H   &lt;br /&gt;
3675H  CPI 5DH              ; Test for &amp;quot;]&amp;quot; key&lt;br /&gt;
3677H  JZ 3798H   &lt;br /&gt;
367AH  CPI 3FH              ; Test for &amp;quot;?&amp;quot; key&lt;br /&gt;
367CH  JZ 3777H   &lt;br /&gt;
367FH  CPI 02H              ; Test for Shift-Down arrow key&lt;br /&gt;
3681H  JZ 3777H   &lt;br /&gt;
3684H  CPI 1EH              ; Test for up key&lt;br /&gt;
3686H  JZ 36EEH   &lt;br /&gt;
3689H  CPI 1FH              ; Test for down key&lt;br /&gt;
368BH  JZ 36FCH   &lt;br /&gt;
368EH  CPI 1DH              ; Test for &amp;quot;left arrow&amp;quot; key&lt;br /&gt;
3690H  JZ 36DDH   &lt;br /&gt;
3693H  CPI 1CH              ; Test for &amp;quot;Right arrow&amp;quot; key&lt;br /&gt;
3695H  JZ 36CAH   &lt;br /&gt;
3698H  CPI 20H              ; Test for space key &lt;br /&gt;
369AH  JZ 36CAH             ; Treat space the same as right arrow  &lt;br /&gt;
369DH  ANI DFH              ; Convert to Upper case &lt;br /&gt;
369FH  CPI 52H              ; Test for &#039;R&#039; character  &lt;br /&gt;
36A1H  JZ 3759H   &lt;br /&gt;
36A4H  CPI 54H              ; Test for &#039;T&#039; character &lt;br /&gt;
36A6H  JZ 37EEH   &lt;br /&gt;
36A9H  CPI 41H              ; Test for &amp;quot;A&amp;quot; key &lt;br /&gt;
36ABH  JZ 3715H   &lt;br /&gt;
36AEH  CPI 47H              ; Test for &amp;quot;G&amp;quot; key &lt;br /&gt;
36B0H  JZ 3715H   &lt;br /&gt;
36B3H  CPI 55H              ; Test for &amp;quot;U&amp;quot; key &lt;br /&gt;
36B5H  JZ 37AEH   &lt;br /&gt;
36B8H  CPI 44H              ; Test for &amp;quot;D&amp;quot; key &lt;br /&gt;
36BAH  JZ 39B9H   &lt;br /&gt;
36BDH  CPI 4CH              ; Test for &amp;quot;L&amp;quot; key &lt;br /&gt;
36BFH  JZ 39C2H   &lt;br /&gt;
36C2H  CPI 50H              ; Test for &amp;quot;P&amp;quot; key &lt;br /&gt;
36C4H  JZ 39C2H   &lt;br /&gt;
36C7H  JMP 365AH            ; Go scan keyboard again   &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Right Arrow key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
36CAH  MVI A,01H            ; Prepare to add 1 to selected file    &lt;br /&gt;
36CCH  LXI H,FCD5H          ; Currently selected file index - temp storage&lt;br /&gt;
36CFH  ADD M                ; Add 1 to the selected file index&lt;br /&gt;
36D0H  INX H                ; Point to file count on screen&lt;br /&gt;
36D1H  CMP M                ; Compare new index with screen file count&lt;br /&gt;
36D2H  JC 370AH             ; Jump to process new file if we didn&#039;t wrap   &lt;br /&gt;
36D5H  JZ 370AH             ; Jump to process new file if = file count   &lt;br /&gt;
36D8H  MVI A,01H            ; Wrap to the first file    &lt;br /&gt;
36DAH  JMP 370AH            ; Go process file 1 as the new selection    &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Left Arrow key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
36DDH  LDA FCD5H            ; Currently selected file index - temp storage&lt;br /&gt;
36E0H  DCR A                ; Move to next lowest file index&lt;br /&gt;
36E1H  JNZ 370AH            ; If no wrap, jump to process new selection&lt;br /&gt;
36E4H  LDA FCD6H            ; Count of files on screen&lt;br /&gt;
36E7H  ANA A                ; Ensure there is at least 1 file on the screen &lt;br /&gt;
36E8H  JZ 365AH             ; Jump to keyboard scan loop if no files on LCD&lt;br /&gt;
36EBH  JMP 370AH            ; Go process new selection as the max (wrap-around)&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Up Arrow key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
36EEH  LDA FCD5H            ; Currently selected file index - temp storage&lt;br /&gt;
36F1H  SUI 04H              ; Subtract 4 from file count (4 files per line)&lt;br /&gt;
36F3H  JC 365AH             ; Jump to keysacn loop if negative&lt;br /&gt;
36F6H  JZ 365AH             ; Jump to keysacn loop if zero&lt;br /&gt;
36F9H  JMP 370AH            ; Go process the new file index setting&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Down Arrow key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
36FCH  MVI A,04H            ; There are 4 files per line &lt;br /&gt;
36FEH  LXI H,FCD5H          ; Currently selected file index - temp storage&lt;br /&gt;
3701H  ADD M                ; Add 4 to the index number&lt;br /&gt;
3702H  MOV C,A              ; Save new index for comparison and further processing  &lt;br /&gt;
3703H  INX H                ; Maximum file index count&lt;br /&gt;
3704H  MOV A,M              ; Load maximum index for bounds  &lt;br /&gt;
3705H  CMP C                ; Compare new index with maximum&lt;br /&gt;
3706H  JC 365AH             ; Jump to keyboard scan if moving past last file   &lt;br /&gt;
3709H  MOV A,C              ; Restore new current file index  &lt;br /&gt;
370AH  PUSH PSW             ; Save new file index for storage after the call   &lt;br /&gt;
370BH  CALL 3AC4H           ; Print selected file using normal video     &lt;br /&gt;
370EH  POP PSW              ; Restore new file index from stack  &lt;br /&gt;
370FH  STA FCCDH            ; Save the new file index    &lt;br /&gt;
3712H  JMP 362FH            ; Print length of selected file using inverse video.    &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;A&amp;quot; or &amp;quot;G&amp;quot; key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3715H  MVI A,3EH            ; Load &amp;quot;&amp;gt;&amp;quot; for the tag symbol&lt;br /&gt;
3717H  CALL 37CAH           ; Go tag all files on the LCD&lt;br /&gt;
371AH  MVI A,01H            ; Indicate last operation as &amp;quot;Tag All&amp;quot;&lt;br /&gt;
371CH  STA FCCCH            ; Last Tag/Untag operation code&lt;br /&gt;
371FH  JMP 362FH            ; Print length of selected file using inverse video.&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Enter key from TS-DOS key scan - Change Directory&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3722H  LDA FCCBH            ; Get NADSBox/Desklink/TPDD2 flag     &lt;br /&gt;
3725H  CPI 02H              ; Test if NADSBox current directory valid   &lt;br /&gt;
3727H  JNZ 365AH            ; Back to keyscan if no &amp;quot;current directory&amp;quot; - Enter is meaningless     &lt;br /&gt;
372AH  LHLD FCE4H           ; LCD Buffer address of current file selection      &lt;br /&gt;
372DH  LXI B,0007H          ; Load offset of file extension       &lt;br /&gt;
3730H  DAD B                ; Point to file extension of selected file &lt;br /&gt;
3731H  MOV A,M              ; Load the 1st byte of the file extension   &lt;br /&gt;
3732H  CPI 3CH              ; Test if 1st byte of extension is &amp;quot;&amp;lt;&amp;quot;   &lt;br /&gt;
3734H  JNZ 365AH            ; Jump to keyscan if current selection not directory entry     &lt;br /&gt;
3737H  CALL 4A3BH           ; Initialize blank filename and attribute byte      &lt;br /&gt;
373AH  LHLD FCE4H           ; LCD Buffer address of current file selection      &lt;br /&gt;
373DH  CALL 3D95H           ; Copy filename at (HL) to TX buffer      &lt;br /&gt;
3740H  CALL 408AH           ; Open TPDD file for Read Mode      &lt;br /&gt;
3743H  LXI H,0002H          ; Load opcode to close currently opened file       &lt;br /&gt;
3746H  CALL 409BH           ; Send Request in HL and await response      &lt;br /&gt;
3749H  LHLD FCE4H           ; LCD Buffer address of current file selection      &lt;br /&gt;
374CH  LXI D,FCC0H          ; NADSBox current directory storage    &lt;br /&gt;
374FH  LXI B,0009H          ; Copy 9 bytes of NADSBox directory to the LCD       &lt;br /&gt;
3752H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
3755H  XRA A                ; Clear A to show 1st page of files &lt;br /&gt;
3756H  JMP 378AH            ; Branch to show the page of files in A     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;R&amp;quot; key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3759H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
375CH  ANA A                ; Test if in Disk mode&lt;br /&gt;
375DH  JNZ 362FH            ; Jump to keyscan if in Disk mode&lt;br /&gt;
3760H  LHLD FCE4H           ; LCD Buffer address of current file selection       &lt;br /&gt;
3763H  CALL 4902H           ; Copy filename at (HL) to current BASIC program&lt;br /&gt;
3766H  CALL 4A51H           ; Get RAM directory address of current BASIC program          &lt;br /&gt;
3769H  CPI C0H              ; Test if filetype is .DO&lt;br /&gt;
376BH  CZ 5000H             ; Call routine to Compress / Decompress .DO files&lt;br /&gt;
376EH  CALL 4C0FH           ; Update system pointers       &lt;br /&gt;
3771H  CALL 3611H           ; Print Copyright and files&lt;br /&gt;
3774H  JMP 362FH            ; Jump to keyscan &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;?&amp;quot; and Shift-Down key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3777H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
377AH  ANA A                ; Test if RAM mode &lt;br /&gt;
377BH  JZ 365AH             ; Branch to keyscan if in RAM mode    &lt;br /&gt;
377EH  LDA FCD6H            ; Count of files on screen     &lt;br /&gt;
3781H  CPI 14H              ; Maximum number of files that fit on the screen   &lt;br /&gt;
3783H  JC 365AH             ; Branch to keyscan if on last page    &lt;br /&gt;
3786H  LDA FCD4H            ; Current Page of files being displayed     &lt;br /&gt;
3789H  INR A                ; Increment to next page of files &lt;br /&gt;
				 &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Show the page of files indicated by A&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
378AH  STA FCD4H            ; Current Page of files being displayed     &lt;br /&gt;
378DH  MVI A,01H            ; Go to 1st file on the new page     &lt;br /&gt;
378FH  STA FCCDH            ; Currently selected file index     &lt;br /&gt;
3792H  CALL 3611H           ; Print copyright and files      &lt;br /&gt;
3795H  JMP 362FH            ; Print length of selected file using inverse video     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;]&amp;quot; and Shift-Up key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3798H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
379BH  ANA A                ; Test if RAM mode &lt;br /&gt;
379CH  JZ 365AH             ; Branch to keyscan if in RAM mode    &lt;br /&gt;
379FH  LDA FCD4H            ; Current Page of files being displayed     &lt;br /&gt;
37A2H  ANA A                ; Test if current page is zero &lt;br /&gt;
37A3H  JZ 365AH             ; Branch to keyscan if already on page 0    &lt;br /&gt;
37A6H  DCR A                ; Decrement the page number &lt;br /&gt;
37A7H  JMP 378AH            ; Show the page of files indicated by A&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle Ctrl-Up key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
37AAH  XRA A                ; Go to page zero&lt;br /&gt;
37ABH  JMP 378AH            ; Show the page of files indicated by A&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;U&amp;quot; key from TS-DOS key scan - Remove all tags&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
37AEH  MVI A,20H            ; Display &#039; &#039; as the tag marker&lt;br /&gt;
37B0H  CALL 37CAH           ; Go process tag for all files&lt;br /&gt;
37B3H  XRA A                ; Indicate last tag operation was untag&lt;br /&gt;
37B4H  STA FCCCH            ; Store as &amp;quot;last tag&amp;quot; operation&lt;br /&gt;
37B7H  JMP 362FH            ; Print length of selected file using inverse video&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Swap TPDD2 Bank number&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
37BAH  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag&lt;br /&gt;
37BDH  DCR A                ; Test if the flag = 1 (TPDD2)&lt;br /&gt;
37BEH  JNZ 365AH            ; Jump to keyscan if not 1&lt;br /&gt;
37C1H  LDA FCCAH            ; Get TPDD Bank Number&lt;br /&gt;
37C4H  XRI 01H              ; Switch to the other bank&lt;br /&gt;
37C6H  STA FCCAH            ; Save TPDD bank number&lt;br /&gt;
37C9H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process Tag or Untag for all files on screen&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
37CAH  STA FCCCH            ; Store tag/untag code for later      &lt;br /&gt;
37CDH  LDA FCD6H            ; Get Maximum file count on screen      &lt;br /&gt;
37D0H  ANA A                ; Test for zero  &lt;br /&gt;
37D1H  RZ		            ; Return if no files on screen&lt;br /&gt;
37D2H  XRA A                ; Clear A  &lt;br /&gt;
37D3H  INR A                ; A=1 to selet 1st file  &lt;br /&gt;
37D4H  STA FCD5H            ; Currently selected file index      &lt;br /&gt;
37D7H  CALL 3ACDH           ; Calculate Row and Column of soon-to-be (newly) selected file       &lt;br /&gt;
37DAH  LHLD FCE4H           ; LCD Buffer address of current file selection       &lt;br /&gt;
37DDH  DCX H                ; Point to Tag location for the file  &lt;br /&gt;
37DEH  LDA FCCCH            ; Get the tag/untag code      &lt;br /&gt;
37E1H  RST 4                ; Display A to the LCD    &lt;br /&gt;
37E2H  LDA FCD5H            ; Get currently selected file index      &lt;br /&gt;
37E5H  LXI H,FCD6H          ; Point to count of files on screen        &lt;br /&gt;
37E8H  CMP M                ; Compare current selection with count of files on LCD  &lt;br /&gt;
37E9H  JC 37D3H             ; Jump to process next file if more files left     &lt;br /&gt;
37ECH  ANA A                ; Set zero flag to indicate files were tagged/untagged  &lt;br /&gt;
37EDH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;T&amp;quot; key key from TS-DOS key scan - TAG&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
37EEH  CALL 3ACDH           ; Calculate Row and Column of soon-to-be (newly) selected file    &lt;br /&gt;
37F1H  CALL 4C2FH           ; Start inverse character mode    &lt;br /&gt;
37F4H  LHLD FCE4H           ; LCD Buffer address of current file selection    &lt;br /&gt;
37F7H  DCX H	            ; Point to the &amp;quot;Tag&amp;quot; area for the file&lt;br /&gt;
37F8H  MVI A,3EH            ; Load the code for &amp;quot;&amp;gt;&amp;quot;   &lt;br /&gt;
37FAH  CMP M                ; Compare if file is already tagged     &lt;br /&gt;
37FBH  JNZ 3800H            ; Skip ahead if already tagged   &lt;br /&gt;
37FEH  MVI A,20H            ; Need to untag - load the untag code   &lt;br /&gt;
3800H  RST 4                ; Display the tag code on the LCD   &lt;br /&gt;
3801H  CALL 4C33H           ; Cancel inverse character mode    &lt;br /&gt;
3804H  LXI H,FCCCH          ; Point to &amp;quot;last tag&amp;quot; operation code     &lt;br /&gt;
3807H  MVI M,01H            ; Indicate last operation was &amp;quot;tag&amp;quot;   &lt;br /&gt;
3809H  JMP 36CAH            ; Move to next file - jump to Right Arrow key handler   &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; 1st level Function Key Handler (handles F4 and F6)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
380CH  CPI 08H              ; Test for valid function key code     &lt;br /&gt;
380EH  JNC 365AH            ; Branch back to scan loop if invalid       &lt;br /&gt;
3811H  CPI 05H              ; Test for F6     &lt;br /&gt;
3813H  JZ 3833H             ; Jump if F6 pressed      &lt;br /&gt;
3816H  CPI 03H              ; Test for F4     &lt;br /&gt;
3818H  RNZ                  ; Return to &amp;quot;Main Loop&amp;quot; if not F4 pressed &lt;br /&gt;
3819H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)       &lt;br /&gt;
381CH  XRI 01H              ; Swap RAM/DISK mode     &lt;br /&gt;
381EH  STA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)       &lt;br /&gt;
3821H  XRA A                ; Clear A to go to 1st page of files   &lt;br /&gt;
3822H  STA FCD4H            ; Current Page of files being displayed       &lt;br /&gt;
3825H  MVI A,01H            ; Select the 1st file in the page       &lt;br /&gt;
3827H  STA FCCDH            ; Currently selected file index       &lt;br /&gt;
382AH  CALL 4C27H           ; CLS statement     &lt;br /&gt;
382DH  CALL 3611H           ; Print the title bar and files        &lt;br /&gt;
3830H  JMP 362FH            ; Print length of selected file using inverse video.       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F6 Function Key Handler&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3833H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
3836H  ANA A                ; Test if in RAM or DISK mode&lt;br /&gt;
3837H  RZ                   ; Return if RAM mode&lt;br /&gt;
3838H  JMP 37AAH            ; Jump to Ctrl-Up key handler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Draw the display.  This takes care of RAM and Disk mode displays, handles&lt;br /&gt;
;    skipping page number to the proper &amp;quot;Disk&amp;quot; page, displaying the Bank# or&lt;br /&gt;
;    current directory for NADSBox/Desklink, showing free space, filling in&lt;br /&gt;
;    empty slots with &amp;quot;-.-&amp;quot;, etc.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
383BH  LXI H,F685H          ; Keyboard buffer  &lt;br /&gt;
383EH  SHLD FCDBH           ; Initialize pointer to file length table (in keyboard buffer)     &lt;br /&gt;
3841H  XRA A                ; Prepare to set 1st file lenght to zero&lt;br /&gt;
3842H  MOV M,A              ; Set LSB of length of 1st file to zero  &lt;br /&gt;
3843H  INX H                ; Increment to MSB of length&lt;br /&gt;
3844H  MOV M,A              ; Set MSB of length of file to zero  &lt;br /&gt;
3845H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)    &lt;br /&gt;
3848H  ANA A                ; Test if RAM or DISK&lt;br /&gt;
3849H  JZ 395DH             ; Jump to show RAM files if in RAM mode   &lt;br /&gt;
384CH  XRA A                ; Prepare to initialize the &amp;quot;page being processed&amp;quot; variable&lt;br /&gt;
384DH  STA FCDAH            ; Clear the &amp;quot;page being processed&amp;quot; variable    &lt;br /&gt;
3850H  CALL 4735H           ; Clear #files displayed, init TPDD and send 1st file dir referene opcode     &lt;br /&gt;
3853H  JNZ 390FH            ; Process unformated disk (empty slots and error message)    &lt;br /&gt;
3856H  LDA FCD4H            ; Current Page of files being displayed    &lt;br /&gt;
3859H  ANA A                ; Test if displaying page 0&lt;br /&gt;
385AH  JZ 3871H             ; Jump if showing page 0 - don&#039;t need to skikp any pages   &lt;br /&gt;
385DH  STA FCDAH            ; Initialize the number of pages left to skip count    &lt;br /&gt;
3860H  CALL 4742H           ; Read next page of files from server     &lt;br /&gt;
3863H  LDA FCDAH            ; Get the &amp;quot;Pages left to skip&amp;quot; count    &lt;br /&gt;
3866H  DCR A                ; Decrement the remaining skip page count &lt;br /&gt;
3867H  JNZ 385DH            ; Keep reading pages until we have skipped enough pages     &lt;br /&gt;
386AH  XRA A                ; Prepare to clear the remaining skip page count &lt;br /&gt;
386BH  STA FCDAH            ; Clear the remaining skip page count     &lt;br /&gt;
386EH  STA FCD6H            ; Count of files on screen     &lt;br /&gt;
3871H  CALL 4742H           ; Read next page of files from server      &lt;br /&gt;
3874H  LDA FCD6H            ; Count of files on screen     &lt;br /&gt;
3877H  CPI 14H              ; Test if all file slots are full   &lt;br /&gt;
3879H  CC 39AAH             ; Print &amp;quot;-.-&amp;quot; for all empty file slots (if any)    &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print NADSBox directory or TPDD Bank number to LCD&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
387CH  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag    &lt;br /&gt;
387FH  ANA A                ; Test if server is TPDD&lt;br /&gt;
3880H  JZ 389FH             ; Skip processing Bank # or Current Dir if TPDD   &lt;br /&gt;
3883H  DCR A                ; Test if server is TPDD2&lt;br /&gt;
3884H  JZ 388DH             ; Jump to print bank number if TPDD2   &lt;br /&gt;
3887H  LXI H,FCC0H          ; Load pointer to NADSBox current directory storage    &lt;br /&gt;
388AH  JMP 38A5H            ; Jump to print the NADSBox / Desklink directory    &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print the TPDD Bank number to LCD&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
388DH  LXI H,2401H          ; Go to Row 1, column 24&lt;br /&gt;
3890H  SHLD F639H           ; Cursor row (1-8) &lt;br /&gt;
3893H  CALL 4C2FH           ; Start inverse character mode &lt;br /&gt;
3896H  MVI A,23H            ; ASCII code for &#039;#&#039; &lt;br /&gt;
3898H  RST 4                ; Send character in A to the LCD&lt;br /&gt;
3899H  LDA FCCAH            ; Load TPDD Bank number &lt;br /&gt;
389CH  ADI 30H              ; Convert to ASCII digit   &lt;br /&gt;
389EH  RST 4                ; Send it to the LCD  &lt;br /&gt;
389FH  CALL 4C33H           ; Cancel inverse character mode&lt;br /&gt;
38A2H  JMP 38B8H            ; Branch to print the function menu, RAM/Disk free, etc.&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print the NADSBox / Desklink current directory in title bar&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
38A5H  PUSH H               ; Save address of the directory string     &lt;br /&gt;
38A6H  LXI H,2101H          ; Prepare to position the cursor in the title bar          &lt;br /&gt;
38A9H  SHLD F639H           ; Cursor row (1-8)         &lt;br /&gt;
38ACH  CALL 4C2FH           ; Start inverse character mode         &lt;br /&gt;
38AFH  POP H                ; Retrieve the directory string from the stack    &lt;br /&gt;
38B0H  MVI C,06H            ; Prepare to redraw 6 chars with inverse video        &lt;br /&gt;
38B2H  CALL 48E5H           ; Redraw C characters from buffer at HL using current video mode         &lt;br /&gt;
38B5H  CALL 4C33H           ; Cancel inverse character mode         &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print funtion menu, RAM/Disk free &amp;amp; selected file length&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
38B8H  LXI H,3E97H          ; Point to Disk function menu          &lt;br /&gt;
38BBH  LXI B,3936H          ; Routine to print free disk space          &lt;br /&gt;
38BEH  LDA FCD9H            ; RAM/Disk mode        &lt;br /&gt;
38C1H  ANA A                ; Test if in Disk mode and skip ahead to print Disk FKeys    &lt;br /&gt;
38C2H  JNZ 38CBH            ; Skip ahead if in disk mode to keep vectors        &lt;br /&gt;
38C5H  LXI H,3ED9H          ; Point to RAM function menu          &lt;br /&gt;
38C8H  LXI B,3922H          ; Routine to print free RAM space          &lt;br /&gt;
38CBH  PUSH B               ; Save routine address to stack     &lt;br /&gt;
38CCH  PUSH H               ; Save pointer to function text to stack     &lt;br /&gt;
38CDH  LDA FCCDH            ; Currently selected file index        &lt;br /&gt;
38D0H  LXI H,FCD6H          ; Count of files on screen          &lt;br /&gt;
38D3H  CMP M                ; Compare selected file with count of files on screen    &lt;br /&gt;
38D4H  JC 38DDH             ; Branch if within bounds       &lt;br /&gt;
38D7H  MOV A,M              ; Get the file count      &lt;br /&gt;
38D8H  ANA A                ; Test if #files = 0    &lt;br /&gt;
38D9H  JNZ 38DDH            ; Skip ahead if not zero        &lt;br /&gt;
38DCH  INR A                ; Don&#039;t allow a count of zero - must be 1    &lt;br /&gt;
38DDH  STA FCD5H            ; Currently selected file index - temp       &lt;br /&gt;
38E0H  LXI H,0B07H          ; Row &amp;amp; column of start of text          &lt;br /&gt;
38E3H  SHLD F639H           ; Cursor row (1-8)          &lt;br /&gt;
38E6H  POP H                ; Get address of text from the stack and display it   &lt;br /&gt;
38E7H  CALL 4A2CH           ; Send buffer at M to screen        &lt;br /&gt;
38EAH  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)       &lt;br /&gt;
38EDH  ANA A                ; Test if in RAM mode   &lt;br /&gt;
38EEH  JZ 3905H             ; Jump if in RAM mode (0 = RAM)       &lt;br /&gt;
38F1H  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag   &lt;br /&gt;
38F4H  ANA A                ; Test if server is TPDD      &lt;br /&gt;
38F5H  JZ 3905H             ; Skip printing of &amp;quot;Bank&amp;quot; or &amp;quot;Mkdr&amp;quot; if TPDD       &lt;br /&gt;
38F8H  LXI H,3FE9H          ; Point to text for &amp;quot;Bank&amp;quot;     &lt;br /&gt;
38FBH  DCR A                ; Test if server is TPDD2      &lt;br /&gt;
38FCH  JZ 3902H             ; Jump to print &amp;quot;Bank&amp;quot; if TPDD2         &lt;br /&gt;
38FFH  LXI H,3FD8H          ; Point to text for &amp;quot;Mkdr&amp;quot;        &lt;br /&gt;
3902H  CALL 4A2CH           ; Send buffer at M to screen                  &lt;br /&gt;
3905H  CALL 3940H           ; Display DISK ON/OFF status on LCD         &lt;br /&gt;
3908H  LXI H,1507H          ; Point to location for &amp;quot;Free&amp;quot; space (RAM or DISK)&lt;br /&gt;
390BH  SHLD F639H           ; Cursor row (1-8)          &lt;br /&gt;
390EH  RET                  &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle unformatted disks.  Print message and show empty slots.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
390FH  XRA A                ; Starting with slot zero...&lt;br /&gt;
3910H  CALL 39AAH           ; Print &amp;quot;-.-&amp;quot; for all empty file slots&lt;br /&gt;
3913H  LXI H,3E97H          ; Point to Disk Function menu string&lt;br /&gt;
3916H  LXI B,391CH          ; Print NOT FORMATTED to the display&lt;br /&gt;
3919H  JMP 38CBH            ; Go process the print and jump to error handler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print &amp;quot;NOT FORMATTED&amp;quot; on the LCD and return&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
391CH  LXI H,`H             ; Point to &amp;quot;NOT FORMATTED&amp;quot; string&lt;br /&gt;
391FH  JMP 4A2CH            ; Send buffer at M to screen&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print RAM free space at current posiiton&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3922H  LHLD FBB2H           ; Start of variable data pointer  &lt;br /&gt;
3925H  XCHG                 ; HL &amp;lt;--&amp;gt; DE&lt;br /&gt;
3926H  LHLD F678H           ; BASIC string buffer pointer  &lt;br /&gt;
3929H  MOV A,L              ; Prepare for 16 bit subtract   &lt;br /&gt;
392AH  SUB E                ; Subtract LSB &lt;br /&gt;
392BH  MOV L,A              ; Save LSB of difference for printing   &lt;br /&gt;
392CH  MOV A,H              ; Prepare for subtrating MSB   &lt;br /&gt;
392DH  SBB D                ; Subtract MSB &lt;br /&gt;
392EH  MOV H,A              ; Save in H for printing   &lt;br /&gt;
392FH  LXI B,FFF2H          ; Load signed number -14       &lt;br /&gt;
3932H  DAD B                ; Subtract 14 from free memory &lt;br /&gt;
3933H  JMP 4C3EH            ; Print binary number in HL at current position     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display free space on disk&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3936H  CALL 4A10H           ; Calculate free space on disk&lt;br /&gt;
3939H  CALL 4C3EH           ; Print binary number in HL at current position&lt;br /&gt;
393CH  MVI A,30H            ; Prepare to add an extra &#039;0&#039; since calc is /10&lt;br /&gt;
393EH  RST 4                ; Send A to the LCD      &lt;br /&gt;
393FH  RET       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display DISK ON/OFF status on LCD&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3940H  LDA FCD9H            ; DISK/RAM mode (0=RAM, 1=DISK)       &lt;br /&gt;
3943H  ANA A                ; Test if in RAM mode   &lt;br /&gt;
3944H  RNZ                  ; Return if not in RAM mode  &lt;br /&gt;
3945H  LDA FB2CH            ; DISK-OFF/ON status   &lt;br /&gt;
3948H  LXI D,3FF2H          ; Load pointer to &amp;quot;OFF&amp;quot; text         &lt;br /&gt;
394BH  CPI DBH              ; Test if DISK mode (vector LSB) indicates ON or OFF     &lt;br /&gt;
394DH  JZ 3953H             ; Branch if in DISK-OFF mode      &lt;br /&gt;
3950H  LXI D,3FF6H          ; Load pointer to &amp;quot;ON&amp;quot; text         &lt;br /&gt;
3953H  LXI H,1908H          ; Location of DISK-OFF/ON indication on LCD         &lt;br /&gt;
3956H  SHLD F639H           ; Cursor row (1-8)   &lt;br /&gt;
3959H  XCHG                 ; HL = pointer to text in DE  &lt;br /&gt;
395AH  JMP 4A2CH            ; Send buffer at M to screen       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display RAM files to LCD and calculate file lengths&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
395DH  LXI H,F9BAH          ; Load pointer to 1st available file slot in catalog&lt;br /&gt;
3960H  XRA A                ; Set count of RAM files on screen to zero &lt;br /&gt;
3961H  STA FCD6H            ; Count of files on screen     &lt;br /&gt;
3964H  MVI A,14H            ; Get max # files that will fit on LCD     &lt;br /&gt;
3966H  DCR A                ; Decrement the max file count &lt;br /&gt;
3967H  PUSH PSW             ; Save count to the stack    &lt;br /&gt;
3968H  MOV A,M              ; Get file type   &lt;br /&gt;
3969H  XRI 80H              ; Compliment ?active bit   &lt;br /&gt;
396BH  ANI 9FH              ; Test if file is active and should be displayed   &lt;br /&gt;
396DH  JNZ 3996H            ; Branch to test next file if not displayed     &lt;br /&gt;
3970H  PUSH H               ; Save address of current catalog file  &lt;br /&gt;
3971H  INX H                ; Point to file address &lt;br /&gt;
3972H  MOV E,M              ; Get LSB of file address   &lt;br /&gt;
3973H  INX H                ; Point to MSB of address &lt;br /&gt;
3974H  MOV D,M              ; Get MSB of file address   &lt;br /&gt;
3975H  XTHL                 ; HL &amp;lt;--&amp;gt; (SP)  Get address of file within catalog&lt;br /&gt;
3976H  PUSH H               ; Push pointer to MSB of address on stack  &lt;br /&gt;
3977H  CALL 3CD3H           ; Calculate length of RAM file      &lt;br /&gt;
397AH  XCHG                 ; HL &amp;lt;--&amp;gt; DE DE has the length&lt;br /&gt;
397BH  CALL 4791H           ; Store next file length to keyboard buffer      &lt;br /&gt;
397EH  POP H                ; Get catalog address of current file from stack &lt;br /&gt;
397FH  XTHL                 ; HL &amp;lt;--&amp;gt; (SP) swap catalog address with pointer to MSB of file address&lt;br /&gt;
3980H  INX H                ; Increment to filename &lt;br /&gt;
3981H  MVI C,06H            ; Prepare to print 6 characters of filename     &lt;br /&gt;
3983H  CALL 48E5H           ; Redraw C characters from buffer at HL using current video mode       &lt;br /&gt;
3986H  MVI A,2EH            ; Load code for &#039;.&#039;      &lt;br /&gt;
3988H  RST 4                ; Send A to the LCD                &lt;br /&gt;
3989H  MVI C,02H            ; Prepare to print 2 ext bytes to LCD      &lt;br /&gt;
398BH  CALL 48E5H           ; Redraw C characters from buffer at HL using current video mode       &lt;br /&gt;
398EH  MVI A,20H            ; Load code for space      &lt;br /&gt;
3990H  RST 4                ; Send A to the LCD           &lt;br /&gt;
3991H  LXI H,FCD6H          ; Count of files on screen        &lt;br /&gt;
3994H  INR M                ; Increment number of files displayed on LCD  &lt;br /&gt;
3995H  POP H                ; Get catalog address of file from stack  &lt;br /&gt;
3996H  LXI D,000BH          ; Load offset to next file locaion in catalog        &lt;br /&gt;
3999H  DAD D                ; Offset HL to next file  &lt;br /&gt;
399AH  POP PSW              ; Restore the file count from the stack    &lt;br /&gt;
399BH  DCR A                ; Decrement the max file count on the LCD  &lt;br /&gt;
399CH  JNZ 3967H            ; Branch to test and display next file until zero      &lt;br /&gt;
399FH  LDA FCD6H            ; Get the count of files actually displayed on screen              &lt;br /&gt;
39A2H  CPI 14H              ; Test if max number of files displayed    &lt;br /&gt;
39A4H  CC 39AAH             ; Branch to display &amp;quot;-.-&amp;quot; for remaining empty slots if not max     &lt;br /&gt;
39A7H  JMP 387CH            ; Print NADSBox directory or TPDD Bank number to LCD      &lt;br /&gt;
				  &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print &amp;quot;-.-&amp;quot; for all empty file slots&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
39AAH  PUSH PSW             ; Save current file index count on stack &lt;br /&gt;
39ABH  LXI H,3FCDH          ; Point to &amp;quot;-.-&amp;quot; text&lt;br /&gt;
39AEH  CALL 4A2CH           ; Send buffer at M to screen &lt;br /&gt;
39B1H  POP PSW              ; Restore current count &lt;br /&gt;
39B2H  INR A                ; Increment file index number&lt;br /&gt;
39B3H  CPI 14H              ; Compare A with max files that fit on LCD&lt;br /&gt;
39B5H  JNZ 39AAH            ; Jump to print next &amp;quot;-.-&amp;quot; if not done&lt;br /&gt;
39B8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;D&amp;quot; key from TS-DOS key scan&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
39B9H  CALL 3AA8H           ; Test if printer busy.  Return if not busy or error&lt;br /&gt;
39BCH  CALL 4C52H           ; LCOPY statement&lt;br /&gt;
39BFH  JMP 362FH            ; Print length of selected file using inverse video.&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle &amp;quot;L&amp;quot;, &amp;quot;P&amp;quot; and &amp;quot;O&amp;quot; keys from TS-DOS key scan - list or print .DO file contents&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
39C2H  STA FCDFH            ; Save key pressed       &lt;br /&gt;
39C5H  LXI D,0007H          ; Load offset of Extension bytes         &lt;br /&gt;
39C8H  LHLD FCE4H           ; LCD Buffer address of current file selection        &lt;br /&gt;
39CBH  DAD D                ; Point to extension bytes in LCD buffer   &lt;br /&gt;
39CCH  MOV A,M              ; Get 1st extension byte     &lt;br /&gt;
39CDH  CPI 44H              ; Compare byte with &amp;quot;D&amp;quot;     &lt;br /&gt;
39CFH  JNZ 362FH            ; Print length of selected file using inverse video if not &amp;quot;D&amp;quot;       &lt;br /&gt;
39D2H  INX H                ; Point to 2nd extension byte  &lt;br /&gt;
39D3H  MOV A,M              ; Load 2nd extension byte for comparison&lt;br /&gt;
39D4H  CPI 4FH              ; Compare with &amp;quot;0&amp;quot;&lt;br /&gt;
39D6H  JNZ 3A06H            ; Jump to print compressed file&lt;br /&gt;
39D9H  CALL 3A49H           ; Prepare file for reading (open disk file, address of RAM file)        &lt;br /&gt;
39DCH  LDA FCDFH            ; Restore key pressed       &lt;br /&gt;
39DFH  CPI 4CH              ; Test if key was &amp;quot;L&amp;quot; - List to LCD     &lt;br /&gt;
39E1H  CZ 4C27H             ; CLS statement if LCD      &lt;br /&gt;
39E4H  CNZ 3AA8H            ; Test if printer busy.  Return if not busy or error       &lt;br /&gt;
39E7H  CALL 3A24H           ; Get next block of data to display/print (HL=address)        &lt;br /&gt;
39EAH  PUSH PSW             ; Push Z flag indicating if a full 128 bytes was read      &lt;br /&gt;
39EBH  CALL 3A6BH           ; Display / print file data bytes at HL, A has length                 &lt;br /&gt;
39EEH  POP PSW              ; Get Z flag indicating if 128 bytes read     &lt;br /&gt;
39EFH  JZ 39E7H             ; Jump to process more if 128 bytes were read last time      &lt;br /&gt;
39F2H  LDA FCDFH            ; Restore key pressed       &lt;br /&gt;
39F5H  CPI 4CH              ; Test if key was &amp;quot;L&amp;quot;              &lt;br /&gt;
39F7H  JNZ 3A00H            ; Skip beep if printing       &lt;br /&gt;
39FAH  MVI A,07H            ; Load code for BELL       &lt;br /&gt;
39FCH  RST 4                ; Go print a BELL (beep)    &lt;br /&gt;
39FDH  CALL 3DF8H           ; Process power-off logic and wait for a key from keyboard        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Clear screen and perform Long Jump&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3A00H  CALL 4C27H           ; CLS statement         &lt;br /&gt;
3A03H  JMP 48B5H            ; Branch to &amp;quot;Long Jump&amp;quot; operation        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handler for the &amp;quot;O&amp;quot; key - print a compressed file?? &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3A06H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)&lt;br /&gt;
3A09H  ANA A                ; Test if in Disk mode &lt;br /&gt;
3A0AH  JNZ 362FH            ; Jump to keyscan if in Disk mode&lt;br /&gt;
3A0DH  LHLD FCE4H           ; LCD Buffer address of current file selection      &lt;br /&gt;
3A10H  CALL 4902H           ; Copy filename at (HL) to current BASIC program&lt;br /&gt;
3A13H  CALL 4A51H           ; Get RAM directory address of current BASIC program&lt;br /&gt;
3A16H  CPI C0H              ; Test if filetype is .DO&lt;br /&gt;
3A18H  CZ 5004H             ; Call routine to Compress / Decompress .DO files&lt;br /&gt;
3A1BH  CALL 4C0FH           ; Update system pointers       &lt;br /&gt;
3A1EH  CALL 3611H           ; Print Copyright and files&lt;br /&gt;
3A21H  JMP 362FH            ; Jump to keyscan &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get next 128 bytes (or less) of data from RAM or disk file for display&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3A24H  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)      &lt;br /&gt;
3A27H  ANA A                ; Test if RAM mode  &lt;br /&gt;
3A28H  JNZ 40B6H            ; If not RAM mode, go send TPDD_READ data opcode and recieve response      &lt;br /&gt;
3A2BH  LHLD FCDDH           ; Get length of file to be displayed / printed       &lt;br /&gt;
3A2EH  LXI B,0080H          ; Prepare to subtract 128 from length&lt;br /&gt;
3A31H  MOV A,C              ; Save 128 to A    &lt;br /&gt;
3A32H  DSUB                 ; Subtract 128 from file length &lt;br /&gt;
3A33H  JNC 3A3AH            ; Branch if length &amp;gt;= 128      &lt;br /&gt;
3A36H  DAD B                ; Add 128 back to length to print &amp;quot;partial&amp;quot; buffer  &lt;br /&gt;
3A37H  MOV A,L              ; Move remainder of bytes to display/print    &lt;br /&gt;
3A38H  MOV L,H              ; Clear LSB of remainder    &lt;br /&gt;
3A39H  MOV C,A              ; Move LSB of remainder to C    &lt;br /&gt;
3A3AH  SHLD FCDDH           ; Save new remaining file length       &lt;br /&gt;
3A3DH  LHLD FCE0H           ; Load the address to be printed / saved       &lt;br /&gt;
3A40H  PUSH H               ; Save on stack    &lt;br /&gt;
3A41H  DAD B                ; Update address to be used for display/printing next time  &lt;br /&gt;
3A42H  SHLD FCE0H           ; Save address to be displayed / printed       &lt;br /&gt;
3A45H  POP H                ; Retrieve address to be printed this loop from stack  &lt;br /&gt;
3A46H  CPI 80H              ; Compare length with maximum    &lt;br /&gt;
3A48H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Initialize Selected file for display (RAM or Disk)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3A49H  CALL 4A3BH           ; Initialize blank filename and attribute byte&lt;br /&gt;
3A4CH  LHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
3A4FH  LDA FCD9H            ; RAM / Disk mode (0=RAM,  1=DISK)     &lt;br /&gt;
3A52H  ANA A                ; Test if in RAM mode &lt;br /&gt;
3A53H  JNZ 3A65H            ; Branch to process Disk files if in Disk mode     &lt;br /&gt;
3A56H  CALL 4A4BH           ; Get RAM directory address of selected file&lt;br /&gt;
3A59H  PUSH D               ; Push file address to stack  &lt;br /&gt;
3A5AH  CALL 3CD3H           ; Calculate length of RAM file, HL=address of catalog entry, DE=file address&lt;br /&gt;
3A5DH  SHLD FCDDH           ; Save length to FDC emulation sector storage area&lt;br /&gt;
3A60H  POP H                ; Pop address of file into H &lt;br /&gt;
3A61H  SHLD FCE0H           ; Save file address&lt;br /&gt;
3A64H  RET		 &lt;br /&gt;
				 &lt;br /&gt;
; =====================================================================================&lt;br /&gt;
; Send TPDD Open command to open selected file&lt;br /&gt;
; =====================================================================================&lt;br /&gt;
3A65H  CALL 3D95H           ; Copy filename at (HL) to TX buffer&lt;br /&gt;
3A68H  JMP 408AH            ; Open TPDD file for Read Mode&lt;br /&gt;
&lt;br /&gt;
; =====================================================================================&lt;br /&gt;
; Display / print file data bytes at HL, A has length&lt;br /&gt;
; =====================================================================================&lt;br /&gt;
3A6BH  XCHG                 ; HL &amp;lt;--&amp;gt; DE  &lt;br /&gt;
3A6CH  ORA A                ; Test if length = 0   &lt;br /&gt;
3A6DH  RZ                   ; Return if length = 0&lt;br /&gt;
3A6EH  MOV C,A              ; Save length count in C     &lt;br /&gt;
3A6FH  LDA FCDFH            ; Load key press value       &lt;br /&gt;
3A72H  CPI 4CH              ; Test if key was &amp;quot;L&amp;quot;     &lt;br /&gt;
3A74H  JNZ 3A82H            ; Jump to print contents if not &amp;quot;L&amp;quot;       &lt;br /&gt;
3A77H  CALL 3A8FH           ; Check for CTRL-C&lt;br /&gt;
3A7AH  LDAX D               ; Load next byte from src pointer    &lt;br /&gt;
3A7BH  RST 4                ; Send A to LCD           &lt;br /&gt;
3A7CH  INX D                ; Increment the pointer   &lt;br /&gt;
3A7DH  DCR C                ; Decrement the length count   &lt;br /&gt;
3A7EH  JNZ 3A77H            ; Keep looping until all data displayed       &lt;br /&gt;
3A81H  RET        &lt;br /&gt;
&lt;br /&gt;
; =====================================================================================&lt;br /&gt;
; Print file data bytes at HL, A has length&lt;br /&gt;
; =====================================================================================&lt;br /&gt;
3A82H  CALL 3A8FH           ; Test for CTRL-C, etc.&lt;br /&gt;
3A85H  LDAX D               ; Load next file byte from source poiner &lt;br /&gt;
3A86H  CALL 4C42H           ; Print A to printer, expanding tabs if necessary&lt;br /&gt;
3A89H  INX D                ; Increment pointer&lt;br /&gt;
3A8AH  DCR C                ; Decrement length count&lt;br /&gt;
3A8BH  JNZ 3A82H            ; Keep looping until all data printed    &lt;br /&gt;
3A8EH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test for ESC, CTRL-C or Space&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3A8FH  CALL 4C4AH           ; Check keyboard queue for pending characters&lt;br /&gt;
3A92H  RZ                   ; Return if no pending characters&lt;br /&gt;
3A93H  CALL 4BEBH           ; Wait for key from keyboard&lt;br /&gt;
3A96H  CPI 03H              ; Test for F4 maybe?  &lt;br /&gt;
3A98H  JZ 3A00H             ; Clear screen and perform Long Jump if F4 maybe?   &lt;br /&gt;
3A9BH  CPI 1BH              ; Test for ESC key  &lt;br /&gt;
3A9DH  JZ 3A00H             ; Clear screen and perform Long Jump if ESC   &lt;br /&gt;
3AA0H  CPI 20H              ; Test for space key  &lt;br /&gt;
3AA2H  JNZ 3A8FH            ; Branch back to wait for ESC, CTRL-C or space if not space    &lt;br /&gt;
3AA5H  JMP 4BEBH            ; Wait for key from keyboard    &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test if printer busy.  Return if not busy, print error if it is&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3AA8H  IN BBH               ; Get printer port input     &lt;br /&gt;
3AAAH  ANI 06H              ; Mask all but BUSY and /BUSY      &lt;br /&gt;
3AACH  XRI 02H              ; Compliment /BUSY      &lt;br /&gt;
3AAEH  JNZ 487BH            ; Printer not ready / FF error        &lt;br /&gt;
3AB1H  RET        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print currently selected file using inverse video&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3AB2H  CALL 3ACDH           ; Calculate Row and Column of newly selected file&lt;br /&gt;
3AB5H  SHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
3AB8H  CALL 4C2FH           ; Start inverse character mode&lt;br /&gt;
3ABBH  DCX H                ; Start drawing from left edge of selection (include space)   &lt;br /&gt;
3ABCH  MVI C,0AH            ; Draw 10 characters       &lt;br /&gt;
3ABEH  CALL 48E5H           ; Redraw C characters from buffer at HL using current video mode&lt;br /&gt;
3AC1H  JMP 4C33H            ; Cancel inverse character mode       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Print selected file using normal video to &amp;quot;unselect&amp;quot; it&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3AC4H  CALL 4C33H           ; Cancel inverse character mode&lt;br /&gt;
3AC7H  CALL 3ACDH           ; Calculate row and column of newly selected file&lt;br /&gt;
3ACAH  JMP 3ABBH            ; Print the file to the LCD       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Calculate Row and Column of soon-to-be (newly) selected file&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3ACDH  LDA FCD5H            ; Currently selected file index       &lt;br /&gt;
3AD0H  DCR A                ; Make selected file zero based   &lt;br /&gt;
3AD1H  MOV L,A              ; Save index to 16-bit HL&lt;br /&gt;
3AD2H  MVI H,00H            ; Make MSB zero&lt;br /&gt;
3AD4H  LXI D,000AH          ; Prepare to multiply index * 10 cols      &lt;br /&gt;
3AD7H  CALL 4C1FH           ; Signed integer muliply (FAC1=HL*DE)&lt;br /&gt;
3ADAH  LXI D,FE28H          ; Load address of line 2 in the LCD buffer&lt;br /&gt;
3ADDH  DAD D                ; Calculate starting LCD buffer address for this file&lt;br /&gt;
3ADEH  INX H                ; Skip the &amp;quot;tag&amp;quot; space on the LCD&lt;br /&gt;
3ADFH  PUSH H               ; Save address on the stack&lt;br /&gt;
3AE0H  LXI B,FE00H          ; Load starting address of LCD character buffer&lt;br /&gt;
3AE3H  DSUB                 ; Calculate file start offset from start of LCD buffer&lt;br /&gt;
3AE4H  LXI D,0028H          ; Load 1 LCD line width&lt;br /&gt;
3AE7H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  Prepare for divide&lt;br /&gt;
3AE8H  CALL 4C1BH           ; Signed integer divide (FAC1=DE/HL)&lt;br /&gt;
3AEBH  MOV A,L              ; Save selected file&#039;s row number to A&lt;br /&gt;
3AECH  INR A                ; Make row 1-based&lt;br /&gt;
3AEDH  STA F639H            ; Cursor row (1-8)&lt;br /&gt;
3AF0H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  DE had remainder*2 from divide&lt;br /&gt;
3AF1H  ASHR                 ; Divide HL by 2&lt;br /&gt;
3AF2H  MOV A,L              ; Prepare to save remainder as the column&lt;br /&gt;
3AF3H  STA F63AH            ; Cursor column (1-40)&lt;br /&gt;
3AF6H  POP H                ; Restore address of LCD buffer location from stack&lt;br /&gt;
3AF7H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F3 Function key handler for RAM mode - Rename&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3AF8H  CALL 4A4BH           ; Get RAM directory address of selected file          &lt;br /&gt;
3AFBH  SHLD FCE0H           ; Save address of file being processed          &lt;br /&gt;
3AFEH  LXI H,3F4AH          ; Address of &amp;quot;New name&amp;quot; string           &lt;br /&gt;
3B01H  CALL 3E1AH           ; Get 6-byte input filename from keyboard          &lt;br /&gt;
3B04H  RZ                   ; Return if no input provided  &lt;br /&gt;
3B05H  CALL 4902H           ; Copy filename at (HL) to current BASIC program          &lt;br /&gt;
3B08H  LHLD FCE0H           ; Load RAM directory address of file being renamed          &lt;br /&gt;
3B0BH  LXI B,0009H          ; Load offset of extension within catalog entry           &lt;br /&gt;
3B0EH  DAD B                ; Point to extension bytes     &lt;br /&gt;
3B0FH  LXI D,FC99H          ; Load address of extension field of current BASIC program name           &lt;br /&gt;
3B12H  MOV A,M              ; Get 1st byte of extension of catalog file being renamed       &lt;br /&gt;
3B13H  STAX D               ; Save extension byte in current BASIC program filename - preserve EXT      &lt;br /&gt;
3B14H  INX D                ; Point to 2nd ext byte of BASIC program name     &lt;br /&gt;
3B15H  INX H                ; Point to 2nd ext byte of catalog filename     &lt;br /&gt;
3B16H  MOV A,M              ; Get 2nd extension byte from catalog filename       &lt;br /&gt;
3B17H  STAX D               ; Save byte in current BASIC program filename area      &lt;br /&gt;
3B18H  CALL 4A51H           ; Get RAM directory address of current BASIC program          &lt;br /&gt;
3B1BH  JNZ 487EH            ; If found, jump to File Exists Error         &lt;br /&gt;
3B1EH  LHLD FCE0H           ; Load catalog address of file being renamed          &lt;br /&gt;
3B21H  INX H                ; Point to LSB of file address     &lt;br /&gt;
3B22H  INX H                ; Point to MSB of file address     &lt;br /&gt;
3B23H  INX H                ; Point to name     &lt;br /&gt;
3B24H  LXI D,FC93H          ; Load address of filename of current BASIC program    &lt;br /&gt;
3B27H  LXI B,0006H          ; Prepare to copy 6 bytes of filename (ext doesn&#039;t change)           &lt;br /&gt;
3B2AH  XCHG                 ; HL &amp;lt;--&amp;gt; DE    &lt;br /&gt;
3B2BH  JMP 4A05H            ; Move BC bytes from M to (DE) with increment         &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F1 Function key handler for DISK mode - Load&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3B2EH  CALL 4A3BH           ; Initialize blank filename and attribute byte      &lt;br /&gt;
3B31H  LHLD FCE4H           ; LCD Buffer address of current file selection      &lt;br /&gt;
3B34H  CALL 3D95H           ; Copy filename at (HL) to TX buffer      &lt;br /&gt;
3B37H  LDA FCCCH            ; Last Tag/Untag operation code     &lt;br /&gt;
3B3AH  ANA A                ; Test if a tag operation is pending &lt;br /&gt;
3B3BH  JNZ 3B56H            ; Branch if doing tag load operation     &lt;br /&gt;
3B3EH  LXI H,3F7AH          ; Point to &amp;quot;Load as:&amp;quot; text       &lt;br /&gt;
3B41H  CALL 3E1AH           ; Get 6-byte filename input from keyboard      &lt;br /&gt;
3B44H  JZ 3B56H             ; Jump to use existing disk name as filename    &lt;br /&gt;
3B47H  CALL 4902H           ; Copy filename at (HL) to current BASIC program      &lt;br /&gt;
3B4AH  LXI B,0002H          ; Prepare to copy 2 extension bytes to current BASIC program space       &lt;br /&gt;
3B4DH  LXI H,FCEFH          ; Point to disk file extension in TX buffer       &lt;br /&gt;
3B50H  LXI D,FC99H          ; Point to current BASIC program extension address       &lt;br /&gt;
3B53H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
3B56H  CALL 4A51H           ; Get RAM directory address of current BASIC program      &lt;br /&gt;
3B59H  JZ 3B69H             ; Branch to load if file doesn&#039;t already exist    &lt;br /&gt;
3B5CH  LXI H,3FB0H          ; Point to &amp;quot;File Exists, Replace?&amp;quot; text       &lt;br /&gt;
3B5FH  CALL 48F4H           ; Print string at HL to col 1 on the bottom line      &lt;br /&gt;
3B62H  CALL 3DEEH           ; Get key from keyboard and test for &#039;Y&#039; or &#039;y&#039;      &lt;br /&gt;
3B65H  RNZ                  ; Return if isn&#039;t &#039;y&#039; or &#039;Y&#039; &lt;br /&gt;
3B66H  CALL 3C38H           ; Kill file in current BASIC program space      &lt;br /&gt;
3B69H  LHLD FD1DH           ; Get file size from RX buffer      &lt;br /&gt;
3B6CH  MOV A,H              ; Swap bytes (big endian in RX buffer)   &lt;br /&gt;
3B6DH  MOV H,L              ; Move LSB to MSB   &lt;br /&gt;
3B6EH  MOV L,A              ; Move MSB to LSB   &lt;br /&gt;
3B6FH  SHLD FD1DH           ; Save with little endian to RX buffer      &lt;br /&gt;
3B72H  LDA FCEFH            ; Get 1st byte of extension from TX buffer     &lt;br /&gt;
3B75H  CPI 44H              ; Test if 1st extension byte is &amp;quot;D&amp;quot;   &lt;br /&gt;
3B77H  JNZ 3B82H            ; Jump if not &amp;quot;D&amp;quot; to check for &amp;quot;C&amp;quot; or &amp;quot;B&amp;quot;     &lt;br /&gt;
3B7AH  LHLD FBAEH           ; Get start of DO files pointer for location of new file       &lt;br /&gt;
3B7DH  MVI A,C0H            ; Load file type code for .DO files     &lt;br /&gt;
3B7FH  JMP 3BA3H            ; Process the file load      &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test file exension type in A for .CO files&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3B82H  CPI 43H              ; Test if A contains &amp;quot;C&amp;quot; &lt;br /&gt;
3B84H  JNZ 3B95H            ; Branch if not .CO file&lt;br /&gt;
3B87H  LHLD FBB0H           ; Start of CO files pointer&lt;br /&gt;
3B8AH  SHLD FCD5H           ; Save in currently selected file index storage area&lt;br /&gt;
3B8DH  LHLD FBB2H           ; Get Start of variable data pointer as location for new file&lt;br /&gt;
3B90H  MVI A,A0H            ; Load file type code for .CO files&lt;br /&gt;
3B92H  JMP 3BA3H            ; Process the file load&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process load of .BA file&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3B95H  LHLD FD1DH           ; Get file size from RX buffer&lt;br /&gt;
3B98H  SHLD FCD5H           ; Save in Currently selected file index storage&lt;br /&gt;
3B9BH  LHLD F99AH           ; Get BASIC program not saved pointer     &lt;br /&gt;
3B9EH  SHLD FCE0H           ; Save as address of file being processed&lt;br /&gt;
3BA1H  MVI A,80H            ; Load file type code for .BA files     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process file load operation&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3BA3H  STA FCDFH            ; Save file type code for later     &lt;br /&gt;
3BA6H  SHLD FCE2H           ; Save address for new file &lt;br /&gt;
3BA9H  LHLD FD1DH           ; Get file size from RX buffer&lt;br /&gt;
3BACH  SHLD FCDDH           ; Save in FDC emulation physical/logical sector storage area&lt;br /&gt;
3BAFH  PUSH H               ; Save file size on stack  &lt;br /&gt;
3BB0H  POP B                ; Copy file size to BC &lt;br /&gt;
3BB1H  LDA FCDFH            ; Get file type code     &lt;br /&gt;
3BB4H  CPI A0H              ; Test for .CO file   &lt;br /&gt;
3BB6H  JZ 3BC0H             ; Skip increment if .CO file (.BA has trailing 0x0000, .DO a 0x1A)    &lt;br /&gt;
3BB9H  INX B                ; Increment file length for .BA and .DO files &lt;br /&gt;
3BBAH  CPI 80H              ; Test if file is .BA   &lt;br /&gt;
3BBCH  JNZ 3BC0H            ; Skip additional increment if .BA     &lt;br /&gt;
3BBFH  INX B                ; Add 1 more to length for .BA files to account for both trailing 0&#039;s &lt;br /&gt;
3BC0H  PUSH B               ; Save updated length on stack  &lt;br /&gt;
3BC1H  CALL 3E48H           ; Find empty catalog entry      &lt;br /&gt;
3BC4H  JC 4887H             ; Generate system error 0x0A (&amp;quot;DD&amp;quot;) if full&lt;br /&gt;
3BC7H  POP B                ; Get length from stack &lt;br /&gt;
3BC8H  PUSH H               ; Save new file catalog address on stack  &lt;br /&gt;
3BC9H  PUSH B               ; Save new file length on stack  &lt;br /&gt;
3BCAH  LHLD FCE2H           ; Get address for new contents of new file      &lt;br /&gt;
3BCDH  CALL 4C0BH           ; Insert BC spaces at M - make room      &lt;br /&gt;
3BD0H  JC 488AH	            ; Branch if error - RAM full error&lt;br /&gt;
3BD3H  LHLD FCE2H           ; Restore address of new file contents&lt;br /&gt;
3BD6H  POP B                ; Get file length from stack   &lt;br /&gt;
3BD7H  MVI M,00H            ; Fill newly created file space with zero&#039;s       &lt;br /&gt;
3BD9H  INX H                ; Increment pointer   &lt;br /&gt;
3BDAH  DCX B                ; Decrement count   &lt;br /&gt;
3BDBH  MOV A,C              ; Move LSB to A to check for zero - could use JNX here!     &lt;br /&gt;
3BDCH  ORA B                ; Or in MSB to check for zero   &lt;br /&gt;
3BDDH  JNZ 3BD7H            ; Keep looping until all are zero       &lt;br /&gt;
3BE0H  DCX H                ; Decrement pointer to last byte in new file   &lt;br /&gt;
3BE1H  POP D                ; Get File catalog address from stack   &lt;br /&gt;
3BE2H  LDA FCDFH            ; Load file type code byte       &lt;br /&gt;
3BE5H  CPI C0H              ; Test for .DO file     &lt;br /&gt;
3BE7H  JNZ 3BF3H            ; Branch if not .DO file       &lt;br /&gt;
3BEAH  MVI M,1AH            ; Terminate .DO file with EOF marker       &lt;br /&gt;
3BECH  LHLD FCE2H           ; Reload address of new file contents        &lt;br /&gt;
3BEFH  DCX H                ; Decrement pointer to jump into middle of loop   &lt;br /&gt;
3BF0H  JMP 3C1BH            ; Write file entry to catalog       &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process end-of-file / file length for .CO and .BA files&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3BF3H  CPI A0H              ; Test if new file is .CO  &lt;br /&gt;
3BF5H  JNZ 3C04H            ; Branch if not .CO - must be .BA &lt;br /&gt;
3BF8H  LHLD FCD5H           ; Get old start of CO files pointer&lt;br /&gt;
3BFBH  SHLD FBB0H           ; Save as current start of CO files pointer     &lt;br /&gt;
3BFEH  LHLD FCE2H           ; Reload address of new file contents&lt;br /&gt;
3C01H  JMP 3C1BH            ; Write file entry to catalog &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process end-of-file for .BA files&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3C04H  PUSH D               ; Push file catalog address to stack    &lt;br /&gt;
3C05H  LHLD FBAEH           ; Get start of DO files pointer          &lt;br /&gt;
3C08H  DCX H                ; Decrement address by 1   &lt;br /&gt;
3C09H  SHLD F99AH           ; Save as new BASIC program not saved pointer          &lt;br /&gt;
3C0CH  INX H                ; Increment back to start of .DO files   &lt;br /&gt;
3C0DH  XCHG                 ; HL &amp;lt;--&amp;gt; DE  DE has start of DO files  &lt;br /&gt;
3C0EH  LHLD FCD5H           ; Get BA file size        &lt;br /&gt;
3C11H  INX H                ; Increment file size to account for trailing 0&#039;s   &lt;br /&gt;
3C12H  INX H                ; Increment file size to account for trailing 0&#039;s   &lt;br /&gt;
3C13H  DAD D                ; Add new length to start of DO files pointer   &lt;br /&gt;
3C14H  SHLD FBAEH           ; Save new start of DO files pointer          &lt;br /&gt;
3C17H  POP D                ; Retrieve file catalog address from stack   &lt;br /&gt;
3C18H  LHLD FCE0H           ; Reload address of new file contents        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Write file entry to catalog&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3C1BH  XCHG                 ; HL &amp;lt;--&amp;gt; DE  DE has file address, HL has catalog address         &lt;br /&gt;
3C1CH  CALL 4C17H           ; Write new entry to catalog (A=type, DE=file address,HL=catalog address)       &lt;br /&gt;
3C1FH  CALL 4127H           ; Open TPDD file and read data to file address being processed       &lt;br /&gt;
3C22H  CALL 4C0FH           ; Update system pointers       &lt;br /&gt;
3C25H  LXI H,0002H          ; Load TPDD_READ opcode in HL        &lt;br /&gt;
3C28H  JMP 409BH            ; Send Request in HL and await response      &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F2 Function key handler for RAM mode - Kill&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3C2BH  LDA FCCCH            ; Get last Tag/Untag operation code       &lt;br /&gt;
3C2EH  ANA A                ; Test if there is a pending tag operation&lt;br /&gt;
3C2FH  CZ 3DE1H             ; Display &amp;quot;Sure ?&amp;quot;, validate and return if validated if no tag&lt;br /&gt;
3C32H  LHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
3C35H  CALL 4902H           ; Copy filename at (HL) to current BASIC program&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Kill file in current BASIC program space&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3C38H  CALL 4A51H           ; Get RAM directory address of current BASIC program&lt;br /&gt;
3C3BH  CPI C0H              ; Test if file is .DO &lt;br /&gt;
3C3DH  JZ 4BFFH             ; Kill .DO file  &lt;br /&gt;
3C40H  CPI A0H              ; Test if file is .CO &lt;br /&gt;
3C42H  JZ 4C07H             ; Kill .CO file &lt;br /&gt;
3C45H  CPI 80H              ; Test if file is .BA&lt;br /&gt;
3C47H  JZ 4C03H             ; Kill .BA file&lt;br /&gt;
3C4AH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F1 Function key handler for RAM mode - Save&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3C4BH  CALL 4A3BH           ; Initialize blank filename and attribute byte      &lt;br /&gt;
3C4EH  CALL 4A4BH           ; Get RAM directory address of selected file      &lt;br /&gt;
3C51H  PUSH D               ; Push file address to stack  &lt;br /&gt;
3C52H  PUSH H               ; Push file catalog address to stack  &lt;br /&gt;
3C53H  INX H                ; Point to LSB of file address &lt;br /&gt;
3C54H  INX H                ; Point to MSB of file address &lt;br /&gt;
3C55H  INX H                ; Point to filename in catalog &lt;br /&gt;
3C56H  LXI D,FCE8H          ; Point to TX buffer data area (payload)&lt;br /&gt;
3C59H  LXI B,0006H          ; Prepare to copy 6 filename bytes to TX packet data&lt;br /&gt;
3C5CH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
3C5FH  MVI A,2EH            ; Load code for &#039;.&#039;     &lt;br /&gt;
3C61H  STAX D               ; Store &#039;.&#039; separator in TX packet data  &lt;br /&gt;
3C62H  INX D                ; Increment TX packet data pointer &lt;br /&gt;
3C63H  LXI B,0002H          ; Prepare to copy 2 extention bytes from catalog&lt;br /&gt;
3C66H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
3C69H  LDA FCCCH            ; Last Tag/Untag operation code     &lt;br /&gt;
3C6CH  ANA A                ; Test if a tag save operation is being performed &lt;br /&gt;
3C6DH  JNZ 3C88H            ; Jump ahead if doing a tag save - skip filename questioning     &lt;br /&gt;
3C70H  LXI H,3F71H          ; Point to &amp;quot;Save as:&amp;quot; text&lt;br /&gt;
3C73H  CALL 3E1AH           ; Get 6-byte input filename from keyboard      &lt;br /&gt;
3C76H  JZ 3C88H             ; Skip ahead to use catalog name if no input given    &lt;br /&gt;
3C79H  CALL 4902H           ; Copy filename at (HL) to current BASIC program             &lt;br /&gt;
3C7CH  LXI B,0006H          ; Prepare to copy 6 filename bytes from input string       &lt;br /&gt;
3C7FH  LXI D,FCE8H          ; Point to filename area in TX buffer       &lt;br /&gt;
3C82H  LXI H,FC93H          ; Filename of current BASIC program         &lt;br /&gt;
3C85H  CALL 4A05H           ; Move BC bytes from M to (DE) with increment      &lt;br /&gt;
3C88H  POP H                ; Restore file catalog address from stack &lt;br /&gt;
3C89H  POP D                ; Restore file address from stack &lt;br /&gt;
3C8AH  PUSH D               ; Save file address on stack  &lt;br /&gt;
3C8BH  CALL 3CD3H           ; Calculate length of RAM file, HL=address of catalog entry, DE=file address&lt;br /&gt;
3C8EH  MOV A,H              ; Test for zero length file - move H to A    &lt;br /&gt;
3C8FH  ORA L                ; OR LSB to test for zero  &lt;br /&gt;
3C90H  JZ 4884H             ; Branch if empty - File Empty Error     &lt;br /&gt;
3C93H  PUSH H               ; Save file address to stack   &lt;br /&gt;
3C94H  MVI A,01H            ; Set file open mode to new file      &lt;br /&gt;
3C96H  STA FCD6H            ; Save open mode to pass to open routine      &lt;br /&gt;
3C99H  CALL 4943H           ; Configure baud, test for NADSBox, get NADSBox dir       &lt;br /&gt;
3C9CH  CALL 4A72H           ; Send Dir Reference opcode       &lt;br /&gt;
3C9FH  JZ 3CCEH             ; Jump to write data if file doesn&#039;t exist (size = 0)     &lt;br /&gt;
3CA2H  LXI H,3F8BH          ; Point to &amp;quot;File Exists, A)ppend R)eplace Q)uit&amp;quot; text        &lt;br /&gt;
3CA5H  CALL 48F4H           ; Print string at HL to col 1 on the bottom line       &lt;br /&gt;
3CA8H  CALL 3DF8H           ; Process power-off logic and wait for a key from keyboard       &lt;br /&gt;
3CABH  ANI DFH              ; Make key uppercase    &lt;br /&gt;
3CADH  RST 4                ; Display key on LCD            &lt;br /&gt;
3CAEH  CPI 52H              ; Test if key is &#039;R&#039;    &lt;br /&gt;
3CB0H  JNZ 3CBCH            ; Jump if not &#039;R&#039;eplace                      &lt;br /&gt;
3CB3H  CALL 431AH           ; Issue TPDD Delete file Opcode       &lt;br /&gt;
3CB6H  CALL 4A72H           ; Send Dir Reference opcode       &lt;br /&gt;
3CB9H  JMP 3CCEH            ; Go write data to the file      &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F1-Save: Test for &#039;A&#039;ppend&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3CBCH  POP H                ; Get file length from stack    &lt;br /&gt;
3CBDH  POP D                ; Get file address from stack    &lt;br /&gt;
3CBEH  CPI 41H              ; Test if response is &#039;A&#039;ppend      &lt;br /&gt;
3CC0H  RNZ                  ; Return if not &#039;A&#039;  &lt;br /&gt;
3CC1H  LDA FCEFH            ; Load 1st byte of extension from TX buffer        &lt;br /&gt;
3CC4H  CPI 44H              ; Test if file is &amp;quot;D&amp;quot;O file      &lt;br /&gt;
3CC6H  RNZ                  ; Don&#039;t allow appending non DO files  &lt;br /&gt;
3CC7H  MVI A,02H            ; Set open mode to open existing (append)        &lt;br /&gt;
3CC9H  STA FCD6H            ; Save mode to pass to open routine        &lt;br /&gt;
3CCCH  PUSH D               ; Save file address on stack     &lt;br /&gt;
3CCDH  PUSH H               ; Save file length on stack     &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Save function - Replace or new file, write data to file&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3CCEH  POP H                ; Retrieve file length from stack    &lt;br /&gt;
3CCFH  POP D                ; Retrieve file address from stack    &lt;br /&gt;
3CD0H  JMP 40C8H            ; Write HL bytes of data from (DE) to TPDD        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Calculate length of RAM file, HL=address of catalog entry, DE=file address&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3CD3H  MOV A,M              ; Get RAM file type from catalog   &lt;br /&gt;
3CD4H  CPI C0H              ; Test for .DO file   &lt;br /&gt;
3CD6H  JZ 3CE6H             ; Jump to calculate length if .DO file    &lt;br /&gt;
3CD9H  CPI A0H              ; Test for .CO file         &lt;br /&gt;
3CDBH  JZ 3CF5H             ; Jump to calculate length if .CO file    &lt;br /&gt;
3CDEH  PUSH D               ; Save address of start of BASIC program to stack  &lt;br /&gt;
3CDFH  CALL 4C13H           ; Call ROM routine to find BASIC end of program&lt;br /&gt;
3CE2H  POP B                ; Get BASIC program start address from stack &lt;br /&gt;
3CE3H  DSUB                 ; Subtract starting address from end address&lt;br /&gt;
3CE4H  DCX H                ; Don&#039;t count trailing 0x00 as part of BASIC program length &lt;br /&gt;
3CE5H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Calculate length of .DO file, HL=Catalog address, DE=file address&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3CE6H  XCHG                 ; HL &amp;lt;--&amp;gt; DE Get file address in HL &lt;br /&gt;
3CE7H  LXI D,0000H          ; Clear file length&lt;br /&gt;
3CEAH  MOV A,M              ; Get next byte from .DO file    &lt;br /&gt;
3CEBH  INX H                ; Increment pointer  &lt;br /&gt;
3CECH  INX D                ; Increment length  &lt;br /&gt;
3CEDH  CPI 1AH              ; Test for EOF marker    &lt;br /&gt;
3CEFH  JNZ 3CEAH            ; Branch to next byte if not EOF      &lt;br /&gt;
3CF2H  DCX D                ; Subtract EOF marker from file length  &lt;br /&gt;
3CF3H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  HL=length &lt;br /&gt;
3CF4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Calculate length of .CO file, HL=Catalog address, DE=file address&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3CF5H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  Get file address in HL &lt;br /&gt;
3CF6H  INX H                ; Increment past .CO load address &lt;br /&gt;
3CF7H  INX H                ; Increment past MSB of load address&lt;br /&gt;
3CF8H  MOV C,M              ; Get LSB of length  &lt;br /&gt;
3CF9H  INX H                ; Increment to MSB of length&lt;br /&gt;
3CFAH  MOV B,M              ; Get MSB of length&lt;br /&gt;
3CFBH  LXI H,0006H          ; Prepare to add 6-byte header to length&lt;br /&gt;
3CFEH  DAD B                ; Add 6-byte header to length&lt;br /&gt;
3CFFH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F7 Function key handler for DISK mode - Mkdir&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D00H  LDA FCCBH            ; NADSBox / TPDD2 / Desklink flag        &lt;br /&gt;
3D03H  ANA A                ; Test if server is TPDD    &lt;br /&gt;
3D04H  RZ                   ; Return if not NADSBox or TPDD2 &lt;br /&gt;
3D05H  DCR A                ; Test if TPDD2    &lt;br /&gt;
3D06H  JZ 37BAH             ; Go Swap TPDD Bank Number if TPDD2       &lt;br /&gt;
3D09H  CALL 4A3BH           ; Must be NADSBOx Initialize blank filename         &lt;br /&gt;
3D0CH  LXI H,3F61H          ; Load pointer to &amp;quot;Directory name:&amp;quot; text          &lt;br /&gt;
3D0FH  CALL 3E1AH           ; Get 6-byte input filename from keyboard         &lt;br /&gt;
3D12H  RZ                   ; Return if no input given &lt;br /&gt;
3D13H  CALL 4902H           ; Copy filename at (HL) to current BASIC program         &lt;br /&gt;
3D16H  LXI H,FC93H          ; Filename of current BASIC program              &lt;br /&gt;
3D19H  LXI D,FCE8H          ; Point to TX buffer data area (payload)          &lt;br /&gt;
3D1CH  LXI B,0006H          ; Prepare to copy 6 filename bytes to TX buffer          &lt;br /&gt;
3D1FH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment         &lt;br /&gt;
3D22H  LXI H,3E3CH          ; Load code for &amp;quot;&amp;lt;&amp;gt;&amp;quot;          &lt;br /&gt;
3D25H  SHLD FCEFH           ; Save &amp;quot;&amp;lt;&amp;gt;&amp;quot; extension bytes in TX buffer - NADSBox Mkdir                   &lt;br /&gt;
3D28H  MVI A,2EH            ; Load code for &#039;.&#039; extension separator        &lt;br /&gt;
3D2AH  STA FCEEH            ; Save &amp;quot;.&amp;quot; to TX buffer        &lt;br /&gt;
3D2DH  CALL 4943H           ; Configure baud, test for NADSBox, get NADSBox dir         &lt;br /&gt;
3D30H  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag        &lt;br /&gt;
3D33H  CPI 02H              ; Test if we have NADSBox current directory      &lt;br /&gt;
3D35H  RNZ                  ; Return if we don&#039;t have current directory  &lt;br /&gt;
3D36H  CALL 4A72H           ; Send Directory Reference opcode         &lt;br /&gt;
3D39H  JNZ 3D4DH            ; If the file exists, branch to open it for READ mode        &lt;br /&gt;
3D3CH  MVI A,01H            ; Load OPEN_WRITE mode into A to create the directory        &lt;br /&gt;
3D3EH  STA FCE8H            ; Save A in TX data storage mode field        &lt;br /&gt;
3D41H  LXI H,0101H          ; Load opcode to open a file          &lt;br /&gt;
3D44H  CALL 409BH           ; Send Request in HL and await response         &lt;br /&gt;
3D47H  LXI H,0002H          ; Load opcode to close the file          &lt;br /&gt;
3D4AH  JMP 409BH            ; Send Request in HL and await response        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Open and close a directory file (from above)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D4DH  CALL 408AH           ; Open TPDD file for Read Mode&lt;br /&gt;
3D50H  JMP 3D47H            ; Branch to close the directory open request&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F5 Function key handler for DISK mode - Format&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D53H  LDA FCCBH            ; NADSBox / Desklink / TPDD2 flag       &lt;br /&gt;
3D56H  CPI 02H              ; Test if we have &amp;quot;current directory&amp;quot; name     &lt;br /&gt;
3D58H  RZ                   ; Return if server is NADSBox / Desklink - No format supported&lt;br /&gt;
3D59H  LXI H,3F1BH          ; Load pointer to &amp;quot;Insert Disk&amp;quot; string&lt;br /&gt;
3D5CH  CALL 48F4H           ; Print string at HL to col 1 on the bottom line        &lt;br /&gt;
3D5FH  CALL 3DEEH           ; Get key from keyboard and test for &#039;Y&#039; or &#039;y&#039;        &lt;br /&gt;
3D62H  RNZ                  ; Return if response not &#039;Y&#039; &lt;br /&gt;
3D63H  CALL 4943H           ; Configure baud, test for NADSBox, get NADSBox dir        &lt;br /&gt;
3D66H  CALL 49E3H           ; Delay routine - about 3ms        &lt;br /&gt;
3D69H  LXI H,0006H          ; Load TPDD_FORMAT opcode in HL&lt;br /&gt;
3D6CH  CALL 409BH           ; Send Request in HL and await response        &lt;br /&gt;
3D6FH  MVI A,07H            ; Load code for BELL       &lt;br /&gt;
3D72H  RET		            ; Go beep to indicate format&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F2 Function key handler for DISK mode - Kill&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D73H  LDA FCCCH            ; Last Tag/Untag operation code      &lt;br /&gt;
3D76H  ANA A                ; Test if there&#039;s an active tag group&lt;br /&gt;
3D77H  CZ 3DE1H             ; Display &amp;quot;Sure ?&amp;quot;, validate and return if validated if no tag&lt;br /&gt;
3D7AH  CALL 4A3BH           ; Initialize blank filename and attribute byte&lt;br /&gt;
3D7DH  CALL 3D83H           ; Copy selected filename to TX buffer and init TPDD/NADSBox&lt;br /&gt;
3D80H  JMP 431AH            ; Issue TPDD Delete file Opcode            &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Copy selected filename to TX buffer and init TPDD/NADSBox&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D83H  LXI B,0009H          ; Prepare to copy 9 filename bytes&lt;br /&gt;
3D86H  LHLD FCE4H           ; LCD Buffer address of current file selection&lt;br /&gt;
3D89H  LXI D,FCE8H          ; Address of TX packet data&lt;br /&gt;
3D8CH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment&lt;br /&gt;
3D8FH  CALL 4943H           ; Configure baud, test for NADSBox, get NADSBox dir&lt;br /&gt;
3D92H  JMP 4A72H            ; Send Dir Reference opcode&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Copy filename at (HL) to TX buffer&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D95H  CALL 4902H           ; Copy filename at (HL) to current BASIC program&lt;br /&gt;
3D98H  LXI H,FC93H          ; Filename of current BASIC program&lt;br /&gt;
3D9BH  CALL 4A57H           ; Send Dir Reference for filename at (HL)&lt;br /&gt;
3D9EH  RET        &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F3 Function key handler for DISK mode - Name&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3D9FH  CALL 4A3BH           ; Initialize blank filename and attribute byte          &lt;br /&gt;
3DA2H  CALL 3D83H           ; Copy selected filename to TX buffer and init TPDD/NADSBox          &lt;br /&gt;
3DA5H  LXI H,FCE8H          ; Point to TX buffer data area (payload)&lt;br /&gt;
3DA8H  LXI D,FC9CH          ; Filename of last program loaded from tape  &lt;br /&gt;
3DABH  LXI B,0009H          ; Prepare to copy 9 bytes to &amp;quot;last program loaded&amp;quot; filename&lt;br /&gt;
3DAEH  CALL 4A05H           ; Move BC bytes from M to (DE) with increment          &lt;br /&gt;
3DB1H  LHLD FD1DH           ; Get file size from RX buffer          &lt;br /&gt;
3DB4H  MOV C,H              ; Save file size MSB to C (swap endian)       &lt;br /&gt;
3DB5H  MOV B,L              ; Save file size LSB to B (swap endian)       &lt;br /&gt;
3DB6H  LXI H,7CC0H          ; ? Load HL with 31936&lt;br /&gt;
3DB9H  DSUB                 ; ? Compare file length with 31936    &lt;br /&gt;
3DBAH  LXI H,3F4AH          ; Address of &amp;quot;New name&amp;quot; string&lt;br /&gt;
3DBDH  JNZ 3DD7H            ; Branch to change filename if not 30656         &lt;br /&gt;
3DC0H  LXI B,0009H          ; Allow a 9-byte filename input string&lt;br /&gt;
3DC3H  CALL 3E1DH           ; Get max BC length input for filename and convert to uppercase          &lt;br /&gt;
3DC6H  RZ                   ; Return if no input provided  &lt;br /&gt;
3DC7H  PUSH H               ; Save pointer to input string to stack      &lt;br /&gt;
3DC8H  PUSH PSW             ; Save string length to stack        &lt;br /&gt;
3DC9H  CALL 4A3BH           ; Initialize blank filename and attribute byte          &lt;br /&gt;
3DCCH  POP PSW              ; Get string length from stack       &lt;br /&gt;
3DCDH  POP H                ; Get string address from stack     &lt;br /&gt;
3DCEH  LXI D,FCE8H          ; Point to TX buffer data area (payload)           &lt;br /&gt;
3DD1H  MOV C,A              ; Copy length to BC       &lt;br /&gt;
3DD2H  MVI B,00H            ; Make MSB of length = 0         &lt;br /&gt;
3DD4H  JMP 41B0H            ; Rename the TPDD file whose name is in (HL)         &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get filename from keyboard and rename Disk file, filename in &amp;quot;current BASIC program&amp;quot;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3DD7H  CALL 3E1AH           ; Get 6-byte input filename from keyboard&lt;br /&gt;
3DDAH  RZ                   ; Return if no input provided &lt;br /&gt;
3DDBH  CALL 4902H           ; Copy filename at (HL) to current BASIC program&lt;br /&gt;
3DDEH  JMP 41A7H            ; Rename the TPDD file whose name is in &amp;quot;current BASIC program&amp;quot; &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Display &amp;quot;Sure ?&amp;quot;, validate and return if validated&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3DE1H  LXI H,3F83H          ; Load pointer to &amp;quot;Sure ?&amp;quot; string&lt;br /&gt;
3DE4H  CALL 48F4H           ; Print string at HL to col 1 on the bottom line &lt;br /&gt;
3DE7H  CALL 3DEEH           ; Get key and test for &#039;Y&#039; or &#039;y&#039; &lt;br /&gt;
3DEAH  JNZ 48B5H            ; Branch to &amp;quot;Long jump&amp;quot; operation to abort if not &#039;y&#039; &lt;br /&gt;
3DEDH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get key from keyboard and test for &#039;Y&#039; or &#039;y&#039;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3DEEH  CALL 3DF8H           ; Process power-off logic and wait for a key from keyboard&lt;br /&gt;
3DF1H  RST 4                ; Display the key on the LCD &lt;br /&gt;
3DF2H  CPI 59H              ; Test if key pressed was &#039;Y&#039;      &lt;br /&gt;
3DF4H  RZ                   ; Return if key pressed was &#039;Y&#039; &lt;br /&gt;
3DF5H  CPI 79H              ; Test if key pressed was &#039;y&#039;      &lt;br /&gt;
3DF7H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process power-off logic and wait for a key from keyboard&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3DF8H  CALL 3DFEH           ; Process automatic poweroff logic&lt;br /&gt;
3DFBH  JMP 4BEBH            ; Wait for key from keyboard&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Process automatic power-off logic during key scan loop&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3DFEH  XRA A                ; Clear A  &lt;br /&gt;
3DFFH  DCR A                ; Set A to 0xFF   &lt;br /&gt;
3E00H  STA F656H            ; Power off exit condition switch  &lt;br /&gt;
3E03H  CALL 4C4AH           ; Check keyboard queue for pending characters&lt;br /&gt;
3E06H  JZ 3DFEH             ; Branch back if no keyboard characters in queue - wait for key&lt;br /&gt;
3E09H  XRA A                ; Clear A  &lt;br /&gt;
3E0AH  STA F656H            ; Power off exit condition switch  &lt;br /&gt;
3E0DH  LXI H,F932H          ; Load address of &amp;quot;Renew Automatic Poweroff Counter Flag&amp;quot;&lt;br /&gt;
3E10H  ORA M                ; Test if auto poweroff counter should be renewed&lt;br /&gt;
3E11H  JZ 4BF7H             ; Renew automatic power-off counter if enabled&lt;br /&gt;
3E14H  CALL 4BF3H           ; Turn off the computer&lt;br /&gt;
3E17H  JMP 3DFEH            ; Branch back to continue processing power off logic&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get max 6-byte input for filename and convert to uppercase&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E1AH  LXI B,0006H          ; Get maximum 6 characters of input&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get max BC length input for filename and convert to uppercase&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E1DH  CALL 3E2FH           ; Get max BC length input string from keyboard&lt;br /&gt;
3E20H  RZ                   ; Return if no input provided &lt;br /&gt;
3E21H  PUSH H               ; Preserve pointer to input string     &lt;br /&gt;
3E22H  PUSH PSW             ; Preserve flags from input       &lt;br /&gt;
3E23H  CALL 4C5EH           ; Get char at M and convert to uppercase&lt;br /&gt;
3E26H  MOV M,A              ; Save uppercase char back to string      &lt;br /&gt;
3E27H  INX H                ; Point to next byte in input     &lt;br /&gt;
3E28H  ANA A                ; Test for NULL - end of string    &lt;br /&gt;
3E29H  JNZ 3E23H            ; Keep looping until end of string        &lt;br /&gt;
3E2CH  POP PSW              ; Restore flags from input routine      &lt;br /&gt;
3E2DH  POP H                ; Restore pointer to input string    &lt;br /&gt;
3E2EH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Get maximum BC length input character string from keyboard&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E2FH  PUSH B               ; Save maximum input length to stack     &lt;br /&gt;
3E30H  CALL 48F4H           ; Print string at HL to col 1 on the bottom line&lt;br /&gt;
3E33H  CALL 4C46H           ; Input and display (no &amp;quot;?&amp;quot;) line and store&lt;br /&gt;
3E36H  JC 48B5H             ; Branch to &amp;quot;Long jump&amp;quot; if CTRL-C       &lt;br /&gt;
3E39H  INX H                ; Point to start of input string    &lt;br /&gt;
3E3AH  MOV A,B              ; Get string length (counting NULL)      &lt;br /&gt;
3E3BH  DCR A                ; Remove NULL from count    &lt;br /&gt;
3E3CH  POP D                ; Restore maximum input length    &lt;br /&gt;
3E3DH  RZ                   ; Return if string length is zero &lt;br /&gt;
3E3EH  CMP E                ; Compare expected length with actual length    &lt;br /&gt;
3E3FH  RC                   ; Return if string is shorter than expected          &lt;br /&gt;
3E40H  PUSH H               ; Save pointer to start of string on stack     &lt;br /&gt;
3E41H  DAD D                ; Add Expected length to pointer    &lt;br /&gt;
3E42H  MVI M,00H            ; Truncate the string to the max length        &lt;br /&gt;
3E44H  POP H                ; Restore pointer to input string    &lt;br /&gt;
3E45H  MOV A,E              ; Update length to reflect maximum      &lt;br /&gt;
3E46H  ORA A                ; Clear zero flag to indicate input provided    &lt;br /&gt;
3E47H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Find Empty catalog entry (only 9 instructions...Don&#039;t bother with Main ROM)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E48H  LXI H,F9AFH         ; Point to the &amp;quot;RickY&amp;quot; catalog entry (start of valid entries)&lt;br /&gt;
3E4BH  LXI B,000BH         ; Load length of each catalog entry&lt;br /&gt;
3E4EH  DAD B               ; Point to next catalog entry to test if empty&lt;br /&gt;
3E4FH  MOV A,M             ; Get file attribute byte from catalog entry&lt;br /&gt;
3E50H  CPI FFH             ; Test if at end of catalog&lt;br /&gt;
3E52H  JZ 3E5AH            ; Jump to report directory full if at end&lt;br /&gt;
3E55H  ADD A               ; Test if MSB is set (entry being used)&lt;br /&gt;
3E56H  JC 3E4EH            ; Jump to test next enry if MSB set&lt;br /&gt;
3E59H  RET                 ; Entry found...return with Carry clear&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Empty catalog entry not found...set Carry and exit&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E5AH  STC                 ; Indicate empty entry not found&lt;br /&gt;
3E5BH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; F5 Function key handler for RAM mode - DOS ON/OF&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E5CH  LHLD FB2CH          ; Get LFILES statement hook address&lt;br /&gt;
3E5FH  LXI B,08DBH         ; Load address of default (DOS-OFF) hook for LFILES&lt;br /&gt;
3E62H  DSUB                ; Test if in DOS-OFF mode&lt;br /&gt;
3E63H  JZ 401FH            ; Jump to add our custom RST 7 hooks if in DOS-OFF mode&lt;br /&gt;
3E66H  JMP 3FFAH           ; Must be in DOS-ON mode, jump to turn it off&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Strings&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
3E69H  DB	0x1B, &amp;quot;p TS-DOS (100 v4.00) (c)87,TSI.          &amp;quot;,0x1B,&#039;q&#039;,0x00&lt;br /&gt;
3E97H  DB   &amp;quot;DISK Free:         File:&amp;quot;,0DH,0AH,&amp;quot;Load Kill Name Ram  Frmt Log       Menu&amp;quot;,00H&lt;br /&gt;
3ED9H  DB   &amp;quot; RAM Free:         File:&amp;quot;,0DH,0AH,&amp;quot;Save Kill Name Disk DOS-           Menu&amp;quot;,00H&lt;br /&gt;
3F1BH  DB   &amp;quot;Insert Disk, Press \&amp;quot;Y\&amp;quot; to begin &amp;quot;,00H&lt;br /&gt;
3F3CH  DB   &amp;quot;NOT FORMATTED&amp;quot;,00H&lt;br /&gt;
3F4AH  DB   &amp;quot;New Name:&amp;quot;,00H&lt;br /&gt;
3F54H  DB   &amp;quot;System name:&amp;quot;,00H&lt;br /&gt;
3F61H  DB   &amp;quot;Directory name:&amp;quot;,00H&lt;br /&gt;
3F71H  DB   &amp;quot;Save as:&amp;quot;,00H&lt;br /&gt;
3F7AH  DB   &amp;quot;Load as:&amp;quot;,00H&lt;br /&gt;
3F83H  DB   &amp;quot;Sure ? &amp;quot;,00H&lt;br /&gt;
3F8BH  DB   &amp;quot;File exists, A)ppend R)eplace Q)uit:&amp;quot;,00H&lt;br /&gt;
3FB0H  DB   &amp;quot;File exists, Replace? (Y/N):&amp;quot;,00H&lt;br /&gt;
3FCDH  DB   &amp;quot;-.-       &amp;quot;,00H&lt;br /&gt;
3FD8H  DB   0x1B,&amp;quot;Y74    &amp;quot;,1BH,&amp;quot;Y7&amp;gt;MkDr&amp;quot;,00H     ;  TODO: Check this&lt;br /&gt;
3FE9H  DB   0x1B,&amp;quot;Y7&amp;gt;Bank&amp;quot;,00H                   ;  TODO: Check this&lt;br /&gt;
3FF2H  DB   &amp;quot;OFF&amp;quot;,00H&lt;br /&gt;
3FF6H  DB   &amp;quot;ON &amp;quot;,00H&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Navigate to:&lt;br /&gt;
 - [[Dissasembly of RAM and ROM versions of TS-DOS]]&lt;br /&gt;
 - [[M100 TS-DOS ROM OptROM Support]]&lt;br /&gt;
 - [[M100 TS-DOS ROM RST 7 Handlers]]&lt;br /&gt;
 - [[M100 TS-DOS ROM TPDD Protocol]]&lt;br /&gt;
 - [[M100 TS-DOS ROM Compression]]&lt;br /&gt;
 - [[M100 TS-DOS ROM Cold Boot Recovery]]&lt;/div&gt;</summary>
		<author><name>Kpettit</name></author>
	</entry>
	<entry>
		<id>https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_OptROM_Support&amp;diff=1375</id>
		<title>M100 TS-DOS ROM OptROM Support</title>
		<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_OptROM_Support&amp;diff=1375"/>
		<updated>2009-04-03T07:30:10Z</updated>

		<summary type="html">&lt;p&gt;Kpettit: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== TS-DOS Model 100/102 ROM OptROM Support ==&lt;br /&gt;
&lt;br /&gt;
This code defines the variables used throughout the TS-DOS application as well as the support routines needed to navigate between the Main ROM and the Option ROM (most of them).  Also included is the TS-DOS startup code.  The assembly labels defined are open for discussion and have not been applied to any of the disassembled code yet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 =========================================================================================&lt;br /&gt;
; TS-DOS M100 ROM version Disassembly&lt;br /&gt;
;&lt;br /&gt;
; Initial Disassembly By Kenneth D. Pettit&lt;br /&gt;
; March, 2009&lt;br /&gt;
;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Variables in ALTLCD buffer&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
NB_CUR_DIR    equ FCC0H              ; NADSBox current directory (&amp;quot;MYFILE.&amp;lt;&amp;gt; &amp;quot;)&lt;br /&gt;
TPDD_BANK     equ FCCAH              ; TPDD2 Bank (side)&lt;br /&gt;
NB_TPDD_FLG   equ FCCBH              ; NADSBox/Desklink/TPDD2 flag (0=TPDD, 1=TPDD2, 2=NADSBox)&lt;br /&gt;
LAST_TAG      equ FCCCH              ; Tag/Untag last operation code&lt;br /&gt;
CUR_FILE      equ FCCDH              ; Currently selected file index on UI (1 based)&lt;br /&gt;
LJ_SP         equ FCCEH              ; Stack pointer upon entry for Long Jump&lt;br /&gt;
LJ_RET        equ FCD0H              ; Return vector for Long Jump &amp;quot;RETURN&amp;quot;&lt;br /&gt;
ERR_MODE      equ FCD2H              ; Print Error Messages flag, 1=Print, 0=Generate System Error&lt;br /&gt;
FDC_OPCODE    equ FCD3H              ; FDC Emulation mode opcode&lt;br /&gt;
CUR_PAGE      equ FCD4H              ; Current page of files being displayed (0 based)&lt;br /&gt;
TMP_FILE_IDX  equ FCD5H              ; Currently selected file index on UI - temp&lt;br /&gt;
FILE_COUNT    equ FCD6H              ; Count of files currently displayed on LCD&lt;br /&gt;
MAX_FILES     equ FCD7H              ; Maximum files that fit on the LCD&lt;br /&gt;
DISP_MODE     equ FCD9H              ; RAM / Disk Display mode (0=RAM,  1=DISK)&lt;br /&gt;
SKIP_PAGE     equ FCDAH              ; TPDD &amp;quot;skip page&amp;quot; count (number of pages to read and discard)&lt;br /&gt;
FILE_LEN      equ FCDBH              ; Pointer to &amp;quot;Current file&amp;quot; length bytes (in keyboard buffer)&lt;br /&gt;
PHYS_SCTR     equ FCDDH              ; FDC Emulation Physical Sector Number / Active File Length LSB&lt;br /&gt;
LOG_SCTR      equ FCDEH              ; FDC Emulation Logical Sector Number / Active File Length MSB&lt;br /&gt;
KEY_TYPE      equ FCDFH              ; Storage for FDC emulation / New file type code / Keypress storage&lt;br /&gt;
FILE_ADDR     equ FCE0H              ; Address of file being displayed/printed/loaded/saved&lt;br /&gt;
FILE_BUFF     equ FCE2H              ; Pointer for TPDD direct read data / address of file being read/written&lt;br /&gt;
TX_PKT_BUF    equ FCE6H              ; Storage for TX packets (28 bytes)&lt;br /&gt;
RX_PKT_BUF    equ FD02H              ; Storage for RX packets (130 bytes ??)&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Main Entry point when called from &amp;quot;CALL 63013,1&amp;quot;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
   &lt;br /&gt;
   .org 0000H&lt;br /&gt;
&lt;br /&gt;
0000H  JMP 00B2H            ; Jump to entry point handler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Pop registers after we power back up from a powerdown (I think)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0003H  POP H&lt;br /&gt;
0004H  POP D&lt;br /&gt;
0005H  POP B&lt;br /&gt;
0006H  POP PSW&lt;br /&gt;
0007H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 1 - Call Main ROM at location whose address follows RST 1 opcode&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0008H  (C3H) JMP 0080H      ; BASIC statement keyword table END to NEW&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 2 - Call Main ROM&#039;s RST 2 routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0010H  (CFH) RST 1          ; Call main ROM at address in following 2 bytes&lt;br /&gt;
0011H  DW    0010H          ; Call the Main ROM&#039;s RST 2 function&lt;br /&gt;
0013H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 3 routine - Compare HL and DE&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0018H  JMP 006CH            ; Jump to comparison routine&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Return to Main ROM.  After issuing the OUT E0H, we will be in Main ROM.  The next opcode&lt;br /&gt;
; in Main ROM after this OUT statement occurs will be a RET (part of RST 1).  We have &lt;br /&gt;
; PUSHed a return address to the stack, so the main ROM&#039;s RET instruction will get us &lt;br /&gt;
; where to intend to go.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
001BH  OUT E0H              ; Send A to the ROM bank port to switch to Main ROM&lt;br /&gt;
001DH  RET                  ; Should never execute this instruction, but just in case&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Send a space to the screen/printer - Not called from anywhere.  Copy of Main ROM.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
001EH  (3EH) MVI A,20H      ; Prepare to print a SPACE&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 3 routine - Send character in A to the screen / printer&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0020H  (CFH) RST 1          ; Call main ROM at address in following 2 bytes&lt;br /&gt;
0021H  DW    0020H          ; Main ROM&#039;s RST 3 routine&lt;br /&gt;
0023H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Power down TRAP.  Let Main ROM deal with it.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0024H  DI                   ; Disable interrupts while we jump   &lt;br /&gt;
0025H  CALL 0097H           ; Jump to Main ROM&#039;s RST handler for this vector &lt;br /&gt;
0028H  POP H      &lt;br /&gt;
0029H  JMP 0003H            ; Pop regs after we power back up from a power-down? &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Hardware Interrupt - Let Main ROM deal with it - Bar Code Reader&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
002CH  DI                   ; Disable interrupts while we jump  &lt;br /&gt;
002DH  CALL 0097H           ; Jump to Main ROM&#039;s RST handler for this vector&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Return from Main ROM hook in RAM returns here via RST 6&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0030H  POP PSW              ; Cleanup stack&lt;br /&gt;
0031H  POP PSW              ; Cleanup stack&lt;br /&gt;
0032H  RET                  ; Return to OptROM execution point        &lt;br /&gt;
&lt;br /&gt;
0033H  NOP                  ; Filler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Hardware Interrupt - Let Main ROM deal with it - RS232 character pending&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0034H  DI                   ; Disable interrupts while we jump&lt;br /&gt;
0035H  CALL 0097H           ; Jump to Main ROM&#039;s RST handler for this vector&lt;br /&gt;
0038H  JMP 00A6H            ; Stack cleanup&lt;br /&gt;
&lt;br /&gt;
003BH  NOP                  ; UNUSED - filler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Hardware Interrupt - Let Main ROM deal with it - Timer background task&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
003CH  DI                   ; Disable interrupts&lt;br /&gt;
003DH  CALL 0097H           ; Jump to Main ROM&#039;s RST handler for this vector&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; This routine gets copied to RAM to be used for switching back to the TS-DOS ROM after&lt;br /&gt;
;      calling a routine in the Main ROM.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0040H  PUSH PSW             ; Preserve the PSW&lt;br /&gt;
0041H  LDA FF45H            ; Contents of port E8H&lt;br /&gt;
0044H  INR A                ; Prepare to switch to OptRom&lt;br /&gt;
0045H  OUT E0H              ; Switch to OptRom&lt;br /&gt;
0047H  RST 6                ; Get sign of FAC1&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; This routine gets copied to RAM and appears to detect the presence of the TS-DOS ROM&lt;br /&gt;
;       after power-up and copies the original &amp;quot;External ROM&amp;quot; detection routine to RAM&lt;br /&gt;
;       if the TS-DOS ROM is no longer present.  At least I think that&#039;s what it&#039;s doing.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0048H  LXI D,F605H          ; Copy address for &amp;quot;Ext ROM detect&amp;quot; routine&lt;br /&gt;
004BH  INR A                ; Set bit to enable OptROM&lt;br /&gt;
004CH  OUT E0H              ; Switch to OptROM&lt;br /&gt;
004EH  XRA A                ; Prepare to switch back to Main ROM&lt;br /&gt;
004FH  LHLD 0049H           ; Load target address of the LXI D instruction above&lt;br /&gt;
0052H  OUT E0H              ; Switch back to Main ROM&lt;br /&gt;
0054H  RST 3                ; Compare DE and HL - Test if OptROM is TS-DOS&lt;br /&gt;
0055H  CPI 01H              ; Test for TS-DOS ROM&lt;br /&gt;
0057H  RC                   ; Return if TS-DOS ROM&lt;br /&gt;
0058H  LXI H,111DH          ; Load &amp;quot;Return&amp;quot; address to the CALL below&lt;br /&gt;
005BH  SHLD FAE0H&lt;br /&gt;
005EH  SHLD F5F2H           ; Save a &amp;quot;Restart signature&amp;quot; ???&lt;br /&gt;
0061H  CALL 2905H           ; Copy the DB number of bytes from the DW address to (DE)&lt;br /&gt;
0064H  DB   24H             ; ....copy 24H bytes&lt;br /&gt;
0065H  DW   036FH           ; ....from ROM addres 036F (external ROM detect)&lt;br /&gt;
0067H  RST 0                ; I&#039;m not sure it it every actually returns here or not&lt;br /&gt;
0068H  NOP&lt;br /&gt;
0069H  CALL FAA4H           ; Call our installed RAM hook to return to TS-DOS&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Compare HL and DE - called by the RST 3 routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
006CH  MOV A,H              ; Move H into A for comparison&lt;br /&gt;
006DH  SUB D                ; Compare MSB first&lt;br /&gt;
006EH  RNZ                  ; Return if no match&lt;br /&gt;
006FH  MOV A,L              ; Now move L into A&lt;br /&gt;
0070H  SUB E                ; Compare LSB&lt;br /&gt;
0071H  RET                  ; Return with flags set&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Copy 8 bytes from DE to HL &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0072H  LXI B,0008H          ; Prepare to copy 8 bytes &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Copy BC bytes from DE to HL &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0075H  LDAX D               ; Load value from (DE)&lt;br /&gt;
0076H  MOV M,A              ; Save value to (HL)&lt;br /&gt;
0077H  INX D                ; Increment DE&lt;br /&gt;
0078H  INX H                ; Increment HL&lt;br /&gt;
0079H  DCX B                ; Decrement counter&lt;br /&gt;
007AH  MOV A,B              ; Prepare to test counter for zero&lt;br /&gt;
007BH  ORA C                ; Test counter for zero&lt;br /&gt;
007CH  JNZ 0075H            ; Keep looping until 8 bytes copied&lt;br /&gt;
007FH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle the RST 1 routine.  Read the Main ROM address from the 2 bytes after the RST 1&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0080H  SHLD F9B2H           ; Save HL off in &amp;quot;RickY&amp;quot; Cat entry so we don&#039;t clobber it&lt;br /&gt;
0083H  POP H                ; Get out return address (location of the ROM address to call&lt;br /&gt;
0084H  PUSH D               ; Push the return address back to the stack as storage &lt;br /&gt;
0085H  MOV E,M              ; Get LSB of the ROM address to call&lt;br /&gt;
0086H  INX H                ; Point to MSB of ROM address to call&lt;br /&gt;
0087H  MOV D,M              ; Get MSB of the ROM address to call&lt;br /&gt;
0088H  INX H                ; Point to return address after the RST 1 DB address&lt;br /&gt;
0089H  XTHL                 ; Put the return address on the stack so we return after the RST 1&lt;br /&gt;
008AH  XCHG                 ; Now get the address within ROM to call&lt;br /&gt;
008BH  PUSH H               ; Push the target ROM address to the stack so we &amp;quot;RETurn&amp;quot; there&lt;br /&gt;
008CH  LXI H,FAA4H          ; Load address of our RAM hook to switch back to our ROM bank and RET&lt;br /&gt;
008FH  XTHL                 ; Push that address on the stack for after the ROM call is complete&lt;br /&gt;
0090H  PUSH H               ; Now put the ROM address back on the stack so we will RET there&lt;br /&gt;
0091H  LHLD F9B2H           ; Restore HL from temp storage in &amp;quot;RickY&amp;quot;&lt;br /&gt;
0094H  JMP 00A6H            ; Branch to switch to Main ROM and &amp;quot;RET&amp;quot; to the address we pushed&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST handler for calling the Main ROM&#039;s RST handlers.  This routine restores the original&lt;br /&gt;
;      RST vector address to the stack, and jumps to the Main ROM&#039;s RST routine while &lt;br /&gt;
;      preserving all register values.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0097H  SHLD F9B4H           ; Save HL temporarily (somewhere in RickY&#039;s name)&lt;br /&gt;
009AH  LXI H,FAA4H          ; Point to our RAM hook for returning to TS-DOS&lt;br /&gt;
009DH  XTHL                 ; Put the hook address as the return address on the stack&lt;br /&gt;
009EH  DCX H                ; Decrement the return address by 4&lt;br /&gt;
009FH  DCX H                ; ...this will result in the starting address of the RST&lt;br /&gt;
00A0H  DCX H                ; ...that brought us here&lt;br /&gt;
00A1H  DCX H&lt;br /&gt;
00A2H  PUSH H               ; Push the RST vector address to the stack&lt;br /&gt;
00A3H  LHLD F9B4H           ; Restore HL upon entry&lt;br /&gt;
00A6H  PUSH PSW             ; Save A to the stack&lt;br /&gt;
00A7H  PUSH H               ; Save the HL to the stack so we can preserve through XTHL&lt;br /&gt;
00A8H  LXI H,1488H          ; Load a RETurn address in the Main ROM (a POP PSW &amp;amp; RET) &lt;br /&gt;
00ABH  XTHL                 ; Push the address and get HL back&lt;br /&gt;
00ACH  LDA FF45H            ; Contents of port E8H - prepare for jump to Main ROM&lt;br /&gt;
00AFH  JMP 001BH            ; Jump to Main ROM &amp;amp; our custom &amp;quot;RET&amp;quot; address in the ROM&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Manual invocation entry point.  This is where we jump when &amp;quot;CALL 63013,1&amp;quot; is invoked&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
00B2H  DI                   ; Disable interrupts so nobody bugs us yet&lt;br /&gt;
00B3H  CPI 08H              ; Check the invocation parameter to test for recovery request&lt;br /&gt;
00B5H  JNC 0100H            ; Jump to test for recovery mode&lt;br /&gt;
00B8H  MOV B,A              ; Save the calling paramter to B&lt;br /&gt;
00B9H  PUSH B               ; Save BC to the stack&lt;br /&gt;
00BAH  PUSH D               ; Save DE to the stack&lt;br /&gt;
00BBH  PUSH H               ; Save HL to the stack&lt;br /&gt;
00BCH  LXI D,0040H          ; Load address of our &amp;quot;Change to OptROM&amp;quot; routine&lt;br /&gt;
00BFH  LXI H,FAA4H          ; Load pointer to somewhere in RAM to hold our routine&lt;br /&gt;
00C2H  CALL 0072H           ; Copy 8 bytes from DE to HL &lt;br /&gt;
00C5H  LXI B,0024H          ; Now prepare to copy 36 bytes worth of &amp;quot;routine&amp;quot;&lt;br /&gt;
00C8H  LXI H,F605H          ; Point to another RAM location&lt;br /&gt;
00CBH  CALL 0075H           ; Copy the next &amp;quot;ROM Bank Switching&amp;quot; routine from our ROM&lt;br /&gt;
00CEH  POP H                ; Restore HL&lt;br /&gt;
00CFH  POP D                ; Restore DE&lt;br /&gt;
00D0H  POP PSW              ; Restore A&lt;br /&gt;
00D1H  EI                   ; Allow interrupts again&lt;br /&gt;
00D2H  JMP 0100H            ; Go test if a &amp;quot;Cold Start&amp;quot; recovery is being requested&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    .org 100H&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test if cold-start recovery requested&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0100H  MOV A,H              ; Move H to A to test HL for zero&lt;br /&gt;
0101H  ORA L                ; Test for zero&lt;br /&gt;
0102H  JZ 7000H             ; Call recovery routine if requested&lt;br /&gt;
0105H  POP H                ; Pop the return address.  We will exit manually&lt;br /&gt;
0106H  CALL 0117H           ; Ensure the TS-DOS progam is installed in the MENU&lt;br /&gt;
0109H  JMP 3535H            ; Jump to the TS-DOS UI&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Move BC bytes from (HL) to (DE) with increment&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
010CH  MOV A,M              ; Get next byte from (HL)&lt;br /&gt;
010DH  STAX D               ; Save byte in (DE)&lt;br /&gt;
010EH  INX H                ; Increment source pointer&lt;br /&gt;
010FH  INX D                ; Increment destination pointer&lt;br /&gt;
0110H  DCX B                ; Decrement loop control&lt;br /&gt;
0111H  MOV A,B              ; Move MSB to A to test for zero&lt;br /&gt;
0112H  ORA C                ; OR in LSB to test for zero&lt;br /&gt;
0113H  JNZ 010CH            ; Branch to copy next byte until done&lt;br /&gt;
0116H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Insert the &amp;quot;TS-DOS&amp;quot; invocation program (BASIC program) into the Catalog / MENU.&lt;br /&gt;
;    we always insert ourselves at the lowest RAM address.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0117H  LXI H,01E1H          ; Point to &amp;quot;TS-DOS&amp;quot; catalog entry in our ROM&lt;br /&gt;
011AH  PUSH H               ; Save the address on the stack for later&lt;br /&gt;
011BH  INX H                ; Point to the text portion of the catalog entry&lt;br /&gt;
011CH  LXI B,0008H          ; Prepare to copy 8 filename byte&lt;br /&gt;
011FH  LXI D,FC93H          ; Filename of current BASIC program&lt;br /&gt;
0122H  CALL 010CH           ; Copy BC bytes from HL to DE - put &amp;quot;TS-DOS  &amp;quot; in cur. BASIC prog.&lt;br /&gt;
0125H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  DE now has the address of the invocation program&lt;br /&gt;
0126H  LHLX                 ; Get the length of the BASIC program into HL&lt;br /&gt;
0127H  SHLD FCC4H           ; Save the BASIC program length in the ALTLCD buffer for now&lt;br /&gt;
012AH  INX D                ; Point to MSB of the length&lt;br /&gt;
012BH  INX D                ; Point to LSB of the pointer to the &amp;quot;Next&amp;quot; BASIC instruction&lt;br /&gt;
012CH  XCHG                 ; HL &amp;lt;--&amp;gt; DE HL has the pointer to the &amp;quot;Next&amp;quot; BASIC inst address&lt;br /&gt;
012DH  SHLD FCC8H           ; Save the &amp;quot;Next&amp;quot; BASIC inst pointer to ALTLCD (start of program)&lt;br /&gt;
0130H  CALL 01D1H           ; Update the System pointers&lt;br /&gt;
0133H  CALL 01CDH           ; Search Catalog for entry matching current BASIC program&lt;br /&gt;
0136H  POP B                ; Pop address in case we return&lt;br /&gt;
0137H  RNZ                  ; Return if &amp;quot;TS-DOS&amp;quot; is already in the catalog&lt;br /&gt;
0138H  LHLD F99AH           ; Get the BASIC program not saved pointer - insert before that&lt;br /&gt;
013BH  SHLD FCC2H           ; Save storage location for the TS-DOS invocation progam&lt;br /&gt;
013EH  LDAX B               ; Load the file type byte from our ROM (B has the address from above)&lt;br /&gt;
013FH  STA FCC6H            ; Store the Type byte in the ALTLCD &lt;br /&gt;
0142H  CALL 0185H           ; Find empty entry in Catalog&lt;br /&gt;
0145H  RC                   ; Return if catalog full&lt;br /&gt;
0146H  PUSH H               ; Save the address of the empty catalog entry to the stack&lt;br /&gt;
0147H  LHLD FCC4H           ; Restore the BASIC program length from ALTLCD&lt;br /&gt;
014AH  MOV B,H              ; Move BASIC program length to BC for copy&lt;br /&gt;
014BH  MOV C,L              ; Move LSB of length&lt;br /&gt;
014CH  PUSH B               ; Save Length to the stack&lt;br /&gt;
014DH  LHLD FCC2H           ; Get address of insertion for TS-DOS just before the unsaved BASIC prog.&lt;br /&gt;
0150H  CALL 01DDH           ; Call Main ROM&#039;s Insert BC spaces at M routine&lt;br /&gt;
0153H  JC 0182H             ; Abort if RAM full&lt;br /&gt;
0156H  LHLD FCC2H           ; Get address of insertion point again&lt;br /&gt;
0159H  XCHG                 ; DE now has insertion point for BASIC program&lt;br /&gt;
015AH  LHLD FCC8H           ; Get the address of the BASIC program (in our ROM) from ALTLCD&lt;br /&gt;
015DH  POP B                ; Restore copy length of the BASIC program&lt;br /&gt;
015EH  CALL 010CH           ; Move BC bytes from (HL) to (DE) with increment&lt;br /&gt;
0161H  POP D                ; Get the address of the empty catalog entry we will use for TS-DOS&lt;br /&gt;
0162H  PUSH D               ; Save it back to the stack&lt;br /&gt;
0163H  LHLD FBAEH           ; Load the start of DO files pointer&lt;br /&gt;
0166H  DCX H                ; Derement the start of DO files pointer&lt;br /&gt;
0167H  SHLD F99AH           ; Save it as the new BASIC program not saved pointer&lt;br /&gt;
016AH  INX H                ; Point to start of DO files again&lt;br /&gt;
016BH  XCHG                 ; Move it to DE&lt;br /&gt;
016CH  LHLD FCC4H           ; Load the TS-DOS BASIC progam length from ALTLCD&lt;br /&gt;
016FH  DAD D                ; Offset the start of DO files by the insertion amount&lt;br /&gt;
0170H  SHLD FBAEH           ; Save the new start of DO files pointer&lt;br /&gt;
0173H  POP D                ; Restore the address of the empty catalog entry&lt;br /&gt;
0174H  LHLD FCC2H           ; Get the starting address of the newly inserted TS-DOS program&lt;br /&gt;
0177H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  Swap for the call to the catalog insertion routine &lt;br /&gt;
0178H  LDA FCC6H            ; Load A with the file type byte&lt;br /&gt;
017BH  CALL 01D5H           ; Save current BASIC program to the Catalog entry at HL&lt;br /&gt;
017EH  CALL 01D1H           ; Update system pointers&lt;br /&gt;
0181H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Insert &amp;quot;TS-DOS&amp;quot; RAM full abort routine ... stack cleanup.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0182H  POP H                ; Pop the BASIC program length from the stack&lt;br /&gt;
0183H  POP H                ; Pop the catalog entry address from the stack&lt;br /&gt;
0184H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Find an empty entry in the Catalog.  HL points to start of new entry&lt;br /&gt;
;     This routine appears again at address 3E48H&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0185H  LXI H,F9AFH          ; Point to &amp;quot;RickY&amp;quot; to start search at beginning of catalog&lt;br /&gt;
0188H  LXI B,000BH          ; Get length of each entry in the Catalog&lt;br /&gt;
018BH  DAD B                ; Point to next entry in the catalog&lt;br /&gt;
018CH  MOV A,M              ; Get the File Attribute byte from the catalog for this file&lt;br /&gt;
018DH  CPI FFH              ; Test if at end of the catalog&lt;br /&gt;
018FH  JZ 0197H             ; Jump to set Carry flag and exit if at end&lt;br /&gt;
0192H  ADD A                ; Test if MSB set (test if entry available)&lt;br /&gt;
0193H  JC 018BH             ; Branch to get next entry if this one is used&lt;br /&gt;
0196H  RET                  ; Return with Carry clear to indicate entry found&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Empty catalog entry not found in Catalog, set Carry and return&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0197H  STC                  ; Set the Carry flag - not found&lt;br /&gt;
0198H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Display function key line routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0199H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
019AH  DW    42A8H&lt;br /&gt;
019CH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Erase function key display routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
019DH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
019EH  DW    428AH&lt;br /&gt;
01A0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Set new function key table routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01A1H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01A2H  DW    5A7CH&lt;br /&gt;
01A4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Wait for key from keyboard routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01A5H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01A6H  DW    12CBH&lt;br /&gt;
01A8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Scan keyboard for character (CTRL-BREAK ==&amp;gt; CTRL-C) routine&lt;br /&gt;
;      This appears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01A9H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01AAH  DW    7242H&lt;br /&gt;
01ACH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Power Down routine&lt;br /&gt;
;      This appears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01ADH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01AEH  DW    13B5H&lt;br /&gt;
01B0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Renew automatic power-off counter routine&lt;br /&gt;
;      This apears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01B1H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01B2H  DW    1BB1H&lt;br /&gt;
01B4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s CLS statement routine&lt;br /&gt;
;      This apears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01B5H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01B6H  DW    4231H&lt;br /&gt;
01B8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Start inverse character mode routine&lt;br /&gt;
;      This appears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01B9H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01BAH  DW    4269H&lt;br /&gt;
01BCH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Cancel inverse video routine&lt;br /&gt;
;      This appears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01BDH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01BEH  DW    426EH&lt;br /&gt;
01C0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Check keyboard queue for pending characters routine&lt;br /&gt;
;      This appers later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01C1H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01C2H  DW    13DBH&lt;br /&gt;
01C4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Stop automatic scrolling routine&lt;br /&gt;
;      This appers later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01C5H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01C6H  DW    423FH&lt;br /&gt;
01C8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Reset vector routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01C9H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01CAH  DW    0000H&lt;br /&gt;
01CCH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Search Catalog for entry matching current BASIC program&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01CDH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01CEH  DW    20AFH&lt;br /&gt;
01D0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Update system pointers routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01D1H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01D2H  DW    2146H&lt;br /&gt;
01D4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s routine to save current BASIC program to the Catalog entry at HL&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01D5H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01D6H  DW    2239H&lt;br /&gt;
01D8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Not a valid entry into ROM and not called anywhere&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01D9H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01DAH  DW    5825H&lt;br /&gt;
01DCH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Insert BC spaces at M routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01DDH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01DEH  DB    6B6DH&lt;br /&gt;
01E0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; TS-DOS entry that will be inserted into the catalog for invoking TS-DOS&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01E1H  DB   80H             ; TS-DOS file type for catalog entry&lt;br /&gt;
01E2H  DB   &amp;quot;TS-DOS  &amp;quot;      ; TS-DOS Catalog name entry&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; BASIC program that will be inserted into RAM to launch TS-DOS from the MENU/Catalog entry&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01EAH  DB   0FH,00H,0EH,80H ; BASIC program length and pointer to &amp;quot;Next&amp;quot; BASIC instruction&lt;br /&gt;
01EDH  DB   0AH,00H,B9H     ; BASIC Line number &amp;quot;10&amp;quot; and BASIC token for CALL&lt;br /&gt;
01EFH  DB   &amp;quot;63013,1&amp;quot;       ; CALL argument &lt;br /&gt;
01F5H  DB   00H,00H         ; BASIC terminating zeros&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
End of disassembly for OptROM Support.&lt;br /&gt;
&lt;br /&gt;
Navigate to:&lt;br /&gt;
 - [[Dissasembly of RAM and ROM versions of TS-DOS]]&lt;br /&gt;
 - [[M100 TS-DOS ROM UI Code]]&lt;br /&gt;
 - [[M100 TS-DOS ROM FKey Handlers]]&lt;br /&gt;
 - [[M100 TS-DOS ROM RST 7 Handlers]]&lt;br /&gt;
 - [[M100 TS-DOS ROM TPDD Protocol]]&lt;br /&gt;
 - [[M100 TS-DOS ROM Compression]]&lt;br /&gt;
 - [[M100 TS-DOS ROM Cold Boot Recovery]]&lt;/div&gt;</summary>
		<author><name>Kpettit</name></author>
	</entry>
	<entry>
		<id>https://bitchin100.com/wiki/index.php?title=Disassembly_of_RAM_and_ROM_versions_of_TS-DOS&amp;diff=1374</id>
		<title>Disassembly of RAM and ROM versions of TS-DOS</title>
		<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=Disassembly_of_RAM_and_ROM_versions_of_TS-DOS&amp;diff=1374"/>
		<updated>2009-04-03T07:26:36Z</updated>

		<summary type="html">&lt;p&gt;Kpettit: /* Model 100/102 ROM Version */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== TS-DOS Dissassembly ==&lt;br /&gt;
&lt;br /&gt;
There are various version of TS-DOS for The Model 100/102, for T200 and for the PC-8201a.  Additionally each of these versions has a ROM and a RAM.  While the majority of the code is equivalent across the various incarnations of TS-DOS, there are some differences due to varying RS-232 hardware and to accomodate execution from OptROM vs. RAM.&lt;br /&gt;
&lt;br /&gt;
The goal of the disassembly is to create a fully commented source file that can be assembled and subsequently modified / enhanced for new functionality.  The disassembly is split into several sections to keep each page &amp;quot;relatively&amp;quot; short.  The disassembly currently will not assemble as it contains absolute addresses that must be converted into assembly labels, or deleted where not needed.&lt;br /&gt;
&lt;br /&gt;
== Model 100/102 ROM Version ==&lt;br /&gt;
 - [[M100 TS-DOS ROM OptROM Support]]&lt;br /&gt;
 - [[M100 TS-DOS ROM UI Code]]&lt;br /&gt;
 - [[M100 TS-DOS ROM FKey Handlers]]&lt;br /&gt;
 - [[M100 TS-DOS ROM RST 7 Handlers]]&lt;br /&gt;
 - [[M100 TS-DOS ROM TPDD Protocol]]&lt;br /&gt;
&lt;br /&gt;
Not Completed Yet&lt;br /&gt;
 - [[M100 TS-DOS ROM Compression]]&lt;br /&gt;
 - [[M100 TS-DOS ROM Cold Boot Recovery]]&lt;br /&gt;
&lt;br /&gt;
== Model 200 RAM Version ==&lt;br /&gt;
[[UI Code]]  [[FKey Handlers]]  [[RST 7 Handlers]]  [[TPDD Protocol]]&lt;/div&gt;</summary>
		<author><name>Kpettit</name></author>
	</entry>
	<entry>
		<id>https://bitchin100.com/wiki/index.php?title=Disassembly_of_RAM_and_ROM_versions_of_TS-DOS&amp;diff=1373</id>
		<title>Disassembly of RAM and ROM versions of TS-DOS</title>
		<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=Disassembly_of_RAM_and_ROM_versions_of_TS-DOS&amp;diff=1373"/>
		<updated>2009-04-03T07:21:47Z</updated>

		<summary type="html">&lt;p&gt;Kpettit: /* Model 100/102 ROM Version */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== TS-DOS Dissassembly ==&lt;br /&gt;
&lt;br /&gt;
There are various version of TS-DOS for The Model 100/102, for T200 and for the PC-8201a.  Additionally each of these versions has a ROM and a RAM.  While the majority of the code is equivalent across the various incarnations of TS-DOS, there are some differences due to varying RS-232 hardware and to accomodate execution from OptROM vs. RAM.&lt;br /&gt;
&lt;br /&gt;
The goal of the disassembly is to create a fully commented source file that can be assembled and subsequently modified / enhanced for new functionality.  The disassembly is split into several sections to keep each page &amp;quot;relatively&amp;quot; short.  The disassembly currently will not assemble as it contains absolute addresses that must be converted into assembly labels, or deleted where not needed.&lt;br /&gt;
&lt;br /&gt;
== Model 100/102 ROM Version ==&lt;br /&gt;
[[M100 TS-DOS ROM OptROM Support]]  [[M100 TS-DOS ROM UI Code]]  &lt;br /&gt;
[[M100 TS-DOS ROM FKey Handlers]]  [[M100 TS-DOS ROM RST 7 Handlers]]  &lt;br /&gt;
[[M100 TS-DOS ROM TPDD Protocol]]&lt;br /&gt;
&lt;br /&gt;
Not Completed Yet&lt;br /&gt;
[[M100 TS-DOS ROM Compression]] [[M100 TS-DOS ROM Cold Boot Recovery]]&lt;br /&gt;
&lt;br /&gt;
== Model 200 RAM Version ==&lt;br /&gt;
[[UI Code]]  [[FKey Handlers]]  [[RST 7 Handlers]]  [[TPDD Protocol]]&lt;/div&gt;</summary>
		<author><name>Kpettit</name></author>
	</entry>
	<entry>
		<id>https://bitchin100.com/wiki/index.php?title=M100_ROM_OptROM_Support&amp;diff=1372</id>
		<title>M100 ROM OptROM Support</title>
		<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=M100_ROM_OptROM_Support&amp;diff=1372"/>
		<updated>2009-04-03T07:12:02Z</updated>

		<summary type="html">&lt;p&gt;Kpettit: M100 ROM OptROM Support moved to M100 TS-DOS ROM OptROM Support: Adding TS-DOS to the page title in case there are other ROMS disassembled in the future.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[M100 TS-DOS ROM OptROM Support]]&lt;/div&gt;</summary>
		<author><name>Kpettit</name></author>
	</entry>
	<entry>
		<id>https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_OptROM_Support&amp;diff=1371</id>
		<title>M100 TS-DOS ROM OptROM Support</title>
		<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_OptROM_Support&amp;diff=1371"/>
		<updated>2009-04-03T07:12:02Z</updated>

		<summary type="html">&lt;p&gt;Kpettit: M100 ROM OptROM Support moved to M100 TS-DOS ROM OptROM Support: Adding TS-DOS to the page title in case there are other ROMS disassembled in the future.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== TS-DOS Model 100/102 ROM OptROM Support ==&lt;br /&gt;
&lt;br /&gt;
This code defines the variables used throughout the TS-DOS application as well as the support routines needed to navigate between the Main ROM and the Option ROM (most of them).  Also included is the TS-DOS startup code.  The assembly labels defined are open for discussion and have not been applied to any of the disassembled code yet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 =========================================================================================&lt;br /&gt;
; TS-DOS M100 ROM version Disassembly&lt;br /&gt;
;&lt;br /&gt;
; Initial Disassembly By Kenneth D. Pettit&lt;br /&gt;
; March, 2009&lt;br /&gt;
;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Variables in ALTLCD buffer&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
NB_CUR_DIR    equ FCC0H              ; NADSBox current directory (&amp;quot;MYFILE.&amp;lt;&amp;gt; &amp;quot;)&lt;br /&gt;
TPDD_BANK     equ FCCAH              ; TPDD2 Bank (side)&lt;br /&gt;
NB_TPDD_FLG   equ FCCBH              ; NADSBox/Desklink/TPDD2 flag (0=TPDD, 1=TPDD2, 2=NADSBox)&lt;br /&gt;
LAST_TAG      equ FCCCH              ; Tag/Untag last operation code&lt;br /&gt;
CUR_FILE      equ FCCDH              ; Currently selected file index on UI (1 based)&lt;br /&gt;
LJ_SP         equ FCCEH              ; Stack pointer upon entry for Long Jump&lt;br /&gt;
LJ_RET        equ FCD0H              ; Return vector for Long Jump &amp;quot;RETURN&amp;quot;&lt;br /&gt;
ERR_MODE      equ FCD2H              ; Print Error Messages flag, 1=Print, 0=Generate System Error&lt;br /&gt;
FDC_OPCODE    equ FCD3H              ; FDC Emulation mode opcode&lt;br /&gt;
CUR_PAGE      equ FCD4H              ; Current page of files being displayed (0 based)&lt;br /&gt;
TMP_FILE_IDX  equ FCD5H              ; Currently selected file index on UI - temp&lt;br /&gt;
FILE_COUNT    equ FCD6H              ; Count of files currently displayed on LCD&lt;br /&gt;
MAX_FILES     equ FCD7H              ; Maximum files that fit on the LCD&lt;br /&gt;
DISP_MODE     equ FCD9H              ; RAM / Disk Display mode (0=RAM,  1=DISK)&lt;br /&gt;
SKIP_PAGE     equ FCDAH              ; TPDD &amp;quot;skip page&amp;quot; count (number of pages to read and discard)&lt;br /&gt;
FILE_LEN      equ FCDBH              ; Pointer to &amp;quot;Current file&amp;quot; length bytes (in keyboard buffer)&lt;br /&gt;
PHYS_SCTR     equ FCDDH              ; FDC Emulation Physical Sector Number / Active File Length LSB&lt;br /&gt;
LOG_SCTR      equ FCDEH              ; FDC Emulation Logical Sector Number / Active File Length MSB&lt;br /&gt;
KEY_TYPE      equ FCDFH              ; Storage for FDC emulation / New file type code / Keypress storage&lt;br /&gt;
FILE_ADDR     equ FCE0H              ; Address of file being displayed/printed/loaded/saved&lt;br /&gt;
FILE_BUFF     equ FCE2H              ; Pointer for TPDD direct read data / address of file being read/written&lt;br /&gt;
TX_PKT_BUF    equ FCE6H              ; Storage for TX packets (28 bytes)&lt;br /&gt;
RX_PKT_BUF    equ FD02H              ; Storage for RX packets (130 bytes ??)&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Main Entry point when called from &amp;quot;CALL 63013,1&amp;quot;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
   &lt;br /&gt;
   .org 0000H&lt;br /&gt;
&lt;br /&gt;
0000H  JMP 00B2H            ; Jump to entry point handler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Pop registers after we power back up from a powerdown (I think)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0003H  POP H&lt;br /&gt;
0004H  POP D&lt;br /&gt;
0005H  POP B&lt;br /&gt;
0006H  POP PSW&lt;br /&gt;
0007H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 1 - Call Main ROM at location whose address follows RST 1 opcode&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0008H  (C3H) JMP 0080H      ; BASIC statement keyword table END to NEW&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 2 - Call Main ROM&#039;s RST 2 routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0010H  (CFH) RST 1          ; Call main ROM at address in following 2 bytes&lt;br /&gt;
0011H  DW    0010H          ; Call the Main ROM&#039;s RST 2 function&lt;br /&gt;
0013H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 3 routine - Compare HL and DE&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0018H  JMP 006CH            ; Jump to comparison routine&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Return to Main ROM.  After issuing the OUT E0H, we will be in Main ROM.  The next opcode&lt;br /&gt;
; in Main ROM after this OUT statement occurs will be a RET (part of RST 1).  We have &lt;br /&gt;
; PUSHed a return address to the stack, so the main ROM&#039;s RET instruction will get us &lt;br /&gt;
; where to intend to go.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
001BH  OUT E0H              ; Send A to the ROM bank port to switch to Main ROM&lt;br /&gt;
001DH  RET                  ; Should never execute this instruction, but just in case&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Send a space to the screen/printer - Not called from anywhere.  Copy of Main ROM.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
001EH  (3EH) MVI A,20H      ; Prepare to print a SPACE&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 3 routine - Send character in A to the screen / printer&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0020H  (CFH) RST 1          ; Call main ROM at address in following 2 bytes&lt;br /&gt;
0021H  DW    0020H          ; Main ROM&#039;s RST 3 routine&lt;br /&gt;
0023H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Power down TRAP.  Let Main ROM deal with it.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0024H  DI                   ; Disable interrupts while we jump   &lt;br /&gt;
0025H  CALL 0097H           ; Jump to Main ROM&#039;s RST handler for this vector &lt;br /&gt;
0028H  POP H      &lt;br /&gt;
0029H  JMP 0003H            ; Pop regs after we power back up from a power-down? &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Hardware Interrupt - Let Main ROM deal with it - Bar Code Reader&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
002CH  DI                   ; Disable interrupts while we jump  &lt;br /&gt;
002DH  CALL 0097H           ; Jump to Main ROM&#039;s RST handler for this vector&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Return from Main ROM hook in RAM returns here via RST 6&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0030H  POP PSW              ; Cleanup stack&lt;br /&gt;
0031H  POP PSW              ; Cleanup stack&lt;br /&gt;
0032H  RET                  ; Return to OptROM execution point        &lt;br /&gt;
&lt;br /&gt;
0033H  NOP                  ; Filler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Hardware Interrupt - Let Main ROM deal with it - RS232 character pending&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0034H  DI                   ; Disable interrupts while we jump&lt;br /&gt;
0035H  CALL 0097H           ; Jump to Main ROM&#039;s RST handler for this vector&lt;br /&gt;
0038H  JMP 00A6H            ; Stack cleanup&lt;br /&gt;
&lt;br /&gt;
003BH  NOP                  ; UNUSED - filler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Hardware Interrupt - Let Main ROM deal with it - Timer background task&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
003CH  DI                   ; Disable interrupts&lt;br /&gt;
003DH  CALL 0097H           ; Jump to Main ROM&#039;s RST handler for this vector&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; This routine gets copied to RAM to be used for switching back to the TS-DOS ROM after&lt;br /&gt;
;      calling a routine in the Main ROM.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0040H  PUSH PSW             ; Preserve the PSW&lt;br /&gt;
0041H  LDA FF45H            ; Contents of port E8H&lt;br /&gt;
0044H  INR A                ; Prepare to switch to OptRom&lt;br /&gt;
0045H  OUT E0H              ; Switch to OptRom&lt;br /&gt;
0047H  RST 6                ; Get sign of FAC1&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; This routine gets copied to RAM and appears to detect the presence of the TS-DOS ROM&lt;br /&gt;
;       after power-up and copies the original &amp;quot;External ROM&amp;quot; detection routine to RAM&lt;br /&gt;
;       if the TS-DOS ROM is no longer present.  At least I think that&#039;s what it&#039;s doing.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0048H  LXI D,F605H          ; Copy address for &amp;quot;Ext ROM detect&amp;quot; routine&lt;br /&gt;
004BH  INR A                ; Set bit to enable OptROM&lt;br /&gt;
004CH  OUT E0H              ; Switch to OptROM&lt;br /&gt;
004EH  XRA A                ; Prepare to switch back to Main ROM&lt;br /&gt;
004FH  LHLD 0049H           ; Load target address of the LXI D instruction above&lt;br /&gt;
0052H  OUT E0H              ; Switch back to Main ROM&lt;br /&gt;
0054H  RST 3                ; Compare DE and HL - Test if OptROM is TS-DOS&lt;br /&gt;
0055H  CPI 01H              ; Test for TS-DOS ROM&lt;br /&gt;
0057H  RC                   ; Return if TS-DOS ROM&lt;br /&gt;
0058H  LXI H,111DH          ; Load &amp;quot;Return&amp;quot; address to the CALL below&lt;br /&gt;
005BH  SHLD FAE0H&lt;br /&gt;
005EH  SHLD F5F2H           ; Save a &amp;quot;Restart signature&amp;quot; ???&lt;br /&gt;
0061H  CALL 2905H           ; Copy the DB number of bytes from the DW address to (DE)&lt;br /&gt;
0064H  DB   24H             ; ....copy 24H bytes&lt;br /&gt;
0065H  DW   036FH           ; ....from ROM addres 036F (external ROM detect)&lt;br /&gt;
0067H  RST 0                ; I&#039;m not sure it it every actually returns here or not&lt;br /&gt;
0068H  NOP&lt;br /&gt;
0069H  CALL FAA4H           ; Call our installed RAM hook to return to TS-DOS&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Compare HL and DE - called by the RST 3 routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
006CH  MOV A,H              ; Move H into A for comparison&lt;br /&gt;
006DH  SUB D                ; Compare MSB first&lt;br /&gt;
006EH  RNZ                  ; Return if no match&lt;br /&gt;
006FH  MOV A,L              ; Now move L into A&lt;br /&gt;
0070H  SUB E                ; Compare LSB&lt;br /&gt;
0071H  RET                  ; Return with flags set&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Copy 8 bytes from DE to HL &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0072H  LXI B,0008H          ; Prepare to copy 8 bytes &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Copy BC bytes from DE to HL &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0075H  LDAX D               ; Load value from (DE)&lt;br /&gt;
0076H  MOV M,A              ; Save value to (HL)&lt;br /&gt;
0077H  INX D                ; Increment DE&lt;br /&gt;
0078H  INX H                ; Increment HL&lt;br /&gt;
0079H  DCX B                ; Decrement counter&lt;br /&gt;
007AH  MOV A,B              ; Prepare to test counter for zero&lt;br /&gt;
007BH  ORA C                ; Test counter for zero&lt;br /&gt;
007CH  JNZ 0075H            ; Keep looping until 8 bytes copied&lt;br /&gt;
007FH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle the RST 1 routine.  Read the Main ROM address from the 2 bytes after the RST 1&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0080H  SHLD F9B2H           ; Save HL off in &amp;quot;RickY&amp;quot; Cat entry so we don&#039;t clobber it&lt;br /&gt;
0083H  POP H                ; Get out return address (location of the ROM address to call&lt;br /&gt;
0084H  PUSH D               ; Push the return address back to the stack as storage &lt;br /&gt;
0085H  MOV E,M              ; Get LSB of the ROM address to call&lt;br /&gt;
0086H  INX H                ; Point to MSB of ROM address to call&lt;br /&gt;
0087H  MOV D,M              ; Get MSB of the ROM address to call&lt;br /&gt;
0088H  INX H                ; Point to return address after the RST 1 DB address&lt;br /&gt;
0089H  XTHL                 ; Put the return address on the stack so we return after the RST 1&lt;br /&gt;
008AH  XCHG                 ; Now get the address within ROM to call&lt;br /&gt;
008BH  PUSH H               ; Push the target ROM address to the stack so we &amp;quot;RETurn&amp;quot; there&lt;br /&gt;
008CH  LXI H,FAA4H          ; Load address of our RAM hook to switch back to our ROM bank and RET&lt;br /&gt;
008FH  XTHL                 ; Push that address on the stack for after the ROM call is complete&lt;br /&gt;
0090H  PUSH H               ; Now put the ROM address back on the stack so we will RET there&lt;br /&gt;
0091H  LHLD F9B2H           ; Restore HL from temp storage in &amp;quot;RickY&amp;quot;&lt;br /&gt;
0094H  JMP 00A6H            ; Branch to switch to Main ROM and &amp;quot;RET&amp;quot; to the address we pushed&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST handler for calling the Main ROM&#039;s RST handlers.  This routine restores the original&lt;br /&gt;
;      RST vector address to the stack, and jumps to the Main ROM&#039;s RST routine while &lt;br /&gt;
;      preserving all register values.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0097H  SHLD F9B4H           ; Save HL temporarily (somewhere in RickY&#039;s name)&lt;br /&gt;
009AH  LXI H,FAA4H          ; Point to our RAM hook for returning to TS-DOS&lt;br /&gt;
009DH  XTHL                 ; Put the hook address as the return address on the stack&lt;br /&gt;
009EH  DCX H                ; Decrement the return address by 4&lt;br /&gt;
009FH  DCX H                ; ...this will result in the starting address of the RST&lt;br /&gt;
00A0H  DCX H                ; ...that brought us here&lt;br /&gt;
00A1H  DCX H&lt;br /&gt;
00A2H  PUSH H               ; Push the RST vector address to the stack&lt;br /&gt;
00A3H  LHLD F9B4H           ; Restore HL upon entry&lt;br /&gt;
00A6H  PUSH PSW             ; Save A to the stack&lt;br /&gt;
00A7H  PUSH H               ; Save the HL to the stack so we can preserve through XTHL&lt;br /&gt;
00A8H  LXI H,1488H          ; Load a RETurn address in the Main ROM (a POP PSW &amp;amp; RET) &lt;br /&gt;
00ABH  XTHL                 ; Push the address and get HL back&lt;br /&gt;
00ACH  LDA FF45H            ; Contents of port E8H - prepare for jump to Main ROM&lt;br /&gt;
00AFH  JMP 001BH            ; Jump to Main ROM &amp;amp; our custom &amp;quot;RET&amp;quot; address in the ROM&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Manual invocation entry point.  This is where we jump when &amp;quot;CALL 63013,1&amp;quot; is invoked&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
00B2H  DI                   ; Disable interrupts so nobody bugs us yet&lt;br /&gt;
00B3H  CPI 08H              ; Check the invocation parameter to test for recovery request&lt;br /&gt;
00B5H  JNC 0100H            ; Jump to test for recovery mode&lt;br /&gt;
00B8H  MOV B,A              ; Save the calling paramter to B&lt;br /&gt;
00B9H  PUSH B               ; Save BC to the stack&lt;br /&gt;
00BAH  PUSH D               ; Save DE to the stack&lt;br /&gt;
00BBH  PUSH H               ; Save HL to the stack&lt;br /&gt;
00BCH  LXI D,0040H          ; Load address of our &amp;quot;Change to OptROM&amp;quot; routine&lt;br /&gt;
00BFH  LXI H,FAA4H          ; Load pointer to somewhere in RAM to hold our routine&lt;br /&gt;
00C2H  CALL 0072H           ; Copy 8 bytes from DE to HL &lt;br /&gt;
00C5H  LXI B,0024H          ; Now prepare to copy 36 bytes worth of &amp;quot;routine&amp;quot;&lt;br /&gt;
00C8H  LXI H,F605H          ; Point to another RAM location&lt;br /&gt;
00CBH  CALL 0075H           ; Copy the next &amp;quot;ROM Bank Switching&amp;quot; routine from our ROM&lt;br /&gt;
00CEH  POP H                ; Restore HL&lt;br /&gt;
00CFH  POP D                ; Restore DE&lt;br /&gt;
00D0H  POP PSW              ; Restore A&lt;br /&gt;
00D1H  EI                   ; Allow interrupts again&lt;br /&gt;
00D2H  JMP 0100H            ; Go test if a &amp;quot;Cold Start&amp;quot; recovery is being requested&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    .org 100H&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test if cold-start recovery requested&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0100H  MOV A,H              ; Move H to A to test HL for zero&lt;br /&gt;
0101H  ORA L                ; Test for zero&lt;br /&gt;
0102H  JZ 7000H             ; Call recovery routine if requested&lt;br /&gt;
0105H  POP H                ; Pop the return address.  We will exit manually&lt;br /&gt;
0106H  CALL 0117H           ; Ensure the TS-DOS progam is installed in the MENU&lt;br /&gt;
0109H  JMP 3535H            ; Jump to the TS-DOS UI&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Move BC bytes from (HL) to (DE) with increment&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
010CH  MOV A,M              ; Get next byte from (HL)&lt;br /&gt;
010DH  STAX D               ; Save byte in (DE)&lt;br /&gt;
010EH  INX H                ; Increment source pointer&lt;br /&gt;
010FH  INX D                ; Increment destination pointer&lt;br /&gt;
0110H  DCX B                ; Decrement loop control&lt;br /&gt;
0111H  MOV A,B              ; Move MSB to A to test for zero&lt;br /&gt;
0112H  ORA C                ; OR in LSB to test for zero&lt;br /&gt;
0113H  JNZ 010CH            ; Branch to copy next byte until done&lt;br /&gt;
0116H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Insert the &amp;quot;TS-DOS&amp;quot; invocation program (BASIC program) into the Catalog / MENU.&lt;br /&gt;
;    we always insert ourselves at the lowest RAM address.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0117H  LXI H,01E1H          ; Point to &amp;quot;TS-DOS&amp;quot; catalog entry in our ROM&lt;br /&gt;
011AH  PUSH H               ; Save the address on the stack for later&lt;br /&gt;
011BH  INX H                ; Point to the text portion of the catalog entry&lt;br /&gt;
011CH  LXI B,0008H          ; Prepare to copy 8 filename byte&lt;br /&gt;
011FH  LXI D,FC93H          ; Filename of current BASIC program&lt;br /&gt;
0122H  CALL 010CH           ; Copy BC bytes from HL to DE - put &amp;quot;TS-DOS  &amp;quot; in cur. BASIC prog.&lt;br /&gt;
0125H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  DE now has the address of the invocation program&lt;br /&gt;
0126H  LHLX                 ; Get the length of the BASIC program into HL&lt;br /&gt;
0127H  SHLD FCC4H           ; Save the BASIC program length in the ALTLCD buffer for now&lt;br /&gt;
012AH  INX D                ; Point to MSB of the length&lt;br /&gt;
012BH  INX D                ; Point to LSB of the pointer to the &amp;quot;Next&amp;quot; BASIC instruction&lt;br /&gt;
012CH  XCHG                 ; HL &amp;lt;--&amp;gt; DE HL has the pointer to the &amp;quot;Next&amp;quot; BASIC inst address&lt;br /&gt;
012DH  SHLD FCC8H           ; Save the &amp;quot;Next&amp;quot; BASIC inst pointer to ALTLCD (start of program)&lt;br /&gt;
0130H  CALL 01D1H           ; Update the System pointers&lt;br /&gt;
0133H  CALL 01CDH           ; Search Catalog for entry matching current BASIC program&lt;br /&gt;
0136H  POP B                ; Pop address in case we return&lt;br /&gt;
0137H  RNZ                  ; Return if &amp;quot;TS-DOS&amp;quot; is already in the catalog&lt;br /&gt;
0138H  LHLD F99AH           ; Get the BASIC program not saved pointer - insert before that&lt;br /&gt;
013BH  SHLD FCC2H           ; Save storage location for the TS-DOS invocation progam&lt;br /&gt;
013EH  LDAX B               ; Load the file type byte from our ROM (B has the address from above)&lt;br /&gt;
013FH  STA FCC6H            ; Store the Type byte in the ALTLCD &lt;br /&gt;
0142H  CALL 0185H           ; Find empty entry in Catalog&lt;br /&gt;
0145H  RC                   ; Return if catalog full&lt;br /&gt;
0146H  PUSH H               ; Save the address of the empty catalog entry to the stack&lt;br /&gt;
0147H  LHLD FCC4H           ; Restore the BASIC program length from ALTLCD&lt;br /&gt;
014AH  MOV B,H              ; Move BASIC program length to BC for copy&lt;br /&gt;
014BH  MOV C,L              ; Move LSB of length&lt;br /&gt;
014CH  PUSH B               ; Save Length to the stack&lt;br /&gt;
014DH  LHLD FCC2H           ; Get address of insertion for TS-DOS just before the unsaved BASIC prog.&lt;br /&gt;
0150H  CALL 01DDH           ; Call Main ROM&#039;s Insert BC spaces at M routine&lt;br /&gt;
0153H  JC 0182H             ; Abort if RAM full&lt;br /&gt;
0156H  LHLD FCC2H           ; Get address of insertion point again&lt;br /&gt;
0159H  XCHG                 ; DE now has insertion point for BASIC program&lt;br /&gt;
015AH  LHLD FCC8H           ; Get the address of the BASIC program (in our ROM) from ALTLCD&lt;br /&gt;
015DH  POP B                ; Restore copy length of the BASIC program&lt;br /&gt;
015EH  CALL 010CH           ; Move BC bytes from (HL) to (DE) with increment&lt;br /&gt;
0161H  POP D                ; Get the address of the empty catalog entry we will use for TS-DOS&lt;br /&gt;
0162H  PUSH D               ; Save it back to the stack&lt;br /&gt;
0163H  LHLD FBAEH           ; Load the start of DO files pointer&lt;br /&gt;
0166H  DCX H                ; Derement the start of DO files pointer&lt;br /&gt;
0167H  SHLD F99AH           ; Save it as the new BASIC program not saved pointer&lt;br /&gt;
016AH  INX H                ; Point to start of DO files again&lt;br /&gt;
016BH  XCHG                 ; Move it to DE&lt;br /&gt;
016CH  LHLD FCC4H           ; Load the TS-DOS BASIC progam length from ALTLCD&lt;br /&gt;
016FH  DAD D                ; Offset the start of DO files by the insertion amount&lt;br /&gt;
0170H  SHLD FBAEH           ; Save the new start of DO files pointer&lt;br /&gt;
0173H  POP D                ; Restore the address of the empty catalog entry&lt;br /&gt;
0174H  LHLD FCC2H           ; Get the starting address of the newly inserted TS-DOS program&lt;br /&gt;
0177H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  Swap for the call to the catalog insertion routine &lt;br /&gt;
0178H  LDA FCC6H            ; Load A with the file type byte&lt;br /&gt;
017BH  CALL 01D5H           ; Save current BASIC program to the Catalog entry at HL&lt;br /&gt;
017EH  CALL 01D1H           ; Update system pointers&lt;br /&gt;
0181H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Insert &amp;quot;TS-DOS&amp;quot; RAM full abort routine ... stack cleanup.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0182H  POP H                ; Pop the BASIC program length from the stack&lt;br /&gt;
0183H  POP H                ; Pop the catalog entry address from the stack&lt;br /&gt;
0184H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Find an empty entry in the Catalog.  HL points to start of new entry&lt;br /&gt;
;     This routine appears again at address 3E48H&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0185H  LXI H,F9AFH          ; Point to &amp;quot;RickY&amp;quot; to start search at beginning of catalog&lt;br /&gt;
0188H  LXI B,000BH          ; Get length of each entry in the Catalog&lt;br /&gt;
018BH  DAD B                ; Point to next entry in the catalog&lt;br /&gt;
018CH  MOV A,M              ; Get the File Attribute byte from the catalog for this file&lt;br /&gt;
018DH  CPI FFH              ; Test if at end of the catalog&lt;br /&gt;
018FH  JZ 0197H             ; Jump to set Carry flag and exit if at end&lt;br /&gt;
0192H  ADD A                ; Test if MSB set (test if entry available)&lt;br /&gt;
0193H  JC 018BH             ; Branch to get next entry if this one is used&lt;br /&gt;
0196H  RET                  ; Return with Carry clear to indicate entry found&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Empty catalog entry not found in Catalog, set Carry and return&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0197H  STC                  ; Set the Carry flag - not found&lt;br /&gt;
0198H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Display function key line routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0199H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
019AH  DW    42A8H&lt;br /&gt;
019CH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Erase function key display routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
019DH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
019EH  DW    428AH&lt;br /&gt;
01A0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Set new function key table routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01A1H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01A2H  DW    5A7CH&lt;br /&gt;
01A4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Wait for key from keyboard routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01A5H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01A6H  DW    12CBH&lt;br /&gt;
01A8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Scan keyboard for character (CTRL-BREAK ==&amp;gt; CTRL-C) routine&lt;br /&gt;
;      This appears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01A9H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01AAH  DW    7242H&lt;br /&gt;
01ACH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Power Down routine&lt;br /&gt;
;      This appears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01ADH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01AEH  DW    13B5H&lt;br /&gt;
01B0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Renew automatic power-off counter routine&lt;br /&gt;
;      This apears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01B1H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01B2H  DW    1BB1H&lt;br /&gt;
01B4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s CLS statement routine&lt;br /&gt;
;      This apears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01B5H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01B6H  DW    4231H&lt;br /&gt;
01B8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Start inverse character mode routine&lt;br /&gt;
;      This appears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01B9H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01BAH  DW    4269H&lt;br /&gt;
01BCH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Cancel inverse video routine&lt;br /&gt;
;      This appears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01BDH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01BEH  DW    426EH&lt;br /&gt;
01C0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Check keyboard queue for pending characters routine&lt;br /&gt;
;      This appers later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01C1H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01C2H  DW    13DBH&lt;br /&gt;
01C4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Stop automatic scrolling routine&lt;br /&gt;
;      This appers later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01C5H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01C6H  DW    423FH&lt;br /&gt;
01C8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Reset vector routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01C9H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01CAH  DW    0000H&lt;br /&gt;
01CCH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Search Catalog for entry matching current BASIC program&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01CDH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01CEH  DW    20AFH&lt;br /&gt;
01D0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Update system pointers routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01D1H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01D2H  DW    2146H&lt;br /&gt;
01D4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s routine to save current BASIC program to the Catalog entry at HL&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01D5H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01D6H  DW    2239H&lt;br /&gt;
01D8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Not a valid entry into ROM and not called anywhere&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01D9H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01DAH  DW    5825H&lt;br /&gt;
01DCH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Insert BC spaces at M routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01DDH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01DEH  DB    6B6DH&lt;br /&gt;
01E0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; TS-DOS entry that will be inserted into the catalog for invoking TS-DOS&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01E1H  DB   80H             ; TS-DOS file type for catalog entry&lt;br /&gt;
01E2H  DB   &amp;quot;TS-DOS  &amp;quot;      ; TS-DOS Catalog name entry&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; BASIC program that will be inserted into RAM to launch TS-DOS from the MENU/Catalog entry&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01EAH  DB   0FH,00H,0EH,80H ; BASIC program length and pointer to &amp;quot;Next&amp;quot; BASIC instruction&lt;br /&gt;
01EDH  DB   0AH,00H,B9H     ; BASIC Line number &amp;quot;10&amp;quot; and BASIC token for CALL&lt;br /&gt;
01EFH  DB   &amp;quot;63013,1&amp;quot;       ; CALL argument &lt;br /&gt;
01F5H  DB   00H,00H         ; BASIC terminating zeros&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
End of disassembly for OptROM Support.&lt;br /&gt;
&lt;br /&gt;
Navigate to [[M100 TS-DOS ROM UI Code]]&lt;/div&gt;</summary>
		<author><name>Kpettit</name></author>
	</entry>
	<entry>
		<id>https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_OptROM_Support&amp;diff=1370</id>
		<title>M100 TS-DOS ROM OptROM Support</title>
		<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_OptROM_Support&amp;diff=1370"/>
		<updated>2009-04-03T07:11:03Z</updated>

		<summary type="html">&lt;p&gt;Kpettit: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== TS-DOS Model 100/102 ROM OptROM Support ==&lt;br /&gt;
&lt;br /&gt;
This code defines the variables used throughout the TS-DOS application as well as the support routines needed to navigate between the Main ROM and the Option ROM (most of them).  Also included is the TS-DOS startup code.  The assembly labels defined are open for discussion and have not been applied to any of the disassembled code yet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 =========================================================================================&lt;br /&gt;
; TS-DOS M100 ROM version Disassembly&lt;br /&gt;
;&lt;br /&gt;
; Initial Disassembly By Kenneth D. Pettit&lt;br /&gt;
; March, 2009&lt;br /&gt;
;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Variables in ALTLCD buffer&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
NB_CUR_DIR    equ FCC0H              ; NADSBox current directory (&amp;quot;MYFILE.&amp;lt;&amp;gt; &amp;quot;)&lt;br /&gt;
TPDD_BANK     equ FCCAH              ; TPDD2 Bank (side)&lt;br /&gt;
NB_TPDD_FLG   equ FCCBH              ; NADSBox/Desklink/TPDD2 flag (0=TPDD, 1=TPDD2, 2=NADSBox)&lt;br /&gt;
LAST_TAG      equ FCCCH              ; Tag/Untag last operation code&lt;br /&gt;
CUR_FILE      equ FCCDH              ; Currently selected file index on UI (1 based)&lt;br /&gt;
LJ_SP         equ FCCEH              ; Stack pointer upon entry for Long Jump&lt;br /&gt;
LJ_RET        equ FCD0H              ; Return vector for Long Jump &amp;quot;RETURN&amp;quot;&lt;br /&gt;
ERR_MODE      equ FCD2H              ; Print Error Messages flag, 1=Print, 0=Generate System Error&lt;br /&gt;
FDC_OPCODE    equ FCD3H              ; FDC Emulation mode opcode&lt;br /&gt;
CUR_PAGE      equ FCD4H              ; Current page of files being displayed (0 based)&lt;br /&gt;
TMP_FILE_IDX  equ FCD5H              ; Currently selected file index on UI - temp&lt;br /&gt;
FILE_COUNT    equ FCD6H              ; Count of files currently displayed on LCD&lt;br /&gt;
MAX_FILES     equ FCD7H              ; Maximum files that fit on the LCD&lt;br /&gt;
DISP_MODE     equ FCD9H              ; RAM / Disk Display mode (0=RAM,  1=DISK)&lt;br /&gt;
SKIP_PAGE     equ FCDAH              ; TPDD &amp;quot;skip page&amp;quot; count (number of pages to read and discard)&lt;br /&gt;
FILE_LEN      equ FCDBH              ; Pointer to &amp;quot;Current file&amp;quot; length bytes (in keyboard buffer)&lt;br /&gt;
PHYS_SCTR     equ FCDDH              ; FDC Emulation Physical Sector Number / Active File Length LSB&lt;br /&gt;
LOG_SCTR      equ FCDEH              ; FDC Emulation Logical Sector Number / Active File Length MSB&lt;br /&gt;
KEY_TYPE      equ FCDFH              ; Storage for FDC emulation / New file type code / Keypress storage&lt;br /&gt;
FILE_ADDR     equ FCE0H              ; Address of file being displayed/printed/loaded/saved&lt;br /&gt;
FILE_BUFF     equ FCE2H              ; Pointer for TPDD direct read data / address of file being read/written&lt;br /&gt;
TX_PKT_BUF    equ FCE6H              ; Storage for TX packets (28 bytes)&lt;br /&gt;
RX_PKT_BUF    equ FD02H              ; Storage for RX packets (130 bytes ??)&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Main Entry point when called from &amp;quot;CALL 63013,1&amp;quot;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
   &lt;br /&gt;
   .org 0000H&lt;br /&gt;
&lt;br /&gt;
0000H  JMP 00B2H            ; Jump to entry point handler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Pop registers after we power back up from a powerdown (I think)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0003H  POP H&lt;br /&gt;
0004H  POP D&lt;br /&gt;
0005H  POP B&lt;br /&gt;
0006H  POP PSW&lt;br /&gt;
0007H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 1 - Call Main ROM at location whose address follows RST 1 opcode&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0008H  (C3H) JMP 0080H      ; BASIC statement keyword table END to NEW&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 2 - Call Main ROM&#039;s RST 2 routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0010H  (CFH) RST 1          ; Call main ROM at address in following 2 bytes&lt;br /&gt;
0011H  DW    0010H          ; Call the Main ROM&#039;s RST 2 function&lt;br /&gt;
0013H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 3 routine - Compare HL and DE&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0018H  JMP 006CH            ; Jump to comparison routine&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Return to Main ROM.  After issuing the OUT E0H, we will be in Main ROM.  The next opcode&lt;br /&gt;
; in Main ROM after this OUT statement occurs will be a RET (part of RST 1).  We have &lt;br /&gt;
; PUSHed a return address to the stack, so the main ROM&#039;s RET instruction will get us &lt;br /&gt;
; where to intend to go.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
001BH  OUT E0H              ; Send A to the ROM bank port to switch to Main ROM&lt;br /&gt;
001DH  RET                  ; Should never execute this instruction, but just in case&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Send a space to the screen/printer - Not called from anywhere.  Copy of Main ROM.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
001EH  (3EH) MVI A,20H      ; Prepare to print a SPACE&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 3 routine - Send character in A to the screen / printer&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0020H  (CFH) RST 1          ; Call main ROM at address in following 2 bytes&lt;br /&gt;
0021H  DW    0020H          ; Main ROM&#039;s RST 3 routine&lt;br /&gt;
0023H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Power down TRAP.  Let Main ROM deal with it.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0024H  DI                   ; Disable interrupts while we jump   &lt;br /&gt;
0025H  CALL 0097H           ; Jump to Main ROM&#039;s RST handler for this vector &lt;br /&gt;
0028H  POP H      &lt;br /&gt;
0029H  JMP 0003H            ; Pop regs after we power back up from a power-down? &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Hardware Interrupt - Let Main ROM deal with it - Bar Code Reader&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
002CH  DI                   ; Disable interrupts while we jump  &lt;br /&gt;
002DH  CALL 0097H           ; Jump to Main ROM&#039;s RST handler for this vector&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Return from Main ROM hook in RAM returns here via RST 6&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0030H  POP PSW              ; Cleanup stack&lt;br /&gt;
0031H  POP PSW              ; Cleanup stack&lt;br /&gt;
0032H  RET                  ; Return to OptROM execution point        &lt;br /&gt;
&lt;br /&gt;
0033H  NOP                  ; Filler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Hardware Interrupt - Let Main ROM deal with it - RS232 character pending&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0034H  DI                   ; Disable interrupts while we jump&lt;br /&gt;
0035H  CALL 0097H           ; Jump to Main ROM&#039;s RST handler for this vector&lt;br /&gt;
0038H  JMP 00A6H            ; Stack cleanup&lt;br /&gt;
&lt;br /&gt;
003BH  NOP                  ; UNUSED - filler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Hardware Interrupt - Let Main ROM deal with it - Timer background task&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
003CH  DI                   ; Disable interrupts&lt;br /&gt;
003DH  CALL 0097H           ; Jump to Main ROM&#039;s RST handler for this vector&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; This routine gets copied to RAM to be used for switching back to the TS-DOS ROM after&lt;br /&gt;
;      calling a routine in the Main ROM.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0040H  PUSH PSW             ; Preserve the PSW&lt;br /&gt;
0041H  LDA FF45H            ; Contents of port E8H&lt;br /&gt;
0044H  INR A                ; Prepare to switch to OptRom&lt;br /&gt;
0045H  OUT E0H              ; Switch to OptRom&lt;br /&gt;
0047H  RST 6                ; Get sign of FAC1&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; This routine gets copied to RAM and appears to detect the presence of the TS-DOS ROM&lt;br /&gt;
;       after power-up and copies the original &amp;quot;External ROM&amp;quot; detection routine to RAM&lt;br /&gt;
;       if the TS-DOS ROM is no longer present.  At least I think that&#039;s what it&#039;s doing.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0048H  LXI D,F605H          ; Copy address for &amp;quot;Ext ROM detect&amp;quot; routine&lt;br /&gt;
004BH  INR A                ; Set bit to enable OptROM&lt;br /&gt;
004CH  OUT E0H              ; Switch to OptROM&lt;br /&gt;
004EH  XRA A                ; Prepare to switch back to Main ROM&lt;br /&gt;
004FH  LHLD 0049H           ; Load target address of the LXI D instruction above&lt;br /&gt;
0052H  OUT E0H              ; Switch back to Main ROM&lt;br /&gt;
0054H  RST 3                ; Compare DE and HL - Test if OptROM is TS-DOS&lt;br /&gt;
0055H  CPI 01H              ; Test for TS-DOS ROM&lt;br /&gt;
0057H  RC                   ; Return if TS-DOS ROM&lt;br /&gt;
0058H  LXI H,111DH          ; Load &amp;quot;Return&amp;quot; address to the CALL below&lt;br /&gt;
005BH  SHLD FAE0H&lt;br /&gt;
005EH  SHLD F5F2H           ; Save a &amp;quot;Restart signature&amp;quot; ???&lt;br /&gt;
0061H  CALL 2905H           ; Copy the DB number of bytes from the DW address to (DE)&lt;br /&gt;
0064H  DB   24H             ; ....copy 24H bytes&lt;br /&gt;
0065H  DW   036FH           ; ....from ROM addres 036F (external ROM detect)&lt;br /&gt;
0067H  RST 0                ; I&#039;m not sure it it every actually returns here or not&lt;br /&gt;
0068H  NOP&lt;br /&gt;
0069H  CALL FAA4H           ; Call our installed RAM hook to return to TS-DOS&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Compare HL and DE - called by the RST 3 routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
006CH  MOV A,H              ; Move H into A for comparison&lt;br /&gt;
006DH  SUB D                ; Compare MSB first&lt;br /&gt;
006EH  RNZ                  ; Return if no match&lt;br /&gt;
006FH  MOV A,L              ; Now move L into A&lt;br /&gt;
0070H  SUB E                ; Compare LSB&lt;br /&gt;
0071H  RET                  ; Return with flags set&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Copy 8 bytes from DE to HL &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0072H  LXI B,0008H          ; Prepare to copy 8 bytes &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Copy BC bytes from DE to HL &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0075H  LDAX D               ; Load value from (DE)&lt;br /&gt;
0076H  MOV M,A              ; Save value to (HL)&lt;br /&gt;
0077H  INX D                ; Increment DE&lt;br /&gt;
0078H  INX H                ; Increment HL&lt;br /&gt;
0079H  DCX B                ; Decrement counter&lt;br /&gt;
007AH  MOV A,B              ; Prepare to test counter for zero&lt;br /&gt;
007BH  ORA C                ; Test counter for zero&lt;br /&gt;
007CH  JNZ 0075H            ; Keep looping until 8 bytes copied&lt;br /&gt;
007FH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle the RST 1 routine.  Read the Main ROM address from the 2 bytes after the RST 1&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0080H  SHLD F9B2H           ; Save HL off in &amp;quot;RickY&amp;quot; Cat entry so we don&#039;t clobber it&lt;br /&gt;
0083H  POP H                ; Get out return address (location of the ROM address to call&lt;br /&gt;
0084H  PUSH D               ; Push the return address back to the stack as storage &lt;br /&gt;
0085H  MOV E,M              ; Get LSB of the ROM address to call&lt;br /&gt;
0086H  INX H                ; Point to MSB of ROM address to call&lt;br /&gt;
0087H  MOV D,M              ; Get MSB of the ROM address to call&lt;br /&gt;
0088H  INX H                ; Point to return address after the RST 1 DB address&lt;br /&gt;
0089H  XTHL                 ; Put the return address on the stack so we return after the RST 1&lt;br /&gt;
008AH  XCHG                 ; Now get the address within ROM to call&lt;br /&gt;
008BH  PUSH H               ; Push the target ROM address to the stack so we &amp;quot;RETurn&amp;quot; there&lt;br /&gt;
008CH  LXI H,FAA4H          ; Load address of our RAM hook to switch back to our ROM bank and RET&lt;br /&gt;
008FH  XTHL                 ; Push that address on the stack for after the ROM call is complete&lt;br /&gt;
0090H  PUSH H               ; Now put the ROM address back on the stack so we will RET there&lt;br /&gt;
0091H  LHLD F9B2H           ; Restore HL from temp storage in &amp;quot;RickY&amp;quot;&lt;br /&gt;
0094H  JMP 00A6H            ; Branch to switch to Main ROM and &amp;quot;RET&amp;quot; to the address we pushed&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST handler for calling the Main ROM&#039;s RST handlers.  This routine restores the original&lt;br /&gt;
;      RST vector address to the stack, and jumps to the Main ROM&#039;s RST routine while &lt;br /&gt;
;      preserving all register values.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0097H  SHLD F9B4H           ; Save HL temporarily (somewhere in RickY&#039;s name)&lt;br /&gt;
009AH  LXI H,FAA4H          ; Point to our RAM hook for returning to TS-DOS&lt;br /&gt;
009DH  XTHL                 ; Put the hook address as the return address on the stack&lt;br /&gt;
009EH  DCX H                ; Decrement the return address by 4&lt;br /&gt;
009FH  DCX H                ; ...this will result in the starting address of the RST&lt;br /&gt;
00A0H  DCX H                ; ...that brought us here&lt;br /&gt;
00A1H  DCX H&lt;br /&gt;
00A2H  PUSH H               ; Push the RST vector address to the stack&lt;br /&gt;
00A3H  LHLD F9B4H           ; Restore HL upon entry&lt;br /&gt;
00A6H  PUSH PSW             ; Save A to the stack&lt;br /&gt;
00A7H  PUSH H               ; Save the HL to the stack so we can preserve through XTHL&lt;br /&gt;
00A8H  LXI H,1488H          ; Load a RETurn address in the Main ROM (a POP PSW &amp;amp; RET) &lt;br /&gt;
00ABH  XTHL                 ; Push the address and get HL back&lt;br /&gt;
00ACH  LDA FF45H            ; Contents of port E8H - prepare for jump to Main ROM&lt;br /&gt;
00AFH  JMP 001BH            ; Jump to Main ROM &amp;amp; our custom &amp;quot;RET&amp;quot; address in the ROM&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Manual invocation entry point.  This is where we jump when &amp;quot;CALL 63013,1&amp;quot; is invoked&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
00B2H  DI                   ; Disable interrupts so nobody bugs us yet&lt;br /&gt;
00B3H  CPI 08H              ; Check the invocation parameter to test for recovery request&lt;br /&gt;
00B5H  JNC 0100H            ; Jump to test for recovery mode&lt;br /&gt;
00B8H  MOV B,A              ; Save the calling paramter to B&lt;br /&gt;
00B9H  PUSH B               ; Save BC to the stack&lt;br /&gt;
00BAH  PUSH D               ; Save DE to the stack&lt;br /&gt;
00BBH  PUSH H               ; Save HL to the stack&lt;br /&gt;
00BCH  LXI D,0040H          ; Load address of our &amp;quot;Change to OptROM&amp;quot; routine&lt;br /&gt;
00BFH  LXI H,FAA4H          ; Load pointer to somewhere in RAM to hold our routine&lt;br /&gt;
00C2H  CALL 0072H           ; Copy 8 bytes from DE to HL &lt;br /&gt;
00C5H  LXI B,0024H          ; Now prepare to copy 36 bytes worth of &amp;quot;routine&amp;quot;&lt;br /&gt;
00C8H  LXI H,F605H          ; Point to another RAM location&lt;br /&gt;
00CBH  CALL 0075H           ; Copy the next &amp;quot;ROM Bank Switching&amp;quot; routine from our ROM&lt;br /&gt;
00CEH  POP H                ; Restore HL&lt;br /&gt;
00CFH  POP D                ; Restore DE&lt;br /&gt;
00D0H  POP PSW              ; Restore A&lt;br /&gt;
00D1H  EI                   ; Allow interrupts again&lt;br /&gt;
00D2H  JMP 0100H            ; Go test if a &amp;quot;Cold Start&amp;quot; recovery is being requested&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    .org 100H&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test if cold-start recovery requested&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0100H  MOV A,H              ; Move H to A to test HL for zero&lt;br /&gt;
0101H  ORA L                ; Test for zero&lt;br /&gt;
0102H  JZ 7000H             ; Call recovery routine if requested&lt;br /&gt;
0105H  POP H                ; Pop the return address.  We will exit manually&lt;br /&gt;
0106H  CALL 0117H           ; Ensure the TS-DOS progam is installed in the MENU&lt;br /&gt;
0109H  JMP 3535H            ; Jump to the TS-DOS UI&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Move BC bytes from (HL) to (DE) with increment&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
010CH  MOV A,M              ; Get next byte from (HL)&lt;br /&gt;
010DH  STAX D               ; Save byte in (DE)&lt;br /&gt;
010EH  INX H                ; Increment source pointer&lt;br /&gt;
010FH  INX D                ; Increment destination pointer&lt;br /&gt;
0110H  DCX B                ; Decrement loop control&lt;br /&gt;
0111H  MOV A,B              ; Move MSB to A to test for zero&lt;br /&gt;
0112H  ORA C                ; OR in LSB to test for zero&lt;br /&gt;
0113H  JNZ 010CH            ; Branch to copy next byte until done&lt;br /&gt;
0116H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Insert the &amp;quot;TS-DOS&amp;quot; invocation program (BASIC program) into the Catalog / MENU.&lt;br /&gt;
;    we always insert ourselves at the lowest RAM address.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0117H  LXI H,01E1H          ; Point to &amp;quot;TS-DOS&amp;quot; catalog entry in our ROM&lt;br /&gt;
011AH  PUSH H               ; Save the address on the stack for later&lt;br /&gt;
011BH  INX H                ; Point to the text portion of the catalog entry&lt;br /&gt;
011CH  LXI B,0008H          ; Prepare to copy 8 filename byte&lt;br /&gt;
011FH  LXI D,FC93H          ; Filename of current BASIC program&lt;br /&gt;
0122H  CALL 010CH           ; Copy BC bytes from HL to DE - put &amp;quot;TS-DOS  &amp;quot; in cur. BASIC prog.&lt;br /&gt;
0125H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  DE now has the address of the invocation program&lt;br /&gt;
0126H  LHLX                 ; Get the length of the BASIC program into HL&lt;br /&gt;
0127H  SHLD FCC4H           ; Save the BASIC program length in the ALTLCD buffer for now&lt;br /&gt;
012AH  INX D                ; Point to MSB of the length&lt;br /&gt;
012BH  INX D                ; Point to LSB of the pointer to the &amp;quot;Next&amp;quot; BASIC instruction&lt;br /&gt;
012CH  XCHG                 ; HL &amp;lt;--&amp;gt; DE HL has the pointer to the &amp;quot;Next&amp;quot; BASIC inst address&lt;br /&gt;
012DH  SHLD FCC8H           ; Save the &amp;quot;Next&amp;quot; BASIC inst pointer to ALTLCD (start of program)&lt;br /&gt;
0130H  CALL 01D1H           ; Update the System pointers&lt;br /&gt;
0133H  CALL 01CDH           ; Search Catalog for entry matching current BASIC program&lt;br /&gt;
0136H  POP B                ; Pop address in case we return&lt;br /&gt;
0137H  RNZ                  ; Return if &amp;quot;TS-DOS&amp;quot; is already in the catalog&lt;br /&gt;
0138H  LHLD F99AH           ; Get the BASIC program not saved pointer - insert before that&lt;br /&gt;
013BH  SHLD FCC2H           ; Save storage location for the TS-DOS invocation progam&lt;br /&gt;
013EH  LDAX B               ; Load the file type byte from our ROM (B has the address from above)&lt;br /&gt;
013FH  STA FCC6H            ; Store the Type byte in the ALTLCD &lt;br /&gt;
0142H  CALL 0185H           ; Find empty entry in Catalog&lt;br /&gt;
0145H  RC                   ; Return if catalog full&lt;br /&gt;
0146H  PUSH H               ; Save the address of the empty catalog entry to the stack&lt;br /&gt;
0147H  LHLD FCC4H           ; Restore the BASIC program length from ALTLCD&lt;br /&gt;
014AH  MOV B,H              ; Move BASIC program length to BC for copy&lt;br /&gt;
014BH  MOV C,L              ; Move LSB of length&lt;br /&gt;
014CH  PUSH B               ; Save Length to the stack&lt;br /&gt;
014DH  LHLD FCC2H           ; Get address of insertion for TS-DOS just before the unsaved BASIC prog.&lt;br /&gt;
0150H  CALL 01DDH           ; Call Main ROM&#039;s Insert BC spaces at M routine&lt;br /&gt;
0153H  JC 0182H             ; Abort if RAM full&lt;br /&gt;
0156H  LHLD FCC2H           ; Get address of insertion point again&lt;br /&gt;
0159H  XCHG                 ; DE now has insertion point for BASIC program&lt;br /&gt;
015AH  LHLD FCC8H           ; Get the address of the BASIC program (in our ROM) from ALTLCD&lt;br /&gt;
015DH  POP B                ; Restore copy length of the BASIC program&lt;br /&gt;
015EH  CALL 010CH           ; Move BC bytes from (HL) to (DE) with increment&lt;br /&gt;
0161H  POP D                ; Get the address of the empty catalog entry we will use for TS-DOS&lt;br /&gt;
0162H  PUSH D               ; Save it back to the stack&lt;br /&gt;
0163H  LHLD FBAEH           ; Load the start of DO files pointer&lt;br /&gt;
0166H  DCX H                ; Derement the start of DO files pointer&lt;br /&gt;
0167H  SHLD F99AH           ; Save it as the new BASIC program not saved pointer&lt;br /&gt;
016AH  INX H                ; Point to start of DO files again&lt;br /&gt;
016BH  XCHG                 ; Move it to DE&lt;br /&gt;
016CH  LHLD FCC4H           ; Load the TS-DOS BASIC progam length from ALTLCD&lt;br /&gt;
016FH  DAD D                ; Offset the start of DO files by the insertion amount&lt;br /&gt;
0170H  SHLD FBAEH           ; Save the new start of DO files pointer&lt;br /&gt;
0173H  POP D                ; Restore the address of the empty catalog entry&lt;br /&gt;
0174H  LHLD FCC2H           ; Get the starting address of the newly inserted TS-DOS program&lt;br /&gt;
0177H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  Swap for the call to the catalog insertion routine &lt;br /&gt;
0178H  LDA FCC6H            ; Load A with the file type byte&lt;br /&gt;
017BH  CALL 01D5H           ; Save current BASIC program to the Catalog entry at HL&lt;br /&gt;
017EH  CALL 01D1H           ; Update system pointers&lt;br /&gt;
0181H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Insert &amp;quot;TS-DOS&amp;quot; RAM full abort routine ... stack cleanup.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0182H  POP H                ; Pop the BASIC program length from the stack&lt;br /&gt;
0183H  POP H                ; Pop the catalog entry address from the stack&lt;br /&gt;
0184H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Find an empty entry in the Catalog.  HL points to start of new entry&lt;br /&gt;
;     This routine appears again at address 3E48H&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0185H  LXI H,F9AFH          ; Point to &amp;quot;RickY&amp;quot; to start search at beginning of catalog&lt;br /&gt;
0188H  LXI B,000BH          ; Get length of each entry in the Catalog&lt;br /&gt;
018BH  DAD B                ; Point to next entry in the catalog&lt;br /&gt;
018CH  MOV A,M              ; Get the File Attribute byte from the catalog for this file&lt;br /&gt;
018DH  CPI FFH              ; Test if at end of the catalog&lt;br /&gt;
018FH  JZ 0197H             ; Jump to set Carry flag and exit if at end&lt;br /&gt;
0192H  ADD A                ; Test if MSB set (test if entry available)&lt;br /&gt;
0193H  JC 018BH             ; Branch to get next entry if this one is used&lt;br /&gt;
0196H  RET                  ; Return with Carry clear to indicate entry found&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Empty catalog entry not found in Catalog, set Carry and return&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0197H  STC                  ; Set the Carry flag - not found&lt;br /&gt;
0198H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Display function key line routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0199H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
019AH  DW    42A8H&lt;br /&gt;
019CH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Erase function key display routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
019DH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
019EH  DW    428AH&lt;br /&gt;
01A0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Set new function key table routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01A1H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01A2H  DW    5A7CH&lt;br /&gt;
01A4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Wait for key from keyboard routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01A5H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01A6H  DW    12CBH&lt;br /&gt;
01A8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Scan keyboard for character (CTRL-BREAK ==&amp;gt; CTRL-C) routine&lt;br /&gt;
;      This appears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01A9H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01AAH  DW    7242H&lt;br /&gt;
01ACH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Power Down routine&lt;br /&gt;
;      This appears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01ADH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01AEH  DW    13B5H&lt;br /&gt;
01B0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Renew automatic power-off counter routine&lt;br /&gt;
;      This apears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01B1H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01B2H  DW    1BB1H&lt;br /&gt;
01B4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s CLS statement routine&lt;br /&gt;
;      This apears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01B5H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01B6H  DW    4231H&lt;br /&gt;
01B8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Start inverse character mode routine&lt;br /&gt;
;      This appears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01B9H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01BAH  DW    4269H&lt;br /&gt;
01BCH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Cancel inverse video routine&lt;br /&gt;
;      This appears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01BDH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01BEH  DW    426EH&lt;br /&gt;
01C0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Check keyboard queue for pending characters routine&lt;br /&gt;
;      This appers later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01C1H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01C2H  DW    13DBH&lt;br /&gt;
01C4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Stop automatic scrolling routine&lt;br /&gt;
;      This appers later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01C5H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01C6H  DW    423FH&lt;br /&gt;
01C8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Reset vector routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01C9H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01CAH  DW    0000H&lt;br /&gt;
01CCH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Search Catalog for entry matching current BASIC program&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01CDH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01CEH  DW    20AFH&lt;br /&gt;
01D0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Update system pointers routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01D1H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01D2H  DW    2146H&lt;br /&gt;
01D4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s routine to save current BASIC program to the Catalog entry at HL&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01D5H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01D6H  DW    2239H&lt;br /&gt;
01D8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Not a valid entry into ROM and not called anywhere&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01D9H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01DAH  DW    5825H&lt;br /&gt;
01DCH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Insert BC spaces at M routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01DDH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01DEH  DB    6B6DH&lt;br /&gt;
01E0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; TS-DOS entry that will be inserted into the catalog for invoking TS-DOS&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01E1H  DB   80H             ; TS-DOS file type for catalog entry&lt;br /&gt;
01E2H  DB   &amp;quot;TS-DOS  &amp;quot;      ; TS-DOS Catalog name entry&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; BASIC program that will be inserted into RAM to launch TS-DOS from the MENU/Catalog entry&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01EAH  DB   0FH,00H,0EH,80H ; BASIC program length and pointer to &amp;quot;Next&amp;quot; BASIC instruction&lt;br /&gt;
01EDH  DB   0AH,00H,B9H     ; BASIC Line number &amp;quot;10&amp;quot; and BASIC token for CALL&lt;br /&gt;
01EFH  DB   &amp;quot;63013,1&amp;quot;       ; CALL argument &lt;br /&gt;
01F5H  DB   00H,00H         ; BASIC terminating zeros&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
End of disassembly for OptROM Support.&lt;br /&gt;
&lt;br /&gt;
Navigate to [[M100 TS-DOS ROM UI Code]]&lt;/div&gt;</summary>
		<author><name>Kpettit</name></author>
	</entry>
	<entry>
		<id>https://bitchin100.com/wiki/index.php?title=Disassembly_of_RAM_and_ROM_versions_of_TS-DOS&amp;diff=1369</id>
		<title>Disassembly of RAM and ROM versions of TS-DOS</title>
		<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=Disassembly_of_RAM_and_ROM_versions_of_TS-DOS&amp;diff=1369"/>
		<updated>2009-04-03T07:05:21Z</updated>

		<summary type="html">&lt;p&gt;Kpettit: /* Model 100/102 ROM Version */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== TS-DOS Dissassembly ==&lt;br /&gt;
&lt;br /&gt;
There are various version of TS-DOS for The Model 100/102, for T200 and for the PC-8201a.  Additionally each of these versions has a ROM and a RAM.  While the majority of the code is equivalent across the various incarnations of TS-DOS, there are some differences due to varying RS-232 hardware and to accomodate execution from OptROM vs. RAM.&lt;br /&gt;
&lt;br /&gt;
The goal of the disassembly is to create a fully commented source file that can be assembled and subsequently modified / enhanced for new functionality.  The disassembly is split into several sections to keep each page &amp;quot;relatively&amp;quot; short.  The disassembly currently will not assemble as it contains absolute addresses that must be converted into assembly labels, or deleted where not needed.&lt;br /&gt;
&lt;br /&gt;
== Model 100/102 ROM Version ==&lt;br /&gt;
[[M100 ROM OptROM Support]]  [[M100 ROM UI Code]]  &lt;br /&gt;
[[M100 ROM FKey Handlers]]  [[M100 ROM RST 7 Handlers]]  &lt;br /&gt;
[[M100 ROM TPDD Protocol]]&lt;br /&gt;
&lt;br /&gt;
Not Completed Yet&lt;br /&gt;
[[M100 ROM Compression]] [[M100 ROM Cold Boot Recovery]]&lt;br /&gt;
&lt;br /&gt;
== Model 200 RAM Version ==&lt;br /&gt;
[[UI Code]]  [[FKey Handlers]]  [[RST 7 Handlers]]  [[TPDD Protocol]]&lt;/div&gt;</summary>
		<author><name>Kpettit</name></author>
	</entry>
	<entry>
		<id>https://bitchin100.com/wiki/index.php?title=OptROM_Support&amp;diff=1368</id>
		<title>OptROM Support</title>
		<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=OptROM_Support&amp;diff=1368"/>
		<updated>2009-04-03T07:01:16Z</updated>

		<summary type="html">&lt;p&gt;Kpettit: OptROM Support moved to M100 ROM OptROM Support: To allow OptROM Support pages per Model&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[M100 ROM OptROM Support]]&lt;/div&gt;</summary>
		<author><name>Kpettit</name></author>
	</entry>
	<entry>
		<id>https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_OptROM_Support&amp;diff=1367</id>
		<title>M100 TS-DOS ROM OptROM Support</title>
		<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_OptROM_Support&amp;diff=1367"/>
		<updated>2009-04-03T07:01:16Z</updated>

		<summary type="html">&lt;p&gt;Kpettit: OptROM Support moved to M100 ROM OptROM Support: To allow OptROM Support pages per Model&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= TS-DOS Model 100/102 =&lt;br /&gt;
&lt;br /&gt;
== OptROM Support ==&lt;br /&gt;
&lt;br /&gt;
This code defines the variables used throughout the TS-DOS application as well as the support routines needed to navigate between the Main ROM and the Option ROM (most of them).  Also included is the TS-DOS startup code.  The assembly labels defined are open for discussion and have not been applied to any of the disassembled code yet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 =========================================================================================&lt;br /&gt;
; TS-DOS M100 ROM version Disassembly&lt;br /&gt;
;&lt;br /&gt;
; By Kenneth D. Pettit&lt;br /&gt;
; March, 2009&lt;br /&gt;
;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Variables in ALTLCD buffer&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
NB_CUR_DIR    equ FCC0H              ; NADSBox current directory (&amp;quot;MYFILE.&amp;lt;&amp;gt; &amp;quot;)&lt;br /&gt;
TPDD_BANK     equ FCCAH              ; TPDD2 Bank (side)&lt;br /&gt;
NB_TPDD_FLG   equ FCCBH              ; NADSBox/Desklink/TPDD2 flag (0=TPDD, 1=TPDD2, 2=NADSBox)&lt;br /&gt;
LAST_TAG      equ FCCCH              ; Tag/Untag last operation code&lt;br /&gt;
CUR_FILE      equ FCCDH              ; Currently selected file index on UI (1 based)&lt;br /&gt;
LJ_SP         equ FCCEH              ; Stack pointer upon entry for Long Jump&lt;br /&gt;
LJ_RET        equ FCD0H              ; Return vector for Long Jump &amp;quot;RETURN&amp;quot;&lt;br /&gt;
ERR_MODE      equ FCD2H              ; Print Error Messages flag, 1=Print, 0=Generate System Error&lt;br /&gt;
FDC_OPCODE    equ FCD3H              ; FDC Emulation mode opcode&lt;br /&gt;
CUR_PAGE      equ FCD4H              ; Current page of files being displayed (0 based)&lt;br /&gt;
TMP_FILE_IDX  equ FCD5H              ; Currently selected file index on UI - temp&lt;br /&gt;
FILE_COUNT    equ FCD6H              ; Count of files currently displayed on LCD&lt;br /&gt;
MAX_FILES     equ FCD7H              ; Maximum files that fit on the LCD&lt;br /&gt;
DISP_MODE     equ FCD9H              ; RAM / Disk Display mode (0=RAM,  1=DISK)&lt;br /&gt;
SKIP_PAGE     equ FCDAH              ; TPDD &amp;quot;skip page&amp;quot; count (number of pages to read and discard)&lt;br /&gt;
FILE_LEN      equ FCDBH              ; Pointer to &amp;quot;Current file&amp;quot; length bytes (in keyboard buffer)&lt;br /&gt;
PHYS_SCTR     equ FCDDH              ; FDC Emulation Physical Sector Number / Active File Length LSB&lt;br /&gt;
LOG_SCTR      equ FCDEH              ; FDC Emulation Logical Sector Number / Active File Length MSB&lt;br /&gt;
KEY_TYPE      equ FCDFH              ; Storage for FDC emulation / New file type code / Keypress storage&lt;br /&gt;
FILE_ADDR     equ FCE0H              ; Address of file being displayed/printed/loaded/saved&lt;br /&gt;
FILE_BUFF     equ FCE2H              ; Pointer for TPDD direct read data / address of file being read/written&lt;br /&gt;
TX_PKT_BUF    equ FCE6H              ; Storage for TX packets (28 bytes)&lt;br /&gt;
RX_PKT_BUF    equ FD02H              ; Storage for RX packets (130 bytes ??)&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Main Entry point when called from &amp;quot;CALL 63013,1&amp;quot;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
   &lt;br /&gt;
   .org 0000H&lt;br /&gt;
&lt;br /&gt;
0000H  JMP 00B2H            ; Jump to entry point handler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Pop registers after we power back up from a powerdown (I think)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0003H  POP H&lt;br /&gt;
0004H  POP D&lt;br /&gt;
0005H  POP B&lt;br /&gt;
0006H  POP PSW&lt;br /&gt;
0007H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 1 - Call Main ROM at location whose address follows RST 1 opcode&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0008H  (C3H) JMP 0080H      ; BASIC statement keyword table END to NEW&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 2 - Call Main ROM&#039;s RST 2 routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0010H  (CFH) RST 1          ; Call main ROM at address in following 2 bytes&lt;br /&gt;
0011H  DW    0010H          ; Call the Main ROM&#039;s RST 2 function&lt;br /&gt;
0013H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 3 routine - Compare HL and DE&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0018H  JMP 006CH            ; Jump to comparison routine&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Return to Main ROM.  After issuing the OUT E0H, we will be in Main ROM.  The next opcode&lt;br /&gt;
; in Main ROM after this OUT statement occurs will be a RET (part of RST 1).  We have &lt;br /&gt;
; PUSHed a return address to the stack, so the main ROM&#039;s RET instruction will get us &lt;br /&gt;
; where to intend to go.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
001BH  OUT E0H              ; Send A to the ROM bank port to switch to Main ROM&lt;br /&gt;
001DH  RET                  ; Should never execute this instruction, but just in case&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Send a space to the screen/printer - Not called from anywhere.  Copy of Main ROM.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
001EH  (3EH) MVI A,20H      ; Prepare to print a SPACE&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 3 routine - Send character in A to the screen / printer&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0020H  (CFH) RST 1          ; Call main ROM at address in following 2 bytes&lt;br /&gt;
0021H  DW    0020H          ; Main ROM&#039;s RST 3 routine&lt;br /&gt;
0023H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Power down TRAP.  Let Main ROM deal with it.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0024H  DI                   ; Disable interrupts while we jump   &lt;br /&gt;
0025H  CALL 0097H           ; Jump to Main ROM&#039;s RST handler for this vector &lt;br /&gt;
0028H  POP H      &lt;br /&gt;
0029H  JMP 0003H            ; Pop regs after we power back up from a power-down? &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Hardware Interrupt - Let Main ROM deal with it - Bar Code Reader&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
002CH  DI                   ; Disable interrupts while we jump  &lt;br /&gt;
002DH  CALL 0097H           ; Jump to Main ROM&#039;s RST handler for this vector&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Return from Main ROM hook in RAM returns here via RST 6&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0030H  POP PSW              ; Cleanup stack&lt;br /&gt;
0031H  POP PSW              ; Cleanup stack&lt;br /&gt;
0032H  RET                  ; Return to OptROM execution point        &lt;br /&gt;
&lt;br /&gt;
0033H  NOP                  ; Filler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Hardware Interrupt - Let Main ROM deal with it - RS232 character pending&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0034H  DI                   ; Disable interrupts while we jump&lt;br /&gt;
0035H  CALL 0097H           ; Jump to Main ROM&#039;s RST handler for this vector&lt;br /&gt;
0038H  JMP 00A6H            ; Stack cleanup&lt;br /&gt;
&lt;br /&gt;
003BH  NOP                  ; UNUSED - filler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Hardware Interrupt - Let Main ROM deal with it - Timer background task&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
003CH  DI                   ; Disable interrupts&lt;br /&gt;
003DH  CALL 0097H           ; Jump to Main ROM&#039;s RST handler for this vector&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; This routine gets copied to RAM to be used for switching back to the TS-DOS ROM after&lt;br /&gt;
;      calling a routine in the Main ROM.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0040H  PUSH PSW             ; Preserve the PSW&lt;br /&gt;
0041H  LDA FF45H            ; Contents of port E8H&lt;br /&gt;
0044H  INR A                ; Prepare to switch to OptRom&lt;br /&gt;
0045H  OUT E0H              ; Switch to OptRom&lt;br /&gt;
0047H  RST 6                ; Get sign of FAC1&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; This routine gets copied to RAM and appears to detect the presence of the TS-DOS ROM&lt;br /&gt;
;       after power-up and copies the original &amp;quot;External ROM&amp;quot; detection routine to RAM&lt;br /&gt;
;       if the TS-DOS ROM is no longer present.  At least I think that&#039;s what it&#039;s doing.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0048H  LXI D,F605H          ; Copy address for &amp;quot;Ext ROM detect&amp;quot; routine&lt;br /&gt;
004BH  INR A                ; Set bit to enable OptROM&lt;br /&gt;
004CH  OUT E0H              ; Switch to OptROM&lt;br /&gt;
004EH  XRA A                ; Prepare to switch back to Main ROM&lt;br /&gt;
004FH  LHLD 0049H           ; Load target address of the LXI D instruction above&lt;br /&gt;
0052H  OUT E0H              ; Switch back to Main ROM&lt;br /&gt;
0054H  RST 3                ; Compare DE and HL - Test if OptROM is TS-DOS&lt;br /&gt;
0055H  CPI 01H              ; Test for TS-DOS ROM&lt;br /&gt;
0057H  RC                   ; Return if TS-DOS ROM&lt;br /&gt;
0058H  LXI H,111DH          ; Load &amp;quot;Return&amp;quot; address to the CALL below&lt;br /&gt;
005BH  SHLD FAE0H&lt;br /&gt;
005EH  SHLD F5F2H           ; Save a &amp;quot;Restart signature&amp;quot; ???&lt;br /&gt;
0061H  CALL 2905H           ; Copy the DB number of bytes from the DW address to (DE)&lt;br /&gt;
0064H  DB   24H             ; ....copy 24H bytes&lt;br /&gt;
0065H  DW   036FH           ; ....from ROM addres 036F (external ROM detect)&lt;br /&gt;
0067H  RST 0                ; I&#039;m not sure it it every actually returns here or not&lt;br /&gt;
0068H  NOP&lt;br /&gt;
0069H  CALL FAA4H           ; Call our installed RAM hook to return to TS-DOS&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Compare HL and DE - called by the RST 3 routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
006CH  MOV A,H              ; Move H into A for comparison&lt;br /&gt;
006DH  SUB D                ; Compare MSB first&lt;br /&gt;
006EH  RNZ                  ; Return if no match&lt;br /&gt;
006FH  MOV A,L              ; Now move L into A&lt;br /&gt;
0070H  SUB E                ; Compare LSB&lt;br /&gt;
0071H  RET                  ; Return with flags set&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Copy 8 bytes from DE to HL &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0072H  LXI B,0008H          ; Prepare to copy 8 bytes &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Copy BC bytes from DE to HL &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0075H  LDAX D               ; Load value from (DE)&lt;br /&gt;
0076H  MOV M,A              ; Save value to (HL)&lt;br /&gt;
0077H  INX D                ; Increment DE&lt;br /&gt;
0078H  INX H                ; Increment HL&lt;br /&gt;
0079H  DCX B                ; Decrement counter&lt;br /&gt;
007AH  MOV A,B              ; Prepare to test counter for zero&lt;br /&gt;
007BH  ORA C                ; Test counter for zero&lt;br /&gt;
007CH  JNZ 0075H            ; Keep looping until 8 bytes copied&lt;br /&gt;
007FH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle the RST 1 routine.  Read the Main ROM address from the 2 bytes after the RST 1&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0080H  SHLD F9B2H           ; Save HL off in &amp;quot;RickY&amp;quot; Cat entry so we don&#039;t clobber it&lt;br /&gt;
0083H  POP H                ; Get out return address (location of the ROM address to call&lt;br /&gt;
0084H  PUSH D               ; Push the return address back to the stack as storage &lt;br /&gt;
0085H  MOV E,M              ; Get LSB of the ROM address to call&lt;br /&gt;
0086H  INX H                ; Point to MSB of ROM address to call&lt;br /&gt;
0087H  MOV D,M              ; Get MSB of the ROM address to call&lt;br /&gt;
0088H  INX H                ; Point to return address after the RST 1 DB address&lt;br /&gt;
0089H  XTHL                 ; Put the return address on the stack so we return after the RST 1&lt;br /&gt;
008AH  XCHG                 ; Now get the address within ROM to call&lt;br /&gt;
008BH  PUSH H               ; Push the target ROM address to the stack so we &amp;quot;RETurn&amp;quot; there&lt;br /&gt;
008CH  LXI H,FAA4H          ; Load address of our RAM hook to switch back to our ROM bank and RET&lt;br /&gt;
008FH  XTHL                 ; Push that address on the stack for after the ROM call is complete&lt;br /&gt;
0090H  PUSH H               ; Now put the ROM address back on the stack so we will RET there&lt;br /&gt;
0091H  LHLD F9B2H           ; Restore HL from temp storage in &amp;quot;RickY&amp;quot;&lt;br /&gt;
0094H  JMP 00A6H            ; Branch to switch to Main ROM and &amp;quot;RET&amp;quot; to the address we pushed&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST handler for calling the Main ROM&#039;s RST handlers.  This routine restores the original&lt;br /&gt;
;      RST vector address to the stack, and jumps to the Main ROM&#039;s RST routine while &lt;br /&gt;
;      preserving all register values.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0097H  SHLD F9B4H           ; Save HL temporarily (somewhere in RickY&#039;s name)&lt;br /&gt;
009AH  LXI H,FAA4H          ; Point to our RAM hook for returning to TS-DOS&lt;br /&gt;
009DH  XTHL                 ; Put the hook address as the return address on the stack&lt;br /&gt;
009EH  DCX H                ; Decrement the return address by 4&lt;br /&gt;
009FH  DCX H                ; ...this will result in the starting address of the RST&lt;br /&gt;
00A0H  DCX H                ; ...that brought us here&lt;br /&gt;
00A1H  DCX H&lt;br /&gt;
00A2H  PUSH H               ; Push the RST vector address to the stack&lt;br /&gt;
00A3H  LHLD F9B4H           ; Restore HL upon entry&lt;br /&gt;
00A6H  PUSH PSW             ; Save A to the stack&lt;br /&gt;
00A7H  PUSH H               ; Save the HL to the stack so we can preserve through XTHL&lt;br /&gt;
00A8H  LXI H,1488H          ; Load a RETurn address in the Main ROM (a POP PSW &amp;amp; RET) &lt;br /&gt;
00ABH  XTHL                 ; Push the address and get HL back&lt;br /&gt;
00ACH  LDA FF45H            ; Contents of port E8H - prepare for jump to Main ROM&lt;br /&gt;
00AFH  JMP 001BH            ; Jump to Main ROM &amp;amp; our custom &amp;quot;RET&amp;quot; address in the ROM&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Manual invocation entry point.  This is where we jump when &amp;quot;CALL 63013,1&amp;quot; is invoked&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
00B2H  DI                   ; Disable interrupts so nobody bugs us yet&lt;br /&gt;
00B3H  CPI 08H              ; Check the invocation parameter to test for recovery request&lt;br /&gt;
00B5H  JNC 0100H            ; Jump to test for recovery mode&lt;br /&gt;
00B8H  MOV B,A              ; Save the calling paramter to B&lt;br /&gt;
00B9H  PUSH B               ; Save BC to the stack&lt;br /&gt;
00BAH  PUSH D               ; Save DE to the stack&lt;br /&gt;
00BBH  PUSH H               ; Save HL to the stack&lt;br /&gt;
00BCH  LXI D,0040H          ; Load address of our &amp;quot;Change to OptROM&amp;quot; routine&lt;br /&gt;
00BFH  LXI H,FAA4H          ; Load pointer to somewhere in RAM to hold our routine&lt;br /&gt;
00C2H  CALL 0072H           ; Copy 8 bytes from DE to HL &lt;br /&gt;
00C5H  LXI B,0024H          ; Now prepare to copy 36 bytes worth of &amp;quot;routine&amp;quot;&lt;br /&gt;
00C8H  LXI H,F605H          ; Point to another RAM location&lt;br /&gt;
00CBH  CALL 0075H           ; Copy the next &amp;quot;ROM Bank Switching&amp;quot; routine from our ROM&lt;br /&gt;
00CEH  POP H                ; Restore HL&lt;br /&gt;
00CFH  POP D                ; Restore DE&lt;br /&gt;
00D0H  POP PSW              ; Restore A&lt;br /&gt;
00D1H  EI                   ; Allow interrupts again&lt;br /&gt;
00D2H  JMP 0100H            ; Go test if a &amp;quot;Cold Start&amp;quot; recovery is being requested&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    .org 100H&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test if cold-start recovery requested&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0100H  MOV A,H              ; Move H to A to test HL for zero&lt;br /&gt;
0101H  ORA L                ; Test for zero&lt;br /&gt;
0102H  JZ 7000H             ; Call recovery routine if requested&lt;br /&gt;
0105H  POP H                ; Pop the return address.  We will exit manually&lt;br /&gt;
0106H  CALL 0117H           ; Ensure the TS-DOS progam is installed in the MENU&lt;br /&gt;
0109H  JMP 3535H            ; Jump to the TS-DOS UI&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Move BC bytes from (HL) to (DE) with increment&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
010CH  MOV A,M              ; Get next byte from (HL)&lt;br /&gt;
010DH  STAX D               ; Save byte in (DE)&lt;br /&gt;
010EH  INX H                ; Increment source pointer&lt;br /&gt;
010FH  INX D                ; Increment destination pointer&lt;br /&gt;
0110H  DCX B                ; Decrement loop control&lt;br /&gt;
0111H  MOV A,B              ; Move MSB to A to test for zero&lt;br /&gt;
0112H  ORA C                ; OR in LSB to test for zero&lt;br /&gt;
0113H  JNZ 010CH            ; Branch to copy next byte until done&lt;br /&gt;
0116H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Insert the &amp;quot;TS-DOS&amp;quot; invocation program (BASIC program) into the Catalog / MENU.&lt;br /&gt;
;    we always insert ourselves at the lowest RAM address.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0117H  LXI H,01E1H          ; Point to &amp;quot;TS-DOS&amp;quot; catalog entry in our ROM&lt;br /&gt;
011AH  PUSH H               ; Save the address on the stack for later&lt;br /&gt;
011BH  INX H                ; Point to the text portion of the catalog entry&lt;br /&gt;
011CH  LXI B,0008H          ; Prepare to copy 8 filename byte&lt;br /&gt;
011FH  LXI D,FC93H          ; Filename of current BASIC program&lt;br /&gt;
0122H  CALL 010CH           ; Copy BC bytes from HL to DE - put &amp;quot;TS-DOS  &amp;quot; in cur. BASIC prog.&lt;br /&gt;
0125H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  DE now has the address of the invocation program&lt;br /&gt;
0126H  LHLX                 ; Get the length of the BASIC program into HL&lt;br /&gt;
0127H  SHLD FCC4H           ; Save the BASIC program length in the ALTLCD buffer for now&lt;br /&gt;
012AH  INX D                ; Point to MSB of the length&lt;br /&gt;
012BH  INX D                ; Point to LSB of the pointer to the &amp;quot;Next&amp;quot; BASIC instruction&lt;br /&gt;
012CH  XCHG                 ; HL &amp;lt;--&amp;gt; DE HL has the pointer to the &amp;quot;Next&amp;quot; BASIC inst address&lt;br /&gt;
012DH  SHLD FCC8H           ; Save the &amp;quot;Next&amp;quot; BASIC inst pointer to ALTLCD (start of program)&lt;br /&gt;
0130H  CALL 01D1H           ; Update the System pointers&lt;br /&gt;
0133H  CALL 01CDH           ; Search Catalog for entry matching current BASIC program&lt;br /&gt;
0136H  POP B                ; Pop address in case we return&lt;br /&gt;
0137H  RNZ                  ; Return if &amp;quot;TS-DOS&amp;quot; is already in the catalog&lt;br /&gt;
0138H  LHLD F99AH           ; Get the BASIC program not saved pointer - insert before that&lt;br /&gt;
013BH  SHLD FCC2H           ; Save storage location for the TS-DOS invocation progam&lt;br /&gt;
013EH  LDAX B               ; Load the file type byte from our ROM (B has the address from above)&lt;br /&gt;
013FH  STA FCC6H            ; Store the Type byte in the ALTLCD &lt;br /&gt;
0142H  CALL 0185H           ; Find empty entry in Catalog&lt;br /&gt;
0145H  RC                   ; Return if catalog full&lt;br /&gt;
0146H  PUSH H               ; Save the address of the empty catalog entry to the stack&lt;br /&gt;
0147H  LHLD FCC4H           ; Restore the BASIC program length from ALTLCD&lt;br /&gt;
014AH  MOV B,H              ; Move BASIC program length to BC for copy&lt;br /&gt;
014BH  MOV C,L              ; Move LSB of length&lt;br /&gt;
014CH  PUSH B               ; Save Length to the stack&lt;br /&gt;
014DH  LHLD FCC2H           ; Get address of insertion for TS-DOS just before the unsaved BASIC prog.&lt;br /&gt;
0150H  CALL 01DDH           ; Call Main ROM&#039;s Insert BC spaces at M routine&lt;br /&gt;
0153H  JC 0182H             ; Abort if RAM full&lt;br /&gt;
0156H  LHLD FCC2H           ; Get address of insertion point again&lt;br /&gt;
0159H  XCHG                 ; DE now has insertion point for BASIC program&lt;br /&gt;
015AH  LHLD FCC8H           ; Get the address of the BASIC program (in our ROM) from ALTLCD&lt;br /&gt;
015DH  POP B                ; Restore copy length of the BASIC program&lt;br /&gt;
015EH  CALL 010CH           ; Move BC bytes from (HL) to (DE) with increment&lt;br /&gt;
0161H  POP D                ; Get the address of the empty catalog entry we will use for TS-DOS&lt;br /&gt;
0162H  PUSH D               ; Save it back to the stack&lt;br /&gt;
0163H  LHLD FBAEH           ; Load the start of DO files pointer&lt;br /&gt;
0166H  DCX H                ; Derement the start of DO files pointer&lt;br /&gt;
0167H  SHLD F99AH           ; Save it as the new BASIC program not saved pointer&lt;br /&gt;
016AH  INX H                ; Point to start of DO files again&lt;br /&gt;
016BH  XCHG                 ; Move it to DE&lt;br /&gt;
016CH  LHLD FCC4H           ; Load the TS-DOS BASIC progam length from ALTLCD&lt;br /&gt;
016FH  DAD D                ; Offset the start of DO files by the insertion amount&lt;br /&gt;
0170H  SHLD FBAEH           ; Save the new start of DO files pointer&lt;br /&gt;
0173H  POP D                ; Restore the address of the empty catalog entry&lt;br /&gt;
0174H  LHLD FCC2H           ; Get the starting address of the newly inserted TS-DOS program&lt;br /&gt;
0177H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  Swap for the call to the catalog insertion routine &lt;br /&gt;
0178H  LDA FCC6H            ; Load A with the file type byte&lt;br /&gt;
017BH  CALL 01D5H           ; Save current BASIC program to the Catalog entry at HL&lt;br /&gt;
017EH  CALL 01D1H           ; Update system pointers&lt;br /&gt;
0181H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Insert &amp;quot;TS-DOS&amp;quot; RAM full abort routine ... stack cleanup.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0182H  POP H                ; Pop the BASIC program length from the stack&lt;br /&gt;
0183H  POP H                ; Pop the catalog entry address from the stack&lt;br /&gt;
0184H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Find an empty entry in the Catalog.  HL points to start of new entry&lt;br /&gt;
;     This routine appears again at address 3E48H&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0185H  LXI H,F9AFH          ; Point to &amp;quot;RickY&amp;quot; to start search at beginning of catalog&lt;br /&gt;
0188H  LXI B,000BH          ; Get length of each entry in the Catalog&lt;br /&gt;
018BH  DAD B                ; Point to next entry in the catalog&lt;br /&gt;
018CH  MOV A,M              ; Get the File Attribute byte from the catalog for this file&lt;br /&gt;
018DH  CPI FFH              ; Test if at end of the catalog&lt;br /&gt;
018FH  JZ 0197H             ; Jump to set Carry flag and exit if at end&lt;br /&gt;
0192H  ADD A                ; Test if MSB set (test if entry available)&lt;br /&gt;
0193H  JC 018BH             ; Branch to get next entry if this one is used&lt;br /&gt;
0196H  RET                  ; Return with Carry clear to indicate entry found&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Empty catalog entry not found in Catalog, set Carry and return&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0197H  STC                  ; Set the Carry flag - not found&lt;br /&gt;
0198H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Display function key line routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0199H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
019AH  DW    42A8H&lt;br /&gt;
019CH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Erase function key display routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
019DH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
019EH  DW    428AH&lt;br /&gt;
01A0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Set new function key table routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01A1H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01A2H  DW    5A7CH&lt;br /&gt;
01A4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Wait for key from keyboard routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01A5H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01A6H  DW    12CBH&lt;br /&gt;
01A8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Scan keyboard for character (CTRL-BREAK ==&amp;gt; CTRL-C) routine&lt;br /&gt;
;      This appears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01A9H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01AAH  DW    7242H&lt;br /&gt;
01ACH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Power Down routine&lt;br /&gt;
;      This appears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01ADH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01AEH  DW    13B5H&lt;br /&gt;
01B0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Renew automatic power-off counter routine&lt;br /&gt;
;      This apears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01B1H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01B2H  DW    1BB1H&lt;br /&gt;
01B4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s CLS statement routine&lt;br /&gt;
;      This apears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01B5H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01B6H  DW    4231H&lt;br /&gt;
01B8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Start inverse character mode routine&lt;br /&gt;
;      This appears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01B9H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01BAH  DW    4269H&lt;br /&gt;
01BCH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Cancel inverse video routine&lt;br /&gt;
;      This appears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01BDH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01BEH  DW    426EH&lt;br /&gt;
01C0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Check keyboard queue for pending characters routine&lt;br /&gt;
;      This appers later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01C1H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01C2H  DW    13DBH&lt;br /&gt;
01C4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Stop automatic scrolling routine&lt;br /&gt;
;      This appers later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01C5H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01C6H  DW    423FH&lt;br /&gt;
01C8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Reset vector routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01C9H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01CAH  DW    0000H&lt;br /&gt;
01CCH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Search Catalog for entry matching current BASIC program&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01CDH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01CEH  DW    20AFH&lt;br /&gt;
01D0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Update system pointers routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01D1H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01D2H  DW    2146H&lt;br /&gt;
01D4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s routine to save current BASIC program to the Catalog entry at HL&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01D5H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01D6H  DW    2239H&lt;br /&gt;
01D8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Not a valid entry into ROM and not called anywhere&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01D9H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01DAH  DW    5825H&lt;br /&gt;
01DCH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Insert BC spaces at M routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01DDH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01DEH  DB    6B6DH&lt;br /&gt;
01E0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; TS-DOS entry that will be inserted into the catalog for invoking TS-DOS&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01E1H  DB   80H             ; TS-DOS file type for catalog entry&lt;br /&gt;
01E2H  DB   &amp;quot;TS-DOS  &amp;quot;      ; TS-DOS Catalog name entry&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; BASIC program that will be inserted into RAM to launch TS-DOS from the MENU/Catalog entry&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01EAH  DB   0FH,00H,0EH,80H ; BASIC program length and pointer to &amp;quot;Next&amp;quot; BASIC instruction&lt;br /&gt;
01EDH  DB   0AH,00H,B9H     ; BASIC Line number &amp;quot;10&amp;quot; and BASIC token for CALL&lt;br /&gt;
01EFH  DB   &amp;quot;63013,1&amp;quot;       ; CALL argument &lt;br /&gt;
01F5H  DB   00H,00H         ; BASIC terminating zeros&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
End of disassembly for OptROM Support.&lt;/div&gt;</summary>
		<author><name>Kpettit</name></author>
	</entry>
	<entry>
		<id>https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_OptROM_Support&amp;diff=1366</id>
		<title>M100 TS-DOS ROM OptROM Support</title>
		<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=M100_TS-DOS_ROM_OptROM_Support&amp;diff=1366"/>
		<updated>2009-04-03T06:58:31Z</updated>

		<summary type="html">&lt;p&gt;Kpettit: New page: = TS-DOS Model 100/102 =  == OptROM Support ==  This code defines the variables used throughout the TS-DOS application as well as the support routines needed to navigate between the Main R...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= TS-DOS Model 100/102 =&lt;br /&gt;
&lt;br /&gt;
== OptROM Support ==&lt;br /&gt;
&lt;br /&gt;
This code defines the variables used throughout the TS-DOS application as well as the support routines needed to navigate between the Main ROM and the Option ROM (most of them).  Also included is the TS-DOS startup code.  The assembly labels defined are open for discussion and have not been applied to any of the disassembled code yet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 =========================================================================================&lt;br /&gt;
; TS-DOS M100 ROM version Disassembly&lt;br /&gt;
;&lt;br /&gt;
; By Kenneth D. Pettit&lt;br /&gt;
; March, 2009&lt;br /&gt;
;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Variables in ALTLCD buffer&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
NB_CUR_DIR    equ FCC0H              ; NADSBox current directory (&amp;quot;MYFILE.&amp;lt;&amp;gt; &amp;quot;)&lt;br /&gt;
TPDD_BANK     equ FCCAH              ; TPDD2 Bank (side)&lt;br /&gt;
NB_TPDD_FLG   equ FCCBH              ; NADSBox/Desklink/TPDD2 flag (0=TPDD, 1=TPDD2, 2=NADSBox)&lt;br /&gt;
LAST_TAG      equ FCCCH              ; Tag/Untag last operation code&lt;br /&gt;
CUR_FILE      equ FCCDH              ; Currently selected file index on UI (1 based)&lt;br /&gt;
LJ_SP         equ FCCEH              ; Stack pointer upon entry for Long Jump&lt;br /&gt;
LJ_RET        equ FCD0H              ; Return vector for Long Jump &amp;quot;RETURN&amp;quot;&lt;br /&gt;
ERR_MODE      equ FCD2H              ; Print Error Messages flag, 1=Print, 0=Generate System Error&lt;br /&gt;
FDC_OPCODE    equ FCD3H              ; FDC Emulation mode opcode&lt;br /&gt;
CUR_PAGE      equ FCD4H              ; Current page of files being displayed (0 based)&lt;br /&gt;
TMP_FILE_IDX  equ FCD5H              ; Currently selected file index on UI - temp&lt;br /&gt;
FILE_COUNT    equ FCD6H              ; Count of files currently displayed on LCD&lt;br /&gt;
MAX_FILES     equ FCD7H              ; Maximum files that fit on the LCD&lt;br /&gt;
DISP_MODE     equ FCD9H              ; RAM / Disk Display mode (0=RAM,  1=DISK)&lt;br /&gt;
SKIP_PAGE     equ FCDAH              ; TPDD &amp;quot;skip page&amp;quot; count (number of pages to read and discard)&lt;br /&gt;
FILE_LEN      equ FCDBH              ; Pointer to &amp;quot;Current file&amp;quot; length bytes (in keyboard buffer)&lt;br /&gt;
PHYS_SCTR     equ FCDDH              ; FDC Emulation Physical Sector Number / Active File Length LSB&lt;br /&gt;
LOG_SCTR      equ FCDEH              ; FDC Emulation Logical Sector Number / Active File Length MSB&lt;br /&gt;
KEY_TYPE      equ FCDFH              ; Storage for FDC emulation / New file type code / Keypress storage&lt;br /&gt;
FILE_ADDR     equ FCE0H              ; Address of file being displayed/printed/loaded/saved&lt;br /&gt;
FILE_BUFF     equ FCE2H              ; Pointer for TPDD direct read data / address of file being read/written&lt;br /&gt;
TX_PKT_BUF    equ FCE6H              ; Storage for TX packets (28 bytes)&lt;br /&gt;
RX_PKT_BUF    equ FD02H              ; Storage for RX packets (130 bytes ??)&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Main Entry point when called from &amp;quot;CALL 63013,1&amp;quot;&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
   &lt;br /&gt;
   .org 0000H&lt;br /&gt;
&lt;br /&gt;
0000H  JMP 00B2H            ; Jump to entry point handler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Pop registers after we power back up from a powerdown (I think)&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0003H  POP H&lt;br /&gt;
0004H  POP D&lt;br /&gt;
0005H  POP B&lt;br /&gt;
0006H  POP PSW&lt;br /&gt;
0007H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 1 - Call Main ROM at location whose address follows RST 1 opcode&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0008H  (C3H) JMP 0080H      ; BASIC statement keyword table END to NEW&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 2 - Call Main ROM&#039;s RST 2 routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0010H  (CFH) RST 1          ; Call main ROM at address in following 2 bytes&lt;br /&gt;
0011H  DW    0010H          ; Call the Main ROM&#039;s RST 2 function&lt;br /&gt;
0013H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 3 routine - Compare HL and DE&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0018H  JMP 006CH            ; Jump to comparison routine&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Return to Main ROM.  After issuing the OUT E0H, we will be in Main ROM.  The next opcode&lt;br /&gt;
; in Main ROM after this OUT statement occurs will be a RET (part of RST 1).  We have &lt;br /&gt;
; PUSHed a return address to the stack, so the main ROM&#039;s RET instruction will get us &lt;br /&gt;
; where to intend to go.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
001BH  OUT E0H              ; Send A to the ROM bank port to switch to Main ROM&lt;br /&gt;
001DH  RET                  ; Should never execute this instruction, but just in case&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Send a space to the screen/printer - Not called from anywhere.  Copy of Main ROM.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
001EH  (3EH) MVI A,20H      ; Prepare to print a SPACE&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST 3 routine - Send character in A to the screen / printer&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0020H  (CFH) RST 1          ; Call main ROM at address in following 2 bytes&lt;br /&gt;
0021H  DW    0020H          ; Main ROM&#039;s RST 3 routine&lt;br /&gt;
0023H  (C9H) RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Power down TRAP.  Let Main ROM deal with it.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0024H  DI                   ; Disable interrupts while we jump   &lt;br /&gt;
0025H  CALL 0097H           ; Jump to Main ROM&#039;s RST handler for this vector &lt;br /&gt;
0028H  POP H      &lt;br /&gt;
0029H  JMP 0003H            ; Pop regs after we power back up from a power-down? &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Hardware Interrupt - Let Main ROM deal with it - Bar Code Reader&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
002CH  DI                   ; Disable interrupts while we jump  &lt;br /&gt;
002DH  CALL 0097H           ; Jump to Main ROM&#039;s RST handler for this vector&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Return from Main ROM hook in RAM returns here via RST 6&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0030H  POP PSW              ; Cleanup stack&lt;br /&gt;
0031H  POP PSW              ; Cleanup stack&lt;br /&gt;
0032H  RET                  ; Return to OptROM execution point        &lt;br /&gt;
&lt;br /&gt;
0033H  NOP                  ; Filler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Hardware Interrupt - Let Main ROM deal with it - RS232 character pending&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0034H  DI                   ; Disable interrupts while we jump&lt;br /&gt;
0035H  CALL 0097H           ; Jump to Main ROM&#039;s RST handler for this vector&lt;br /&gt;
0038H  JMP 00A6H            ; Stack cleanup&lt;br /&gt;
&lt;br /&gt;
003BH  NOP                  ; UNUSED - filler&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Hardware Interrupt - Let Main ROM deal with it - Timer background task&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
003CH  DI                   ; Disable interrupts&lt;br /&gt;
003DH  CALL 0097H           ; Jump to Main ROM&#039;s RST handler for this vector&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; This routine gets copied to RAM to be used for switching back to the TS-DOS ROM after&lt;br /&gt;
;      calling a routine in the Main ROM.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0040H  PUSH PSW             ; Preserve the PSW&lt;br /&gt;
0041H  LDA FF45H            ; Contents of port E8H&lt;br /&gt;
0044H  INR A                ; Prepare to switch to OptRom&lt;br /&gt;
0045H  OUT E0H              ; Switch to OptRom&lt;br /&gt;
0047H  RST 6                ; Get sign of FAC1&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; This routine gets copied to RAM and appears to detect the presence of the TS-DOS ROM&lt;br /&gt;
;       after power-up and copies the original &amp;quot;External ROM&amp;quot; detection routine to RAM&lt;br /&gt;
;       if the TS-DOS ROM is no longer present.  At least I think that&#039;s what it&#039;s doing.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0048H  LXI D,F605H          ; Copy address for &amp;quot;Ext ROM detect&amp;quot; routine&lt;br /&gt;
004BH  INR A                ; Set bit to enable OptROM&lt;br /&gt;
004CH  OUT E0H              ; Switch to OptROM&lt;br /&gt;
004EH  XRA A                ; Prepare to switch back to Main ROM&lt;br /&gt;
004FH  LHLD 0049H           ; Load target address of the LXI D instruction above&lt;br /&gt;
0052H  OUT E0H              ; Switch back to Main ROM&lt;br /&gt;
0054H  RST 3                ; Compare DE and HL - Test if OptROM is TS-DOS&lt;br /&gt;
0055H  CPI 01H              ; Test for TS-DOS ROM&lt;br /&gt;
0057H  RC                   ; Return if TS-DOS ROM&lt;br /&gt;
0058H  LXI H,111DH          ; Load &amp;quot;Return&amp;quot; address to the CALL below&lt;br /&gt;
005BH  SHLD FAE0H&lt;br /&gt;
005EH  SHLD F5F2H           ; Save a &amp;quot;Restart signature&amp;quot; ???&lt;br /&gt;
0061H  CALL 2905H           ; Copy the DB number of bytes from the DW address to (DE)&lt;br /&gt;
0064H  DB   24H             ; ....copy 24H bytes&lt;br /&gt;
0065H  DW   036FH           ; ....from ROM addres 036F (external ROM detect)&lt;br /&gt;
0067H  RST 0                ; I&#039;m not sure it it every actually returns here or not&lt;br /&gt;
0068H  NOP&lt;br /&gt;
0069H  CALL FAA4H           ; Call our installed RAM hook to return to TS-DOS&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Compare HL and DE - called by the RST 3 routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
006CH  MOV A,H              ; Move H into A for comparison&lt;br /&gt;
006DH  SUB D                ; Compare MSB first&lt;br /&gt;
006EH  RNZ                  ; Return if no match&lt;br /&gt;
006FH  MOV A,L              ; Now move L into A&lt;br /&gt;
0070H  SUB E                ; Compare LSB&lt;br /&gt;
0071H  RET                  ; Return with flags set&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Copy 8 bytes from DE to HL &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0072H  LXI B,0008H          ; Prepare to copy 8 bytes &lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Copy BC bytes from DE to HL &lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0075H  LDAX D               ; Load value from (DE)&lt;br /&gt;
0076H  MOV M,A              ; Save value to (HL)&lt;br /&gt;
0077H  INX D                ; Increment DE&lt;br /&gt;
0078H  INX H                ; Increment HL&lt;br /&gt;
0079H  DCX B                ; Decrement counter&lt;br /&gt;
007AH  MOV A,B              ; Prepare to test counter for zero&lt;br /&gt;
007BH  ORA C                ; Test counter for zero&lt;br /&gt;
007CH  JNZ 0075H            ; Keep looping until 8 bytes copied&lt;br /&gt;
007FH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Handle the RST 1 routine.  Read the Main ROM address from the 2 bytes after the RST 1&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0080H  SHLD F9B2H           ; Save HL off in &amp;quot;RickY&amp;quot; Cat entry so we don&#039;t clobber it&lt;br /&gt;
0083H  POP H                ; Get out return address (location of the ROM address to call&lt;br /&gt;
0084H  PUSH D               ; Push the return address back to the stack as storage &lt;br /&gt;
0085H  MOV E,M              ; Get LSB of the ROM address to call&lt;br /&gt;
0086H  INX H                ; Point to MSB of ROM address to call&lt;br /&gt;
0087H  MOV D,M              ; Get MSB of the ROM address to call&lt;br /&gt;
0088H  INX H                ; Point to return address after the RST 1 DB address&lt;br /&gt;
0089H  XTHL                 ; Put the return address on the stack so we return after the RST 1&lt;br /&gt;
008AH  XCHG                 ; Now get the address within ROM to call&lt;br /&gt;
008BH  PUSH H               ; Push the target ROM address to the stack so we &amp;quot;RETurn&amp;quot; there&lt;br /&gt;
008CH  LXI H,FAA4H          ; Load address of our RAM hook to switch back to our ROM bank and RET&lt;br /&gt;
008FH  XTHL                 ; Push that address on the stack for after the ROM call is complete&lt;br /&gt;
0090H  PUSH H               ; Now put the ROM address back on the stack so we will RET there&lt;br /&gt;
0091H  LHLD F9B2H           ; Restore HL from temp storage in &amp;quot;RickY&amp;quot;&lt;br /&gt;
0094H  JMP 00A6H            ; Branch to switch to Main ROM and &amp;quot;RET&amp;quot; to the address we pushed&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; RST handler for calling the Main ROM&#039;s RST handlers.  This routine restores the original&lt;br /&gt;
;      RST vector address to the stack, and jumps to the Main ROM&#039;s RST routine while &lt;br /&gt;
;      preserving all register values.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0097H  SHLD F9B4H           ; Save HL temporarily (somewhere in RickY&#039;s name)&lt;br /&gt;
009AH  LXI H,FAA4H          ; Point to our RAM hook for returning to TS-DOS&lt;br /&gt;
009DH  XTHL                 ; Put the hook address as the return address on the stack&lt;br /&gt;
009EH  DCX H                ; Decrement the return address by 4&lt;br /&gt;
009FH  DCX H                ; ...this will result in the starting address of the RST&lt;br /&gt;
00A0H  DCX H                ; ...that brought us here&lt;br /&gt;
00A1H  DCX H&lt;br /&gt;
00A2H  PUSH H               ; Push the RST vector address to the stack&lt;br /&gt;
00A3H  LHLD F9B4H           ; Restore HL upon entry&lt;br /&gt;
00A6H  PUSH PSW             ; Save A to the stack&lt;br /&gt;
00A7H  PUSH H               ; Save the HL to the stack so we can preserve through XTHL&lt;br /&gt;
00A8H  LXI H,1488H          ; Load a RETurn address in the Main ROM (a POP PSW &amp;amp; RET) &lt;br /&gt;
00ABH  XTHL                 ; Push the address and get HL back&lt;br /&gt;
00ACH  LDA FF45H            ; Contents of port E8H - prepare for jump to Main ROM&lt;br /&gt;
00AFH  JMP 001BH            ; Jump to Main ROM &amp;amp; our custom &amp;quot;RET&amp;quot; address in the ROM&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Manual invocation entry point.  This is where we jump when &amp;quot;CALL 63013,1&amp;quot; is invoked&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
00B2H  DI                   ; Disable interrupts so nobody bugs us yet&lt;br /&gt;
00B3H  CPI 08H              ; Check the invocation parameter to test for recovery request&lt;br /&gt;
00B5H  JNC 0100H            ; Jump to test for recovery mode&lt;br /&gt;
00B8H  MOV B,A              ; Save the calling paramter to B&lt;br /&gt;
00B9H  PUSH B               ; Save BC to the stack&lt;br /&gt;
00BAH  PUSH D               ; Save DE to the stack&lt;br /&gt;
00BBH  PUSH H               ; Save HL to the stack&lt;br /&gt;
00BCH  LXI D,0040H          ; Load address of our &amp;quot;Change to OptROM&amp;quot; routine&lt;br /&gt;
00BFH  LXI H,FAA4H          ; Load pointer to somewhere in RAM to hold our routine&lt;br /&gt;
00C2H  CALL 0072H           ; Copy 8 bytes from DE to HL &lt;br /&gt;
00C5H  LXI B,0024H          ; Now prepare to copy 36 bytes worth of &amp;quot;routine&amp;quot;&lt;br /&gt;
00C8H  LXI H,F605H          ; Point to another RAM location&lt;br /&gt;
00CBH  CALL 0075H           ; Copy the next &amp;quot;ROM Bank Switching&amp;quot; routine from our ROM&lt;br /&gt;
00CEH  POP H                ; Restore HL&lt;br /&gt;
00CFH  POP D                ; Restore DE&lt;br /&gt;
00D0H  POP PSW              ; Restore A&lt;br /&gt;
00D1H  EI                   ; Allow interrupts again&lt;br /&gt;
00D2H  JMP 0100H            ; Go test if a &amp;quot;Cold Start&amp;quot; recovery is being requested&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    .org 100H&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Test if cold-start recovery requested&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0100H  MOV A,H              ; Move H to A to test HL for zero&lt;br /&gt;
0101H  ORA L                ; Test for zero&lt;br /&gt;
0102H  JZ 7000H             ; Call recovery routine if requested&lt;br /&gt;
0105H  POP H                ; Pop the return address.  We will exit manually&lt;br /&gt;
0106H  CALL 0117H           ; Ensure the TS-DOS progam is installed in the MENU&lt;br /&gt;
0109H  JMP 3535H            ; Jump to the TS-DOS UI&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Move BC bytes from (HL) to (DE) with increment&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
010CH  MOV A,M              ; Get next byte from (HL)&lt;br /&gt;
010DH  STAX D               ; Save byte in (DE)&lt;br /&gt;
010EH  INX H                ; Increment source pointer&lt;br /&gt;
010FH  INX D                ; Increment destination pointer&lt;br /&gt;
0110H  DCX B                ; Decrement loop control&lt;br /&gt;
0111H  MOV A,B              ; Move MSB to A to test for zero&lt;br /&gt;
0112H  ORA C                ; OR in LSB to test for zero&lt;br /&gt;
0113H  JNZ 010CH            ; Branch to copy next byte until done&lt;br /&gt;
0116H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Insert the &amp;quot;TS-DOS&amp;quot; invocation program (BASIC program) into the Catalog / MENU.&lt;br /&gt;
;    we always insert ourselves at the lowest RAM address.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0117H  LXI H,01E1H          ; Point to &amp;quot;TS-DOS&amp;quot; catalog entry in our ROM&lt;br /&gt;
011AH  PUSH H               ; Save the address on the stack for later&lt;br /&gt;
011BH  INX H                ; Point to the text portion of the catalog entry&lt;br /&gt;
011CH  LXI B,0008H          ; Prepare to copy 8 filename byte&lt;br /&gt;
011FH  LXI D,FC93H          ; Filename of current BASIC program&lt;br /&gt;
0122H  CALL 010CH           ; Copy BC bytes from HL to DE - put &amp;quot;TS-DOS  &amp;quot; in cur. BASIC prog.&lt;br /&gt;
0125H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  DE now has the address of the invocation program&lt;br /&gt;
0126H  LHLX                 ; Get the length of the BASIC program into HL&lt;br /&gt;
0127H  SHLD FCC4H           ; Save the BASIC program length in the ALTLCD buffer for now&lt;br /&gt;
012AH  INX D                ; Point to MSB of the length&lt;br /&gt;
012BH  INX D                ; Point to LSB of the pointer to the &amp;quot;Next&amp;quot; BASIC instruction&lt;br /&gt;
012CH  XCHG                 ; HL &amp;lt;--&amp;gt; DE HL has the pointer to the &amp;quot;Next&amp;quot; BASIC inst address&lt;br /&gt;
012DH  SHLD FCC8H           ; Save the &amp;quot;Next&amp;quot; BASIC inst pointer to ALTLCD (start of program)&lt;br /&gt;
0130H  CALL 01D1H           ; Update the System pointers&lt;br /&gt;
0133H  CALL 01CDH           ; Search Catalog for entry matching current BASIC program&lt;br /&gt;
0136H  POP B                ; Pop address in case we return&lt;br /&gt;
0137H  RNZ                  ; Return if &amp;quot;TS-DOS&amp;quot; is already in the catalog&lt;br /&gt;
0138H  LHLD F99AH           ; Get the BASIC program not saved pointer - insert before that&lt;br /&gt;
013BH  SHLD FCC2H           ; Save storage location for the TS-DOS invocation progam&lt;br /&gt;
013EH  LDAX B               ; Load the file type byte from our ROM (B has the address from above)&lt;br /&gt;
013FH  STA FCC6H            ; Store the Type byte in the ALTLCD &lt;br /&gt;
0142H  CALL 0185H           ; Find empty entry in Catalog&lt;br /&gt;
0145H  RC                   ; Return if catalog full&lt;br /&gt;
0146H  PUSH H               ; Save the address of the empty catalog entry to the stack&lt;br /&gt;
0147H  LHLD FCC4H           ; Restore the BASIC program length from ALTLCD&lt;br /&gt;
014AH  MOV B,H              ; Move BASIC program length to BC for copy&lt;br /&gt;
014BH  MOV C,L              ; Move LSB of length&lt;br /&gt;
014CH  PUSH B               ; Save Length to the stack&lt;br /&gt;
014DH  LHLD FCC2H           ; Get address of insertion for TS-DOS just before the unsaved BASIC prog.&lt;br /&gt;
0150H  CALL 01DDH           ; Call Main ROM&#039;s Insert BC spaces at M routine&lt;br /&gt;
0153H  JC 0182H             ; Abort if RAM full&lt;br /&gt;
0156H  LHLD FCC2H           ; Get address of insertion point again&lt;br /&gt;
0159H  XCHG                 ; DE now has insertion point for BASIC program&lt;br /&gt;
015AH  LHLD FCC8H           ; Get the address of the BASIC program (in our ROM) from ALTLCD&lt;br /&gt;
015DH  POP B                ; Restore copy length of the BASIC program&lt;br /&gt;
015EH  CALL 010CH           ; Move BC bytes from (HL) to (DE) with increment&lt;br /&gt;
0161H  POP D                ; Get the address of the empty catalog entry we will use for TS-DOS&lt;br /&gt;
0162H  PUSH D               ; Save it back to the stack&lt;br /&gt;
0163H  LHLD FBAEH           ; Load the start of DO files pointer&lt;br /&gt;
0166H  DCX H                ; Derement the start of DO files pointer&lt;br /&gt;
0167H  SHLD F99AH           ; Save it as the new BASIC program not saved pointer&lt;br /&gt;
016AH  INX H                ; Point to start of DO files again&lt;br /&gt;
016BH  XCHG                 ; Move it to DE&lt;br /&gt;
016CH  LHLD FCC4H           ; Load the TS-DOS BASIC progam length from ALTLCD&lt;br /&gt;
016FH  DAD D                ; Offset the start of DO files by the insertion amount&lt;br /&gt;
0170H  SHLD FBAEH           ; Save the new start of DO files pointer&lt;br /&gt;
0173H  POP D                ; Restore the address of the empty catalog entry&lt;br /&gt;
0174H  LHLD FCC2H           ; Get the starting address of the newly inserted TS-DOS program&lt;br /&gt;
0177H  XCHG                 ; HL &amp;lt;--&amp;gt; DE  Swap for the call to the catalog insertion routine &lt;br /&gt;
0178H  LDA FCC6H            ; Load A with the file type byte&lt;br /&gt;
017BH  CALL 01D5H           ; Save current BASIC program to the Catalog entry at HL&lt;br /&gt;
017EH  CALL 01D1H           ; Update system pointers&lt;br /&gt;
0181H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Insert &amp;quot;TS-DOS&amp;quot; RAM full abort routine ... stack cleanup.&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0182H  POP H                ; Pop the BASIC program length from the stack&lt;br /&gt;
0183H  POP H                ; Pop the catalog entry address from the stack&lt;br /&gt;
0184H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Find an empty entry in the Catalog.  HL points to start of new entry&lt;br /&gt;
;     This routine appears again at address 3E48H&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0185H  LXI H,F9AFH          ; Point to &amp;quot;RickY&amp;quot; to start search at beginning of catalog&lt;br /&gt;
0188H  LXI B,000BH          ; Get length of each entry in the Catalog&lt;br /&gt;
018BH  DAD B                ; Point to next entry in the catalog&lt;br /&gt;
018CH  MOV A,M              ; Get the File Attribute byte from the catalog for this file&lt;br /&gt;
018DH  CPI FFH              ; Test if at end of the catalog&lt;br /&gt;
018FH  JZ 0197H             ; Jump to set Carry flag and exit if at end&lt;br /&gt;
0192H  ADD A                ; Test if MSB set (test if entry available)&lt;br /&gt;
0193H  JC 018BH             ; Branch to get next entry if this one is used&lt;br /&gt;
0196H  RET                  ; Return with Carry clear to indicate entry found&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Empty catalog entry not found in Catalog, set Carry and return&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0197H  STC                  ; Set the Carry flag - not found&lt;br /&gt;
0198H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Display function key line routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
0199H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
019AH  DW    42A8H&lt;br /&gt;
019CH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Erase function key display routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
019DH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
019EH  DW    428AH&lt;br /&gt;
01A0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Set new function key table routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01A1H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01A2H  DW    5A7CH&lt;br /&gt;
01A4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Wait for key from keyboard routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01A5H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01A6H  DW    12CBH&lt;br /&gt;
01A8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Scan keyboard for character (CTRL-BREAK ==&amp;gt; CTRL-C) routine&lt;br /&gt;
;      This appears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01A9H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01AAH  DW    7242H&lt;br /&gt;
01ACH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Power Down routine&lt;br /&gt;
;      This appears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01ADH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01AEH  DW    13B5H&lt;br /&gt;
01B0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Renew automatic power-off counter routine&lt;br /&gt;
;      This apears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01B1H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01B2H  DW    1BB1H&lt;br /&gt;
01B4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s CLS statement routine&lt;br /&gt;
;      This apears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01B5H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01B6H  DW    4231H&lt;br /&gt;
01B8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Start inverse character mode routine&lt;br /&gt;
;      This appears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01B9H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01BAH  DW    4269H&lt;br /&gt;
01BCH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Cancel inverse video routine&lt;br /&gt;
;      This appears later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01BDH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01BEH  DW    426EH&lt;br /&gt;
01C0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Check keyboard queue for pending characters routine&lt;br /&gt;
;      This appers later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01C1H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01C2H  DW    13DBH&lt;br /&gt;
01C4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Stop automatic scrolling routine&lt;br /&gt;
;      This appers later in the code also&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01C5H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01C6H  DW    423FH&lt;br /&gt;
01C8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Reset vector routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01C9H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01CAH  DW    0000H&lt;br /&gt;
01CCH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Search Catalog for entry matching current BASIC program&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01CDH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01CEH  DW    20AFH&lt;br /&gt;
01D0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Update system pointers routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01D1H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01D2H  DW    2146H&lt;br /&gt;
01D4H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s routine to save current BASIC program to the Catalog entry at HL&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01D5H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01D6H  DW    2239H&lt;br /&gt;
01D8H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Not a valid entry into ROM and not called anywhere&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01D9H  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01DAH  DW    5825H&lt;br /&gt;
01DCH  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; Call Main ROM&#039;s Insert BC spaces at M routine&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01DDH  RST 1                ; Call main ROM at address in following 2 bytes&lt;br /&gt;
01DEH  DB    6B6DH&lt;br /&gt;
01E0H  RET&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; TS-DOS entry that will be inserted into the catalog for invoking TS-DOS&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01E1H  DB   80H             ; TS-DOS file type for catalog entry&lt;br /&gt;
01E2H  DB   &amp;quot;TS-DOS  &amp;quot;      ; TS-DOS Catalog name entry&lt;br /&gt;
&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
; BASIC program that will be inserted into RAM to launch TS-DOS from the MENU/Catalog entry&lt;br /&gt;
; =========================================================================================&lt;br /&gt;
01EAH  DB   0FH,00H,0EH,80H ; BASIC program length and pointer to &amp;quot;Next&amp;quot; BASIC instruction&lt;br /&gt;
01EDH  DB   0AH,00H,B9H     ; BASIC Line number &amp;quot;10&amp;quot; and BASIC token for CALL&lt;br /&gt;
01EFH  DB   &amp;quot;63013,1&amp;quot;       ; CALL argument &lt;br /&gt;
01F5H  DB   00H,00H         ; BASIC terminating zeros&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
End of disassembly for OptROM Support.&lt;/div&gt;</summary>
		<author><name>Kpettit</name></author>
	</entry>
	<entry>
		<id>https://bitchin100.com/wiki/index.php?title=Disassembly_of_RAM_and_ROM_versions_of_TS-DOS&amp;diff=1365</id>
		<title>Disassembly of RAM and ROM versions of TS-DOS</title>
		<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=Disassembly_of_RAM_and_ROM_versions_of_TS-DOS&amp;diff=1365"/>
		<updated>2009-04-03T06:52:54Z</updated>

		<summary type="html">&lt;p&gt;Kpettit: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== TS-DOS Dissassembly ==&lt;br /&gt;
&lt;br /&gt;
There are various version of TS-DOS for The Model 100/102, for T200 and for the PC-8201a.  Additionally each of these versions has a ROM and a RAM.  While the majority of the code is equivalent across the various incarnations of TS-DOS, there are some differences due to varying RS-232 hardware and to accomodate execution from OptROM vs. RAM.&lt;br /&gt;
&lt;br /&gt;
The goal of the disassembly is to create a fully commented source file that can be assembled and subsequently modified / enhanced for new functionality.  The disassembly is split into several sections to keep each page &amp;quot;relatively&amp;quot; short.  The disassembly currently will not assemble as it contains absolute addresses that must be converted into assembly labels, or deleted where not needed.&lt;br /&gt;
&lt;br /&gt;
== Model 100/102 ROM Version ==&lt;br /&gt;
[[OptROM Support]]  [[UI Code]]  [[FKey Handlers]]  [[RST 7 Handlers]]  [[TPDD Protocol]]&lt;br /&gt;
&lt;br /&gt;
Not Completed Yet&lt;br /&gt;
[[Compression/Decompression]] [[Cold Boot Recovery]]&lt;br /&gt;
&lt;br /&gt;
== Model 200 RAM Version ==&lt;br /&gt;
[[UI Code]]  [[FKey Handlers]]  [[RST 7 Handlers]]  [[TPDD Protocol]]&lt;/div&gt;</summary>
		<author><name>Kpettit</name></author>
	</entry>
	<entry>
		<id>https://bitchin100.com/wiki/index.php?title=Disassembly_of_RAM_and_ROM_versions_of_TS-DOS&amp;diff=1364</id>
		<title>Disassembly of RAM and ROM versions of TS-DOS</title>
		<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=Disassembly_of_RAM_and_ROM_versions_of_TS-DOS&amp;diff=1364"/>
		<updated>2009-04-03T06:51:36Z</updated>

		<summary type="html">&lt;p&gt;Kpettit: New page: == TS-DOS Dissassembly ==  There are various version of TS-DOS for The Model 100/102, for T200 and for the PC-8201a.  Additionally each of these versions has a ROM and a RAM.  While the ma...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== TS-DOS Dissassembly ==&lt;br /&gt;
&lt;br /&gt;
There are various version of TS-DOS for The Model 100/102, for T200 and for the PC-8201a.  Additionally each of these versions has a ROM and a RAM.  While the majority of the code is equivalent across the various incarnations of TS-DOS, there are some differences due to varying RS-232 hardware and to accomodate execution from OptROM vs. RAM.&lt;br /&gt;
&lt;br /&gt;
The goal of the disassembly is to create a fully commented source file that can be assembled and subsequently modified / enhanced for new functionality.  The disassembly is split into several sections to keep each page &amp;quot;relatively&amp;quot; short.  The disassembly currently will not assemble as it contains absolute addresses that must be converted into assembly labels, or deleted where not needed.&lt;br /&gt;
&lt;br /&gt;
== Model 100/102 ROM Version ==&lt;br /&gt;
[[OptROM Support]]  [[UI Code]]  [[FKey Handlers]]  [[RST 7 Handlers]]  [[TPDD Protocol]]&lt;br /&gt;
&lt;br /&gt;
= Not Completed Yet =&lt;br /&gt;
[[Compression/Decompression]] [[Cold Boot Recovery]]&lt;br /&gt;
&lt;br /&gt;
== Model 200 RAM Version ==&lt;br /&gt;
[[UI Code]]  [[FKey Handlers]]  [[RST 7 Handlers]]  [[TPDD Protocol]]&lt;/div&gt;</summary>
		<author><name>Kpettit</name></author>
	</entry>
	<entry>
		<id>https://bitchin100.com/wiki/index.php?title=TS-DOS&amp;diff=1363</id>
		<title>TS-DOS</title>
		<link rel="alternate" type="text/html" href="https://bitchin100.com/wiki/index.php?title=TS-DOS&amp;diff=1363"/>
		<updated>2009-04-03T06:33:52Z</updated>

		<summary type="html">&lt;p&gt;Kpettit: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Variants of TS-DOS ==&lt;br /&gt;
&lt;br /&gt;
TS-DOS on ROM can be purchased from [http://club100.org Club100]&lt;br /&gt;
&lt;br /&gt;
TS-DOS RAM version can be downloaded from [https://club100.org Club100]&lt;br /&gt;
&lt;br /&gt;
== Tips and Tricks ==&lt;br /&gt;
&lt;br /&gt;
[[Using TS-DOS RAM&#039;s DOS Without the GUI]]&lt;br /&gt;
&lt;br /&gt;
[[Category:TPDD Client]]&lt;br /&gt;
&lt;br /&gt;
== TS-DOS Disassembly ==&lt;br /&gt;
&lt;br /&gt;
[[Dissasembly of RAM and ROM versions of TS-DOS]]&lt;/div&gt;</summary>
		<author><name>Kpettit</name></author>
	</entry>
</feed>