TRS-80 DOS - NEWDOS/80 v2.0 for the Model I - SYS1/SYS Disassembled

Page Customization

Introduction/Summary

The SYS1/SYS module is the second part of the NEWDOS/80 v2.0 bootstrap sequence for the TRS-80 Model I, loaded immediately after BOOT/SYS and SYS0/SYS. Its main purpose is to set up the necessary input/output (I/O) routines and disk error handling before transferring control to the next DOS component.

Core Functionality

SYS1/SYS primarily consists of two major sections:

I/O and Driver Setup

This section loads and initializes key I/O routines required by the DOS.

It contains the code for the printer driver (for outputting to a parallel printer).

It also contains routines for the keyboard input and screen output used by the DOS command line interface and internal commands.

The module ensures that the fundamental system I/O is configured and ready for the higher-level DOS components.

Disk Error Processing

This is a critical component of the SYS1/SYS module.

It holds the routine that handles all Disk Errors encountered during disk operations (like reading or writing a sector).

When an error occurs, this routine is executed to analyze the status reported by the Floppy Disk Controller (FDC).

It is responsible for determining the type of error (e.g., CRC error, seek error, write protect) and taking the appropriate action, which typically involves displaying an error message and giving the user options, such as Retry (R), Ignore (I), or Cancel (C).

In essence, SYS1/SYS acts as the DOS's primary interface to the machine's I/O hardware and establishes the low-level logic for reliable disk usage and error recovery. After executing and setting up these services, it passes control to the next stage of the DOS loading sequence.

Variables:

AddressBytesPurpose
4022H1Cursor blink state storage. Non-zero = cursor was on, Zero = cursor was off.
402DH3DOS No-Error Exit vector (JP instruction). Programs jump here on successful completion.
4030H3DOS Error-Already-Displayed Exit vector. Jump here when error message already shown.
4200H256DOS Sector buffer (also aliased at 5100H-51FFH for overlay area).
4300H24Storage area including PDRIVE and SYSTEM specifications.
4312H1BREAK key enable flag. C9H = enabled (RET instruction), C3H = disabled (JP instruction).
4313H2BREAK key handler jump address (used when 4312H contains C3H).
4318H80DOS Command buffer. User input and commands are stored here (4318H-4367H).
4368H1SYSTEM storage - system state flags.
4369H1SYSTEM storage - additional flags (bit 5 checked for certain operations).
436AH1DOS system flags byte 1.
  • Bit 7 = MINI-DOS active
  • Bit 6 = DOS-CALL active
  • Bit 5 = command processing state
  • Bit 4 = additional state flag
436BH1DOS system flags byte 2.
  • Bit 7 = special return mode
  • Bit 6 = stack save mode
  • Bit 2 = error state
436CH1DOS system flags byte 3.
  • Bit 6 = chaining active flag
  • Bit 5 = additional state
436DH1DOS system flags byte 4.
  • Bit 5 = R command repeat flag
4371H42PDRIVE storage area (4371H-439AH). Contains physical drive configuration data.
439BH2Saved stack pointer for MINI-DOS. Stores SP when entering MINI-DOS for later restoration.
439DH2Saved stack pointer for DOS-CALL. Stores SP when entering DOS-CALL mode.
43A7H2Saved command buffer pointer. Stores original (4318H) value for R command repeat functionality.
4408H3DOS command execution return address vector.
4467HDOS message display routine entry point.
4480H32Filename parsing buffer. Parsed filename components stored here.
45B0HBREAK key handler routine address (stored into 4313H).
45B5HCharacter case conversion routine.
4CD5HFilespec parsing subroutine.
4CD9HFilespec validation subroutine.
4CC5HString comparison subroutine.
4F58HCommand name lookup table. Contains DOS command names with attributes.
51A7H3ASCII string "CMD" - command file extension.
51AAH3ASCII string "JCL" - job control language extension.
51ADH3ASCII string "TO" with null terminator - COPY command keyword.
51B0H5ASCII string "MINI-" - prefix for MINI-DOS ready message.
51B5H16ASCII string "NEWDOS/80 READY" with CR terminator - DOS prompt message.
51C5H4System parameter table (1CH, 1FH, 03H, 00H).
51E0H32Working buffer at end of overlay area. Used for temporary filename storage.

Disassembly

4D00H - DOS OVERLAY COMMAND DISPATCHER

This is the entry point of the NEWDOS/80 DOS Overlay module (SYS6/SYS). When the DOS receives a command, it loads this overlay and jumps here with Register A containing a command dispatch code to determine which function to execute. Register C also contains a secondary dispatch counter for some functions.

4D00
CP 23H FE 23
Compare Register A against # (23H = comment marker). If the command line starts with #, it's a comment and should be ignored.
4D02
If the Z FLAG is set (command is a comment), JUMP to 4D8AH to exit cleanly with no error.
4D05
CP 43H FE 43
Compare Register A against 43H. This checks for a specific dispatch code (possibly C for certain command class).
4D07
If the Z FLAG is set, JUMP to 4D7CH to handle this command type (sets Carry flag and exits).
4D09
CP 63H FE 63
Compare Register A against 63H. This checks for lowercase c dispatch code.
4D0B
If the Z FLAG is set, JUMP to 4E30H to reset stack and process command.
4D0E
CP 83H FE 83
Compare Register A against 83H (dispatch code for file-related function).
4D10
If the Z FLAG is set, JUMP to 513DH to handle file specification parsing.
4D13
CP A3H FE A3
Compare Register A against A3H (dispatch code for drive path insertion).
4D15
If the Z FLAG is set, JUMP to 4F2AH to insert drive specification into filename.
4D18
CP C3H FE C3
Compare Register A against C3H (dispatch code for DOS-CALL entry).
4D1A
If the Z FLAG is set, JUMP to 4D5BH to handle DOS-CALL function entry (saving registers and state).

The following section uses Register C as a countdown counter to dispatch to different command handlers. Each DEC C decrements the counter, and when it reaches zero, that handler is called.

4D1C
DEC C 0D
DECrement the value stored in Register C by 1. Check if dispatch code is 1.
4D1D
If the Z FLAG is set (C was 1), JUMP to 4D59H to perform POP AF and RET (simple return).
4D1F
DEC C 0D
DECrement Register C again. Check if dispatch code is 2.
4D20
If the Z FLAG is set (C was 2), JUMP to 50B7H to display the LIB (library) command list.
4D23
DEC C 0D
DECrement Register C again. Check if dispatch code is 3.
4D24
If the Z FLAG is set (C was 3), JUMP to 4D32H to continue counting down further dispatch codes.
4D27
DEC C 0D
DECrement Register C again. Check if dispatch code is 4.
4D28
If the Z FLAG is set (C was 4), JUMP to 50DBH to enter MINI-DOS mode.
4D2B
DEC C 0D
DECrement Register C again. Check if dispatch code is 5.
4D2C
If the Z FLAG is set (C was 5), JUMP to 4D80H to clear system flags and exit.
4D2E
DEC C 0D
DECrement Register C again. Check if dispatch code is 6.
4D2F
If the Z FLAG is set (C was 6), JUMP to 50FAH to exit MINI-DOS (MDRET function).
4D32
DEC C 0D
DECrement Register C again. Check if dispatch code is 7.
4D33
If the Z FLAG is set (C was 7), JUMP to 4D78H to pop two values and continue to exit.
4D35
DEC C 0D
DECrement Register C again. Check if dispatch code is 8.
4D36
If the Z FLAG is set (C was 8), JUMP to 4E34H to process command without stack reset.
4D39
DEC C 0D
DECrement Register C again. Check if dispatch code is 9.
4D3A
If the Z FLAG is set (C was 9), JUMP to 4D48H to display error message and exit.
4D3C
DEC C 0D
DECrement Register C again. Check if dispatch code is 10.
4D3D
DEC C 0D
DECrement Register C again. Check if dispatch code is 11.
4D3E
If the Z FLAG is set (C was 11), JUMP to 5150H to parse filespec.
4D41
DEC C 0D
DECrement Register C again. Check if dispatch code is 12.
4D42
If the Z FLAG is set (C was 12), JUMP to 4D80H to clear flags and exit.

If none of the dispatch codes matched, return an ILLEGAL ENTRY error (error code 2AH).

4D44
LD A,2AH 3E 2A
Load Register A with error code 2AH (42 decimal = "ILLEGAL ENTRY" error).
4D46
OR A B7
OR Register A with itself to set flags (clears Z flag, sets NZ to indicate error).
4D47
RET C9
RETurn to caller with error code in A and NZ flag indicating error.

4D48H - ERROR MESSAGE DISPLAY AND EXIT

This routine displays an error message and exits via the DOS display routine at 4467H. HL points to a message table entry at 51C5H.

4D48
LD HL,51C5H 21 C5 51
Point Register Pair HL to address 51C5H, which contains message control bytes for error display.
4D4B
JUMP to the DOS string display routine at 4467H to output the error message.

4D4EH - RST 28H SVC PREPARATION ROUTINE

This routine prepares for a DOS supervisor call (RST 28H) by saving the alternate register set and setting up parameters. This is used internally by DOS to load and execute system modules.

4D4E
EXX D9
Exchange BC, DE, HL with their alternate (prime) register counterparts BC', DE', HL'.
4D4F
LD BC,E301H 01 01 E3
Load Register Pair BC' with E301H. B'=E3H is a SVC function code, C'=01H is a parameter.
4D52
LD DE,49D3H 11 D3 49
Load Register Pair DE' with 49D3H, a return address in the DOS resident module.
4D55
PUSH BC C5
Save BC' (E301H) onto the stack.
4D56
PUSH DE D5
Save DE' (49D3H) onto the stack as return address.
4D57
EXX D9
Exchange back to main register set BC, DE, HL.
4D58
RST 28H EF
Execute DOS Supervisor Call. The function loaded/executed depends on previous setup. This performs a DOS internal operation.

4D59H - SIMPLE POP AND RETURN

Simple return routine that pops the AF register and returns. Used when a command completes with the status already set.

4D59
POP AF F1
Restore Register Pair AF from the stack.
4D5A
RET C9
RETurn to caller with restored flags.

4D5BH - DOS-CALL ENTRY HANDLER

This routine handles entry into DOS-CALL mode, which allows user programs to invoke DOS functions and commands. It saves all registers, manages the DOS-CALL nesting level, and sets up the stack for DOS operations. Address 4419H vectors here via dispatch code C3H.

4D5B
GOSUB to 512BH to save all registers (HL, DE, BC, AF, alternate set, IX, IY) onto the stack for DOS-CALL entry.
4D5E
LD BC,0000H 01 00 00
Load Register Pair BC with 0000H as initial previous stack pointer value (indicates first DOS-CALL level).
4D61
EX DE,HL EB
Exchange DE and HL. HL (from caller) now in DE, preserving the command pointer.
4D62
LD HL,436AH 21 6A 43
Point Register Pair HL to address 436AH, the DOS system status flags byte.
  • Bit 7 = MINI-DOS active
  • Bit 6 = DOS-CALL active
  • Bit 5 = command processing state
  • Bit 4 = additional state flag
4D65
BIT 6,(HL) CB 76
Test bit 6 of the status byte at 436AH. This bit indicates if DOS-CALL is already active (nested DOS-CALL).
4D67
SET 6,(HL) CB F6
SET bit 6 at 436AH to mark that DOS-CALL mode is now active.
4D69
If the Z FLAG is set (bit 6 was 0, first DOS-CALL), JUMP to 4D6FH to continue with BC=0000H.
4D6B
LD BC,(439DH) ED 4B 9D 43
If nested DOS-CALL, fetch the previous DOS-CALL stack pointer from 439DH into BC.
4D6F
PUSH BC C5
Save BC (previous stack pointer, or 0000H if first level) onto the stack.
4D70
LD (439DH),SP ED 73 9D 43
Store the current Stack Pointer into 439DH. This saves the DOS-CALL entry point for later restoration.
4D74
EX DE,HL EB
Exchange DE and HL again. HL now points to the command to execute.
4D75
JUMP to 4E35H to set up error handlers and process the DOS command pointed to by HL.

4D78H - DOUBLE POP AND CONTINUE TO EXIT

This routine pops two values from the stack (discarding return addresses) and continues to the standard exit routine.

4D78
POP AF F1
Discard a return address from the stack by popping into AF.
4D79
POP AF F1
Discard another return address from the stack.
4D7A
JUMP to 4D8BH to continue with standard exit processing.

4D7CH - SET CARRY AND EXIT

This routine clears A, sets the Carry flag, and exits. Used to indicate a specific completion state (possibly indicating BREAK was pressed or a special condition).

4D7C
XOR A AF
XOR Register A with itself, setting A to 00H and clearing all flags.
4D7D
SCF 37
Set the Carry Flag to indicate a special exit condition.
4D7E
JUMP to 4D8BH to continue with standard exit processing.

4D80H - CLEAR SYSTEM FLAGS AND EXIT

This routine clears certain system flags in the DOS status bytes at 4369H and 436AH, then exits cleanly. Used when completing operations that need to reset DOS state.

4D80
LD HL,436AH 21 6A 43
Point Register Pair HL to address 436AH, the DOS system status flags byte.
  • Bit 7 = MINI-DOS active
  • Bit 6 = DOS-CALL active
  • Bit 5 = command processing state
  • Bit 4 = additional state flag
4D83
LD A,(HL) 7E
Load Register A with the current value of the status byte at 436AH.
4D84
AND 2FH E6 2F
AND Register A with 2FH (00101111b) to clear bits 7, 6, and 4. This clears MINI-DOS flag (bit 7), DOS-CALL flag (bit 6), and another control bit.
4D86
LD (HL),A 77
Store the modified flags back to 436AH.
4D87
DEC HL 2B
DECrement HL to point to 4369H, another system status byte.
4D88
RES 5,(HL) CB AE
RESet bit 5 at address 4369H. This clears a control flag used during command processing.

4D8AH - CLEAN EXIT ENTRY POINT

This is a common entry point for clean exits. A is zeroed and processing continues to check DOS state and return appropriately.

4D8A
XOR A AF
XOR Register A with itself, setting A to 00H (no error) and clearing all flags.

4D8BH - MAIN EXIT PROCESSING ROUTINE

This is the main exit processing routine for DOS commands. It disables interrupts, checks DOS state flags to determine if in DOS-CALL or MINI-DOS mode, and handles the appropriate exit sequence. The entry flags (Z, C) from previous code indicate the exit status.

4D8B
DI F3
Disable Interrupts during critical exit processing to prevent reentrant issues.
4D8C
LD HL,436BH 21 6B 43
Point Register Pair HL to address 436BH, a DOS system storage byte.
  • Bit 7 = special return mode
  • Bit 6 = stack save mode
  • Bit 2 = error state
4D8F
LD (HL),00H 36 00
Store 00H at 436BH, clearing this status/counter byte.
  • Bit 7 = special return mode
  • Bit 6 = stack save mode
  • Bit 2 = error state
4D91
DEC HL 2B
DECrement HL to point to 436AH (main status flags).
  • Bit 7 = MINI-DOS active
  • Bit 6 = DOS-CALL active
  • Bit 5 = command processing state
  • Bit 4 = additional state flag
4D92
LD B,(HL) 46
Load Register B with the status flags from 436AH. This contains MINI-DOS, DOS-CALL, and other flags.
4D93
DEC HL 2B
DECrement HL to point to 4369H (secondary status flags).
4D94
LD C,(HL) 4E
Load Register C with the secondary status flags from 4369H.
4D95
LD E,0BH 1E 0B
Load Register E with 0BH (11 decimal) as a default error code (possibly "FILE NOT IN DIRECTORY").
4D97
PUSH AF F5
Save Register A (error code) and Flags onto the stack.
4D98
BIT 2,B CB 50
Test bit 2 of Register B (flags from 436AH). This checks a specific DOS state flag.
  • Bit 7 = MINI-DOS active
  • Bit 6 = DOS-CALL active
  • Bit 5 = command processing state
  • Bit 4 = additional state flag
4D9A
If the NZ FLAG is set (bit 2 was 1), JUMP to 4DBFH to handle error exit through RST 28H.
4D9C
POP AF F1
Restore Register A (error code) and Flags from the stack.
4D9D
PUSH AF F5
Save Register A and Flags again for later use.
4D9E
If the CARRY FLAG is set (error condition), JUMP to 4DA2H to check error value.
4DA0
If the Z FLAG is set (successful, no error, A=0), JUMP to 4DACH to handle clean exit.

If we reach here, NZ and NC are set, meaning there's a non-zero error code in A.

4DA2
CP 38H FE 38
Compare Register A against 38H (56 decimal = "DISK WRITE PROTECTED" error).
4DA4
If the Z FLAG is set (error was 38H), JUMP to 4DACH to handle this specific error normally.
4DA6
LD E,04H 1E 04
Load Register E with error code 04H (possibly "ILLEGAL FILE NAME").
4DA8
BIT 5,C CB 69
Test bit 5 of Register C (flags from 4369H). This checks if error display is suppressed.
4DAA
If the NZ FLAG is set (bit 5 was 1, display suppressed), JUMP to 4DBFH to exit via RST 28H error handler.

Continue with normal error/exit processing.

4DAC
RES 6,(HL) CB B6
RESet bit 6 at address 4369H. This clears a DOS state flag.
4DAE
BIT 6,B CB 70
Test bit 6 of Register B (flags from 436AH). This checks if DOS-CALL mode is active.
  • Bit 7 = MINI-DOS active
  • Bit 6 = DOS-CALL active
  • Bit 5 = command processing state
  • Bit 4 = additional state flag
4DB0
If the NZ FLAG is set (DOS-CALL mode active), JUMP to 4E10H to handle DOS-CALL exit.
4DB2
LD A,(436CH) 3A 6C 43
Load Register A with the value from 436CH, another DOS system storage byte.
  • Bit 6 = chaining active flag
  • Bit 5 = additional state
4DB5
BIT 6,A CB 77
Test bit 6 of the value from 436CH. This checks a chaining-related flag.
  • Bit 6 = chaining active flag
  • Bit 5 = additional state
4DB7
If the Z FLAG is set (bit 6 was 0), JUMP to 4DC4H to continue checking MINI-DOS state.
4DB9
BIT 5,C CB 69
Test bit 5 of Register C (flags from 4369H) again.
4DBB
If the NZ FLAG is set (bit 5 was 1), JUMP to 4DC4H to continue.
4DBD
LD E,0CH 1E 0C
Load Register E with error code 0CH (12 decimal = "ILLEGAL DISK CHANGE").

Execute RST 28H to invoke DOS error handler or load another module.

4DBF
LD D,EBH 16 EB
Load Register D with EBH as the high byte of a function code for RST 28H.
4DC1
LD A,D 7A
Load Register A with the value from D (EBH) for the RST 28H call.
4DC2
LD C,E 4B
Load Register C with the error code from E.
4DC3
RST 28H EF
Execute DOS Supervisor Call with A=EBH and C=error code. This invokes the DOS error handler.

Check if MINI-DOS mode is active.

4DC4
BIT 7,B CB 78
Test bit 7 of Register B (flags from 436AH). This checks if MINI-DOS mode is active.
  • Bit 7 = MINI-DOS active
  • Bit 6 = DOS-CALL active
  • Bit 5 = command processing state
  • Bit 4 = additional state flag
4DC6
If the NZ FLAG is set (MINI-DOS active), JUMP to 4DDCH to display MINI-DOS prompt.

Normal DOS READY mode - reset stack to DOS area and set up BREAK key handling.

4DC8
LD SP,41E0H 31 E0 41
Load the Stack Pointer with 41E0H, the top of the DOS stack area.
4DCB
BIT 5,A CB 6F
Test bit 5 of Register A (value from 436CH). This checks the BREAK key state setting.
  • Bit 6 = chaining active flag
  • Bit 5 = additional state
4DCD
LD HL,45B0H 21 B0 45
Point Register Pair HL to address 45B0H, the BREAK key handling routine in DOS.
4DD0
LD (4313H),HL 22 13 43
Store this address at 4313H, setting up the BREAK key jump vector.
4DD3
LD A,C3H 3E C3
Load Register A with C3H (JP opcode). This will disable BREAK by jumping past the handler.
4DD5
If the Z FLAG is set (bit 5 was 0, BREAK should be disabled), JUMP to 4DD9H to store C3H.
4DD7
LD A,C9H 3E C9
Load Register A with C9H (RET opcode). This enables BREAK by returning immediately from handler check.
4DD9
LD (4312H),A 32 12 43
Store the opcode (C3H or C9H) at 4312H, the BREAK key enable/disable location.

Set up to display DOS READY prompt.

4DDC
LD HL,51B5H 21 B5 51
Point Register Pair HL to address 51B5H, which contains the string "NEWDOS/80 READY".
4DDF
BIT 7,B CB 78
Test bit 7 of Register B again to check for MINI-DOS mode.
4DE1
If the Z FLAG is set (not MINI-DOS), JUMP to 4DEAH to display normal DOS READY prompt.

MINI-DOS mode - restore stack and display MINI-DOS prompt.

4DE3
LD SP,(439BH) ED 7B 9B 43
Load the Stack Pointer from 439BH, restoring the MINI-DOS entry stack.
4DE7
LD HL,51B0H 21 B0 51
Point Register Pair HL to address 51B0H, which contains the string "MINI-" prefix.

Display the prompt and wait for next command.

4DEA
EI FB
Enable Interrupts now that critical processing is complete.
4DEB
LD A,0DH 3E 0D
Load Register A with 0DH (Carriage Return) to start a new line.
4DED
GOSUB to ROM routine at 0033H to display the character in A (carriage return) at cursor position.
4DF0
BIT 5,C CB 69
Test bit 5 of Register C (flags from 4369H). Check if prompt display is suppressed.
4DF2
If the Z FLAG is set (prompt not suppressed), GOSUB to 4467H to display the READY prompt string pointed to by HL.
4DF5
LD HL,436AH 21 6A 43
Point Register Pair HL to address 436AH (system status flags).
  • Bit 7 = MINI-DOS active
  • Bit 6 = DOS-CALL active
  • Bit 5 = command processing state
  • Bit 4 = additional state flag
4DF8
SET 5,(HL) CB EE
SET bit 5 at 436AH. This marks that DOS is at command prompt waiting for input.
  • Bit 7 = MINI-DOS active
  • Bit 6 = DOS-CALL active
  • Bit 5 = command processing state
  • Bit 4 = additional state flag

Set up to read the next command from keyboard.

4DFA
LD BC,E308H 01 08 E3
Load Register Pair BC with E308H. B=E3H is SVC function code, C=08H is parameter.
4DFD
LD DE,49D6H 11 D6 49
Load Register Pair DE with 49D6H, the return address after command processing.
4E00
PUSH BC C5
Save BC onto the stack.
4E01
PUSH DE D5
Save DE (return address) onto the stack.
4E02
LD HL,(4318H) 2A 18 43
Load Register Pair HL with the value at 4318H, the start of the DOS command buffer.
4E05
LD (43A7H),HL 22 A7 43
Store the command buffer start address at 43A7H for reference by the R (recall) command.
4E08
LD B,4FH 06 4F
Load Register B with 4FH (79 decimal), the maximum command line length minus 1.
4E0A
LD HL,4318H 21 18 43
Point Register Pair HL to address 4318H, the DOS command input buffer.
4E0D
JUMP to ROM routine at 0040H to wait for keyboard input. B=max chars, HL=buffer address. After input, execution returns to the address pushed earlier (49D6H).

4E10H - DOS-CALL EXIT HANDLER

This routine handles exiting from DOS-CALL mode. It restores the stack pointer and registers that were saved on DOS-CALL entry, and manages nested DOS-CALL levels.

4E10
POP DE D1
Discard the saved flags from the stack into DE.
4E11
LD SP,(439DH) ED 7B 9D 43
Load the Stack Pointer from 439DH, restoring to the DOS-CALL entry point.
4E15
BIT 5,C CB 69
Test bit 5 of Register C (flags from 4369H).
4E17
If the Z FLAG is set (bit 5 was 0), JUMP to 4E1DH to continue exit processing.
4E19
BIT 4,B CB 60
Test bit 4 of Register B (flags from 436AH).
  • Bit 7 = MINI-DOS active
  • Bit 6 = DOS-CALL active
  • Bit 5 = command processing state
  • Bit 4 = additional state flag
4E1B
If the NZ FLAG is set (bit 4 was 1), JUMP BACK to 4DDCH to display prompt instead of returning.

Pop the previous stack pointer and manage DOS-CALL nesting.

4E1D
POP BC C1
Pop the previous DOS-CALL stack pointer from the stack into BC.
4E1E
LD A,B 78
Load Register A with the high byte of the previous stack pointer.
4E1F
OR C B1
OR Register A with C (low byte). Check if BC is zero (first DOS-CALL level).
4E20
If the NZ FLAG is set (BC not zero, still nested), JUMP to 4E25H to skip flag clearing.
4E22
INC HL 23
INCrement HL to point to 436AH.
  • Bit 7 = MINI-DOS active
  • Bit 6 = DOS-CALL active
  • Bit 5 = command processing state
  • Bit 4 = additional state flag
4E23
RES 6,(HL) CB B6
RESet bit 6 at 436AH. This clears the DOS-CALL active flag (we're leaving the outermost level).
4E25
RES 4,(HL) CB A6
RESet bit 4 at current HL address. Clear another state flag.
4E27
LD (439DH),BC ED 43 9D 43
Store BC (previous stack pointer) back at 439DH for nested DOS-CALL tracking.
4E2B
PUSH DE D5
Save DE onto the stack.
4E2C
POP AF F1
Pop into AF to restore flags for return.
4E2D
JUMP to 511BH to restore all saved registers and return from DOS-CALL.

4E30H - COMMAND EXECUTION WITH STACK RESET

This routine resets the stack pointer to the DOS stack area and then processes a command. Used for dispatch code 63H.

4E30
LD SP,41E0H 31 E0 41
Load the Stack Pointer with 41E0H, resetting to the top of the DOS stack area.
4E33
PUSH AF F5
Save Register A and Flags onto the stack.

4E34H - COMMAND EXECUTION WITHOUT STACK RESET

Entry point for command execution without resetting stack. Falls through from 4E33H or jumped to directly.

4E34
POP AF F1
Restore Register A and Flags from the stack.

4E35H - COMMAND SETUP AND PARSING

This routine sets up error handling vectors and begins parsing the command in the DOS command buffer. HL points to the command string. This is the main entry point after DOS-CALL setup or direct command entry.

4E35
LD BC,402DH 01 2D 40
Load Register Pair BC with 402DH, the address of the DOS "no-error exit" routine.
4E38
LD DE,4408H 11 08 44
Load Register Pair DE with 4408H, the address of a DOS command execution routine.
4E3B
PUSH BC C5
Save BC (402DH = no-error exit) onto the stack as a return address.
4E3C
PUSH DE D5
Save DE (4408H) onto the stack as another return address.
4E3D
EX DE,HL EB
Exchange DE and HL. Now DE points to the command string, HL=4408H.
4E3E
LD HL,436AH 21 6A 43
Point Register Pair HL to address 436AH (system status flags).
  • Bit 7 = MINI-DOS active
  • Bit 6 = DOS-CALL active
  • Bit 5 = command processing state
  • Bit 4 = additional state flag
4E41
RES 5,(HL) CB AE
RESet bit 5 at 436AH. Clear the "at command prompt" flag since we're now processing a command.
  • Bit 7 = MINI-DOS active
  • Bit 6 = DOS-CALL active
  • Bit 5 = command processing state
  • Bit 4 = additional state flag
4E43
LD HL,4318H 21 18 43
Point Register Pair HL to address 4318H, the DOS command buffer.
4E46
LD B,50H 06 50
Load Register B with 50H (80 decimal), the maximum command buffer size.

[LOOP START] Copy the command from DE to the DOS command buffer at 4318H, converting to uppercase via 45B5H.

4E48
LD A,(HL) 7E
Load Register A with the current character in the destination buffer (for initial check).
4E49
CP 0DH FE 0D
Compare Register A against 0DH (Carriage Return). Check if we've reached end of existing buffer content.
4E4B
RET Z C8
If the Z FLAG is set (found CR, empty command), RETurn immediately (to 4408H then 402DH).
4E4C
PUSH HL E5
Save destination pointer HL onto the stack.
4E4D
LD A,(DE) 1A
Load Register A with the next character from the source command at DE.
4E4E
INC DE 13
INCrement DE to point to the next source character.
4E4F
GOSUB to 45B5H to convert character in A to uppercase if it's a lowercase letter.
4E52
CP 0DH FE 0D
Compare Register A against 0DH (Carriage Return). Check if end of source command.
4E54
LD (HL),A 77
Store the (possibly uppercased) character at the destination buffer location.
4E55
INC HL 23
INCrement HL to point to the next destination position.
4E56
If the Z FLAG is set (character was CR, end of command), JUMP to 4E5FH to finish copy.
4E58
[LOOP] DECrement B and Jump if Not Zero back to 4E4DH to copy next character.

Command too long - return error code 36H (LINE TOO LONG).

4E5A
POP AF F1
Discard the saved HL from the stack.
4E5B
LD A,36H 3E 36
Load Register A with error code 36H (54 decimal = "LINE TOO LONG").
4E5D
OR A B7
OR Register A with itself to set NZ flag indicating error.
4E5E
RET C9
RETurn with error code in A.

Command copied successfully. Check for "R" (recall) command.

4E5F
LD A,(436DH) 3A 6D 43
Load Register A with the value from 436DH, a DOS system flag byte.
  • Bit 5 = R command repeat flag
4E62
BIT 5,A CB 6F
Test bit 5 of the flags. This checks if the "R" command feature is enabled.
4E64
If the Z FLAG is set (R command disabled), JUMP to 4E75H to skip R command check.
4E66
LD HL,(4318H) 2A 18 43
Load Register Pair HL with the first two bytes from the command buffer (command string start).
4E69
LD DE,0D52H 11 52 0D
Load Register Pair DE with 0D52H. This is R (52H) followed by CR (0DH) - the "R" recall command.
4E6C
RST 18H DF
Execute RST 18H to compare HL with DE (Model I Level II BASIC compare routine).
4E6D
If the NZ FLAG is set (command is not "R"), JUMP to 4E75H to continue with normal parsing.

The "R" command was entered - recall the previous command.

4E6F
LD HL,(43A7H) 2A A7 43
Load Register Pair HL with the previous command pointer from 43A7H.
4E72
LD (4318H),HL 22 18 43
Store the previous command pointer at 4318H, effectively recalling the last command.

Continue with command lookup in command table.

4E75
POP HL E1
Restore HL (command buffer position) from the stack.
4E76
LD DE,4F58H 11 58 4F
Point Register Pair DE to address 4F58H, the start of the DOS command name table.

[LOOP START] Compare command against entries in the command table. Each table entry has the command name followed by attribute byte and jump address.

4E79
PUSH HL E5
Save the current command buffer pointer onto the stack.
4E7A
LD A,(DE) 1A
Load Register A with a character from the command table entry.
4E7B
CP (HL) BE
Compare table character against the corresponding command buffer character.
4E7C
INC DE 13
INCrement DE to point to the next table character.
4E7D
INC HL 23
INCrement HL to point to the next command buffer character.
4E7E
[LOOP] If the Z FLAG is set (characters matched), LOOP BACK to 4E7AH to compare next character.

Characters didn't match. Check if we've matched enough (bit 7 of table char indicates end of command name).

4E80
DEC HL 2B
DECrement HL to point back to the mismatched command buffer character.
4E81
DEC DE 1B
DECrement DE to point back to the mismatched table character.
4E82
RLCA 07
Rotate Register A left. This moves bit 7 into the Carry flag. Bit 7 set means end of command name.
4E83
If the NO CARRY FLAG is set (bit 7 was 0, not end of name), JUMP to 4E8AH to try next table entry.

Bit 7 was set - we reached end of table command name. Now check if input command also ended here.

4E85
GOSUB to 4CD5H to check if the command buffer character at (HL) is a valid delimiter (space, comma, CR, etc.).
4E88
If the NO CARRY FLAG is set (valid delimiter found, command matched!), JUMP to 4EA7H to execute the command.

Command name in table doesn't match. Skip to next table entry.

4E8A
POP HL E1
Restore HL (original command buffer start) from the stack.
4E8B
LD A,(DE) 1A
Load Register A with the current table character.
4E8C
RLCA 07
Rotate A left to check if bit 7 is set (end of command name).
4E8D
INC DE 13
INCrement DE past this character.
4E8E
[LOOP] If the NO CARRY FLAG is set (bit 7 was 0), LOOP BACK to 4E8BH to skip more characters.

Reached end of this table entry's name. Skip the 2-byte attribute and address that follow.

4E90
INC DE 13
INCrement DE past the attribute byte.
4E91
INC DE 13
INCrement DE past the address high byte.
4E92
LD A,(DE) 1A
Load Register A with the next byte (start of next command name, or 00H if end of table).
4E93
OR A B7
OR Register A with itself to check if it's zero (end of table).
4E94
[LOOP] If the NZ FLAG is set (not end of table), LOOP BACK to 4E79H to try next command.

End of command table - command not found. Check if it might be a * (asterisk/star) command for running programs.

4E96
LD BC,E443H 01 43 E4
Load Register Pair BC with E443H. B=E4H is a SVC code, C=43H is parameter for RST 28H call.
4E99
LD D,41H 16 41
Load Register D with 41H as parameter for the unrecognized command handler.
4E9B
LD A,(HL) 7E
Load Register A with the first character of the command.
4E9C
CP 2AH FE 2A
Compare Register A against * (2AH = asterisk). Check if this is a "run program" command.
4E9E
If the NZ FLAG is set (not asterisk), JUMP to 4EB0H to try to execute as unrecognized command.

Asterisk command - invoke RST 28H to load and run a program file.

4EA0
LD A,EBH 3E EB
Load Register A with EBH as SVC function code for RST 28H.
4EA2
LD C,07H 0E 07
Load Register C with 07H as parameter.
4EA4
RST 28H EF
Execute DOS Supervisor Call to load and run the program specified after the asterisk.
4EA5
POP BC C1
Clean up stack by popping BC.
4EA6
RET C9
RETurn to caller.

4EA7H - COMMAND FOUND - EXECUTE HANDLER

A matching command was found in the table. DE points to the attribute byte. Extract the attribute and jump address, then execute the command.

4EA7
POP BC C1
Discard the saved command buffer start from the stack.
4EA8
LD A,(DE) 1A
Load Register A with the attribute byte from the command table entry.
4EA9
LD C,A 4F
Copy the attribute byte to Register C.
4EAA
INC DE 13
INCrement DE to point to the low byte of the jump address.
4EAB
LD A,(DE) 1A
Load Register A with the low byte of the command handler address.
4EAC
LD B,A 47
Copy the low address byte to Register B.
4EAD
INC DE 13
INCrement DE to point to the high byte of the jump address.
4EAE
LD A,(DE) 1A
Load Register A with the high byte of the command handler address.
4EAF
LD D,A 57
Copy the high address byte to Register D. Now D contains high byte, B contains low byte.

Check command attributes and permissions before executing.

4EB0
BIT 6,C CB 71
Test bit 6 of the attribute byte in C. This indicates if the command requires special privileges.
4EB2
If the Z FLAG is set (bit 6 was 0, no special privilege needed), JUMP to 4EC3H to continue.
4EB4
LD A,(436AH) 3A 6A 43
Load Register A with the DOS status flags from 436AH.
  • Bit 7 = MINI-DOS active
  • Bit 6 = DOS-CALL active
  • Bit 5 = command processing state
  • Bit 4 = additional state flag
4EB7
RLCA 07
Rotate A left to check if bit 7 (MINI-DOS mode) is active.
4EB8
If the NO CARRY FLAG is set (not MINI-DOS), JUMP to 4EC3H to continue.
4EBA
AND 80H E6 80
AND Register A with 80H to isolate the original bit 6 (now in position 7 after RLCA).
4EBC
LD A,38H 3E 38
Load Register A with error code 38H (56 decimal = "ILLEGAL WHILE IN MINI-DOS").
4EBE
If the NZ FLAG is set (privileged command in MINI-DOS), JUMP to 4D8BH to exit with error.
4EC1
OR A B7
OR A to set flags based on A value.
4EC2
RET C9
RETurn (this path shouldn't normally execute).

Extract module number from attribute and prepare to load/execute the command handler.

4EC3
LD A,C 79
Load Register A with the attribute byte from C.
4EC4
AND 1FHAND 00011111 E6 1F
AND Register A with 1FH to extract bits 0-4 (the SYS module number).
4EC6
LD C,A 4F
Store the module number back in C.
4EC7
PUSH BC C5
Save BC (B=low addr, C=module number) onto the stack.
4EC8
LD C,D 4A
Load Register C with D (high byte of handler address).
4EC9
LD A,C 79
Load Register A with C (now the high address byte / additional attribute info).
4ECA
AND C0H E6 C0
AND Register A with C0H to isolate the top 2 bits (command type indicators).
4ECC
If the NZ FLAG is set (special type), GOSUB to 514DH to parse filespec into buffer at 4480H.
4ECF
If the NZ FLAG is set (error in filespec), JUMP to 4EF1H to handle error.
4ED1
BIT 5,C CB 69
Test bit 5 of C. This checks if command needs special parameter handling.
4ED3
If the Z FLAG is set (bit 5 was 0), JUMP to 4EF5H to skip additional processing.

Additional command parameter processing (for commands like CLTO, etc.).

4ED5
GOSUB to 4CD9H to skip spaces and get next non-space character in command.
4ED8
If the CARRY FLAG is set (error), JUMP to 4EA5H to clean up and return.
4EDA
PUSH BC C5
Save BC onto the stack.
4EDB
LD BC,51ADH 01 AD 51
Load Register Pair BC with 51ADH, pointing to the string "CLTO" (or similar short command abbreviation).
4EDE
GOSUB to 4CC5H to compare command parameter against the string at BC.
4EE1
POP BC C1
Restore BC from the stack.
4EE2
If the NZ FLAG is set (didn't match "CLTO"), JUMP to 4EE9H to continue.
4EE4
GOSUB to 4CD9H to skip to next parameter.
4EE7
If the CARRY FLAG is set (error), JUMP to 4EA5H to exit.
4EE9
PUSH DE D9
Save DE onto the stack.
4EEA
LD DE,51E0H 11 E0 51
Point Register Pair DE to address 51E0H, a parameter buffer area.
4EED
GOSUB to 5150H to parse filespec from command line.
4EF0
POP DE D1
Restore DE from the stack.
4EF1
LD A,30H 3E 30
Load Register A with error code 30H (48 decimal = "FILE SPEC ERROR").
4EF3
If the NZ FLAG is set (filespec error), JUMP to 4EA5H to return error.

Check more attribute bits and continue setup.

4EF5
BIT 4,C CB 61
Test bit 4 of C (attribute byte). Check if delimiter check is needed.
4EF7
If the NZ FLAG is set (bit 4 was 1), GOSUB to 4CD5H to check for valid delimiter.
4EFA
If the NZ FLAG is set (invalid delimiter), JUMP to 4EA5H to return error.
4EFC
BIT 3,C CB 59
Test bit 3 of C (attribute byte). Check if HL should be pushed for the handler.
4EFE
If the Z FLAG is set (bit 3 was 0), JUMP to 4F02H to skip EX (SP),HL.
4F00
EX (SP),HL E3
Exchange HL with top of stack. Push current HL and retrieve saved value.
4F01
PUSH HL E5
Save HL (now the exchanged value) onto the stack.

Check attribute bits 0-2 for additional handler setup.

4F02
LD A,C 79
Load Register A with the attribute byte from C.
4F03
AND 07HAND 00000111 E6 07
AND Register A with 07H to isolate bits 0-2 (parameter count).
4F05
If the Z FLAG is set (parameter count is 0), JUMP to 4F15H to skip parameter table lookup.
4F07
PUSH HL E5
Save HL onto the stack.
4F08
LD HL,51A4H 21 A4 51
Point Register Pair HL to address 51A4H, a table of short command abbreviations.

[LOOP] Calculate offset into abbreviation table based on parameter count.

4F0B
INC HL 23
INCrement HL to advance through the table.
4F0C
INC HL 23
INCrement HL again (each entry is 3 bytes).
4F0D
INC HL 23
INCrement HL again.
4F0E
DEC A 3D
DECrement A (parameter count).
4F0F
[LOOP] If the NZ FLAG is set (more iterations needed), LOOP BACK to 4F0BH.
4F11
GOSUB to 4F2AH to insert drive specification into the command (if needed).
4F14
POP HL E1
Restore HL from the stack.

Final setup before calling the command handler.

4F15
LD A,C 79
Load Register A with the attribute byte from C.
4F16
LD BC,49D3H 01 D3 49
Load Register Pair BC with 49D3H, a return address in the DOS resident module.
4F19
PUSH BC C5
Push the return address onto the stack.
4F1A
BIT 7,A CB 7F
Test bit 7 of the attribute byte. This indicates if the command handler needs to be loaded from disk.
4F1C
RET Z C8
If the Z FLAG is set (bit 7 was 0, handler already in memory), RETurn. The handler address is already on the stack.

Handler needs to be loaded from disk. Set up RST 28H call to load the SYS module.

4F1D
LD B,00H 06 00
Load Register B with 00H.
4F1F
LD HL,4200H 21 00 42
Point Register Pair HL to address 4200H, the DOS sector buffer where the module will be loaded.
4F22
BIT 6,A CB 77
Test bit 6 of the attribute byte to determine which load routine to use.
4F24
If the Z FLAG is set (bit 6 was 0), JUMP to 4424H to use one load method.
4F27
Otherwise, JUMP to 4420H to use alternate load method. Both load the SYS module and execute it.

4F2AH - INSERT DRIVE SPECIFICATION INTO FILESPEC

This routine inserts a drive specification (e.g., "0/") at the beginning of a filename if one isn't already present. DE points to the command buffer, HL points to a table of 3-byte entries containing default drive info.

4F2A
PUSH DE D5
Save DE (command buffer pointer) onto the stack.
4F2B
PUSH BC C5
Save BC onto the stack.
4F2C
LD BC,091CH 01 1C 09
Load Register Pair BC with 091CH. B=09H (9 = max filename chars to scan), C=1CH (28 = filename field size).

Top of loop to scan the filename to see if it already has a drive spec or colon.

4F2F
LD A,(DE) 1A
Load Register A with the current character from the command buffer.
4F30
CP 3AH FE 3A
Compare Register A against : (3AH = colon). Check if this is a drive separator.
4F32
If the Z FLAG is set (found colon), JUMP to 4F3EH - drive spec exists, just insert path.
4F34
CP 2FH FE 2F
Compare Register A against / (2FH = slash). Check if this is a path separator.
4F36
If the CARRY FLAG is set (char < 2FH, meaning delimiter found), JUMP to 4F3EH.
4F38
If the Z FLAG is set (found slash), JUMP to 4F55H - drive spec already exists.
4F3A
DEC C 0D
DECrement the filename field size counter C.
4F3B
INC DE 13
INCrement DE to point to next character.
4F3C
[LOOP] DECrement B and Jump if Not Zero back to 4F2FH to check next character.

No drive spec found - need to insert one. First, shift the filename right to make room.

4F3E
INC HL 23
INCrement HL to skip first byte of drive info table entry.
4F3F
INC HL 23
INCrement HL to skip second byte.
4F40
PUSH HL E5
Save HL (pointing to drive number byte) onto the stack.
4F41
EX DE,HL EB
Exchange DE and HL. HL now points to filename, DE is the table pointer.
4F42
LD B,00H 06 00
Load Register B with 00H, making BC = C (the remaining field count).
4F44
ADD HL,BC 09
ADD BC to HL to point to the end of the filename.
4F45
LD D,H 54
Copy H to D.
4F46
LD E,L 5D
Copy L to E. DE now equals HL (end of current filename).
4F47
DEC HL 2B
DECrement HL to point one byte before (source for LDDR).
4F48
INC DE 13
INCrement DE by 3 to create space for "n/" drive prefix.
4F49
INC DE 13
INCrement DE again.
4F4A
INC DE 13
INCrement DE once more. DE now points 3 bytes past end.
4F4B
LDDR ED B8
LDDR - Block move bytes from HL to DE, decrementing, repeat for BC bytes. This shifts filename right by 3 positions.
4F4D
POP HL E1
Restore HL (pointing to drive info in table) from the stack.
4F4E
LD C,03H 0E 03
Load Register C with 03H (3 bytes to copy: drive number, slash, maybe colon).
4F50
LDDR ED B8
LDDR - Copy 3 bytes from drive info table to the filename area.
4F52
LD A,2FH 3E 2F
Load Register A with / (2FH = slash).
4F54
LD (DE),A 12
Store the slash at the position pointed to by DE (start of path).

Clean up and return.

4F55
POP BC C1
Restore BC from the stack.
4F56
POP DE D1
Restore DE from the stack.
4F57
RET C9
RETurn to caller.

4F58H - DOS COMMAND NAME TABLE

This is the DOS Command Name Table. Each entry contains: the command name (with bit 7 set on the last character), an attribute byte, and a 2-byte handler address. The table is terminated by a 00H byte. The disassembler has interpreted these as instructions, but they are actually ASCII data.

4F58
Data: "APPEND" 41 50 50 45 4E C4
APPEND command name. Last char 'D' has bit 7 set (44H | 80H = C4H).
Attribute: 68H, Address: 0068H (points to handler)

The remaining entries follow the same pattern. Here are a few notable ones identified in the data:

4F61
Data: "ATTRIB" 41 54 54 52 49 C2
ATTRIB - Set file attributes command.
4F6A
Data: "AUTO" 41 55 54 CF
AUTO - Auto-execute command on boot.
4F71
Data: "BASIC" 42 41 53 49 C3
BASIC - Enter BASIC interpreter.
4F7A
Data: "BLINK" 42 4C 49 4E CB
BLINK - Set cursor blink rate.
4F82
Data: "BOOT" 42 4F 4F D4
BOOT - Reboot the system.
4F8A
Data: "BREAK" 42 52 45 41 CB
BREAK - Enable/disable BREAK key.
4F91
Data: "CHAIN" 43 48 41 49 CE
CHAIN - Execute commands from file.
4F99
Data: "CHNON" 43 48 4E 4F CE
CHNON - Continue chaining.
4FA1
Data: "CLEAR" 43 4C 45 41 D2
CLEAR - Clear routing.
4FA9
Data: "CLOCK" 43 4C 4F 43 CB
CLOCK - Display/set clock.
4FB1
Data: "CLS" 43 4C D3
CLS - Clear screen.
4FB7
Data: "COPY" 43 4F 50 D9
COPY - Copy files/disks.
4FBE
Data: "CREATE" 43 52 45 41 54 C5
CREATE - Create a file.
4FC7
Data: "DATE" 44 41 54 C5
DATE - Display/set date.
4FCE
Data: "DEBUG" 44 45 42 55 C7
DEBUG - Enter debugger.
4FD6
Data: "DIR" 44 49 D2
DIR - Display directory.
4FDC
Data: "DO" 44 CF
DO - Same as CHAIN.
4FE1
Data: "DUMP" 44 55 4D D0
DUMP - Dump memory/file.
4FE8
Data: "ERROR" 45 52 52 4F D2
ERROR - Display error message.
4FF0
Data: "FORMAT" 46 4F 52 4D 41 D4
FORMAT - Format a diskette.
4FF9
Data: "FREE" 46 52 45 C5
FREE - Display free space.
5000
Data: "HIMEM" 48 49 4D 45 CD
HIMEM - Set high memory limit.
5008
Data: "JKL" 4A 4B CC
JKL - Print screen function.
500D
Data: "KILL" 4B 49 4C CC
KILL - Delete a file.
5015
Data: "LC" 4C C3
LC - Lower case toggle.
501A
Data: "LCDVR" 4C 43 44 56 D2
LCDVR - Lower case driver.
5022
Data: "LIB" 4C 49 C2
LIB - Display command library.
5028
Data: "LIST" 4C 49 53 D4
LIST - List a file.
502F
Data: "LOAD" 4C 4F 41 C4
LOAD - Load a program.
5036
Data: "MDBORT" 4D 44 42 4F 52 D4
MDBORT - MINI-DOS abort.
503F
Data: "MDCOPY" 4D 44 43 4F 50 D9
MDCOPY - MINI-DOS copy.
5048
Data: "MDRET" 4D 44 52 45 D4
MDRET - MINI-DOS return.
5050
Data: "PAUSE" 50 41 55 53 C5
PAUSE - Pause and wait for keypress.
5058
Data: "PDRIVE" 50 44 52 49 56 C5
PDRIVE - Physical drive setup.
5061
Data: "PRINT" 50 52 49 4E D4
PRINT - Print a file.
5069
Data: "PROT" 50 52 4F D4
PROT - Protect disk.
5070
Data: "PURGE" 50 55 52 47 C5
PURGE - Purge files.
5078
Data: "R" D2
R - Recall previous command.
507C
Data: "RENAME" 52 45 4E 41 4D C5
RENAME - Rename a file.
5086
Data: "ROUTE" 52 4F 55 54 C5
ROUTE - Route I/O.
508D
Data: "STMT" 53 54 4D D4
STMT - Statement.
5094
Data: "SYSTEM" 53 59 53 54 45 CD
SYSTEM - System options.
509D
Data: "TIME" 54 49 4D C5
TIME - Display/set time.
50A4
Data: "VERIFY" 56 45 52 49 46 D9
VERIFY - Verify disk writes.
50AD
Data: "WRDIRP" 57 52 44 49 52 D0
WRDIRP - Write directory protected.
50B5
Data: 00H 00H 00 00
End of command table marker (two zero bytes).

50B7H - LIB COMMAND - DISPLAY LIBRARY LIST

This routine implements the LIB command, which displays a list of all available DOS commands from the command table. It walks through the table at 4F58H and displays each command name, formatting them in columns.

50B7
LD HL,4F58H 21 58 4F
Point Register Pair HL to address 4F58H, the start of the command name table.
50BA
LD C,08H 0E 08
Load Register C with 08H (8), the number of commands per line before a carriage return.

[LOOP START] - Process each command table entry.

50BC
LD B,08H 06 08
Load Register B with 08H (8), the column width for each command name.

[INNER LOOP START] - Display characters of one command name.

50BE
LD A,(HL) 7E
Load Register A with the current character from the command name.
50BF
BIT 7,A CB 7F
Test bit 7 of the character. If set, this is the last character of the command name.
50C1
INC HL 23
INCrement HL to point to the next character.
50C2
If the NZ FLAG is set (bit 7 was 1, last char), JUMP to 50C9H to skip remaining column padding.
50C4
GOSUB to 519FH to display the character in A.
50C7
[INNER LOOP] DECrement B and Jump if Not Zero back to 50BEH to display next character.

Done with this command name - skip the attribute and address bytes.

50C9
INC HL 23
INCrement HL past the attribute byte.
50CA
INC HL 23
INCrement HL past the address bytes.
50CB
LD A,(HL) 7E
Load Register A with the next byte (start of next command or 00H if end).
50CC
OR A B7
OR A with itself to check if zero (end of table).
50CD
If the Z FLAG is set (end of table), JUMP to 519DH to output final CR and return.
50D0
DEC C 0D
DECrement the column counter C.
50D1
If the Z FLAG is set (column counter reached 0), GOSUB to 519DH to output CR for new line.
50D4
If the Z FLAG is set (new line started), JUMP BACK to 50BAH to reset column counter.
50D6
GOSUB to 5195H to pad with spaces to align columns.
50D9
[MAIN LOOP] JUMP BACK to 50BCH to process the next command name.

50DBH - MINI-DOS ENTRY HANDLER

This routine handles entry into MINI-DOS mode. MINI-DOS is a special feature of NEWDOS/80 that allows the user to execute DOS commands while a user program is suspended (typically entered by pressing DFG simultaneously). This routine saves the current program state and prepares the system for MINI-DOS operation.

50DB
DI F3
Disable interrupts to prevent any interference during the critical state-saving process.
50DC
GOSUB to 512BH to save all CPU registers onto the stack. This preserves the complete state of the interrupted program.
50DF
LD HL,436AH 21 6A 43
Point Register Pair HL to the DOS system flags byte at 436AH (part of SYSTEM storage area 4368H-4370H).
  • Bit 7 = MINI-DOS active
  • Bit 6 = DOS-CALL active
  • Bit 5 = command processing state
  • Bit 4 = additional state flag
50E2
LD A,(HL) 7E
Load Register A with the current DOS system flags from 436AH.
  • Bit 7 = MINI-DOS active
  • Bit 6 = DOS-CALL active
  • Bit 5 = command processing state
  • Bit 4 = additional state flag
50E3
AND C0H E6 C0
Mask off all but the top two bits (bits 7 and 6) of the system flags. These bits indicate special DOS states.
50E5
If either bit 7 or bit 6 is set (meaning DOS is already in a special state like DOS-CALL or MINI-DOS active), JUMP to 511AH to abort the MINI-DOS entry attempt.

At this point, we've confirmed DOS is in a normal state and can safely enter MINI-DOS mode. Now save the current context and set up MINI-DOS.

50E7
LD A,(4022H) 3A 22 40
Load Register A with the current cursor blink state from 4022H. This will be restored when exiting MINI-DOS.
50EA
PUSH AF F5
Save the cursor blink state onto the stack for later restoration.
50EB
LD (439BH),SP ED 73 9B 43
Store the current stack pointer into 439BH (DOS storage area). This saves the exact stack position so we can return to the interrupted program later.
50EF
SET 7,(HL) CB FE
Set bit 7 of the system flags at 436AH. This flag indicates that MINI-DOS mode is now active.
  • Bit 7 = MINI-DOS active
  • Bit 6 = DOS-CALL active
  • Bit 5 = command processing state
  • Bit 4 = additional state flag
50F1
EI FB
Re-enable interrupts now that the critical state-saving is complete.
50F2
LD A,0DH 3E 0D
Load Register A with 0DH (carriage return character) to start output on a new line.
50F4
GOSUB to ROM routine at 0033H to display the carriage return, moving cursor to start of next line.
50F7
JUMP to 4D8AH to enter the DOS command loop. DOS will display "MINI-NEWDOS/80 READY" and await user commands.

50FAH - MINI-DOS EXIT HANDLER (MDRET Command)

This routine handles exiting from MINI-DOS mode and returning to the interrupted user program. It corresponds to the MDRET DOS command. The routine restores all saved CPU state and resumes execution of the suspended program.

50FA
LD HL,436AH 21 6A 43
Point Register Pair HL to the DOS system flags byte at 436AH.
  • Bit 7 = MINI-DOS active
  • Bit 6 = DOS-CALL active
  • Bit 5 = command processing state
  • Bit 4 = additional state flag
50FD
BIT 7,(HL) CB 7E
Test bit 7 of the system flags to verify that MINI-DOS mode is actually active.
50FF
If bit 7 is NOT set (MINI-DOS not active), JUMP to 4D44H to return error code 2AH (invalid command in current context).

MINI-DOS mode is confirmed active. Now restore the saved state and return to the interrupted program.

5102
LD SP,(439BH) ED 7B 9B 43
Restore the stack pointer from 439BH to the exact position it was at when MINI-DOS was entered.
5106
LD A,0EH 3E 0E
Load Register A with 0EH (cursor OFF control code).
5108
GOSUB to ROM routine at 0033H to turn off the cursor.
510B
POP AF F1
Restore the original cursor blink state (saved at 50EAH) from the stack into Register A.
510C
OR A B7
Test if the original cursor state was zero (cursor was off).
510D
LD B,A 47
Copy the cursor state to Register B for safekeeping.
510E
LD A,0FH 3E 0F
Load Register A with 0FH (cursor ON control code).
5110
If the Z FLAG is set (original cursor state was zero/off), GOSUB to ROM routine at 0033H to turn cursor back on. Otherwise skip this call.
5113
LD A,B 78
Restore the cursor state value from Register B back to Register A.
5114
LD (4022H),A 32 22 40
Store the cursor state back to 4022H, fully restoring the original cursor configuration.
5117
DI F3
Disable interrupts for the critical register restoration process.
5118
RES 7,(HL) CB BE
Clear bit 7 of the system flags at 436AH, indicating that MINI-DOS mode is no longer active.
  • Bit 7 = MINI-DOS active
  • Bit 6 = DOS-CALL active
  • Bit 5 = command processing state
  • Bit 4 = additional state flag

511AH - REGISTER RESTORATION AND RETURN

This routine restores all CPU registers from the stack and returns to the caller. It is used both as the exit path from MINI-DOS (MDRET) and as an abort path when MINI-DOS entry is rejected.

511A
XOR A AF
Set Register A to zero and clear all flags. This indicates successful completion (no error).
511B
EX AF,AF' 08
Exchange Register AF with the alternate register set AF'. This preserves the zero/success status.
511C
POP IY FD E1
Restore Register Pair IY from the stack.
511E
POP IX DD E1
Restore Register Pair IX from the stack.
5120
POP AF F1
Restore Register Pair AF from the stack (this was the alternate AF').
5121
POP BC C1
Restore Register Pair BC from the stack (alternate set).
5122
POP DE D1
Restore Register Pair DE from the stack (alternate set).
5123
POP HL E1
Restore Register Pair HL from the stack (alternate set).
5124
EXX D9
Exchange BC, DE, HL with their alternate register sets BC', DE', HL'. Now we're working with the main registers.
5125
POP BC C1
Restore Register Pair BC (main set) from the stack.
5126
POP DE D1
Restore Register Pair DE (main set) from the stack.
5127
POP HL E1
Restore Register Pair HL (main set) from the stack.
5128
EX AF,AF' 08
Exchange AF with AF' to restore the original AF register pair.
5129
EI FB
Re-enable interrupts now that register restoration is complete.
512A
RET C9
Return to the interrupted program. Execution resumes exactly where it was suspended.

512BH - SAVE ALL REGISTERS TO STACK

This routine saves all CPU registers (including alternate register sets, IX, and IY) onto the stack. It is called at the start of operations that need to preserve the complete CPU state, such as entering MINI-DOS or handling DOS-CALL.

512B
POP AF F1
Pop the return address from the stack into AF. This is necessary because we need to save registers but the return address is on top of the stack.
512C
PUSH HL E5
Save Register Pair HL (main set) onto the stack.
512D
PUSH DE D5
Save Register Pair DE (main set) onto the stack.
512E
PUSH BC C5
Save Register Pair BC (main set) onto the stack.
512F
EX AF,AF' 08
Exchange AF with the alternate AF' register. Now A contains the return address high byte.
5130
EXX D9
Exchange BC, DE, HL with their alternate sets BC', DE', HL'. Now we can save the alternate registers.
5131
PUSH HL E5
Save Register Pair HL' (alternate set) onto the stack.
5132
PUSH DE D5
Save Register Pair DE' (alternate set) onto the stack.
5133
PUSH BC C5
Save Register Pair BC' (alternate set) onto the stack.
5134
PUSH AF F5
Save Register Pair AF' (alternate set, currently in AF) onto the stack.
5135
PUSH IX DD E5
Save Index Register IX onto the stack.
5137
PUSH IY FD E5
Save Index Register IY onto the stack.
5139
EXX D9
Exchange back to the main register set (BC, DE, HL).
513A
EX AF,AF' 08
Exchange back to the main AF register (which contains our return address).
513B
PUSH AF F5
Push the return address back onto the stack so RET will work correctly.
513C
RET C9
Return to the caller. All registers have been saved on the stack.

513DH - SKIP FILENAME EXTENSION HANDLER

This routine processes a filename and skips past any extension marker (period or slash) to position HL at the start of the actual filename or past the extension.

513D
GOSUB to 5150H to parse/copy filename characters.
5140
PUSH AF F5
Save the flags from the parsing operation.
5141
LD A,(HL) 7E
Load Register A with the current character pointed to by HL.
5142
SUB 03H D6 03
Subtract 03H from Register A. Testing if the character is 03H (end of text marker).
5144
If the character was 03H (end of text), JUMP to 5148H.
5146
SUB 0AH D6 0A
Subtract 0AH more from Register A. Now testing if original was 0DH (carriage return). 03H + 0AH = 0DH.
5148
If the character was 0DH (carriage return), JUMP to 514BH to finish.
514A
INC HL 23
Advance HL to point to the next character in the buffer.
514B
POP AF F1
Restore the flags from the earlier parsing operation.
514C
RET C9
Return to the caller with HL positioned past the filename/extension.

514DH - PARSE FILENAME WITH DESTINATION BUFFER

Entry point that sets up a destination buffer address before calling the main filename parser.

514D
LD DE,4480H 11 80 44
Point Register Pair DE to 4480H, a buffer in the DOS main module area for storing the parsed filename.

5150H - FILENAME PARSER

This routine parses a filename from the source buffer (pointed to by HL) and copies valid characters to the destination buffer (pointed to by DE). It handles special cases like asterisk wildcards and validates alphanumeric characters.

5150
PUSH DE D5
Save the destination buffer pointer onto the stack.
5151
LD B,20H 06 20
Load Register B with 20H (32 decimal) as a maximum character count for the filename parsing loop.
5153
GOSUB to 515AH to perform the actual character-by-character filename parsing.
5156
POP DE D1
Restore the original destination buffer pointer from the stack.
5157
LD B,00H 06 00
Set Register B to zero, indicating successful completion or the final character count.
5159
RET C9
Return to the caller.

515AH - CHARACTER-BY-CHARACTER FILENAME PARSER

This is the inner parsing loop that processes each character of a filename. It handles wildcards (*), validates alphanumeric characters, and copies valid characters to the destination buffer. Called with HL pointing to source, DE pointing to destination, and B containing the maximum character count.

515A
LD A,(HL) 7E
Load Register A with the current source character pointed to by HL.
515B
CP 2AH FE 2A
Compare the character against 2AH (ASCII: * asterisk wildcard). If equal, Z FLAG is set.
515D
If the character is NOT an asterisk, JUMP to 5163H to process it as a normal character.

Character is an asterisk (*) wildcard - copy it and advance pointers.

515F
LD (DE),A 12
Store the asterisk character into the destination buffer.
5160
INC DE 13
Advance the destination pointer to the next position.
5161
INC HL 23
Advance the source pointer to the next character.
5162
DEC B 05
Decrement the character counter.

[LOOP START] - Main character validation loop begins here.

5163
PUSH HL E5
Save the current source pointer onto the stack.
5164
LD A,(HL) 7E
Load Register A with the current character.
5165
SUB 30H D6 30
Subtract 30H (ASCII '0') from the character. This converts ASCII digits '0'-'9' to values 0-9.
5167
CP 0AH FE 0A
Compare against 0AH (10 decimal). If the result is less than 10, the original character was a digit '0'-'9'.
5169
GOSUB to 5189H to check if the character is alphabetic (if not a digit). Returns CARRY if valid alphanumeric.
516C
If NO CARRY (character is not alphanumeric), JUMP to 5184H to finish with an error/end condition.

Character passed the digit test or was confirmed alphabetic. Now check for special delimiters.

516E
LD A,(HL) 7E
Reload the original character from the source.
516F
SUB 2EH D6 2E
Subtract 2EH (ASCII '.') from the character. Testing for period (filename/extension separator).
5171
CP 0DH FE 0D
Compare against 0DH. If the original character was between 2EH ('.') and 3AH (':'), this checks range.
5173
GOSUB to 5189H for additional character validation.
5176
If CARRY is set (character is a valid part of filename), JUMP to 517EH to copy it.

Character is a delimiter (like period) - mark end of filename portion.

5178
LD A,03H 3E 03
Load Register A with 03H (end-of-text marker).
517A
LD (DE),A 12
Store the end-of-text marker into the destination buffer.
517B
POP AF F1
Discard the saved HL (stored at 5163H) by popping into AF.
517C
XOR A AF
Set Register A to zero and clear flags (Z FLAG set, indicating success).
517D
RET C9
Return to the caller with Z FLAG set indicating successful parse.

Character is valid - copy it to destination and continue loop.

517E
LD A,(HL) 7E
Load the valid character from the source.
517F
LD (DE),A 12
Store the character into the destination buffer.
5180
INC DE 13
Advance the destination pointer.
5181
INC HL 23
Advance the source pointer.
5182
[LOOP] Decrement B and if not zero, LOOP BACK to 516EH to process the next character.

Reached end of loop (maximum characters processed) or hit invalid character.

5184
OR 01H F6 01
OR Register A with 01H to ensure NZ FLAG is set (indicating we didn't end cleanly on a delimiter).
5186
POP HL E1
Restore the source pointer from the stack.
5187
LD A,(HL) 7E
Load the current character into Register A (the character that caused loop exit).
5188
RET C9
Return with NZ FLAG set and the terminating character in A.

5189H - ALPHABETIC CHARACTER CHECK

This subroutine checks if the character at (HL) is an alphabetic letter (A-Z or a-z). Returns with CARRY set if the character is alphabetic. If called after a digit test fails, it determines if the character is a valid filename character.

5189
RET C D8
If CARRY is already set (from previous digit check indicating valid digit), return immediately - character is valid.
518A
LD A,(HL) 7E
Load the character from the source buffer.
518B
SUB 41H D6 41
Subtract 41H (ASCII 'A') from the character. This normalizes uppercase letters to 0-25.
518D
CP 1AH FE 1A
Compare against 1AH (26 decimal). If result is less than 26, the character was 'A'-'Z'.
518F
RET C D8
If CARRY is set (character is uppercase letter 'A'-'Z'), return with CARRY indicating valid.

Not an uppercase letter - check for lowercase.

5190
SUB 20H D6 20
Subtract 20H more (the difference between lowercase and uppercase in ASCII). Now checking for 'a'-'z'.
5192
CP 1AH FE 1A
Compare against 1AH (26). If result is less than 26, the character was 'a'-'z'.
5194
RET C9
Return. CARRY set if lowercase letter, CARRY clear if not alphabetic.

5195H - DISPLAY MULTIPLE SPACES

This routine displays multiple space characters. Called with B containing the count of spaces to display.

5195
LD A,20H 3E 20
[LOOP START] Load Register A with 20H (ASCII space character).
5197
GOSUB to 519FH to display the space character.
519A
[LOOP] Decrement B and if not zero, LOOP BACK to 5195H to display another space.
519C
RET C9
Return after all spaces have been displayed.

519DH - DISPLAY CARRIAGE RETURN

This routine displays a carriage return character (0DH), moving the cursor to the beginning of the next line.

519D
LD A,0DH 3E 0D
Load Register A with 0DH (carriage return character).

519FH - DISPLAY CHARACTER WITH REGISTER PRESERVATION

This utility routine displays the character in Register A while preserving the DE register pair. This is important when DE is being used as a pointer during string operations.

519F
PUSH DE D5
Save Register Pair DE onto the stack.
51A0
PUSH AF F5
Save the character to be displayed (in A) and flags onto the stack.
51A1
GOSUB to ROM routine at 0033H to display the character at the current cursor position and advance the cursor.
51A4
POP AF F1
Restore Register A and flags from the stack.
51A5
POP DE D1
Restore Register Pair DE from the stack.
51A6
RET C9
Return to the caller with DE preserved.

51A7H - DOS COMMAND NAME STRINGS

This area contains ASCII strings used by DOS, including abbreviated command names. These are not executable code but data referenced by command lookup and display routines.

51A7
DB 'CMD' 43 4D 44
ASCII string "CMD" - Command file extension or CMD keyword.
51AA
DB 'JCL' 4A 43 4C
ASCII string "JCL" - Job Control Language file extension.
51AD
DB 'TO' 54 4F
ASCII string "TO" - Used in COPY command syntax (COPY filespec TO filespec).
51AF
NOP 00
Null terminator for the "TO" string.

51B0H - MINI-DOS READY MESSAGE

This is the "MINI-" prefix displayed before "NEWDOS/80 READY" when in MINI-DOS mode.

51B0
DB 'MINI-' 4D 49 4E 49 2D
ASCII string "MINI-" displayed as prefix when MINI-DOS is active.

51B5H - NEWDOS/80 READY MESSAGE

This is the main DOS prompt message displayed when DOS is ready for command input.

51B5
DB 'NEWDOS/80 READY' 4E 45 57 44 4F 53 2F 38 30 20 52 45 41 44 59
ASCII string "NEWDOS/80 READY" - the DOS command prompt message.
51C4
DB 0DH 0D
Carriage return terminator for the READY message.

51C5H - SYSTEM PARAMETER TABLE

This small table contains system configuration parameters used by various DOS routines.

51C5
DB 1CH 1C
System parameter: 1CH (28 decimal) - possibly a count or offset value.
51C6
DB 1FH 1F
System parameter: 1FH (31 decimal).
51C7
DB 03H 03
System parameter: 03H (3 decimal).
51C8
DB 00H 00
System parameter: 00H (null/zero).
51C9-51DFH
DB 00H (×23) 00 00 00 ...
Reserved/unused bytes initialized to zero. This padding fills space to 51DFH.

51E0H - END OF DOS OVERLAY AREA

The remaining bytes from 51E0H to 51FFH are reserved space at the end of the DOS overlay area. This area may be used for temporary storage or left as padding.

51E0-51FFH
DS 32 00 00 00 ...
Reserved space (32 bytes) at the end of the DOS overlay area. May be used as a working buffer by DOS commands.