TRSDOS v2.3 Disassembled

Background

TRSDOS was the DOS which Tandy supplied when a Model I user bought a Drive 0 kit. While there are a few different DOS’s available for the Model I, TRSDOS was the first and, as a result, the most simplistic. It required a minimum of 32K of RAM and at least one disk drive, although four disk drives were supported.

TRSDOS v2.3 is broken into two types of programs: The nucleaus and overlays/user programs.

  • Since some rudimentary disk support is hard coded into the Level II ROM, part of the nucleus (otherwise known as SYS0/SYS) loads into 4000H-4200H. This portion contains the jumps that were implemented in the ROM itself as well as an overlay loader, disk I/O services, the disk driver, TRACE and TIME displays, the interrupt service routine, all core resident data structures, 2 sector buffers and system initialization code. The actual program portion of the nucleus loads into RAM from 4200H-4E00H.
  • The remainder of TRSDOS v2.3 is overlay modules and user programs which are loaded on demand. To make the most of the little RAM available, only the nucleus stays in memory. In general, overlays load from 4E00H-5200H and utility programs load from 5200H.

TRSDOS v2.3 is NOT interrupt driven. It performs all of its tasks on demand. There are two library functions TRACE and CLOCK which do, however, make use of interrupts if involked.

OVERLAY FILES

BOOT/SYS

When a Model I is powered on or RESET, the LEVEL II ROM (from 0696H-06CBH) determines if the system has disks by polling the disk controller at 37ECH. If the controller exists, drive 0, track 0, sector 0 is loaded, byte by byte, by the ROM into 4200H-42FFH and then jumped to. So that the sector actually has a name on the diskette, that sector is called BOOT/SYS.

Loading a specific known-location single density single sector is easy. Finding and loading other files by name is a bit harder, so BOOT/SYS’s main job is to find SYS0/SYS and load SYS0/SYS into RAM.

A disassembly of BOOT/SYS can be found here.


SYS0/SYS (the “nucleus”)

As soon as SYS0/SYS is loaded into RAM by BOOT/SYS, it does the following:

  1. Disables interrupts.
  2. Selects interrupt “mode 1” (meaning that when interrupts are enabled, all interrupts will be vectored to 0038H).
  3. Initializes 5200H (the memory location used by user called programs).
  4. Calculates the memory size and puts that into 4049H.
  5. Initializes the device address table of 43B8H-43BFH.
  6. Initializes the device mnemonic table of 43C0H-43CCH.
  7. Loads an alternate keyboard driver into 43D8H-43FBH.
  8. Sets up a keyboard buffer.
  9. Copies the video driver address, video ram buffer address, printer driver address, and printer buffer into the device tables.
  10. Copies the keyboard DCB to 4358H-435FH.
  11. Puts the clock interrupt routine location and the disk interrupt routine location into the interrupt scan list at 405B and 4059, and then tells the interrupt controller that these exist.
  12. Sets DEBUG to DISABLED and sets up the clock interrupts.
  13. Displays the TRSDOS Banner.
  14. Checks for an ENTER key and either processes AUTO if none or loads SYS1/SYS to wait for a command.

A disassembly of SYS0/SYS can be found here.


SYS1/SYS

SYS1/SYS processes all commands and is TRSDOS’s command line interpreter. Once it sees an ENTER key, it determines if a library command or a user file has been requested. If a library command is found, either SYS1/SYS or SYS6/SYS will process it. If the command isn’t a library command, the SYS1/SYS assumes it is a program on the diskette and goes to find and execute it.

Since SYS1/SYS has so many different jobs to do, it can be involked with one of six options:

10 and 20: Read and process next command from the keyboard.

  1. Enable interrupts.
  2. Initialize an empty stack pointer to 41FEH.
  3. Test the system conditions flags (LEVEL II or TRSDOS, RUN active or not active, SYS6 loaded or not loaded, Chaining active or inactive, PROT allowed or disallowed, and DEBUG inactive or active).
  4. Display DOS READY and process the keyboard entry and 63 character keyboard buffer.
  5. If an ENTER key is pressed, jump to option 30.

30: Interpret the command in the command line buffer.

  1. Copy the command line to the system DCB at 4480H.
  2. Compare the command to a list Library commands embedded in SYS1/SYS and process if found.
  3. Compare the command to a list Library commands embedded in SYS6/SYS and process if found.
  4. Add a CMD suffix to the command line in the system DCB, and call the nucleus to load and execute it.

40: Move a string to the DCB and validate as a filename. DE points to the DCB and HL the address of the command line buffer. 8 characters are read, and if a “/” is next, then 3 characters and if a “.” is next, then 8 characters, and if a “:” is next, then 1 character. A 03H delimeter is put at the end.

50: Add a suffix to a command that is missing a suffix. DE points to the DCB and HL the address of the 3 character extension. 9 characters are tested, including for the possibility of a /, ., or : or a terminator. If / is found, then there is already an extension and the routine exits. If not, a 4 character hole is punched in the middle of the filename and “/CMD” is added.

60: Parse whatever parameters may come after the filename. Checks for parenthesis, commas, spaces, and a hex delimiter.

A disassembly of SYS1/SYS can be found here.


SYS2/SYS

SYS2/SYS handles the OPEN and INITIALIZE (i.e., NEW FILE) file management.

A disassembly of SYS2/SYS can be found here.


SYS3/SYS

SYS3/SYS handles the CLOSE and KILL file management.

A disassembly of SYS3/SYS can be found here.


SYS4/SYS

SYS4/SYS handles errors.

A disassembly of SYS4/SYS can be found here.


SYS5/SYS

SYS5/SYS handles DEBUG.

A disassembly of SYS5/SYS can be found here.


SYS6/SYS

A disassembly of SYS6/SYS can be found here.

SYS6/SYS handles most library functions


BASIC/CMD

A disassembly of BASIC/CMD can be found here.