================================================================================
                       Z16 COMPUTER REFERENCE MANUAL
                               Version 1.0
================================================================================

1. ARCHITECTURE OVERVIEW
--------------------------------------------------------------------------------

[CPU Specifications]
- Word Size:      16-bit (2 bytes)
- Byte Order:     Little Endian (Low Byte first)
- Memory:         64KB (0x0000 - 0xFFFF)

[Registers]
The CPU has 8 general-purpose 16-bit registers:
  R0 - R5 : General Purpose (R0-R3 often used for math, R4-R5 for pointers)
  SP (R6) : Stack Pointer (Initializes to 0xFFFF)
  PC (R7) : Program Counter

[Memory Map]
  0x0000 - 0xCFFF : User RAM (Program Code & Data)
  0xD000 - 0xEFFF : MMIO Window (8KB) - Active Device Mapped Here
  0xF000 - 0xFFFF : Reserved / High RAM

--------------------------------------------------------------------------------
2. INSTRUCTION SET (ISA)
--------------------------------------------------------------------------------
Instructions are 16-bit words. Some take an additional 16-bit immediate word.
Format: [Opcode: 8 bits] [Dest: 4 bits] [Src: 4 bits]
Binary Storage: [Low Byte: Dest|Src] [High Byte: Opcode]

[System]
  NOP       0x00  ; Do nothing
  HALT      0xFF  ; Stop CPU

[Data Transfer]
  SET       0x01  ; SET Rd, Immediate     (Reg[Rd] = NextWord)
  MOV       0x02  ; MOV Rd, Rs            (Reg[Rd] = Reg[Rs])
  LODB      0x03  ; LODB Rd, [Rs]         (Reg[Rd] = ByteAt(Reg[Rs]))
  STOB      0x04  ; STOB Rs, [Rd]         (ByteAt(Reg[Rd]) = Reg[Rs])
  LODW      0x05  ; LODW Rd, [Rs]         (Reg[Rd] = WordAt(Reg[Rs]))
  STOW      0x06  ; STOW Rs, [Rd]         (WordAt(Reg[Rd]) = Reg[Rs])

[Arithmetic Logic Unit (ALU)]
  ADD       0x10  ; ADD Rd, Rs            (Rd = Rd + Rs)
  SUB       0x11  ; SUB Rd, Rs            (Rd = Rd - Rs)
  AND       0x12  ; AND Rd, Rs            (Rd = Rd & Rs)
  OR        0x13  ; OR  Rd, Rs            (Rd = Rd | Rs)
  XOR       0x14  ; XOR Rd, Rs            (Rd = Rd ^ Rs)
  NOT       0x15  ; NOT Rd                (Rd = ~Rd)
  CMP       0x16  ; CMP Rd, Rs            (Flags = Rd - Rs)

[Flow Control]
  JMP       0x20  ; JMP Addr              (PC = Immediate)
  JZ        0x21  ; JZ  Addr              (PC = Immediate if Zero Flag)
  JNZ       0x22  ; JNZ Addr              (PC = Immediate if !Zero Flag)
  JG        0x23  ; JG  Addr              (Signed >)
  JL        0x24  ; JL  Addr              (Signed <)
  JLE       0x25  ; JLE Addr              (Signed <=)
  JGE       0x26  ; JGE Addr              (Signed >=)

[Stack]
  PUSH      0x30  ; PUSH Rs               (Stack[--SP] = Rs)
  POP       0x31  ; POP Rd                (Rd = Stack[SP++])
  CALL      0x32  ; CALL Addr             (Push PC, PC = Immediate)
  RET       0x33  ; RET                   (Pop PC)

[Hardware IO]
  HW_SCAN   0xF0  ; HW_SCAN               (R0 = Total Devices Connected)
  HW_SELECT 0xF1  ; HW_SELECT Rs          (Map Device ID in Rs to 0xD000)
  HW_TYPE   0xF2  ; HW_TYPE Rd, Rs        (Rd = Type ID of Device ID in Rs)

--------------------------------------------------------------------------------
3. BANK SWITCHING & IO BUS
--------------------------------------------------------------------------------
The Z16 uses a "Bank Switched" IO model.
- You cannot access all devices at once.
- You must SELECT a device to make it visible at address 0xD000.

[Procedure]
1. HW_SCAN: Returns the count of devices.
2. Loop 0..Count and use HW_TYPE to find what you need.
   - Type 1: Monitor
   - Type 2: Disk Drive
3. Save the Device IDs (Bus IDs) in RAM for later use.
4. HW_SELECT <ID>: Connects that device to 0xD000.

[LOL-DOS Standard Bus ID Locations]
The OS stores the discovered Bus IDs at these fixed RAM addresses:
  0x0080 : Monitor ID
  0x0082 : Boot Disk ID (Drive A)
  0x0084 : Data Disk ID (Drive B)

--------------------------------------------------------------------------------
4. PERIPHERAL: MONITOR (Type 1)
--------------------------------------------------------------------------------
Resolution: 64 columns x 32 rows
Mapped Window: 0xD000 - 0xE003 (Requires HW_SELECT)

[Memory Map Relative to 0xD000]
  +0x0000 (0-2047)    : Text VRAM (ASCII Characters)
  +0x0800 (2048-4095) : Color CRAM (Color Codes)
  +0x1000 (4096)      : Cursor X Register (0-63)
  +0x1001 (4097)      : Cursor Y Register (0-31)
  +0x1002 (4098)      : Command Register (Write 1 = Clear Screen)
  +0x1003 (4099)      : Key Buffer (Read = Key Code, Write 0 = Clear)

[Colors]
  0=Black, 1=Red, 2=Green, 3=Blue, 4=White
  (High nibble = Background, Low nibble = Foreground)
  Example: 0x02 = Green Text on Black.

--------------------------------------------------------------------------------
5. PERIPHERAL: DISK DRIVE (Type 2)
--------------------------------------------------------------------------------
Storage: 4KB Sectors (Floppy Disk)
Mapped Window: 0xD000 - 0xD003 (Requires HW_SELECT)

[Registers Relative to 0xD000]
  +0 : COMMAND Register (Write Only)
       1 = LOAD Sector from Disk to Internal Buffer
       2 = SAVE Internal Buffer to Disk
       3 = RESET Data Pointer to 0
  +1 : STATUS Register (Read Only)
       0 = Ready
       1 = Success
       2 = Error (Out of Bounds)
       3 = No Disk / Error
  +2 : SECTOR INDEX (Read/Write)
       Set this before triggering LOAD/SAVE.
  +3 : DATA PORT (Read/Write)
       Reads/Writes one byte from the internal buffer and auto-increments pointer.

[Usage Sequence]
1. HW_SELECT <DriveID>
2. Write Sector Index to +2.
3. Write 1 (Load) to +0.
4. Loop Read +1 until Status is 1.
5. Write 3 (Reset) to +0.
6. Loop Read +3 to get data bytes.

--------------------------------------------------------------------------------
6. FILESYSTEM (LOL-FS)
--------------------------------------------------------------------------------
Sector 0 is the File Allocation Table (TOC).
It contains a list of 16-byte entries.

[Entry Format (16 Bytes)]
  Bytes 0-9   : Filename (ASCII, 0-padded)
  Byte 10     : Start Sector
  Byte 11     : File Size (in Sectors)
  Bytes 12-15 : Reserved/Padding

[Boot Process]
1. OS loads Sector 0 of Drive A.
2. OS scans for files.
3. User types 'r' -> OS loads "GAME" (File 0) from Sector 1 to RAM 0x1000.
4. OS performs CALL 0x1000.

--------------------------------------------------------------------------------
7. MANUAL ASSEMBLY EXAMPLE
--------------------------------------------------------------------------------
Task: Draw 'X' (88) in Green (2) at Top-Left.

1. Load Monitor Bus ID (Assumed 0 stored at RAM 0x80)
   SET R3, 0x0080  -> [30 01] [80 00]
   LODW R0, [R3]   -> [03 05]

2. Select Monitor
   HW_SELECT R0    -> [00 F1]

3. Write 'X' to VRAM (0xD000)
   SET R3, 0xD000  -> [30 01] [00 D0]
   SET R1, 88      -> [10 01] [58 00]
   STOB R1, [R3]   -> [31 04]

4. Write Green to CRAM (0xD800)
   SET R3, 0xD800  -> [30 01] [00 D8]
   SET R1, 2       -> [10 01] [02 00]
   STOB R1, [R3]   -> [31 04]

5. Return
   RET             -> [00 33]
