svi-328.dev

MSYSGEN — 608M System Generation Program

Disassembly analysis of MSYSGEN.COM from the CP/M 2.27 system disk for the SVI-328 with SV-608M expansion. This utility copies the CP/M system tracks (boot sector + BIOS + CCP/BDOS) between floppy disks and the SV-608M hard disk.

Source: MSYSGEN.asm

Overview

MSYSGEN is the SV-608M equivalent of CP/M’s standard SYSGEN utility. It provides two operations:

User Interface

On startup, MSYSGEN prints:

608M System Generation Program
Press "H" for Hard disk generation or
      "F" for Floppy disk generation or
      ENTER to exit):

Both modes loop back to the mode-selection prompt after completion, allowing multiple operations in one session.

Floppy Generation Mode

Flow

  1. Detect drive type — calls BIOS SELDSK(0) to select drive A: and reads the SPT (Sectors Per Track) field from its DPB (Disk Parameter Block). If SPT = 34 (standard 40-track single-sided floppy), the default drive letter is A. Otherwise (e.g. 80-column format), it defaults to E.

  2. Patch BIOS entry points — uses self-modifying code to create direct CALL targets into the BIOS’s internal track read and write routines. The BIOS base address is derived from the warm boot vector at 0001h. Two dispatch entries are used:
    • WBOOT + 51h → BIOS internal READ (floppy system tracks)
    • WBOOT + 54h → BIOS internal WRITE (floppy system tracks)
  3. Read source — prompts “Insert Source disk on the floppy drive” and asks for the source drive letter. Calls the patched BIOS READ routine, which reads the system tracks from the source floppy into a buffer at 4000h.

  4. Rearrange data — copies the read data from the BIOS’s non-contiguous memory layout into a contiguous holding buffer at 0900h using four LDIR block moves:

    Source Destination Size Content
    4000h 0900h 128 bytes Boot sector
    5500h 0980h 2,048 bytes System code (part 1)
    5D00h 1180h 3,584 bytes System code (part 2)
    4080h 1F80h 5,248 bytes System code (part 3)

    The non-contiguous source addresses reflect the BIOS’s internal DMA layout for reading heterogeneous track formats (track 0 has 128-byte sectors; track 1 has 256-byte sectors).

  5. Write destination — prompts “Insert Destination disk” and asks for the destination drive letter. The four LDIR blocks are reversed (0900h → 4000h, etc.) to restore the BIOS memory layout, then the patched BIOS WRITE routine writes the system tracks to the destination floppy.

  6. Loop — prints “Function complete.” and returns to step 3 for additional copy operations. Ctrl-C returns to the main menu.

Self-Modifying Code

MSYSGEN cannot use the standard BIOS jump table entries (READ/WRITE) for system track I/O because those entry points operate on individual CP/M logical sectors within the data area. Instead, it patches two code fragments (SUB06/SUB07) at runtime to call internal BIOS routines that handle multi-sector system-track transfers with inline parameter tables.

The inline parameter table after each patched CALL contains 6 bytes:

Offset Size Content
0–1 16 DMA buffer address (4000h)
2 8 Track/head parameter
3 8 Additional parameter
4 8 Drive number (0-based, patched at runtime)
5 8 Sector count

The drive number byte is patched via SELF_MOD2 / SELF_MOD3 based on the user’s drive letter selection (drive letter minus ‘A’).

Hard Disk Generation Mode

Flow

  1. Open T0T1.SYS — sets up an FCB (File Control Block) at 0677h with the filename T0T1 SYS and calls BDOS function 15 (Open File). If the file is not found, reports “File T0T1.SYS was not found?”.

  2. Read file into buffer — uses BDOS function 26 (Set DMA Address) and function 20 (Read Sequential) in a loop to read 98 records (128 bytes each = 12,544 bytes total) from T0T1.SYS into a buffer at 0900h. If the file is shorter than 98 records, reports “File T0T1.SYS was corrupted?”.

  3. Check SASI drive — resets the SASI bus via port 40h, then checks status. If the MSG signal is not asserted or the target doesn’t respond to selection, reports “Hard disk write error !”.

  4. Write to hard disk — executes a full SASI Write transaction to write 49 sectors (12,544 bytes) starting at sector address 0 on the hard disk. This overwrites the reserved system tracks of partition 1 (B: in floppy BIOS, A: in HDD BIOS).

  5. Report result — prints “Function complete.” or the appropriate error message, then returns to the main menu.

T0T1.SYS File

T0T1.SYS is a binary file containing the CP/M system image for the hard disk’s reserved tracks. The name stands for Track 0, Track 1 — the two system tracks on a floppy disk. The file must be present on a CP/M floppy disk accessible to MSYSGEN.

Note: T0T1.SYS contains a distinct BIOS build from the floppy system disk (2,608 byte differences out of 5,248). The HDD BIOS remaps drive letters (A:–D: = HDD partitions, E: = floppy) and uses SASI instead of FDC for loading CCP+BDOS during warm boot.

The file contains 12,544 bytes (98 CP/M records), which maps to 49 hard disk sectors of 256 bytes. When written to the hard disk at sector 0, this populates the 2 reserved system tracks of partition 1 (OFF = 2 in the DPB), covering the boot sector, BIOS, CCP, and BDOS.

SASI Write Command

The SASI Write transaction follows the standard bus phase protocol:

Step Phase Action
1 Bus Free Poll port 46h until status = 00h
2 Target Selection Write 01h to port 41h, then 01h to port 43h
3 Command Send 6-byte command block via port 41h
4 Data Out OUTIR 49 × 256 bytes from buffer to port 41h
5 Status Read result from port 42h (bit 1 = error)
6 Message In Read completion byte from port 42h

The 6-byte SASI Group 0 command block sent during step 3:

Byte Value Field
0 0Ah Write opcode
1 00h LUN 0, sector address bits 20–16 = 0
2 00h Sector address bits 15–8 = 0
3 00h Sector address bits 7–0 = 0
4 31h Block count = 49 sectors
5 07h Control: retries enabled, no ECC, step = 15 µs

The sector address 0 corresponds to the first physical sector on the hard disk — the beginning of partition B:’s reserved system area.

Note: the control byte is 07h (no immediate ECC correction), unlike the BIOS’s normal Read command which uses 47h (ECC enabled). This is consistent with the WD1002-SHD manual — ECC correction is a read-time feature and does not apply to writes.

CP/M BDOS Functions Used

Function C reg Name Usage in MSYSGEN
2 02h Console Output Echo typed characters (SUB05)
6 06h Direct Console Non-blocking keyboard input (SUB04)
9 09h Print String Display $-terminated messages
15 0Fh Open File Open T0T1.SYS (SUB25)
20 14h Read Sequential Read T0T1.SYS records (SUB27)
26 1Ah Set DMA Address Set buffer pointer for file I/O (SUB26)

Memory Map

0100h–0431h   Code (main menu, floppy/HDD generation, SASI routines)
0432h–06FFh   String data ($-terminated messages and filenames)
0673h         DATA4       — default drive letter ('A' or 'E')
0674h–0676h   SUB28       — patched: JP BIOS_SELDSK
0677h–06A0h   FCB area    — File Control Block for T0T1.SYS
0683h–06A0h   FCB name    — "T0T1    SYS" + 30 bytes FCB state
0900h–3400h   I/O buffer  — holding area for system track data
4000h–6B00h   BIOS DMA    — where BIOS reads/writes floppy system tracks

Subroutine Reference

Label Address Description
LBL1 0100h Main menu — prompt and dispatch H/F/ENTER
SUB03 015Fh Floppy generation — read source, write destination
SUB04 0293h Read keyboard — BDOS 6 polling loop
SUB05 029Fh Echo character — BDOS 2 wrapper
SUB06 02A8h Patched BIOS floppy READ (inline params at 02ABh)
SUB07 02B2h Patched BIOS floppy WRITE (inline params at 02B5h)
SUB08 02BCh Hard disk generation — read T0T1.SYS, SASI Write
SUB09 0315h Error: “File T0T1.SYS was not found?”
SUB10 0319h Error: “File T0T1.SYS was corrupted?”
SUB11 031Dh Error: “Hard disk write error !”
SUB12 0321h Success: “Function complete.”
SUB13 0325h Read one sequential record from T0T1.SYS
SUB15 033Dh Check SASI drive — reset, select, verify BSY
SUB16 0366h SASI bus reset — OUT (40h), delay loop
SUB17 0372h SASI Write transaction — full bus phase sequence
SUB18 0384h Wait for Bus Free (00h), then Target Selection
SUB19 0396h Send SASI Write command block (6 bytes)
SUB20 03B7h Data Out phase — OUTIR 49 × 256 bytes
SUB21 03DBh Wait for REQ — poll status bit 0 (BSY)
SUB22 03E5h Status phase — wait for 1Bh, read result
SUB23 03F1h Message In phase — wait for 1Fh, read completion
SUB24 03FFh Send one command byte — wait for 0Bh, write port 41h
SUB25 040Dh BDOS 15 — Open File
SUB26 0419h BDOS 26 — Set DMA Address
SUB27 0425h BDOS 20 — Read Sequential

Error Handling

MSYSGEN has minimal error handling:

There is no timeout on the SASI bus phase polls. If the hard disk controller hangs mid-transaction, MSYSGEN will busy-wait forever — the same limitation as the BIOS itself.

Relationship to Other Utilities