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
MSYSGEN is the SV-608M equivalent of CP/M’s standard SYSGEN utility. It
provides two operations:
T0T1.SYS file from a floppy
disk and writes its contents to the hard disk’s reserved system sectors
via the SASI bus.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.
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.
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.
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).
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.
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’).
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?”.
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?”.
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 !”.
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).
Report result — prints “Function complete.” or the appropriate error message, then returns to the main menu.
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.
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.
| 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) |
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
| 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 |
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.