|
@@ -1,25 +1,118 @@
|
|
|
-; z80dasm 1.1.6
|
|
|
-; command line: z80dasm -g 0000h -l -a -b block_monroe_oc8820_r3.00 -o monroe_test.asm ../prom/monroe_oc8820_boot_prom_r3_00C_tms2516_ea751e22.bin
|
|
|
-displaymem equ 0x3000
|
|
|
-nomemchecks equ 9
|
|
|
+; ================================================================================
|
|
|
+; Monroe OC8820 Boot ROM Disassembly - Version R3.00C
|
|
|
+; ================================================================================
|
|
|
+; Original file: monroe_oc8820_boot_prom_r3_00C_tms2516_ea751e22.bin
|
|
|
+; ROM Type: TMS2516 (2KB EPROM)
|
|
|
+; Disassembler: z80dasm 1.1.6
|
|
|
+;
|
|
|
+; This is the boot ROM for the Monroe OC8820 computer system.
|
|
|
+; The system uses a Z80 CPU with bank-switched memory architecture.
|
|
|
+;
|
|
|
+; Memory Map:
|
|
|
+; 0x0000-0x07FF : Boot ROM (this code)
|
|
|
+; 0x3000-0x3FFF : Display memory
|
|
|
+; 0xC000-0xFFFF : Banked RAM (controlled by I/O ports)
|
|
|
+; 0xFF80-0xFFFF : System variables area
|
|
|
+;
|
|
|
+; I/O Port Map:
|
|
|
+; 0x78-0x7B : Hard disk controller (DMA-based)
|
|
|
+; 0xA0 : DART A (Dual Async Receiver/Transmitter) - Channel A data (printer)
|
|
|
+; 0xA1 : DART A (Dual Async Receiver/Transmitter) - Channel A command
|
|
|
+; 0xA2 : DART B (Dual Async Receiver/Transmitter) - Channel B data (keyboard)
|
|
|
+; 0xA3 : DART B (Dual Async Receiver/Transmitter) - Channel B command
|
|
|
+; 0xA4 : SIO A (Serial I/O) - Channel A data (comm)
|
|
|
+; 0xA5 : SIO A (Serial I/O) - Channel A command
|
|
|
+; 0xA6 : SIO B (Serial I/O) - Channel B data (RS-232C)
|
|
|
+; 0xA7 : SIO B (Serial I/O) - Channel B command
|
|
|
+; 0xA8 : CTC (Counter Timer Circuit) - Channel 0 (Communications baud)
|
|
|
+; 0xA9 : CTC Channel 1 (AUX RS-232C baud)
|
|
|
+; 0xAA : CTC Channel 2 (Printer baud)
|
|
|
+; 0xAB : CTC Channel 3
|
|
|
+; 0xB0-0xB3 : Floppy disk controller (WD179x family)
|
|
|
+; 0xB0: Status/Command, 0xB2: Sector, 0xB3: Track
|
|
|
+; 0xB4-0xB5 : Z80 PIO A data and control ports
|
|
|
+; 0xB4: PIO A data (floppy INTRQ signal, DMA control), 0xB5: PIO A control
|
|
|
+; 0xB8-0xB9 : CRT controller (6845 CRTC)
|
|
|
+; 0xB8: Register select, 0xB9: Data
|
|
|
+; 0xC0 : Floppy drive selection and control
|
|
|
+; 0xC4 : Program map A base address (memory banking)
|
|
|
+; 0xC5 : Program map B base address (memory banking)
|
|
|
+; 0xC6 : DMA map A base address (floppy DMA control)
|
|
|
+; 0xC7 : DMA map B base address (hard disk DMA control)
|
|
|
+; 0xC8 : Map and system control register (banking enable/disable)
|
|
|
+; 0xD4-0xD8 : Graphics and color control
|
|
|
+; 0xFF : Hardware detection port
|
|
|
+;
|
|
|
+; Boot Device Selection System:
|
|
|
+; The Monroe OC8820 features sophisticated multi-device boot capability:
|
|
|
+;
|
|
|
+; 1. HARDWARE AUTO-DETECTION (Port 0xFF):
|
|
|
+; - Reading 0 = Floppy-only configuration
|
|
|
+; - Reading 1 = Hard disk + floppy configuration
|
|
|
+; - Reading 2+ = Advanced hard disk configuration
|
|
|
+;
|
|
|
+; 2. BOOT PRIORITY ORDER:
|
|
|
+; - HARD DISK FIRST (when detected): Uses DMA controller at ports 0x78-0x7B
|
|
|
+; - FLOPPY FALLBACK: Uses WD179x controller at ports 0xB0-0xB3 (PIO A at 0xB4-0xB5)
|
|
|
+; - Systematic retry: Tests floppy drives 0-3 with 8 total attempts
|
|
|
+; - Final recovery: Special commands 0x10/0x11 on Drive 0 only
|
|
|
+;
|
|
|
+; 3. DUAL OPERATING SYSTEM SUPPORT:
|
|
|
+; - Monroe OS8 (proprietary system)
|
|
|
+; - CP/M (industry standard)
|
|
|
+; - Boot path selection via calculated jumps at 0x05D0
|
|
|
+;
|
|
|
+; Communication Specifications:
|
|
|
+; DART A & B : High-speed serial (baud rate depends on system clock)
|
|
|
+; SIO A & B : High-speed serial (same rate as DART ports)
|
|
|
+; Printer Port : Lower-speed serial/parallel (baud rate depends on system clock)
|
|
|
+; CTC Timing : Ch0/1: ÷16 prescaler, time const 3; Ch2: ÷256 prescaler, time const 78
|
|
|
+ ; Number of memory banks to test
|
|
|
+; CRT Display : 80 characters/line text mode (184 total horizontal timing)
|
|
|
+; ================================================================================
|
|
|
+; Constants
|
|
|
+displaymem: equ 0x3000 ; Start of display memory
|
|
|
+nomemchecks: equ 9 ; Number of memory banks to test (1-9)
|
|
|
+
|
|
|
org 00000h
|
|
|
|
|
|
+; ================================================================================
|
|
|
+; RESET VECTOR AND BOOT SEQUENCE
|
|
|
+; ================================================================================
|
|
|
+; Z80 starts execution here after reset
|
|
|
+
|
|
|
l0000h:
|
|
|
- di ;0000 no interrupt
|
|
|
- ld sp,0ffa6h ;0001 init stack
|
|
|
- xor a ;0004 A=0
|
|
|
- jp l_init ;0005 go init 00046h
|
|
|
- ld de,0303eh ;0008 point to screen ram
|
|
|
- call cleartopline ;000b go clear top line 0052dh
|
|
|
- nop ;000e
|
|
|
- nop ;000f
|
|
|
- pop hl ;0010 get return addr
|
|
|
+ di ;0000 Disable interrupts during boot
|
|
|
+ ld sp,0ffa6h ;0001 Initialize stack pointer (top of RAM minus workspace)
|
|
|
+ xor a ;0004 Clear A register (A=0)
|
|
|
+ jp l_init ;0005 Jump to main initialization routine
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; DISPLAY MESSAGE ROUTINE ENTRY POINT
|
|
|
+; ================================================================================
|
|
|
+; This routine is called to display text messages on screen
|
|
|
+; Entry: DE = screen position, HL = message address
|
|
|
+; Message format: first byte = length, followed by ASCII text
|
|
|
+
|
|
|
+display_entry:
|
|
|
+ ld de,0303eh ;0008 Default screen position (row 3, col 62?)
|
|
|
+ call cleartopline ;000b Clear the top line of display
|
|
|
+ nop ;000e Padding
|
|
|
+ nop ;000f Padding
|
|
|
+ pop hl ;0010 Get return address (points to message)
|
|
|
+
|
|
|
displaymsg:
|
|
|
- ld c,(hl) ;0011 load count
|
|
|
- inc hl ;0012 bump
|
|
|
- ld b,000h ;0013
|
|
|
- jp printroutine ;0015
|
|
|
- rst 38h ;0018
|
|
|
+ ld c,(hl) ;0011 Load message length from first byte
|
|
|
+ inc hl ;0012 Point to message text
|
|
|
+ ld b,000h ;0013 Clear B (BC now = message length)
|
|
|
+ jp printroutine ;0015 Jump to print routine
|
|
|
+; ================================================================================
|
|
|
+; RST VECTOR TABLE (0x0018-0x003F)
|
|
|
+; ================================================================================
|
|
|
+; All RST vectors point to RST 38h (0x0038) - likely a common error handler
|
|
|
+; The Z80 RST instructions provide fast calls to these addresses
|
|
|
+
|
|
|
+ rst 38h ;0018 RST 18h -> RST 38h
|
|
|
rst 38h ;0019
|
|
|
rst 38h ;001a
|
|
|
rst 38h ;001b
|
|
@@ -27,7 +120,7 @@ displaymsg:
|
|
|
rst 38h ;001d
|
|
|
rst 38h ;001e
|
|
|
rst 38h ;001f
|
|
|
- rst 38h ;0020
|
|
|
+ rst 38h ;0020 RST 20h -> RST 38h
|
|
|
rst 38h ;0021
|
|
|
rst 38h ;0022
|
|
|
rst 38h ;0023
|
|
@@ -35,7 +128,7 @@ displaymsg:
|
|
|
rst 38h ;0025
|
|
|
rst 38h ;0026
|
|
|
rst 38h ;0027
|
|
|
- rst 38h ;0028
|
|
|
+ rst 38h ;0028 RST 28h -> RST 38h
|
|
|
rst 38h ;0029
|
|
|
rst 38h ;002a
|
|
|
rst 38h ;002b
|
|
@@ -43,7 +136,7 @@ displaymsg:
|
|
|
rst 38h ;002d
|
|
|
rst 38h ;002e
|
|
|
rst 38h ;002f
|
|
|
- rst 38h ;0030
|
|
|
+ rst 38h ;0030 RST 30h -> RST 38h
|
|
|
rst 38h ;0031
|
|
|
rst 38h ;0032
|
|
|
rst 38h ;0033
|
|
@@ -51,7 +144,7 @@ displaymsg:
|
|
|
rst 38h ;0035
|
|
|
rst 38h ;0036
|
|
|
rst 38h ;0037
|
|
|
- rst 38h ;0038
|
|
|
+ rst 38h ;0038 RST 38h - Common error handler
|
|
|
rst 38h ;0039
|
|
|
rst 38h ;003a
|
|
|
rst 38h ;003b
|
|
@@ -59,1415 +152,2002 @@ displaymsg:
|
|
|
rst 38h ;003d
|
|
|
rst 38h ;003e
|
|
|
rst 38h ;003f
|
|
|
- jp l0000h ;0040
|
|
|
- jp l0000h ;0043
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; WARM BOOT AND RESTART VECTORS
|
|
|
+; ================================================================================
|
|
|
+
|
|
|
+ jp l0000h ;0040 Warm boot - restart system
|
|
|
+ jp l0000h ;0043 Another restart vector
|
|
|
+; ================================================================================
|
|
|
+; MAIN SYSTEM INITIALIZATION
|
|
|
+; ================================================================================
|
|
|
+; This routine initializes all I/O controllers and system hardware
|
|
|
+
|
|
|
l_init:
|
|
|
- out (0c0h),a ;0046 clear io, floppy control
|
|
|
- out (0c4h),a ;0048 clear io,Program map A base
|
|
|
- out (0c5h),a ;004a clear io,Program map B base
|
|
|
- out (0c6h),a ;004c clear io,DMA map A base
|
|
|
- out (0c7h),a ;004e clear io,DMA map B base
|
|
|
- out (0d4h),a ;0050 clear io,Hi-res color
|
|
|
- out (0d8h),a ;0052 clear io,Hi-res start
|
|
|
- ld hl,PIOA_start ;0054
|
|
|
- jp l0562h ;0057 do OTIR loop on following data 00562h
|
|
|
+ out (0c0h),a ;0046 Clear floppy disk controller
|
|
|
+ out (0c4h),a ;0048 Clear Program map A base address
|
|
|
+ out (0c5h),a ;004a Clear Program map B base address
|
|
|
+ out (0c6h),a ;004c Clear DMA map A base address
|
|
|
+ out (0c7h),a ;004e Clear DMA map B base address
|
|
|
+ out (0d4h),a ;0050 Clear Hi-res color control
|
|
|
+ out (0d8h),a ;0052 Clear Hi-res graphics start address
|
|
|
+ ld hl,PIOA_start ;0054 Point to I/O initialization data table
|
|
|
+ jp l0562h ;0057 Jump to OTIR routine to initialize peripherals
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; I/O CONTROLLER INITIALIZATION DATA TABLE
|
|
|
+; ================================================================================
|
|
|
+; This table contains initialization sequences for various Z80 peripheral chips
|
|
|
+; Format: Port address, Count, Data bytes...
|
|
|
+; Used by OTIR routine at 0562h
|
|
|
|
|
|
; BLOCK 'PIOA' (start 0x005a end 0x008b)
|
|
|
PIOA_start:
|
|
|
- defb 0b5h ;005a io port CRT register select
|
|
|
- defb 004h ;005b count 4
|
|
|
- defb 0cfh ;005c
|
|
|
- defb 0b8h ;005d
|
|
|
- defb 037h ;005e
|
|
|
- defb 0efh ;005f
|
|
|
- ;
|
|
|
- defb 0b4h ;0060 io port PIO A data
|
|
|
- defb 001h ;0061 count 1
|
|
|
- defb 001h ;0062
|
|
|
- ;
|
|
|
- defb 0a1h ;0063 io port DART A command
|
|
|
- defb 006h ;0064 count 6
|
|
|
- defb 048h ;0065
|
|
|
- defb 048h ;0066
|
|
|
- defb 004h ;0067
|
|
|
- defb 044h ;0068
|
|
|
- defb 005h ;0069
|
|
|
- defb 0eah ;006a
|
|
|
- ;
|
|
|
- defb 0a3h ;006b io port DART B command
|
|
|
- defb 008h ;006c count 8
|
|
|
- defb 048h ;006d
|
|
|
- defb 048h ;006e
|
|
|
- defb 004h ;006f
|
|
|
- defb 044h ;0070
|
|
|
- defb 001h ;0071
|
|
|
- defb 000h ;0072
|
|
|
- defb 003h ;0073
|
|
|
- defb 0c1h ;0074
|
|
|
- ;
|
|
|
- defb 0a5h ;0075 io port SIO A command
|
|
|
- defb 002h ;0076 count 2
|
|
|
- defb 048h ;0077
|
|
|
- defb 048h ;0078
|
|
|
- ;
|
|
|
- defb 0a7h ;0079 io port SIO B command
|
|
|
- defb 002h ;007a count 2
|
|
|
- defb 048h ;007b
|
|
|
- defb 048h ;007c
|
|
|
- ;
|
|
|
- defb 0a8h ;007d io port CTC CHANNEL 0 - Communications baud rate
|
|
|
- defb 002h ;007e count 2
|
|
|
- defb 003h ;007f
|
|
|
- defb 003h ;0080
|
|
|
- ;
|
|
|
- defb 0a9h ;0081 io port CTC CHANNEL 1 - AUX RS-232C baud rate
|
|
|
- defb 002h ;0082 count 2
|
|
|
- defb 003h ;0083
|
|
|
- defb 003h ;0084
|
|
|
- ;
|
|
|
- defb 0aah ;0085 io port CTC CHANNEL 2 - Printer baud rate
|
|
|
- defb 002h ;0086 count 2
|
|
|
- defb 057h ;0087
|
|
|
- defb 04eh ;0088
|
|
|
- ;
|
|
|
- defb 000h ;0089 io port reset
|
|
|
- defb 000h ;008a count 0 terminator
|
|
|
+ ; CRT Controller initialization (6845 compatible)
|
|
|
+ defb 0b5h ;005a I/O port: CRT register select
|
|
|
+ defb 004h ;005b Count: 4 bytes to follow
|
|
|
+ defb 0cfh ;005c Reg 0: Horizontal Total = 207+1=208 chars/line
|
|
|
+ defb 0b8h ;005d Reg 1: Horizontal Displayed = 184 (likely 80 char mode with wide timing)
|
|
|
+ defb 037h ;005e Reg 2: Horizontal Sync Position = 55 (after visible)
|
|
|
+ defb 0efh ;005f Reg 3: Sync Width = V:14 lines, H:15 chars
|
|
|
+
|
|
|
+ ; PIO A Data Port
|
|
|
+ defb 0b4h ;0060 I/O port: PIO A data
|
|
|
+ defb 001h ;0061 Count: 1 byte to follow
|
|
|
+ defb 001h ;0062 Data: Enable something
|
|
|
+
|
|
|
+ ; DART A (Serial port A) initialization
|
|
|
+ defb 0a1h ;0063 I/O port: DART A command
|
|
|
+ defb 006h ;0064 Count: 6 bytes to follow
|
|
|
+ defb 048h ;0065 Reset command
|
|
|
+ defb 048h ;0066 Reset command (double reset)
|
|
|
+ defb 004h ;0067 Write register 4: Clock/format control
|
|
|
+ defb 044h ;0068 16x clock, 1 stop bit, no parity
|
|
|
+ defb 005h ;0069 Write register 5: Transmit control
|
|
|
+ defb 0eah ;006a DTR active, RTS active, Tx enable, 8 bits
|
|
|
+
|
|
|
+ ; DART B (Serial port B) initialization
|
|
|
+ defb 0a3h ;006b I/O port: DART B command
|
|
|
+ defb 008h ;006c Count: 8 bytes to follow
|
|
|
+ defb 048h ;006d Reset command
|
|
|
+ defb 048h ;006e Reset command (double reset)
|
|
|
+ defb 004h ;006f Write register 4: Clock/format control
|
|
|
+ defb 044h ;0070 16x clock, 1 stop bit, no parity
|
|
|
+ defb 001h ;0071 Write register 1: Interrupt control
|
|
|
+ defb 000h ;0072 No interrupts enabled
|
|
|
+ defb 003h ;0073 Write register 3: Receive control
|
|
|
+ defb 0c1h ;0074 Rx enable, 8 bits per char
|
|
|
+
|
|
|
+ ; SIO A (Serial I/O A) initialization
|
|
|
+ defb 0a5h ;0075 I/O port: SIO A command
|
|
|
+ defb 002h ;0076 Count: 2 bytes to follow
|
|
|
+ defb 048h ;0077 Reset command
|
|
|
+ defb 048h ;0078 Reset command (double reset)
|
|
|
+
|
|
|
+ ; SIO B (Serial I/O B) initialization
|
|
|
+ defb 0a7h ;0079 I/O port: SIO B command
|
|
|
+ defb 002h ;007a Count: 2 bytes to follow
|
|
|
+ defb 048h ;007b Reset command
|
|
|
+ defb 048h ;007c Reset command (double reset)
|
|
|
+
|
|
|
+ ; CTC (Counter Timer Circuit) initialization
|
|
|
+ ; Used to generate baud rate clocks for serial communications
|
|
|
+
|
|
|
+ ; CTC Channel 0 - Communications baud rate generator
|
|
|
+ defb 0a8h ;007d I/O port: CTC CHANNEL 0
|
|
|
+ defb 002h ;007e Count: 2 bytes to follow
|
|
|
+ defb 003h ;007f Control: Timer mode, prescaler 16, auto-trigger
|
|
|
+ defb 003h ;0080 Time constant: 3 (high-speed rate)
|
|
|
+
|
|
|
+ ; CTC Channel 1 - Auxiliary RS-232C baud rate generator
|
|
|
+ defb 0a9h ;0081 I/O port: CTC CHANNEL 1
|
|
|
+ defb 002h ;0082 Count: 2 bytes to follow
|
|
|
+ defb 003h ;0083 Control: Timer mode, prescaler 16, auto-trigger
|
|
|
+ defb 003h ;0084 Time constant: 3 (same rate as channel 0)
|
|
|
+
|
|
|
+ ; CTC Channel 2 - Printer baud rate generator
|
|
|
+ defb 0aah ;0085 I/O port: CTC CHANNEL 2
|
|
|
+ defb 002h ;0086 Count: 2 bytes to follow
|
|
|
+ defb 057h ;0087 Control: Timer mode, prescaler 256, auto-trigger
|
|
|
+ defb 04eh ;0088 Time constant: 78 (slower rate for printer)
|
|
|
+
|
|
|
+ ; End of I/O initialization table
|
|
|
+ defb 000h ;0089 Terminator: port 0 (invalid)
|
|
|
+ defb 000h ;008a Terminator: count 0
|
|
|
+
|
|
|
PIOA_end:
|
|
|
- ld ix,initcontinue ;008b continuation addr 00092h
|
|
|
- jp setupclearscreen ;008f setup display and clear screen 00505h
|
|
|
+ ld ix,initcontinue ;008b Set continuation address after screen setup
|
|
|
+ jp setupclearscreen ;008f Initialize display and clear screen
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; INITIALIZATION CONTINUATION
|
|
|
+; ================================================================================
|
|
|
+; Returns here after display is initialized and cleared
|
|
|
+
|
|
|
initcontinue:
|
|
|
- ld a,080h ;0092
|
|
|
- out (0d4h),a ;0094 out 0d4h,80h Hi-res color enable copy, buzzer off
|
|
|
- ld de,displaymem ;0096 point to display upper left corner 03000h
|
|
|
- ld hl,TESTING_start ;0099 point to message 0009fh
|
|
|
- jp displaymsg ;009c go display message at HL 00011h
|
|
|
+ ld a,080h ;0092 Enable hi-res graphics, disable buzzer
|
|
|
+ out (0d4h),a ;0094 Write to hi-res color control register
|
|
|
+ ld de,displaymem ;0096 Point to start of display memory
|
|
|
+ ld hl,TESTING_start ;0099 Point to "Testing." message
|
|
|
+ jp displaymsg ;009c Display the message
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; "TESTING." MESSAGE DATA
|
|
|
+; ================================================================================
|
|
|
|
|
|
; BLOCK 'TESTING' (start 0x009f end 0x00a8)
|
|
|
TESTING_start:
|
|
|
- defb 008h ;009f 8 bytes "Testing."
|
|
|
- defb 054h ;00a0
|
|
|
- defb 065h ;00a1
|
|
|
- defb 073h ;00a2
|
|
|
- defb 074h ;00a3
|
|
|
- defb 069h ;00a4
|
|
|
- defb 06eh ;00a5
|
|
|
- defb 067h ;00a6
|
|
|
- defb 02eh ;00a7
|
|
|
+ defb 008h ;009f Message length: 8 characters
|
|
|
+ defb 054h ;00a0 'T'
|
|
|
+ defb 065h ;00a1 'e'
|
|
|
+ defb 073h ;00a2 's'
|
|
|
+ defb 074h ;00a3 't'
|
|
|
+ defb 069h ;00a4 'i'
|
|
|
+ defb 06eh ;00a5 'n'
|
|
|
+ defb 067h ;00a6 'g'
|
|
|
+ defb 02eh ;00a7 '.'
|
|
|
TESTING_end:
|
|
|
- ld a,005h ;00a8
|
|
|
- out (0a3h),a ;00aa DART B command
|
|
|
- ld a,068h ;00ac
|
|
|
- out (0a3h),a ;00ae DART B command
|
|
|
- ld a,0f0h ;00b0 ?????
|
|
|
- out (0c8h),a ;00b2 Map and system control
|
|
|
- ld ix,0c001h ;00b4
|
|
|
- ld bc,00c5h ;00b8
|
|
|
- ld d,nomemchecks ;00bb Start test memory bank (1-9), go to zero afterwards 009h
|
|
|
- ld a,0a0h ;00bd Check if 256k memory or 128k
|
|
|
- out (0c5h),a ;00bf Program map B base
|
|
|
- ld (ix-001h),b ;00c1
|
|
|
- dec b ;00c4
|
|
|
- inc a ;00c5
|
|
|
- out (0c5h),a ;00c6 Program map B base
|
|
|
- ld (ix-001h),b ;00c8
|
|
|
- dec a ;00cb
|
|
|
- out (0c5h),a ;00cc Program map B base
|
|
|
- ld b,(ix-001h) ;00ce
|
|
|
- inc b ;00d1
|
|
|
- jr z,skip256 ;00d2 $+4 skip for start of memtest
|
|
|
- ld d,011h ;00d4
|
|
|
+; ================================================================================
|
|
|
+; MEMORY DETECTION AND TEST INITIALIZATION
|
|
|
+; ================================================================================
|
|
|
+; This section detects memory size (128K vs 256K) and sets up memory testing
|
|
|
+
|
|
|
+ ld a,005h ;00a8 DART B register 5 (transmit control)
|
|
|
+ out (0a3h),a ;00aa Select register 5
|
|
|
+ ld a,068h ;00ac Enable transmit, 7 bits, no break
|
|
|
+ out (0a3h),a ;00ae Configure DART B transmit
|
|
|
+ ld a,0f0h ;00b0 Memory mapping control value
|
|
|
+ out (0c8h),a ;00b2 Set map and system control register
|
|
|
+ ld ix,0c001h ;00b4 Point to banked memory + 1 (0xC001)
|
|
|
+ ld bc,00c5h ;00b8 BC = 0x00C5 (memory map port in C)
|
|
|
+ ld d,nomemchecks ;00bb D = 9 (number of memory banks to test)
|
|
|
+
|
|
|
+; Memory size detection routine
|
|
|
+ ld a,0a0h ;00bd Test value for 256K detection
|
|
|
+ out (0c5h),a ;00bf Set program map B base to 0xA0
|
|
|
+ ld (ix-001h),b ;00c1 Write test value (0x00) to 0xC000
|
|
|
+ dec b ;00c4 B = 0xFF
|
|
|
+ inc a ;00c5 A = 0xA1
|
|
|
+ out (0c5h),a ;00c6 Set program map B base to 0xA1
|
|
|
+ ld (ix-001h),b ;00c8 Write 0xFF to 0xC000 in new bank
|
|
|
+ dec a ;00cb A = 0xA0 (back to first bank)
|
|
|
+ out (0c5h),a ;00cc Switch back to first bank
|
|
|
+ ld b,(ix-001h) ;00ce Read back value from 0xC000
|
|
|
+ inc b ;00d1 Increment (0x00 becomes 0x01)
|
|
|
+ jr z,skip256 ;00d2 If zero, we have 256K (0xFF+1=0x00)
|
|
|
+ ld d,011h ;00d4 If not zero, set to test 17 banks (256K)
|
|
|
+
|
|
|
skip256:
|
|
|
- ld b,d ;00d6
|
|
|
- ld hl,memtesteval ;00d7 00122h
|
|
|
- ld de,0000h ;00da
|
|
|
+ ld b,d ;00d6 B = number of banks to test
|
|
|
+ ld hl,memtesteval ;00d7 Point to memory test bank list
|
|
|
+ ld de,0000h ;00da Clear error counters
|
|
|
+; ================================================================================
|
|
|
+; MAIN MEMORY TEST LOOP
|
|
|
+; ================================================================================
|
|
|
+; Tests each memory bank using rotating bit patterns
|
|
|
+
|
|
|
beginmemtest:
|
|
|
- outi ;00dd Switch memory map
|
|
|
- jr z,memcmp ;00df
|
|
|
- exx ;00e1
|
|
|
- ld b,055h ;00e2 memory check value
|
|
|
- ld e,000h ;00e4
|
|
|
+ outi ;00dd Switch memory bank: output (HL) to port C(0xC5), HL++, B--
|
|
|
+ jr z,memcmp ;00df If B=0, all banks tested - check results
|
|
|
+ exx ;00e1 Switch to alternate register set
|
|
|
+ ld b,055h ;00e2 Start with test pattern 0x55 (01010101)
|
|
|
+ ld e,000h ;00e4 Clear local error accumulator
|
|
|
+
|
|
|
+; Test loop for current memory bank using rotating patterns
|
|
|
memtestloop:
|
|
|
- ld hl,0c000h ;00e6 Start for membank that has been switch into
|
|
|
- ld c,b ;00e9
|
|
|
+ ld hl,0c000h ;00e6 Start of current memory bank
|
|
|
+ ld c,b ;00e9 Copy test pattern to C
|
|
|
+
|
|
|
+; Write test pattern to entire 16K bank
|
|
|
memtestwriteloop:
|
|
|
- ld (hl),c ;00ea
|
|
|
- rlc c ;00eb
|
|
|
- inc l ;00ed
|
|
|
- jr nz,memtestwriteloop ;00ee -4
|
|
|
- rlc c ;00f0
|
|
|
- inc h ;00f2
|
|
|
- jr nz,memtestwriteloop ;00f3 -9
|
|
|
- ld h,0c0h ;00f5
|
|
|
- ld c,b ;00f7
|
|
|
+ ld (hl),c ;00ea Write pattern to memory
|
|
|
+ rlc c ;00eb Rotate pattern left (01010101 -> 10101010)
|
|
|
+ inc l ;00ed Next byte (low address)
|
|
|
+ jr nz,memtestwriteloop ;00ee Continue until L wraps to 0
|
|
|
+ rlc c ;00f0 Rotate pattern again for next page
|
|
|
+ inc h ;00f2 Next page (high address)
|
|
|
+ jr nz,memtestwriteloop ;00f3 Continue until H wraps to 0
|
|
|
+
|
|
|
+; Read back and verify test pattern
|
|
|
+ ld h,0c0h ;00f5 Reset to start of bank
|
|
|
+ ld c,b ;00f7 Restore original test pattern
|
|
|
+
|
|
|
memtestreadloop:
|
|
|
- ld a,(hl) ;00f8
|
|
|
- xor c ;00f9
|
|
|
- or e ;00fa
|
|
|
- ld e,a ;00fb
|
|
|
- rlc c ;00fc
|
|
|
- inc l ;00fe
|
|
|
- jr nz,memtestreadloop ;00ff
|
|
|
- rlc c ;0101
|
|
|
- inc h ;0103
|
|
|
- jr nz,memtestreadloop ;0104
|
|
|
- rlc b ;0106
|
|
|
- jr nc,memtestloop ;0108
|
|
|
- ld a,e ;010a
|
|
|
- exx ;010b
|
|
|
- and a ;010c
|
|
|
- jr z,memgood ;010d
|
|
|
- inc a ;010f
|
|
|
- jr z,memerror ;0110
|
|
|
- or d ;0112
|
|
|
- ld d,a ;0113
|
|
|
- jr memgood ;0114
|
|
|
+ ld a,(hl) ;00f8 Read memory location
|
|
|
+ xor c ;00f9 Compare with expected pattern
|
|
|
+ or e ;00fa Accumulate errors in E
|
|
|
+ ld e,a ;00fb Store error accumulator
|
|
|
+ rlc c ;00fc Rotate expected pattern
|
|
|
+ inc l ;00fe Next byte
|
|
|
+ jr nz,memtestreadloop ;00ff Continue until L wraps
|
|
|
+ rlc c ;0101 Rotate pattern for next page
|
|
|
+ inc h ;0103 Next page
|
|
|
+ jr nz,memtestreadloop ;0104 Continue until H wraps
|
|
|
+ rlc b ;0106 Rotate base pattern for next iteration
|
|
|
+ jr nc,memtestloop ;0108 Continue if not back to original (8 patterns)
|
|
|
+
|
|
|
+; Process test results for this bank
|
|
|
+ ld a,e ;010a Get error accumulator
|
|
|
+ exx ;010b Switch back to main register set
|
|
|
+ and a ;010c Test for errors
|
|
|
+ jr z,memgood ;010d No errors - bank is good
|
|
|
+ inc a ;010f Check if all bits failed (0xFF -> 0x00)
|
|
|
+ jr z,memerror ;0110 Complete failure - count as bad bank
|
|
|
+ or d ;0112 Partial failure - OR with global error flags
|
|
|
+ ld d,a ;0113 Store combined error status
|
|
|
+ jr memgood ;0114 Continue testing
|
|
|
+
|
|
|
memerror:
|
|
|
- inc e ;0116
|
|
|
+ inc e ;0116 Increment bad bank counter
|
|
|
+
|
|
|
memgood:
|
|
|
- ld a,b ;0117
|
|
|
- cp 004h ;0118
|
|
|
- jr nz,beginmemtest ;011a
|
|
|
- ld a,020h ;011c
|
|
|
- out (0c0h),a ;011e Floppy external control Motor on!
|
|
|
- jr beginmemtest ;0120
|
|
|
-memtesteval: ;Memory ports
|
|
|
- defb 0a1h ;0122 count 16
|
|
|
- defb 0c1h ;0123
|
|
|
- defb 0e1h ;0124
|
|
|
- defb 000h ;0125
|
|
|
- defb 020h ;0126
|
|
|
- defb 040h ;0127
|
|
|
- defb 060h ;0128
|
|
|
- defb 080h ;0129
|
|
|
- defb 0a0h ;012a //Start of 256kB memtest
|
|
|
- defb 0c0h ;012b
|
|
|
- defb 0e0h ;012c
|
|
|
- defb 001h ;012d
|
|
|
- defb 021h ;012e
|
|
|
- defb 041h ;012f
|
|
|
- defb 061h ;0130
|
|
|
- defb 081h ;0131
|
|
|
- nop ;0132
|
|
|
+ ld a,b ;0117 Check remaining bank count
|
|
|
+ cp 004h ;0118 Is this bank 4?
|
|
|
+ jr nz,beginmemtest ;011a If not bank 4, continue testing
|
|
|
+ ld a,020h ;011c FDC control: Drive B select (dual drive system)
|
|
|
+ out (0c0h),a ;011e Write to floppy controller control register
|
|
|
+ jr beginmemtest ;0120 Continue memory testing
|
|
|
+; ================================================================================
|
|
|
+; MEMORY BANK SELECTION TABLE
|
|
|
+; ================================================================================
|
|
|
+; This table contains the bank values written to port 0xC5 (Program map B base)
|
|
|
+; Each value maps a different 16K memory bank into the 0xC000-0xFFFF address space
|
|
|
+
|
|
|
+memtesteval: ; Memory bank mapping values
|
|
|
+ defb 0a1h ;0122 Bank count: 161 (actually used as counter)
|
|
|
+ defb 0c1h ;0123 Memory bank 0xC1
|
|
|
+ defb 0e1h ;0124 Memory bank 0xE1
|
|
|
+ defb 000h ;0125 Memory bank 0x00
|
|
|
+ defb 020h ;0126 Memory bank 0x20
|
|
|
+ defb 040h ;0127 Memory bank 0x40
|
|
|
+ defb 060h ;0128 Memory bank 0x60
|
|
|
+ defb 080h ;0129 Memory bank 0x80
|
|
|
+ defb 0a0h ;012a Memory bank 0xA0 (Start of 256KB test range)
|
|
|
+ defb 0c0h ;012b Memory bank 0xC0
|
|
|
+ defb 0e0h ;012c Memory bank 0xE0
|
|
|
+ defb 001h ;012d Memory bank 0x01
|
|
|
+ defb 021h ;012e Memory bank 0x21
|
|
|
+ defb 041h ;012f Memory bank 0x41
|
|
|
+ defb 061h ;0130 Memory bank 0x61
|
|
|
+ defb 081h ;0131 Memory bank 0x81
|
|
|
+; ================================================================================
|
|
|
+; MEMORY TEST RESULTS EVALUATION
|
|
|
+; ================================================================================
|
|
|
+; Check if memory test found any errors and decide next action
|
|
|
+nop
|
|
|
memcmp:
|
|
|
- xor a ;0133
|
|
|
- or d ;0134
|
|
|
- or e ;0135 Any errors?
|
|
|
- jr z,floppystart ;0136
|
|
|
- ld ix,memcheckdisplay ;0138
|
|
|
- jp setupcrt ;013c
|
|
|
+ xor a ;0133 Clear A register
|
|
|
+ or d ;0134 Check global error flags in D
|
|
|
+ or e ;0135 Check bad bank count in E - Any errors?
|
|
|
+ jr z,floppystart ;0136 If no errors, proceed to floppy boot
|
|
|
+ ld ix,memcheckdisplay ;0138 Memory errors found - prepare error display
|
|
|
+ jp setupcrt ;013c Jump to CRT setup for error display
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; MEMORY ERROR DISPLAY ROUTINE
|
|
|
+; ================================================================================
|
|
|
+
|
|
|
memcheckdisplay:
|
|
|
- ld de,displaymem ;013f
|
|
|
- ld hl,ERROR2_start ;0142
|
|
|
- jp displaymsg ;0145
|
|
|
+ ld de,displaymem ;013f Point to display memory
|
|
|
+ ld hl,ERROR2_start ;0142 Point to error message
|
|
|
+ jp displaymsg ;0145 Display "Error #2 :Call service."
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; ERROR #2 MESSAGE DATA
|
|
|
+; ================================================================================
|
|
|
|
|
|
; BLOCK 'ERROR2' (start 0x0148 end 0x0160)
|
|
|
ERROR2_start:
|
|
|
- defb 017h ;0148 count 23
|
|
|
- defb 045h ;0149 Error #2 :Call service.
|
|
|
- defb 072h ;014a
|
|
|
- defb 072h ;014b
|
|
|
- defb 06fh ;014c
|
|
|
- defb 072h ;014d
|
|
|
- defb 020h ;014e
|
|
|
- defb 023h ;014f
|
|
|
- defb 032h ;0150
|
|
|
- defb 020h ;0151
|
|
|
- defb 03ah ;0152
|
|
|
- defb 043h ;0153
|
|
|
- defb 061h ;0154
|
|
|
- defb 06ch ;0155
|
|
|
- defb 06ch ;0156
|
|
|
- defb 020h ;0157
|
|
|
- defb 073h ;0158
|
|
|
- defb 065h ;0159
|
|
|
- defb 072h ;015a
|
|
|
- defb 076h ;015b
|
|
|
- defb 069h ;015c
|
|
|
- defb 063h ;015d
|
|
|
- defb 065h ;015e
|
|
|
- defb 02eh ;015f
|
|
|
+ defb 017h ;0148 Message length: 23 characters
|
|
|
+ defb 045h ;0149 'E' - "Error #2 :Call service."
|
|
|
+ defb 072h ;014a 'r'
|
|
|
+ defb 072h ;014b 'r'
|
|
|
+ defb 06fh ;014c 'o'
|
|
|
+ defb 072h ;014d 'r'
|
|
|
+ defb 020h ;014e ' '
|
|
|
+ defb 023h ;014f '#'
|
|
|
+ defb 032h ;0150 '2'
|
|
|
+ defb 020h ;0151 ' '
|
|
|
+ defb 03ah ;0152 ':'
|
|
|
+ defb 043h ;0153 'C'
|
|
|
+ defb 061h ;0154 'a'
|
|
|
+ defb 06ch ;0155 'l'
|
|
|
+ defb 06ch ;0156 'l'
|
|
|
+ defb 020h ;0157 ' '
|
|
|
+ defb 073h ;0158 's'
|
|
|
+ defb 065h ;0159 'e'
|
|
|
+ defb 072h ;015a 'r'
|
|
|
+ defb 076h ;015b 'v'
|
|
|
+ defb 069h ;015c 'i'
|
|
|
+ defb 063h ;015d 'c'
|
|
|
+ defb 065h ;015e 'e'
|
|
|
+ defb 02eh ;015f '.'
|
|
|
ERROR2_end:
|
|
|
- halt ;0160
|
|
|
+ halt ;0160 System halt - requires service intervention
|
|
|
+; ================================================================================
|
|
|
+; FLOPPY DISK BOOT INITIALIZATION
|
|
|
+; ================================================================================
|
|
|
+; Memory test passed - prepare for floppy disk boot
|
|
|
+
|
|
|
floppystart:
|
|
|
- out (0c5h),a ;0161 Program map B base
|
|
|
- out (0c8h),a ;0163 Map and system control
|
|
|
- dec hl ;0165
|
|
|
- dec hl ;0166
|
|
|
- ld a,(hl) ;0167
|
|
|
+ out (0c5h),a ;0161 Clear program map B base (A=0 from memcmp)
|
|
|
+ out (0c8h),a ;0163 Clear map and system control (disable banking)
|
|
|
+ dec hl ;0165 HL was pointing past end of memory test table
|
|
|
+ dec hl ;0166 Move back to get the memory size indicator
|
|
|
+ ld a,(hl) ;0167 Load memory configuration value
|
|
|
+
|
|
|
floppystart2:
|
|
|
- rrca ;0168
|
|
|
- and 080h ;0169
|
|
|
- ld (0ff80h),a ;016b
|
|
|
- ld de,0ffa6h ;016e
|
|
|
- ld hl,005beh ;0171
|
|
|
- ld bc,0005ah ;0174
|
|
|
- ldir ;0177
|
|
|
- call setupclearscreen2 ;0179
|
|
|
+ rrca ;0168 Rotate right with carry to get MSB
|
|
|
+ and 080h ;0169 Isolate bit 7 (128K vs 256K indicator)
|
|
|
+ ld (0ff80h),a ;016b Store memory size flag: 0x80=256K, 0x00=128K
|
|
|
+ ld de,0ffa6h ;016e Destination: high RAM workspace area
|
|
|
+ ld hl,005beh ;0171 Source: ROM data block at 0x05BE
|
|
|
+ ld bc,0005ah ;0174 Count: 90 bytes of runtime data
|
|
|
+ ldir ;0177 Copy ROM constants to RAM workspace
|
|
|
+ call setupclearscreen2 ;0179 Clear screen and setup display for boot
|
|
|
+; ================================================================================
|
|
|
+; DISK BOOT SEQUENCE WITH AUTO-RETRY
|
|
|
+; ================================================================================
|
|
|
+; ================================================================================
|
|
|
+; BOOT DEVICE DETECTION AND PRIORITY SYSTEM
|
|
|
+; ================================================================================
|
|
|
+; Memory initialization complete - attempt to boot with device auto-detection
|
|
|
+;
|
|
|
+; BOOT PRIORITY ORDER:
|
|
|
+; 1. Auto-detect controller type (port 0xFF) to determine available devices
|
|
|
+; 2. If hard disk detected: Try hard disk FIRST (faster, larger capacity)
|
|
|
+; 3. If hard disk fails or not present: Fall back to floppy disk drives
|
|
|
+; 4. Try drives in order: Drive 0, 1, 2, 3 (up to 8 total attempts)
|
|
|
+
|
|
|
readydiskloop:
|
|
|
- call readydisk ;017c
|
|
|
- call sub_061ch ;017f
|
|
|
- ld a,0ffh ;0182
|
|
|
- jr c,skipinvert ;0184
|
|
|
- cpl ;0186
|
|
|
+ call readydisk ;017c Display "Ready For System Disk" message
|
|
|
+ call sub_061ch ;017f *** CRITICAL *** Initialize disk controller & detect HDD vs floppy
|
|
|
+ ld a,0ffh ;0182 Load 0xFF (default retry flag)
|
|
|
+ jr c,skipinvert ;0184 Keep 0xFF if carry set (controller error - floppy only mode)
|
|
|
+ cpl ;0186 Invert to 0x00 (normal operation - HDD detection successful)
|
|
|
skipinvert:
|
|
|
- ld (0ff93h),a ;0187
|
|
|
- ld hl,00404h ;018a
|
|
|
- ld (0ff91h),hl ;018d
|
|
|
- or a ;0190
|
|
|
- jr nz,l01c3h ;0191
|
|
|
- ld c,010h ;0193
|
|
|
- call sub_065ah ;0195
|
|
|
- jr c,l01abh ;0198
|
|
|
- ld bc,00000h ;019a
|
|
|
- call sub_040eh ;019d
|
|
|
- jr c,l01abh ;01a0
|
|
|
- call sub_03a2h ;01a2
|
|
|
- ld a,(0ff8bh) ;01a5
|
|
|
- ld (0ff91h),a ;01a8
|
|
|
+ ld (0ff93h),a ;0187 Store boot device mode: 0xFF=floppy-only, 0x00=HDD+floppy available
|
|
|
+ ld hl,00404h ;018a H=4 retries, L=4 track number?
|
|
|
+ ld (0ff91h),hl ;018d Store retry count and track parameters
|
|
|
+ or a ;0190 Test the boot device mode flag
|
|
|
+ jr nz,l01c3h ;0191 If floppy-only mode (0xFF), skip HDD attempts, go to drive loop
|
|
|
+
|
|
|
+ ; *** HARD DISK BOOT ATTEMPTS (when HDD controller detected) ***
|
|
|
+ ; Normal boot mode: Try hard disk operations FIRST
|
|
|
+ ld c,010h ;0193 Hard disk command 0x10 (seek track 0/recalibrate)
|
|
|
+ call sub_065ah ;0195 Execute hard disk command through DMA
|
|
|
+ jr c,l01abh ;0198 If HDD error, try alternate HDD command
|
|
|
+ ld bc,00000h ;019a B=drive 0, C=track 0 (hard disk drive 0)
|
|
|
+ call sub_040eh ;019d Attempt to read boot sector from hard disk
|
|
|
+ jr c,l01abh ;01a0 If HDD read error, try alternate HDD approach
|
|
|
+ call sub_03a2h ;01a2 Process successful HDD sector read
|
|
|
+ ld a,(0ff8bh) ;01a5 Get boot validation result from HDD
|
|
|
+ ld (0ff91h),a ;01a8 Store HDD boot result
|
|
|
+
|
|
|
l01abh:
|
|
|
- ld c,011h ;01ab
|
|
|
- call sub_065ah ;01ad
|
|
|
- jr c,l01c3h ;01b0
|
|
|
- ld bc,0000h ;01b2
|
|
|
- call sub_040eh ;01b5
|
|
|
- jr c,l01c3h ;01b8
|
|
|
- call sub_03a2h ;01ba
|
|
|
- ld a,(0ff8bh) ;01bd
|
|
|
- ld (0ff92h),a ;01c0
|
|
|
+ ; *** ALTERNATE HARD DISK ATTEMPT ***
|
|
|
+ ld c,011h ;01ab Hard disk command 0x11 (alternate seek/step command)
|
|
|
+ call sub_065ah ;01ad Execute alternate hard disk command through DMA
|
|
|
+ jr c,l01c3h ;01b0 If HDD command error, fall back to floppy drives
|
|
|
+ ld bc,0000h ;01b2 B=drive 0, C=track 0 (hard disk drive 0)
|
|
|
+ call sub_040eh ;01b5 Second attempt to read HDD boot sector
|
|
|
+ jr c,l01c3h ;01b8 If HDD read still fails, fall back to floppy drives
|
|
|
+ call sub_03a2h ;01ba Process successful HDD sector read
|
|
|
+ ld a,(0ff8bh) ;01bd Get final HDD boot validation result
|
|
|
+ ld (0ff92h),a ;01c0 Store HDD boot result flag
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; FLOPPY DRIVE FALLBACK AND DRIVE SELECTION LOOP
|
|
|
+; ================================================================================
|
|
|
+; Reached when: 1) Hard disk not detected, 2) Hard disk boot failed, or 3) Force floppy mode
|
|
|
+; Systematically tries all floppy drives (0-3) with multiple retry attempts
|
|
|
+
|
|
|
l01c3h:
|
|
|
- ld a,001h ;01c3
|
|
|
- ld c,008h ;01c5
|
|
|
+ ld a,001h ;01c3 Start with drive bit 0 (will create drive ID 0xA1)
|
|
|
+ ld c,008h ;01c5 Retry counter: 8 attempts across all floppy drives
|
|
|
+
|
|
|
+driveloop:
|
|
|
l01c7h:
|
|
|
- or 0a0h ;01c7
|
|
|
- out (0c0h),a ;01c9 Floppy external control
|
|
|
- ld b,a ;01cb
|
|
|
+ ; *** FLOPPY DRIVE SELECTION ***
|
|
|
+ ; Drive encoding: 0xA1=Drive 0, 0xA2=Drive 1, 0xA4=Drive 2, 0xA8=Drive 3
|
|
|
+ or 0a0h ;01c7 OR with 0xA0 base: creates floppy controller commands
|
|
|
+ out (0c0h),a ;01c9 Select floppy drive via port 0xC0 (different from HDD ports 0x78-0x7B)
|
|
|
+ ld b,a ;01cb Save current drive select value
|
|
|
+
|
|
|
+; Wait for floppy drive ready status
|
|
|
l01cch:
|
|
|
- in a,(0b0h) ;01cc Floppy status
|
|
|
- rr a ;01ce
|
|
|
- jr c,l01cch ;01d0
|
|
|
- in a,(0b0h) ;01d2 Floppy status
|
|
|
- add a,a ;01d4
|
|
|
- jr c,l01ddh ;01d5
|
|
|
- call delayloop ;01d7
|
|
|
- call loadingdisk ;01da
|
|
|
+ in a,(0b0h) ;01cc Read floppy controller status register (port 0xB0, not HDD 0x79)
|
|
|
+ rr a ;01ce Rotate right - check busy bit (bit 0) into carry
|
|
|
+ jr c,l01cch ;01d0 Loop while floppy drive is busy (bit 0 = 1)
|
|
|
+ in a,(0b0h) ;01d2 Read floppy status again
|
|
|
+ add a,a ;01d4 Shift left - check ready bit (bit 7) into carry
|
|
|
+ jr c,l01ddh ;01d5 If floppy drive ready (bit 7 = 1), continue to next drive
|
|
|
+ call delayloop ;01d7 Floppy drive not ready - wait a bit
|
|
|
+ call loadingdisk ;01da Display "Loading..." and attempt boot from this floppy drive
|
|
|
+
|
|
|
+; *** DRIVE ADVANCEMENT AND RETRY LOGIC ***
|
|
|
l01ddh:
|
|
|
- inc c ;01dd
|
|
|
- ld a,b ;01de
|
|
|
- add a,a ;01df
|
|
|
- and 00fh ;01e0
|
|
|
- jr nz,l01c7h ;01e2
|
|
|
- ld a,(0ff93h) ;01e4
|
|
|
- or a ;01e7
|
|
|
- jr nz,l0204h ;01e8
|
|
|
- in a,(0ffh) ;01ea ????
|
|
|
- and 020h ;01ec
|
|
|
- jr nz,l0204h ;01ee
|
|
|
- ld c,010h ;01f0
|
|
|
- call sub_065ah ;01f2
|
|
|
- ld b,000h ;01f5
|
|
|
- call nc,loadingdisk ;01f7
|
|
|
- ld c,011h ;01fa
|
|
|
- call sub_065ah ;01fc
|
|
|
- ld b,000h ;01ff
|
|
|
- call nc,loadingdisk ;0201
|
|
|
+ inc c ;01dd Increment attempt counter (8 total attempts across all drives)
|
|
|
+ ld a,b ;01de Restore drive select value from previous iteration
|
|
|
+ add a,a ;01df Shift left to advance to next drive: 0xA1->0xA2->0xA4->0xA8
|
|
|
+ and 00fh ;01e0 Mask to keep only drive bits (removes 0xA0 base, leaves 1,2,4,8)
|
|
|
+ jr nz,l01c7h ;01e2 Continue loop if more drives to try (bits 1,2,4,8 not all exhausted)
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; ALL FLOPPY DRIVES EXHAUSTED - FINAL FALLBACK ATTEMPTS
|
|
|
+; ================================================================================
|
|
|
+; Reached when all floppy drives 0-3 have been tried and failed to boot
|
|
|
+
|
|
|
+ ld a,(0ff93h) ;01e4 Load boot mode flag from memory
|
|
|
+ or a ;01e7 Test if normal boot mode (0x00) or retry mode (0xFF)
|
|
|
+ jr nz,l0204h ;01e8 If already in retry mode, skip to "No System Device" error
|
|
|
+ in a,(0ffh) ;01ea Read hardware status port 0xFF (same port used for HDD detection)
|
|
|
+ and 020h ;01ec Check bit 5 - unknown hardware condition/status
|
|
|
+ jr nz,l0204h ;01ee If bit 5 set, skip directly to error message
|
|
|
+
|
|
|
+; *** DESPERATE FINAL ATTEMPTS ON DRIVE 0 ONLY ***
|
|
|
+; Special recovery commands specifically for Drive 0 as last resort
|
|
|
+ ld c,010h ;01f0 Load floppy command 0x10 (likely recalibrate/restore)
|
|
|
+ call sub_065ah ;01f2 Execute floppy controller command
|
|
|
+ ld b,000h ;01f5 Force selection of Drive 0 specifically
|
|
|
+ call nc,loadingdisk ;01f7 If command succeeded (no carry), try loading from Drive 0
|
|
|
+ ld c,011h ;01fa Load floppy command 0x11 (likely seek home/step in)
|
|
|
+ call sub_065ah ;01fc Execute second recovery command
|
|
|
+ ld b,000h ;01ff Force Drive 0 selection again
|
|
|
+ call nc,loadingdisk ;0201 If command succeeded, make final boot attempt from Drive 0
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; BOOT FAILURE - DISPLAY ERROR AND RESTART BOOT SEQUENCE
|
|
|
+; ================================================================================
|
|
|
+
|
|
|
l0204h:
|
|
|
- call setupclearscreen2 ;0204
|
|
|
- ld bc,002a3h ;0207
|
|
|
- ld hl,0061ah ;020a
|
|
|
- otir ;020d
|
|
|
- ld de,03000h ;020f
|
|
|
- ld hl,NOSYSTEM_start ;0212
|
|
|
- jp displaymsg ;0215
|
|
|
+ call setupclearscreen2 ;0204 Clear screen and setup display for error
|
|
|
+ ld bc,002a3h ;0207 B=2 bytes, C=0xA3 port (memory control?)
|
|
|
+ ld hl,0061ah ;020a Source: ROM data at 0x061A
|
|
|
+ otir ;020d Output 2 bytes to port 0xA3 (setup display controller)
|
|
|
+ ld de,03000h ;020f Display memory base address
|
|
|
+ ld hl,NOSYSTEM_start ;0212 Point to "No System Device On Line." message
|
|
|
+ jp displaymsg ;0215 Display error message and wait
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; "NO SYSTEM DEVICE ON LINE" MESSAGE AND RETRY LOOP
|
|
|
+; ================================================================================
|
|
|
|
|
|
; BLOCK 'NOSYSTEM' (start 0x0218 end 0x0232)
|
|
|
NOSYSTEM_start:
|
|
|
- defb 019h ;0218 count 25
|
|
|
- defb 04eh ;0219 No System Device On Line.
|
|
|
- defb 06fh ;021a
|
|
|
- defb 020h ;021b
|
|
|
- defb 053h ;021c
|
|
|
- defb 079h ;021d
|
|
|
- defb 073h ;021e
|
|
|
- defb 074h ;021f
|
|
|
- defb 065h ;0220
|
|
|
- defb 06dh ;0221
|
|
|
- defb 020h ;0222
|
|
|
- defb 044h ;0223
|
|
|
- defb 065h ;0224
|
|
|
- defb 076h ;0225
|
|
|
- defb 069h ;0226
|
|
|
- defb 063h ;0227
|
|
|
- defb 065h ;0228
|
|
|
- defb 020h ;0229
|
|
|
- defb 04fh ;022a
|
|
|
- defb 06eh ;022b
|
|
|
- defb 020h ;022c
|
|
|
- defb 04ch ;022d
|
|
|
- defb 069h ;022e
|
|
|
- defb 06eh ;022f
|
|
|
- defb 065h ;0230
|
|
|
- defb 02eh ;0231
|
|
|
+ defb 019h ;0218 Message length: 25 characters
|
|
|
+ defb 04eh ;0219 'N' - "No System Device On Line."
|
|
|
+ defb 06fh ;021a 'o'
|
|
|
+ defb 020h ;021b ' '
|
|
|
+ defb 053h ;021c 'S'
|
|
|
+ defb 079h ;021d 'y'
|
|
|
+ defb 073h ;021e 's'
|
|
|
+ defb 074h ;021f 't'
|
|
|
+ defb 065h ;0220 'e'
|
|
|
+ defb 06dh ;0221 'm'
|
|
|
+ defb 020h ;0222 ' '
|
|
|
+ defb 044h ;0223 'D'
|
|
|
+ defb 065h ;0224 'e'
|
|
|
+ defb 076h ;0225 'v'
|
|
|
+ defb 069h ;0226 'i'
|
|
|
+ defb 063h ;0227 'c'
|
|
|
+ defb 065h ;0228 'e'
|
|
|
+ defb 020h ;0229 ' '
|
|
|
+ defb 04fh ;022a 'O'
|
|
|
+ defb 06eh ;022b 'n'
|
|
|
+ defb 020h ;022c ' '
|
|
|
+ defb 04ch ;022d 'L'
|
|
|
+ defb 069h ;022e 'i'
|
|
|
+ defb 06eh ;022f 'n'
|
|
|
+ defb 065h ;0230 'e'
|
|
|
+ defb 02eh ;0231 '.'
|
|
|
NOSYSTEM_end:
|
|
|
- call delayloop ;0232
|
|
|
- call delayloop ;0235
|
|
|
- call delayloop ;0238
|
|
|
- jp readydiskloop ;023b
|
|
|
+ call delayloop ;0232 Wait for user to see message (~1 second)
|
|
|
+ call delayloop ;0235 Additional delay (~1 second)
|
|
|
+ call delayloop ;0238 Final delay (~1 second, total ~3 seconds)
|
|
|
+ jp readydiskloop ;023b Restart entire boot sequence - infinite retry loop!
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; CRITICAL ERROR HANDLER - SYSTEM HALT
|
|
|
+; ================================================================================
|
|
|
+; This routine is called for fatal hardware errors that require service
|
|
|
+
|
|
|
l023eh:
|
|
|
- ld ix,returnsetupcrt1 ;023e
|
|
|
- jp setupcrt ;0242
|
|
|
+ ld ix,returnsetupcrt1 ;023e Setup return address for CRT initialization
|
|
|
+ jp setupcrt ;0242 Initialize CRT controller and return here
|
|
|
+
|
|
|
returnsetupcrt1:
|
|
|
- call screenclearnetry2 ;0245
|
|
|
- rst 10h ;0248
|
|
|
+ call screenclearnetry2 ;0245 Clear screen and setup for error display
|
|
|
+ rst 10h ;0248 RST 10h: Display message routine
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; ERROR #0 MESSAGE DATA
|
|
|
+; ================================================================================
|
|
|
|
|
|
; BLOCK 'ERROR0' (start 0x0249 end 0x0261)
|
|
|
ERROR0_start:
|
|
|
- defb 017h ;0249 count 23
|
|
|
- defb 045h ;024a Error #0: Call service.
|
|
|
- defb 072h ;024b
|
|
|
- defb 072h ;024c
|
|
|
- defb 06fh ;024d
|
|
|
- defb 072h ;024e
|
|
|
- defb 020h ;024f
|
|
|
- defb 023h ;0250
|
|
|
- defb 030h ;0251
|
|
|
- defb 03ah ;0252
|
|
|
- defb 020h ;0253
|
|
|
- defb 043h ;0254
|
|
|
- defb 061h ;0255
|
|
|
- defb 06ch ;0256
|
|
|
- defb 06ch ;0257
|
|
|
- defb 020h ;0258
|
|
|
- defb 073h ;0259
|
|
|
- defb 065h ;025a
|
|
|
- defb 072h ;025b
|
|
|
- defb 076h ;025c
|
|
|
- defb 069h ;025d
|
|
|
- defb 063h ;025e
|
|
|
- defb 065h ;025f
|
|
|
- defb 02eh ;0260
|
|
|
+ defb 017h ;0249 Message length: 23 characters
|
|
|
+ defb 045h ;024a 'E' - "Error #0: Call service."
|
|
|
+ defb 072h ;024b 'r'
|
|
|
+ defb 072h ;024c 'r'
|
|
|
+ defb 06fh ;024d 'o'
|
|
|
+ defb 072h ;024e 'r'
|
|
|
+ defb 020h ;024f ' '
|
|
|
+ defb 023h ;0250 '#'
|
|
|
+ defb 030h ;0251 '0'
|
|
|
+ defb 03ah ;0252 ':'
|
|
|
+ defb 020h ;0253 ' '
|
|
|
+ defb 043h ;0254 'C'
|
|
|
+ defb 061h ;0255 'a'
|
|
|
+ defb 06ch ;0256 'l'
|
|
|
+ defb 06ch ;0257 'l'
|
|
|
+ defb 020h ;0258 ' '
|
|
|
+ defb 073h ;0259 's'
|
|
|
+ defb 065h ;025a 'e'
|
|
|
+ defb 072h ;025b 'r'
|
|
|
+ defb 076h ;025c 'v'
|
|
|
+ defb 069h ;025d 'i'
|
|
|
+ defb 063h ;025e 'c'
|
|
|
+ defb 065h ;025f 'e'
|
|
|
+ defb 02eh ;0260 '.'
|
|
|
ERROR0_end:
|
|
|
- halt ;0261
|
|
|
+ halt ;0261 System halt - requires service call
|
|
|
+; ================================================================================
|
|
|
+; DISK LOADING ROUTINE - MAIN BOOT SECTOR LOADER
|
|
|
+; ================================================================================
|
|
|
+; This routine displays "Loading" message and attempts to load the boot sector
|
|
|
+; Input: B = drive number (0-3)
|
|
|
+; Uses: All registers, modifies disk parameters at 0xFF81-0xFF82
|
|
|
+
|
|
|
loadingdisk:
|
|
|
- push bc ;0262
|
|
|
- xor a ;0263
|
|
|
- ld (0ff81h),a ;0264
|
|
|
- ld (0ff82h),a ;0267
|
|
|
- rst 8 ;026a
|
|
|
+ push bc ;0262 Save BC (drive number and parameters)
|
|
|
+ xor a ;0263 Clear A register (A = 0)
|
|
|
+ ld (0ff81h),a ;0264 Clear disk status parameter 1
|
|
|
+ ld (0ff82h),a ;0267 Clear disk status parameter 2
|
|
|
+ rst 8 ;026a RST 8: Display message routine
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; "LOADING " MESSAGE DATA
|
|
|
+; ================================================================================
|
|
|
|
|
|
; BLOCK 'LOADING' (start 0x026b end 0x0274)
|
|
|
LOADING_start:
|
|
|
- defb 008h ;026b count 8
|
|
|
- defb 04ch ;026c Loading
|
|
|
- defb 06fh ;026d
|
|
|
- defb 061h ;026e
|
|
|
- defb 064h ;026f
|
|
|
- defb 069h ;0270
|
|
|
- defb 06eh ;0271
|
|
|
- defb 067h ;0272
|
|
|
- defb 020h ;0273
|
|
|
+ defb 008h ;026b Message length: 8 characters
|
|
|
+ defb 04ch ;026c 'L' - "Loading "
|
|
|
+ defb 06fh ;026d 'o'
|
|
|
+ defb 061h ;026e 'a'
|
|
|
+ defb 064h ;026f 'd'
|
|
|
+ defb 069h ;0270 'i'
|
|
|
+ defb 06eh ;0271 'n'
|
|
|
+ defb 067h ;0272 'g'
|
|
|
+ defb 020h ;0273 ' '
|
|
|
LOADING_end:
|
|
|
- pop ix ;0274
|
|
|
- call sub_04a1h ;0276
|
|
|
- jr c,l023eh ;0279
|
|
|
- ld bc,0000h ;027b
|
|
|
- call sub_040eh ;027e
|
|
|
- jr c,l02ddh ;0281
|
|
|
- ld hl,(0ff81h) ;0283
|
|
|
- ld a,l ;0286
|
|
|
- and a ;0287
|
|
|
- jr z,l029ch ;0288
|
|
|
- ld a,h ;028a
|
|
|
- and 003h ;028b
|
|
|
- in a,(0ffh) ;028d
|
|
|
- jr z,l0298h ;028f
|
|
|
- bit 0,a ;0291
|
|
|
- jr nz,l029ch ;0293
|
|
|
+ pop ix ;0274 Restore IX from stack (return address)
|
|
|
+ call sub_04a1h ;0276 Initialize disk controller and seek to track 0
|
|
|
+ jr c,l023eh ;0279 If seek error, jump to fatal error handler
|
|
|
+ ld bc,0000h ;027b B=track 0, C=sector 0 (boot sector location)
|
|
|
+ call sub_040eh ;027e Read boot sector from disk
|
|
|
+ jr c,l02ddh ;0281 If read error, handle disk error
|
|
|
+
|
|
|
+ ; Check disk status and system configuration
|
|
|
+ ld hl,(0ff81h) ;0283 Load disk status parameters (2 bytes)
|
|
|
+ ld a,l ;0286 Get low byte of status
|
|
|
+ and a ;0287 Test if zero (no special conditions)
|
|
|
+ jr z,l029ch ;0288 If zero, continue with normal boot process
|
|
|
+ ld a,h ;028a Get high byte of status
|
|
|
+ and 003h ;028b Mask bits 0-1 (configuration bits)
|
|
|
+ in a,(0ffh) ;028d Read system status port 0xFF
|
|
|
+ jr z,l0298h ;028f If masked value is zero, check bit 1
|
|
|
+ bit 0,a ;0291 Test bit 0 of system status
|
|
|
+ jr nz,l029ch ;0293 If bit 0 set, continue normal boot
|
|
|
l0295h:
|
|
|
- jp l034bh ;0295
|
|
|
+ jp l034bh ;0295 Jump to alternate boot routine
|
|
|
+
|
|
|
l0298h:
|
|
|
- bit 1,a ;0298
|
|
|
- jr z,l0295h ;029a
|
|
|
+ bit 1,a ;0298 Test bit 1 of system status
|
|
|
+ jr z,l0295h ;029a If bit 1 clear, jump to alternate boot routine
|
|
|
+
|
|
|
l029ch:
|
|
|
- call sub_03a2h ;029c
|
|
|
- jp c,l0343h ;029f
|
|
|
- jr z,l02b6h ;02a2
|
|
|
- call sub_040eh ;02a4
|
|
|
- jr c,l02ddh ;02a7
|
|
|
- ld hl,0401fh ;02a9
|
|
|
- bit 0,(hl) ;02ac
|
|
|
- jp nz,l034fh ;02ae
|
|
|
- call sub_040eh ;02b1
|
|
|
- jr c,l02ddh ;02b4
|
|
|
+ call sub_03a2h ;029c Process and validate boot sector data
|
|
|
+ jp c,l0343h ;029f If validation failed (carry set), handle error
|
|
|
+ jr z,l02b6h ;02a2 If zero flag set, skip additional sector read
|
|
|
+ call sub_040eh ;02a4 Read additional sector data if needed
|
|
|
+ jr c,l02ddh ;02a7 If read error, handle disk error
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; BOOT SECTOR VALIDATION AND EXECUTION SETUP
|
|
|
+; ================================================================================
|
|
|
+; Boot sector successfully read - now validate and prepare for execution
|
|
|
+
|
|
|
+ ld hl,0401fh ;02a9 Point to boot sector signature/validity location
|
|
|
+ bit 0,(hl) ;02ac Check boot sector validity bit 0
|
|
|
+ jp nz,l034fh ;02ae If validity bit set, handle invalid boot sector
|
|
|
+ call sub_040eh ;02b1 Read final sector data if needed
|
|
|
+ jr c,l02ddh ;02b4 If read error, handle disk error
|
|
|
+
|
|
|
l02b6h:
|
|
|
- exx ;02b6
|
|
|
- ld hl,0400eh ;02b7
|
|
|
- ld d,(hl) ;02ba
|
|
|
- inc hl ;02bb
|
|
|
- ld e,(hl) ;02bc
|
|
|
- push de ;02bd
|
|
|
- pop iy ;02be
|
|
|
- ld hl,04080h ;02c0
|
|
|
- ld c,(hl) ;02c3
|
|
|
- inc hl ;02c4
|
|
|
- inc hl ;02c5
|
|
|
- ld d,(hl) ;02c6
|
|
|
- inc hl ;02c7
|
|
|
- ld e,(hl) ;02c8
|
|
|
- inc hl ;02c9
|
|
|
- ld a,(hl) ;02ca
|
|
|
- inc hl ;02cb
|
|
|
- ld l,(hl) ;02cc
|
|
|
- ld h,a ;02cd
|
|
|
- ex de,hl ;02ce
|
|
|
- push hl ;02cf
|
|
|
- ld a,e ;02d0
|
|
|
- add a,0ffh ;02d1
|
|
|
- ld a,d ;02d3
|
|
|
- exx ;02d4
|
|
|
- ld e,000h ;02d5
|
|
|
- adc a,e ;02d7
|
|
|
- ld d,a ;02d8
|
|
|
- pop hl ;02d9
|
|
|
- call sub_0414h ;02da
|
|
|
+ exx ;02b6 Switch to alternate register set (BC',DE',HL')
|
|
|
+ ld hl,0400eh ;02b7 Point to boot program load address in boot sector
|
|
|
+ ld d,(hl) ;02ba Get high byte of load address
|
|
|
+ inc hl ;02bb Move to next byte
|
|
|
+ ld e,(hl) ;02bc Get low byte of load address
|
|
|
+ push de ;02bd Save complete load address
|
|
|
+ pop iy ;02be IY = target load address for boot program
|
|
|
+ ld hl,04080h ;02c0 Point to boot sector parameter block
|
|
|
+ ld c,(hl) ;02c3 Get boot parameter 1
|
|
|
+ inc hl ;02c4 Skip reserved byte
|
|
|
+ inc hl ;02c5 Point to next parameter
|
|
|
+ ld d,(hl) ;02c6 Get parameter high byte
|
|
|
+ inc hl ;02c7 Move to next
|
|
|
+ ld e,(hl) ;02c8 Get parameter low byte
|
|
|
+ inc hl ;02c9 Move to next
|
|
|
+ ld a,(hl) ;02ca Get additional parameter byte
|
|
|
+ inc hl ;02cb Move to final parameter
|
|
|
+ ld l,(hl) ;02cc Get final parameter byte
|
|
|
+ ld h,a ;02cd Combine A and L into HL
|
|
|
+ ex de,hl ;02ce Exchange DE and HL registers
|
|
|
+ push hl ;02cf Save HL on stack
|
|
|
+ ld a,e ;02d0 Get low byte for calculation
|
|
|
+ add a,0ffh ;02d1 Add 255 (effectively subtract 1 with carry)
|
|
|
+ ld a,d ;02d3 Get high byte
|
|
|
+ exx ;02d4 Switch back to main register set
|
|
|
+ ld e,000h ;02d5 E = 0 for addition
|
|
|
+ adc a,e ;02d7 Add high byte with carry from previous operation
|
|
|
+ ld d,a ;02d8 D = calculated high byte for sector loading
|
|
|
+ pop hl ;02d9 Restore HL from stack (boot program parameters)
|
|
|
+ call sub_0414h ;02da Load complete boot program from disk into memory
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; BOOT PROGRAM EXECUTION AND TRANSFER OF CONTROL
|
|
|
+; ================================================================================
|
|
|
+; Boot program successfully loaded - now transfer control to the loaded code
|
|
|
+
|
|
|
l02ddh:
|
|
|
- jr c,l0347h ;02dd
|
|
|
- ld a,(0ff8bh) ;02df
|
|
|
- cp 002h ;02e2
|
|
|
- jr z,l02eeh ;02e4
|
|
|
- xor a ;02e6
|
|
|
- ex af,af' ;02e7
|
|
|
- exx ;02e8
|
|
|
- jp 0ffa6h ;02e9
|
|
|
+ jr c,l0347h ;02dd If disk load error (carry set), handle error
|
|
|
+ ld a,(0ff8bh) ;02df Get boot completion status flag
|
|
|
+ cp 002h ;02e2 Check if status = 2 (special boot mode)
|
|
|
+ jr z,l02eeh ;02e4 If special mode, use alternate execution path
|
|
|
+
|
|
|
+ ; Standard boot execution: Transfer control to loaded program
|
|
|
+ xor a ;02e6 Clear A register (A = 0)
|
|
|
+ ex af,af' ;02e7 Save AF to alternate AF' register
|
|
|
+ exx ;02e8 Switch to alternate register set
|
|
|
+ jp 0ffa6h ;02e9 *** TRANSFER CONTROL TO LOADED BOOT PROGRAM! ***
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; ALTERNATE BOOT EXECUTION PATH
|
|
|
+; ================================================================================
|
|
|
+; Special boot mode handling (status = 2)
|
|
|
+
|
|
|
l02ech:
|
|
|
- ex af,af' ;02ec
|
|
|
- adc a,c ;02ed
|
|
|
+ ex af,af' ;02ec Restore AF from alternate register
|
|
|
+ adc a,c ;02ed Add C with carry for parameter processing
|
|
|
+
|
|
|
l02eeh:
|
|
|
- push ix ;02ee
|
|
|
- pop bc ;02f0
|
|
|
- ld a,(0ff8bh) ;02f1
|
|
|
- ld de,00013h ;02f4
|
|
|
- ld hl,0ff8dh ;02f7
|
|
|
- jr nz,l033fh ;02fa
|
|
|
- cp 002h ;02fc
|
|
|
- jp nz,0ffb8h ;02fe
|
|
|
- push bc ;0301
|
|
|
- bit 3,c ;0302
|
|
|
- jr nz,l030bh ;0304
|
|
|
- ld a,0ffh ;0306
|
|
|
- ld (0ff81h),a ;0308
|
|
|
+ push ix ;02ee Save IX register (return address)
|
|
|
+ pop bc ;02f0 BC = return address from IX
|
|
|
+ ld a,(0ff8bh) ;02f1 Get boot completion status flag
|
|
|
+ ld de,00013h ;02f4 DE = 0x0013 (parameter constant)
|
|
|
+ ld hl,0ff8dh ;02f7 HL = system parameter storage area
|
|
|
+ jr nz,l033fh ;02fa If status not zero, jump to error 0x33
|
|
|
+ cp 002h ;02fc Compare status with 2 (special boot mode)
|
|
|
+ jp nz,0ffb8h ;02fe If not 2, jump to alternate boot entry point
|
|
|
+
|
|
|
+ ; Special boot mode (status = 2) - setup system parameters
|
|
|
+ push bc ;0301 Save return address
|
|
|
+ bit 3,c ;0302 Test bit 3 of return address low byte
|
|
|
+ jr nz,l030bh ;0304 If bit 3 set, skip disk flag setup
|
|
|
+ ld a,0ffh ;0306 Set disk parameter flag
|
|
|
+ ld (0ff81h),a ;0308 Store at disk parameter location
|
|
|
+
|
|
|
l030bh:
|
|
|
- in a,(0ffh) ;030b
|
|
|
- ld c,a ;030d
|
|
|
- xor a ;030e
|
|
|
- bit 0,c ;030f
|
|
|
- jr z,l0315h ;0311
|
|
|
- ld a,00fh ;0313
|
|
|
+ in a,(0ffh) ;030b Read system status port 0xFF
|
|
|
+ ld c,a ;030d Save status in C
|
|
|
+ xor a ;030e Clear A register (A = 0)
|
|
|
+ bit 0,c ;030f Test bit 0 of system status
|
|
|
+ jr z,l0315h ;0311 If bit 0 clear, skip
|
|
|
+ ld a,00fh ;0313 Set A = 0x0F (enable low nibble)
|
|
|
+
|
|
|
l0315h:
|
|
|
- bit 1,c ;0315
|
|
|
- jr z,l031bh ;0317
|
|
|
- or 0f0h ;0319
|
|
|
+ bit 1,c ;0315 Test bit 1 of system status
|
|
|
+ jr z,l031bh ;0317 If bit 1 clear, skip
|
|
|
+ or 0f0h ;0319 Set high nibble (A |= 0xF0)
|
|
|
+
|
|
|
l031bh:
|
|
|
- ld b,a ;031b
|
|
|
- ld a,(0ff81h) ;031c
|
|
|
- cpl ;031f
|
|
|
- and a ;0320
|
|
|
- jr z,l0334h ;0321
|
|
|
- push bc ;0323
|
|
|
- push ix ;0324
|
|
|
- pop bc ;0326
|
|
|
- ld a,c ;0327
|
|
|
- sub 007h ;0328
|
|
|
- ld b,a ;032a
|
|
|
- ld a,080h ;032b
|
|
|
+ ld b,a ;031b B = combined system configuration mask
|
|
|
+ ld a,(0ff81h) ;031c Get disk parameter flag
|
|
|
+ cpl ;031f Complement (invert all bits)
|
|
|
+ and a ;0320 Test if result is zero
|
|
|
+ jr z,l0334h ;0321 If zero (was 0xFF), skip complex calculation
|
|
|
+
|
|
|
+ ; Complex bit manipulation for drive/system configuration
|
|
|
+ push bc ;0323 Save BC (config mask and status)
|
|
|
+ push ix ;0324 Save IX
|
|
|
+ pop bc ;0326 BC = IX (return address)
|
|
|
+ ld a,c ;0327 Get low byte of return address
|
|
|
+ sub 007h ;0328 Subtract 7 (adjust for calculation)
|
|
|
+ ld b,a ;032a B = adjusted value
|
|
|
+ ld a,080h ;032b Start with bit 7 set (0x80)
|
|
|
+
|
|
|
+ ; Rotate bit pattern based on adjusted return address
|
|
|
l032dh:
|
|
|
- rlca ;032d
|
|
|
- rlca ;032e
|
|
|
- djnz l032dh ;032f
|
|
|
- pop bc ;0331
|
|
|
- and b ;0332
|
|
|
- rrca ;0333
|
|
|
+ rlca ;032d Rotate left with carry (shift bit pattern)
|
|
|
+ rlca ;032e Rotate left again (2 positions per loop)
|
|
|
+ djnz l032dh ;032f Decrement B and loop until B=0
|
|
|
+ pop bc ;0331 Restore BC (config mask and status)
|
|
|
+ and b ;0332 Mask with configuration bits
|
|
|
+ rrca ;0333 Rotate right once (adjust final position)
|
|
|
+
|
|
|
l0334h:
|
|
|
- xor b ;0334
|
|
|
- pop bc ;0335
|
|
|
- ld (0ff81h),a ;0336
|
|
|
- ld a,(0ff8bh) ;0339
|
|
|
- jp 0ffb8h ;033c
|
|
|
+ xor b ;0334 XOR with configuration mask
|
|
|
+ pop bc ;0335 Restore original BC (return address)
|
|
|
+ ld (0ff81h),a ;0336 Store final calculated system parameter
|
|
|
+ ld a,(0ff8bh) ;0339 Get boot completion status
|
|
|
+ jp 0ffb8h ;033c Jump to final boot entry point in RAM
|
|
|
+; ================================================================================
|
|
|
+; BOOT ERROR CLASSIFICATION AND DISPLAY
|
|
|
+; ================================================================================
|
|
|
+; Various boot errors are classified and appropriate error messages displayed
|
|
|
+
|
|
|
l033fh:
|
|
|
- ld a,033h ;033f
|
|
|
- jr l0351h ;0341
|
|
|
+ ld a,033h ;033f Error code 0x33 (51 decimal) - set error number
|
|
|
+ jr l0351h ;0341 Jump to error display routine
|
|
|
+
|
|
|
l0343h:
|
|
|
- ld a,030h ;0343
|
|
|
- jr l0351h ;0345
|
|
|
+ ld a,030h ;0343 Error code 0x30 (48 decimal) - validation error
|
|
|
+ jr l0351h ;0345 Jump to error display routine
|
|
|
+
|
|
|
l0347h:
|
|
|
- ld a,032h ;0347
|
|
|
- jr l0351h ;0349
|
|
|
+ ld a,032h ;0347 Error code 0x32 (50 decimal) - disk read error
|
|
|
+ jr l0351h ;0349 Jump to error display routine
|
|
|
+
|
|
|
l034bh:
|
|
|
- ld a,039h ;034b
|
|
|
- jr l0351h ;034d
|
|
|
+ ld a,039h ;034b Error code 0x39 (57 decimal) - system configuration error
|
|
|
+ jr l0351h ;034d Jump to error display routine
|
|
|
+
|
|
|
l034fh:
|
|
|
- ld a,031h ;034f
|
|
|
+ ld a,031h ;034f Error code 0x31 (49 decimal) - invalid boot sector
|
|
|
+
|
|
|
+; Common error display routine - converts error code to display
|
|
|
l0351h:
|
|
|
- push ix ;0351
|
|
|
- push af ;0353
|
|
|
- call screenclearnetry2 ;0354
|
|
|
- push de ;0357
|
|
|
- rst 10h ;0358
|
|
|
+ push ix ;0351 Save IX register (return address)
|
|
|
+ push af ;0353 Save error code on stack
|
|
|
+ call screenclearnetry2 ;0354 Clear screen and setup display
|
|
|
+ push de ;0357 Save DE register
|
|
|
+ rst 10h ;0358 RST 10h: Display message routine
|
|
|
|
|
|
-; BLOCK 'INVALID' (start 0x0359 end 0x0382)
|
|
|
+; ================================================================================
|
|
|
+; ERROR #10 MESSAGE DATA - INVALID SYSTEM DISK
|
|
|
+; ================================================================================
|
|
|
+
|
|
|
+; BLOCK 'INVALID' (start 0x0359 end 0x0382)
|
|
|
INVALID_start:
|
|
|
- defb 028h ;0359 count 40
|
|
|
- defb 045h ;035a Error #10: Invalid System Disk in Drive
|
|
|
- defb 072h ;035b
|
|
|
- defb 072h ;035c
|
|
|
- defb 06fh ;035d
|
|
|
- defb 072h ;035e
|
|
|
- defb 020h ;035f
|
|
|
- defb 023h ;0360
|
|
|
- defb 031h ;0361
|
|
|
- defb 030h ;0362
|
|
|
- defb 03ah ;0363
|
|
|
- defb 020h ;0364
|
|
|
- defb 049h ;0365
|
|
|
- defb 06eh ;0366
|
|
|
- defb 076h ;0367
|
|
|
- defb 061h ;0368
|
|
|
- defb 06ch ;0369
|
|
|
- defb 069h ;036a
|
|
|
- defb 064h ;036b
|
|
|
- defb 020h ;036c
|
|
|
- defb 053h ;036d
|
|
|
- defb 079h ;036e
|
|
|
- defb 073h ;036f
|
|
|
- defb 074h ;0370
|
|
|
- defb 065h ;0371
|
|
|
- defb 06dh ;0372
|
|
|
- defb 020h ;0373
|
|
|
- defb 044h ;0374
|
|
|
- defb 069h ;0375
|
|
|
- defb 073h ;0376
|
|
|
- defb 06bh ;0377
|
|
|
- defb 020h ;0378
|
|
|
- defb 069h ;0379
|
|
|
- defb 06eh ;037a
|
|
|
- defb 020h ;037b
|
|
|
- defb 044h ;037c
|
|
|
- defb 072h ;037d
|
|
|
- defb 069h ;037e
|
|
|
- defb 076h ;037f
|
|
|
- defb 065h ;0380
|
|
|
- defb 020h ;0381
|
|
|
+ defb 028h ;0359 Message length: 40 characters
|
|
|
+ defb 045h ;035a 'E' - "Error #10: Invalid System Disk in Drive "
|
|
|
+ defb 072h ;035b 'r'
|
|
|
+ defb 072h ;035c 'r'
|
|
|
+ defb 06fh ;035d 'o'
|
|
|
+ defb 072h ;035e 'r'
|
|
|
+ defb 020h ;035f ' '
|
|
|
+ defb 023h ;0360 '#'
|
|
|
+ defb 031h ;0361 '1'
|
|
|
+ defb 030h ;0362 '0'
|
|
|
+ defb 03ah ;0363 ':'
|
|
|
+ defb 020h ;0364 ' '
|
|
|
+ defb 049h ;0365 'I'
|
|
|
+ defb 06eh ;0366 'n'
|
|
|
+ defb 076h ;0367 'v'
|
|
|
+ defb 061h ;0368 'a'
|
|
|
+ defb 06ch ;0369 'l'
|
|
|
+ defb 069h ;036a 'i'
|
|
|
+ defb 064h ;036b 'd'
|
|
|
+ defb 020h ;036c ' '
|
|
|
+ defb 053h ;036d 'S'
|
|
|
+ defb 079h ;036e 'y'
|
|
|
+ defb 073h ;036f 's'
|
|
|
+ defb 074h ;0370 't'
|
|
|
+ defb 065h ;0371 'e'
|
|
|
+ defb 06dh ;0372 'm'
|
|
|
+ defb 020h ;0373 ' '
|
|
|
+ defb 044h ;0374 'D'
|
|
|
+ defb 069h ;0375 'i'
|
|
|
+ defb 073h ;0376 's'
|
|
|
+ defb 06bh ;0377 'k'
|
|
|
+ defb 020h ;0378 ' '
|
|
|
+ defb 069h ;0379 'i'
|
|
|
+ defb 06eh ;037a 'n'
|
|
|
+ defb 020h ;037b ' '
|
|
|
+ defb 044h ;037c 'D'
|
|
|
+ defb 072h ;037d 'r'
|
|
|
+ defb 069h ;037e 'i'
|
|
|
+ defb 076h ;037f 'v'
|
|
|
+ defb 065h ;0380 'e'
|
|
|
+ defb 020h ;0381 ' '
|
|
|
INVALID_end:
|
|
|
- pop hl ;0382
|
|
|
- pop bc ;0383
|
|
|
- ld de,0008h ;0384
|
|
|
- add hl,de ;0387
|
|
|
- add hl,de ;0388
|
|
|
- inc hl ;0389
|
|
|
- ld a,004h ;038a Select display memory
|
|
|
- out (0c8h),a ;038c Map and system control
|
|
|
- ld (hl),b ;038e
|
|
|
- xor a ;038f
|
|
|
- out (0c8h),a ;0390 Map and system control
|
|
|
- call delayloop ;0392
|
|
|
- call delayloop ;0395
|
|
|
- call setupclearscreen2 ;0398
|
|
|
- call readydisk ;039b
|
|
|
- exx ;039e
|
|
|
- pop bc ;039f
|
|
|
- scf ;03a0
|
|
|
- ret ;03a1
|
|
|
+ pop hl ;0382 Restore HL register (display parameters)
|
|
|
+ pop bc ;0383 Restore BC register (error code and return address)
|
|
|
+ ld de,0008h ;0384 DE = 8 (offset for drive number display)
|
|
|
+ add hl,de ;0387 HL += 8 (position for drive number)
|
|
|
+ add hl,de ;0388 HL += 8 again (total offset = 16)
|
|
|
+ inc hl ;0389 HL += 1 (final position for drive character)
|
|
|
+ ld a,004h ;038a Memory bank 4 (display memory access)
|
|
|
+ out (0c8h),a ;038c Select display memory bank
|
|
|
+ ld (hl),b ;038e Store drive number/character in display
|
|
|
+ xor a ;038f Clear A (bank 0)
|
|
|
+ out (0c8h),a ;0390 Restore normal memory mapping
|
|
|
+ call delayloop ;0392 Wait for user to see error message
|
|
|
+ call delayloop ;0395 Additional delay
|
|
|
+ call setupclearscreen2 ;0398 Clear screen and prepare for retry
|
|
|
+ call readydisk ;039b Display "Ready For System Disk" again
|
|
|
+ exx ;039e Switch to alternate register set
|
|
|
+ pop bc ;039f Restore registers from stack
|
|
|
+ scf ;03a0 Set carry flag (error condition)
|
|
|
+ ret ;03a1 Return to caller
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; BOOT SECTOR VALIDATION ROUTINE
|
|
|
+; ================================================================================
|
|
|
+; Validates boot sector contents and determines next actions
|
|
|
+; Input: Boot sector loaded at 0x4000
|
|
|
+; Output: Carry set if invalid, Z flag indicates additional reads needed
|
|
|
+
|
|
|
sub_03a2h:
|
|
|
- ld a,003h ;03a2
|
|
|
- ld (0ff8bh),a ;03a4
|
|
|
- ld hl,0401dh ;03a7
|
|
|
- ld a,(hl) ;03aa
|
|
|
- cp 0e5h ;03ab
|
|
|
- scf ;03ad
|
|
|
- ret z ;03ae
|
|
|
- cp 06ch ;03af
|
|
|
- scf ;03b1
|
|
|
- ret z ;03b2
|
|
|
- add a,001h ;03b3
|
|
|
- jr nc,l03bdh ;03b5
|
|
|
- ld hl,0ff8bh ;03b7
|
|
|
- ld (hl),002h ;03ba
|
|
|
- ret ;03bc
|
|
|
+ ld a,003h ;03a2 Set boot status = 3 (validation in progress)
|
|
|
+ ld (0ff8bh),a ;03a4 Store at boot status location
|
|
|
+ ld hl,0401dh ;03a7 Point to boot sector validation byte
|
|
|
+ ld a,(hl) ;03aa Load validation byte
|
|
|
+ cp 0e5h ;03ab Check for 0xE5 (invalid marker 1)
|
|
|
+ scf ;03ad Set carry flag (error)
|
|
|
+ ret z ;03ae Return if invalid (0xE5)
|
|
|
+ cp 06ch ;03af Check for 0x6C (invalid marker 2)
|
|
|
+ scf ;03b1 Set carry flag (error)
|
|
|
+ ret z ;03b2 Return if invalid (0x6C)
|
|
|
+ add a,001h ;03b3 Add 1 to validation byte
|
|
|
+ jr nc,l03bdh ;03b5 If no carry, continue validation
|
|
|
+ ld hl,0ff8bh ;03b7 Point to boot status
|
|
|
+ ld (hl),002h ;03ba Set status = 2 (special boot mode)
|
|
|
+ ret ;03bc Return with status 2
|
|
|
+
|
|
|
l03bdh:
|
|
|
- inc hl ;03bd
|
|
|
- ld b,(hl) ;03be
|
|
|
- ld a,b ;03bf
|
|
|
- inc hl ;03c0
|
|
|
- ld c,(hl) ;03c1
|
|
|
- add a,001h ;03c2
|
|
|
- adc a,c ;03c4
|
|
|
- ld hl,0ff8bh ;03c5
|
|
|
- ld (hl),002h ;03c8
|
|
|
- jr z,l03d4h ;03ca
|
|
|
- ld (hl),001h ;03cc
|
|
|
- ld a,b ;03ce
|
|
|
- or c ;03cf
|
|
|
- scf ;03d0
|
|
|
- ret z ;03d1
|
|
|
- or a ;03d2
|
|
|
- ret ;03d3
|
|
|
+ inc hl ;03bd Move to next boot sector parameter
|
|
|
+ ld b,(hl) ;03be Get parameter 1
|
|
|
+ ld a,b ;03bf Copy to A
|
|
|
+ inc hl ;03c0 Move to next parameter
|
|
|
+ ld c,(hl) ;03c1 Get parameter 2
|
|
|
+ add a,001h ;03c2 Add 1 to parameter 1
|
|
|
+ adc a,c ;03c4 Add parameter 2 with carry
|
|
|
+ ld hl,0ff8bh ;03c5 Point to boot status
|
|
|
+ ld (hl),002h ;03c8 Set status = 2 (default)
|
|
|
+ jr z,l03d4h ;03ca If sum is zero, continue
|
|
|
+ ld (hl),001h ;03cc Set status = 1 (normal boot)
|
|
|
+ ld a,b ;03ce Get parameter 1 again
|
|
|
+ or c ;03cf OR with parameter 2
|
|
|
+ scf ;03d0 Set carry flag (error)
|
|
|
+ ret z ;03d1 Return with error if both parameters are zero
|
|
|
+ or a ;03d2 Clear carry flag (success)
|
|
|
+ ret ;03d3 Return with success
|
|
|
+
|
|
|
l03d4h:
|
|
|
- ld bc,0001h ;03d4
|
|
|
- or a ;03d7
|
|
|
- ret ;03d8
|
|
|
+ ld bc,0001h ;03d4 BC = 1 (additional sector needed)
|
|
|
+ or a ;03d7 Clear carry flag (success, additional read needed)
|
|
|
+ ret ;03d8 Return indicating additional sector read required
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; "READY FOR SYSTEM DISK" MESSAGE DISPLAY
|
|
|
+; ================================================================================
|
|
|
+; Displays the ready message showing ROM version
|
|
|
+
|
|
|
readydisk:
|
|
|
- ld de,displaymem ;03d9
|
|
|
- rst 10h ;03dc
|
|
|
+ ld de,displaymem ;03d9 DE = display memory base address
|
|
|
+ rst 10h ;03dc RST 10h: Display message routine
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; "READY FOR SYSTEM DISK" MESSAGE DATA
|
|
|
+; ================================================================================
|
|
|
|
|
|
; BLOCK 'READY' (start 0x03dd end 0x03fb)
|
|
|
READY_start:
|
|
|
- defb 01dh ;03dd count 29
|
|
|
- defb 052h ;03de R3-00C Ready For System Disk
|
|
|
- defb 033h ;03df
|
|
|
- defb 02dh ;03e0
|
|
|
- defb 030h ;03e1
|
|
|
- defb 030h ;03e2
|
|
|
- defb 043h ;03e3
|
|
|
- defb 020h ;03e4
|
|
|
- defb 052h ;03e5
|
|
|
- defb 065h ;03e6
|
|
|
- defb 061h ;03e7
|
|
|
- defb 064h ;03e8
|
|
|
- defb 079h ;03e9
|
|
|
- defb 020h ;03ea
|
|
|
- defb 046h ;03eb
|
|
|
- defb 06fh ;03ec
|
|
|
- defb 072h ;03ed
|
|
|
- defb 020h ;03ee
|
|
|
- defb 053h ;03ef
|
|
|
- defb 079h ;03f0
|
|
|
- defb 073h ;03f1
|
|
|
- defb 074h ;03f2
|
|
|
- defb 065h ;03f3
|
|
|
- defb 06dh ;03f4
|
|
|
- defb 020h ;03f5
|
|
|
- defb 044h ;03f6
|
|
|
- defb 069h ;03f7
|
|
|
- defb 073h ;03f8
|
|
|
- defb 06bh ;03f9
|
|
|
- defb 020h ;03fa
|
|
|
+ defb 01dh ;03dd Message length: 29 characters
|
|
|
+ defb 052h ;03de 'R' - "R3-00C Ready For System Disk "
|
|
|
+ defb 033h ;03df '3'
|
|
|
+ defb 02dh ;03e0 '-'
|
|
|
+ defb 030h ;03e1 '0'
|
|
|
+ defb 030h ;03e2 '0'
|
|
|
+ defb 043h ;03e3 'C'
|
|
|
+ defb 020h ;03e4 ' '
|
|
|
+ defb 052h ;03e5 'R'
|
|
|
+ defb 065h ;03e6 'e'
|
|
|
+ defb 061h ;03e7 'a'
|
|
|
+ defb 064h ;03e8 'd'
|
|
|
+ defb 079h ;03e9 'y'
|
|
|
+ defb 020h ;03ea ' '
|
|
|
+ defb 046h ;03eb 'F'
|
|
|
+ defb 06fh ;03ec 'o'
|
|
|
+ defb 072h ;03ed 'r'
|
|
|
+ defb 020h ;03ee ' '
|
|
|
+ defb 053h ;03ef 'S'
|
|
|
+ defb 079h ;03f0 'y'
|
|
|
+ defb 073h ;03f1 's'
|
|
|
+ defb 074h ;03f2 't'
|
|
|
+ defb 065h ;03f3 'e'
|
|
|
+ defb 06dh ;03f4 'm'
|
|
|
+ defb 020h ;03f5 ' '
|
|
|
+ defb 044h ;03f6 'D'
|
|
|
+ defb 069h ;03f7 'i'
|
|
|
+ defb 073h ;03f8 's'
|
|
|
+ defb 06bh ;03f9 'k'
|
|
|
+ defb 020h ;03fa ' '
|
|
|
READY_end:
|
|
|
- call delayloop ;03fb
|
|
|
- ret ;03fe
|
|
|
- ld b,00ah ;03ff
|
|
|
- ld hl,0000h ;0401
|
|
|
+ call delayloop ;03fb Wait briefly after displaying message
|
|
|
+ ret ;03fe Return to caller
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; INTERNAL DELAY ROUTINE (PART OF READY FUNCTION)
|
|
|
+; ================================================================================
|
|
|
+; This is part of the ready function flow, not a standalone delay routine
|
|
|
+
|
|
|
+ ld b,00ah ;03ff B = 10 (outer loop counter)
|
|
|
+ ld hl,0000h ;0401 HL = 0 (inner loop counter)
|
|
|
l0404h:
|
|
|
- inc hl ;0404
|
|
|
- ld a,l ;0405
|
|
|
- or h ;0406
|
|
|
- jr nz,l0404h ;0407
|
|
|
- djnz l0404h ;0409
|
|
|
- jp memcmp ;040b
|
|
|
+ inc hl ;0404 Increment HL
|
|
|
+ ld a,l ;0405 Test if HL reached 0x0000 again
|
|
|
+ or h ;0406 (after wrapping around 65536 times)
|
|
|
+ jr nz,l0404h ;0407 Continue inner loop until HL wraps to 0
|
|
|
+ djnz l0404h ;0409 Decrement B and repeat outer loop
|
|
|
+ jp memcmp ;040b Jump to memory compare routine
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; DISK SECTOR READ ROUTINES
|
|
|
+; ================================================================================
|
|
|
+; Main disk I/O routines for reading boot sectors and program data
|
|
|
+
|
|
|
sub_040eh:
|
|
|
- ld de,00100h ;040e
|
|
|
- ld hl,04000h ;0411
|
|
|
+ ld de,00100h ;040e DE = 0x0100 (256 bytes = 1 sector)
|
|
|
+ ld hl,04000h ;0411 HL = 0x4000 (sector buffer address)
|
|
|
+
|
|
|
sub_0414h:
|
|
|
- push bc ;0414
|
|
|
- push ix ;0415
|
|
|
- pop bc ;0417
|
|
|
- ld a,c ;0418
|
|
|
- pop bc ;0419
|
|
|
- cp 010h ;041a
|
|
|
- jp nc,l06c1h ;041c
|
|
|
+ push bc ;0414 Save BC (track/sector parameters)
|
|
|
+ push ix ;0415 Save IX
|
|
|
+ pop bc ;0417 BC = IX (return address)
|
|
|
+ ld a,c ;0418 Get low byte of return address
|
|
|
+ pop bc ;0419 Restore original BC
|
|
|
+ cp 010h ;041a Check if return address low byte < 0x10
|
|
|
+ jp nc,l06c1h ;041c If >= 0x10, jump to alternate routine
|
|
|
+
|
|
|
l041fh:
|
|
|
- ld a,005h ;041f
|
|
|
+ ld a,005h ;041f A = 5 (retry counter for disk operations)
|
|
|
+
|
|
|
l0421h:
|
|
|
- ex af,af' ;0421
|
|
|
- push bc ;0422
|
|
|
- ex (sp),hl ;0423
|
|
|
- ld a,l ;0424
|
|
|
- and 00fh ;0425
|
|
|
- push bc ;0427
|
|
|
- push af ;0428
|
|
|
- ld a,(0ff81h) ;0429
|
|
|
- and a ;042c
|
|
|
- ld b,000h ;042d
|
|
|
- jr z,l0433h ;042f
|
|
|
- ld b,010h ;0431
|
|
|
+ ex af,af' ;0421 Save retry counter in AF'
|
|
|
+ push bc ;0422 Save BC (track/sector)
|
|
|
+ ex (sp),hl ;0423 Exchange HL with top of stack
|
|
|
+ ld a,l ;0424 Get low byte
|
|
|
+ and 00fh ;0425 Mask to lower 4 bits
|
|
|
+ push bc ;0427 Save BC again
|
|
|
+ push af ;0428 Save masked value
|
|
|
+ ld a,(0ff81h) ;0429 Get disk parameter flag
|
|
|
+ and a ;042c Test if zero
|
|
|
+ ld b,000h ;042d B = 0 (default sector offset)
|
|
|
+ jr z,l0433h ;042f If flag is zero, use offset 0
|
|
|
+ ld b,010h ;0431 B = 0x10 (alternate sector offset)
|
|
|
+
|
|
|
l0433h:
|
|
|
- pop af ;0433
|
|
|
- add a,b ;0434
|
|
|
- inc a ;0435
|
|
|
- out (0b2h),a ;0436 Floppy sector register
|
|
|
- add hl,hl ;0438
|
|
|
- add hl,hl ;0439
|
|
|
- add hl,hl ;043a
|
|
|
- add hl,hl ;043b
|
|
|
- cp 011h ;043c
|
|
|
- ld a,h ;043e
|
|
|
- out (0b3h),a ;043f Floppy data register
|
|
|
- jr c,l0453h ;0441
|
|
|
- rra ;0443
|
|
|
- out (0b3h),a ;0444 Floppy data register
|
|
|
- push ix ;0446
|
|
|
- pop bc ;0448
|
|
|
- ld a,b ;0449
|
|
|
- jr nc,l044eh ;044a
|
|
|
- or 010h ;044c
|
|
|
+ pop af ;0433 Restore masked value from stack
|
|
|
+ add a,b ;0434 Add sector offset (0 or 0x10)
|
|
|
+ inc a ;0435 Add 1 (sectors are 1-based)
|
|
|
+ out (0b2h),a ;0436 Write to floppy sector register
|
|
|
+ add hl,hl ;0438 HL *= 2 (shift left)
|
|
|
+ add hl,hl ;0439 HL *= 2 (shift left again)
|
|
|
+ add hl,hl ;043a HL *= 2 (shift left again)
|
|
|
+ add hl,hl ;043b HL *= 2 (total: HL *= 16 for track calculation)
|
|
|
+ cp 011h ;043c Compare sector with 17
|
|
|
+ ld a,h ;043e Get high byte (track number)
|
|
|
+ out (0b3h),a ;043f Write to floppy track register
|
|
|
+ jr c,l0453h ;0441 If sector < 17, skip extended handling
|
|
|
+ rra ;0443 Rotate right (divide by 2)
|
|
|
+ out (0b3h),a ;0444 Write modified track to floppy register
|
|
|
+ push ix ;0446 Save IX
|
|
|
+ pop bc ;0448 BC = IX
|
|
|
+ ld a,b ;0449 Get high byte of IX
|
|
|
+ jr nc,l044eh ;044a If no carry from rotate, skip
|
|
|
+ or 010h ;044c Set bit 4 (extended track flag)
|
|
|
+
|
|
|
l044eh:
|
|
|
- ld (0ff82h),a ;044e
|
|
|
- out (0c0h),a ;0451 Floppy external control
|
|
|
+ ld (0ff82h),a ;044e Store drive control byte
|
|
|
+ out (0c0h),a ;0451 Write to floppy drive control register
|
|
|
+
|
|
|
l0453h:
|
|
|
- pop bc ;0453
|
|
|
- pop hl ;0454
|
|
|
- ld a,01dh ;0455
|
|
|
- call setfloppystatus ;0457
|
|
|
- and 098h ;045a
|
|
|
- jr nz,l0486h ;045c
|
|
|
- call sub_04c1h ;045e
|
|
|
+ pop bc ;0453 Restore BC (track/sector parameters)
|
|
|
+ pop hl ;0454 Restore HL (buffer address)
|
|
|
+ ld a,01dh ;0455 Floppy command 0x1D (read sector with retry)
|
|
|
+ call setfloppystatus ;0457 Execute floppy command and wait for completion
|
|
|
+ and 098h ;045a Check error bits: bit 7=not ready, 4=CRC error, 3=lost data
|
|
|
+ jr nz,l0486h ;045c If any error bits set, handle error
|
|
|
+ call sub_04c1h ;045e Setup DMA transfer parameters
|
|
|
+
|
|
|
+; Multi-sector read loop
|
|
|
l0461h:
|
|
|
- ld a,(0ff82h) ;0461
|
|
|
- bit 4,a ;0464
|
|
|
- ld a,082h ;0466
|
|
|
- jr z,l046ch ;0468
|
|
|
- ld a,08ah ;046a
|
|
|
+ ld a,(0ff82h) ;0461 Get drive control byte
|
|
|
+ bit 4,a ;0464 Test bit 4 (extended track flag)
|
|
|
+ ld a,082h ;0466 Floppy command 0x82 (read data)
|
|
|
+ jr z,l046ch ;0468 If bit 4 clear, use standard command
|
|
|
+ ld a,08ah ;046a Floppy command 0x8A (read data - extended)
|
|
|
+
|
|
|
l046ch:
|
|
|
- call setfloppystatus ;046c
|
|
|
- and 09ch ;046f
|
|
|
- jr nz,l0486h ;0471
|
|
|
- inc h ;0473
|
|
|
- inc bc ;0474
|
|
|
- dec d ;0475
|
|
|
- ret z ;0476
|
|
|
- ld a,c ;0477
|
|
|
- and 00fh ;0478
|
|
|
- jr z,l041fh ;047a
|
|
|
- in a,(0b2h) ;047c Floppy sector register
|
|
|
- inc a ;047e
|
|
|
- out (0b2h),a ;047f Floppy sector register
|
|
|
- ld a,005h ;0481
|
|
|
+ call setfloppystatus ;046c Execute read command and wait
|
|
|
+ and 09ch ;046f Check error bits: bit 7=not ready, 4=CRC, 3=lost data, 2=record not found
|
|
|
+ jr nz,l0486h ;0471 If any error, handle it
|
|
|
+ inc h ;0473 Increment buffer high byte (next page)
|
|
|
+ inc bc ;0474 Increment sector count
|
|
|
+ dec d ;0475 Decrement remaining sector count
|
|
|
+ ret z ;0476 Return if all sectors read (D=0)
|
|
|
+ ld a,c ;0477 Get current sector number
|
|
|
+ and 00fh ;0478 Mask to lower 4 bits (sectors 0-15)
|
|
|
+ jr z,l041fh ;047a If wrapped to 0, start new track
|
|
|
+ in a,(0b2h) ;047c Read current sector register
|
|
|
+ inc a ;047e Increment to next sector
|
|
|
+ out (0b2h),a ;047f Write back to sector register
|
|
|
+ ld a,005h ;0481 Reset retry counter to 5
|
|
|
+
|
|
|
l0483h:
|
|
|
- ex af,af' ;0483
|
|
|
- jr l0461h ;0484
|
|
|
+ ex af,af' ;0483 Save retry counter
|
|
|
+ jr l0461h ;0484 Continue reading next sector
|
|
|
+
|
|
|
+; Error handling for disk read operations
|
|
|
l0486h:
|
|
|
- scf ;0486
|
|
|
- bit 7,a ;0487
|
|
|
- ret nz ;0489
|
|
|
- ex af,af' ;048a
|
|
|
- dec a ;048b
|
|
|
- jr nz,l0421h ;048c
|
|
|
- ex af,af' ;048e
|
|
|
- bit 4,a ;048f
|
|
|
- jr z,l049fh ;0491
|
|
|
- ld a,(0ff81h) ;0493
|
|
|
- and a ;0496
|
|
|
- jr nz,l049fh ;0497
|
|
|
- cpl ;0499
|
|
|
- ld (0ff81h),a ;049a
|
|
|
- jr l041fh ;049d
|
|
|
+ scf ;0486 Set carry flag (error)
|
|
|
+ bit 7,a ;0487 Test bit 7 (drive not ready)
|
|
|
+ ret nz ;0489 Return immediately if drive not ready
|
|
|
+ ex af,af' ;048a Get retry counter
|
|
|
+ dec a ;048b Decrement retry count
|
|
|
+ jr nz,l0421h ;048c If retries left, try again
|
|
|
+ ex af,af' ;048e Restore error status
|
|
|
+ bit 4,a ;048f Test bit 4 (CRC error)
|
|
|
+ jr z,l049fh ;0491 If not CRC error, return failure
|
|
|
+ ld a,(0ff81h) ;0493 Get disk parameter flag
|
|
|
+ and a ;0496 Test if zero
|
|
|
+ jr nz,l049fh ;0497 If non-zero, return failure
|
|
|
+ cpl ;0499 Complement (0x00 -> 0xFF)
|
|
|
+ ld (0ff81h),a ;049a Store inverted flag (try alternate sectors)
|
|
|
+ jr l041fh ;049d Retry with alternate sector numbering
|
|
|
+
|
|
|
l049fh:
|
|
|
- scf ;049f
|
|
|
- ret ;04a0
|
|
|
+ scf ;049f Set carry flag (permanent error)
|
|
|
+ ret ;04a0 Return with error
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; DISK INITIALIZATION AND SEEK ROUTINE
|
|
|
+; ================================================================================
|
|
|
+; Initialize floppy controller and seek to track 0
|
|
|
+
|
|
|
sub_04a1h:
|
|
|
- push bc ;04a1
|
|
|
- push ix ;04a2
|
|
|
- pop bc ;04a4
|
|
|
- ld a,c ;04a5
|
|
|
- pop bc ;04a6
|
|
|
- cp 010h ;04a7
|
|
|
- jp nc,l0788h ;04a9
|
|
|
- ld a,001h ;04ac
|
|
|
- call setfloppystatus ;04ae
|
|
|
- and 004h ;04b1
|
|
|
- ret nz ;04b3
|
|
|
- scf ;04b4
|
|
|
- ret ;04b5
|
|
|
+ push bc ;04a1 Save BC register
|
|
|
+ push ix ;04a2 Save IX register
|
|
|
+ pop bc ;04a4 BC = IX (return address)
|
|
|
+ ld a,c ;04a5 Get low byte of return address
|
|
|
+ pop bc ;04a6 Restore original BC
|
|
|
+ cp 010h ;04a7 Check if return address low byte < 0x10
|
|
|
+ jp nc,l0788h ;04a9 If >= 0x10, jump to alternate routine
|
|
|
+ ld a,001h ;04ac Floppy command 0x01 (restore/recalibrate to track 0)
|
|
|
+ call setfloppystatus ;04ae Execute restore command
|
|
|
+ and 004h ;04b1 Check bit 2 (seek error/track 0 not found)
|
|
|
+ ret nz ;04b3 Return with error if seek failed
|
|
|
+ scf ;04b4 Set carry flag (error - unexpected!)
|
|
|
+ ret ;04b5 Return with error
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; FLOPPY CONTROLLER COMMAND EXECUTION
|
|
|
+; ================================================================================
|
|
|
+; Sends command to floppy controller and waits for completion
|
|
|
+; Input: A = floppy command
|
|
|
+; Output: A = final status register
|
|
|
+
|
|
|
setfloppystatus:
|
|
|
- out (0b0h),a ;04b6 Floppy status
|
|
|
+ out (0b0h),a ;04b6 Write command to floppy controller
|
|
|
+
|
|
|
+ ; Wait for controller ready (INTRQ signal)
|
|
|
l04b8h:
|
|
|
- in a,(0b4h) ;04b8 PIO A data
|
|
|
- bit 4,a ;04ba
|
|
|
- jr z,l04b8h ;04bc
|
|
|
- in a,(0b0h) ;04be floppy status and command
|
|
|
- ret ;04c0
|
|
|
+ in a,(0b4h) ;04b8 Read PIO A data register
|
|
|
+ bit 4,a ;04ba Test bit 4 (floppy controller INTRQ signal)
|
|
|
+ jr z,l04b8h ;04bc Wait until INTRQ goes high (command complete)
|
|
|
+ in a,(0b0h) ;04be Read final status from floppy controller
|
|
|
+ ret ;04c0 Return with status in A
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; DMA SETUP ROUTINES
|
|
|
+; ================================================================================
|
|
|
+; Configure Z80 DMA controller for floppy disk data transfers
|
|
|
+
|
|
|
sub_04c1h:
|
|
|
- push bc ;04c1
|
|
|
- ld bc,0b301h ;04c2
|
|
|
- jr l04cbh ;04c5
|
|
|
+ push bc ;04c1 Save BC register
|
|
|
+ ld bc,0b301h ;04c2 B=0xB3 (DMA port), C=0x01 (DMA command)
|
|
|
+ jr l04cbh ;04c5 Jump to common DMA setup
|
|
|
+
|
|
|
sub_04c7h:
|
|
|
- push bc ;04c7
|
|
|
- ld bc,07803h ;04c8
|
|
|
+ push bc ;04c7 Save BC register
|
|
|
+ ld bc,07803h ;04c8 B=0x78 (different setting), C=0x03 (DMA command)
|
|
|
+
|
|
|
l04cbh:
|
|
|
- ld a,b ;04cb
|
|
|
- ld (0ff8ch),a ;04cc
|
|
|
- ld a,c ;04cf
|
|
|
- out (0b4h),a ;04d0 PIO A data
|
|
|
- ld bc,006ach ;04d2
|
|
|
- ld a,0c3h ;04d5
|
|
|
+ ld a,b ;04cb Get DMA parameter
|
|
|
+ ld (0ff8ch),a ;04cc Store DMA configuration
|
|
|
+ ld a,c ;04cf Get DMA command
|
|
|
+ out (0b4h),a ;04d0 Write to PIO A data register (DMA control)
|
|
|
+ ld bc,006ach ;04d2 B=6 (loop counter), C=0xAC (DMA port)
|
|
|
+ ld a,0c3h ;04d5 DMA reset command
|
|
|
+
|
|
|
l04d7h:
|
|
|
- out (c),a ;04d7
|
|
|
- djnz l04d7h ;04d9
|
|
|
- ld a,07dh ;04db
|
|
|
- out (c),a ;04dd
|
|
|
- out (c),l ;04df
|
|
|
- out (c),h ;04e1
|
|
|
- out (c),e ;04e3
|
|
|
- out (c),d ;04e5
|
|
|
- push hl ;04e7
|
|
|
- ld hl,004fbh ;04e8
|
|
|
- ld b,003h ;04eb
|
|
|
- otir ;04ed
|
|
|
- ld a,(0ff8ch) ;04ef
|
|
|
- out (c),a ;04f2
|
|
|
- ld b,005h ;04f4
|
|
|
- otir ;04f6
|
|
|
- pop hl ;04f8
|
|
|
- pop bc ;04f9
|
|
|
- ret ;04fa
|
|
|
- inc d ;04fb
|
|
|
- jr z,l0483h ;04fc
|
|
|
- adc a,d ;04fe
|
|
|
- rst 8 ;04ff
|
|
|
- ld bc,087cfh ;0500
|
|
|
+ out (c),a ;04d7 Send reset command to DMA controller
|
|
|
+ djnz l04d7h ;04d9 Repeat 6 times (ensure DMA is reset)
|
|
|
+ ld a,07dh ;04db DMA disable command
|
|
|
+ out (c),a ;04dd Send disable to DMA controller
|
|
|
+ out (c),l ;04df Send L register to DMA (low address byte)
|
|
|
+ out (c),h ;04e1 Send H register to DMA (high address byte)
|
|
|
+ out (c),e ;04e3 Send E register to DMA (low count byte)
|
|
|
+ out (c),d ;04e5 Send D register to DMA (high count byte)
|
|
|
+ push hl ;04e7 Save HL register
|
|
|
+ ld hl,004fbh ;04e8 Point to DMA parameter table
|
|
|
+ ld b,003h ;04eb Send 3 bytes
|
|
|
+ otir ;04ed Output 3 bytes from (HL) to port C
|
|
|
+ ld a,(0ff8ch) ;04ef Get stored DMA configuration
|
|
|
+ out (c),a ;04f2 Send to DMA controller
|
|
|
+ ld b,005h ;04f4 Send 5 more bytes
|
|
|
+ otir ;04f6 Output 5 bytes from (HL) to port C
|
|
|
+ pop hl ;04f8 Restore HL register
|
|
|
+ pop bc ;04f9 Restore BC register
|
|
|
+ ret ;04fa Return
|
|
|
+
|
|
|
+ ; DMA parameter table
|
|
|
+ inc d ;04fb DMA parameter byte 1
|
|
|
+ jr z,l0483h ;04fc DMA parameter bytes 2-3
|
|
|
+ adc a,d ;04fe DMA parameter byte 4
|
|
|
+ rst 8 ;04ff DMA parameter byte 5 (restart vector)
|
|
|
+ ld bc,087cfh ;0500 DMA parameter bytes 6-7-8
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; SCREEN SETUP AND CLEAR ROUTINES
|
|
|
+; ================================================================================
|
|
|
+; Initialize CRT controller and clear display memory
|
|
|
+
|
|
|
setupclearscreen2:
|
|
|
- pop ix ;0503
|
|
|
+ pop ix ;0503 Get return address from stack
|
|
|
+
|
|
|
setupclearscreen:
|
|
|
-;entry during initiation with IX=0092
|
|
|
- xor a ;0505 start A=0
|
|
|
- ld bc,00eb9h ;0506 C=B9 B=14
|
|
|
- ld hl,0054fh ;0509
|
|
|
-setupclearloop :
|
|
|
- out (0b8h),a ;050cCRT register select
|
|
|
- inc a ;050e A++
|
|
|
- outi ;050f C)=(HL++) and B--
|
|
|
- jr nz,setupclearloop ;0511 loop until B==0 (14 bytes to write) $-5
|
|
|
- ld de,03002h ;0513
|
|
|
- ld hl,displaymem ;0516
|
|
|
- ld bc,00ffeh ;0519
|
|
|
-;RST 08 jump in here HL=300C DE=300E BC=4E IX=032F
|
|
|
+ ; Entry point during initialization with IX=0x0092
|
|
|
+ xor a ;0505 A = 0 (starting register number)
|
|
|
+ ld bc,00eb9h ;0506 C=0xB9 (CRT data port), B=14 (register count)
|
|
|
+ ld hl,0054fh ;0509 Point to CRT register table
|
|
|
+
|
|
|
+setupclearloop:
|
|
|
+ out (0b8h),a ;050c Write register number to CRT register select
|
|
|
+ inc a ;050e Increment to next register number
|
|
|
+ outi ;050f Output (HL) to port C, increment HL, decrement B
|
|
|
+ jr nz,setupclearloop ;0511 Loop until B=0 (all 14 registers written)
|
|
|
+ ld de,03002h ;0513 DE = display memory + 2 (destination)
|
|
|
+ ld hl,displaymem ;0516 HL = display memory base (source)
|
|
|
+ ld bc,00ffeh ;0519 BC = 4094 bytes (2K display memory - 2)
|
|
|
+
|
|
|
+; RST 08 jumps here with different parameters: HL=300C, DE=300E, BC=004E, IX=032F
|
|
|
l051ch:
|
|
|
- ld a,004h ;051c Select display memory
|
|
|
- out (0c8h),a ;051e Output to screen out C8,04 Map and system control
|
|
|
- xor a ;0520
|
|
|
- ld (hl),a ;0521 put 00h at 3000h or 300Ch
|
|
|
- inc hl ;0522 bump
|
|
|
- ld (hl),020h ;0523 put 20h at 3001h or 300Dh
|
|
|
- dec hl ;0525 go back point to original
|
|
|
- ldir ;0526 copy 00 20 through 4K or 80 words
|
|
|
- xor a ;0528 Reset map A=0
|
|
|
- out (0c8h),a ;0529 out C8,00 Map and system control
|
|
|
- jp (ix) ;052b continue
|
|
|
+ ld a,004h ;051c Memory bank 4 (display memory)
|
|
|
+ out (0c8h),a ;051e Select display memory bank
|
|
|
+ xor a ;0520 A = 0 (clear character)
|
|
|
+ ld (hl),a ;0521 Store 0x00 at display memory (character)
|
|
|
+ inc hl ;0522 Move to attribute byte
|
|
|
+ ld (hl),020h ;0523 Store 0x20 (space character attribute)
|
|
|
+ dec hl ;0525 Go back to character position
|
|
|
+ ldir ;0526 Copy pattern throughout display memory
|
|
|
+ xor a ;0528 A = 0 (normal memory bank)
|
|
|
+ out (0c8h),a ;0529 Restore normal memory mapping
|
|
|
+ jp (ix) ;052b Continue execution at IX
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; CLEAR TOP LINE ROUTINE
|
|
|
+; ================================================================================
|
|
|
+; Clears a single line (80 characters) at the specified address
|
|
|
+
|
|
|
cleartopline:
|
|
|
- push de ;052d save old DE
|
|
|
- ld l,e ;052e HL=DE
|
|
|
+ push de ;052d Save original DE
|
|
|
+ ld l,e ;052e HL = DE (copy destination address)
|
|
|
ld h,d ;052f
|
|
|
- inc de ;0530 DE+=2
|
|
|
+ inc de ;0530 DE += 2 (destination for copy)
|
|
|
inc de ;0531
|
|
|
- ld bc,0004eh ;0532 80-2
|
|
|
- push ix ;0535 save old IX
|
|
|
- ld ix,clearlineend ;0537 exit addr 0053dh
|
|
|
- jr l051ch ;053b clear line 300C 80char $-3
|
|
|
- ;clear line returns here
|
|
|
+ ld bc,0004eh ;0532 BC = 78 words (80 chars - 2 = 78 more chars)
|
|
|
+ push ix ;0535 Save original IX
|
|
|
+ ld ix,clearlineend ;0537 Set return address to 0x053D
|
|
|
+ jr l051ch ;053b Jump to screen clear routine
|
|
|
+
|
|
|
+ ; Screen clear routine returns here
|
|
|
clearlineend:
|
|
|
- pop ix ;053d restore old IX
|
|
|
- pop de ;053f restore old DE
|
|
|
- ret ;0540
|
|
|
+ pop ix ;053d Restore original IX
|
|
|
+ pop de ;053f Restore original DE
|
|
|
+ ret ;0540 Return to caller
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; TEXT DISPLAY ROUTINE
|
|
|
+; ================================================================================
|
|
|
+; Displays text messages on screen using character/attribute pairs
|
|
|
+; Input: BC = character count, HL = message source, DE = screen target
|
|
|
|
|
|
-; BLOCK 'DB' (start 0x0541 end 0x055d)
|
|
|
printroutine:
|
|
|
-;print routine
|
|
|
-;BC count
|
|
|
-;HL message source
|
|
|
-;DE screen target
|
|
|
- ld a,004h ;0541 Select display memory
|
|
|
- out (0c8h),a ;0543 Output to screen Map and system control
|
|
|
+ ld a,004h ;0541 Memory bank 4 (display memory)
|
|
|
+ out (0c8h),a ;0543 Select display memory bank
|
|
|
+
|
|
|
printcharloop:
|
|
|
- inc de ;0545 do every other addr
|
|
|
- ldi ;0546 (DE++)=(HL++) and BC--
|
|
|
- jp pe,printcharloop ;0548 repeat while BC not 0 00545h
|
|
|
- xor a ;054b Reset map
|
|
|
- out (0c8h),a ;054c Reset to memory Map and system control
|
|
|
- jp (hl) ;054e
|
|
|
-;data to be output to io port B9 14 byte CRT data register
|
|
|
- defb 069h ;054f
|
|
|
- defb 050h ;0550
|
|
|
- defb 056h ;0551
|
|
|
- defb 00bh ;0552
|
|
|
- defb 019h ;0553
|
|
|
- defb 003h ;0554
|
|
|
- defb 018h ;0555
|
|
|
- defb 018h ;0556
|
|
|
- defb 000h ;0557
|
|
|
- defb 00bh ;0558
|
|
|
- defb 020h ;0559
|
|
|
- defb 000h ;055a
|
|
|
- defb 000h ;055b
|
|
|
- defb 000h ;055c
|
|
|
-DB_end:
|
|
|
- pop hl ;055d
|
|
|
- jr l0562h ;055e
|
|
|
+ inc de ;0545 Skip to attribute byte (every other address)
|
|
|
+ ldi ;0546 Copy (HL) to (DE), increment both, decrement BC
|
|
|
+ jp pe,printcharloop ;0548 Continue while BC ≠ 0 (parity even = BC not zero)
|
|
|
+ xor a ;054b A = 0 (normal memory bank)
|
|
|
+ out (0c8h),a ;054c Restore normal memory mapping
|
|
|
+ jp (hl) ;054e Jump to address in HL
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; CRT CONTROLLER REGISTER TABLE (6845 CRTC)
|
|
|
+; ================================================================================
|
|
|
+; 14-byte table of values for CRT controller registers R0-R13
|
|
|
+
|
|
|
+CRT_REGISTER_TABLE:
|
|
|
+ defb 069h ;054f R0: Horizontal Total = 105 characters
|
|
|
+ defb 050h ;0550 R1: Horizontal Displayed = 80 characters
|
|
|
+ defb 056h ;0551 R2: Horizontal Sync Position = 86
|
|
|
+ defb 00bh ;0552 R3: Horizontal Sync Width = 11
|
|
|
+ defb 019h ;0553 R4: Vertical Total = 25 rows
|
|
|
+ defb 003h ;0554 R5: Vertical Total Adjust = 3
|
|
|
+ defb 018h ;0555 R6: Vertical Displayed = 24 rows
|
|
|
+ defb 018h ;0556 R7: Vertical Sync Position = 24
|
|
|
+ defb 000h ;0557 R8: Interlace Mode = 0 (non-interlaced)
|
|
|
+ defb 00bh ;0558 R9: Maximum Scan Line = 11 (12 lines per char)
|
|
|
+ defb 020h ;0559 R10: Cursor Start = 32 (cursor off)
|
|
|
+ defb 000h ;055a R11: Cursor End = 0
|
|
|
+ defb 000h ;055b R12: Start Address High = 0
|
|
|
+ defb 000h ;055c R13: Start Address Low = 0
|
|
|
+CRT_TABLE_END:
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; ADVANCED SCREEN CLEAR ROUTINES
|
|
|
+; ================================================================================
|
|
|
+
|
|
|
+ pop hl ;055d Restore HL register
|
|
|
+ jr l0562h ;055e Jump to screen clear loop
|
|
|
+
|
|
|
screenclearloop:
|
|
|
- otir ;0560 out B bytes from (HL) to (C)
|
|
|
+ otir ;0560 Output B bytes from (HL) to port C
|
|
|
+
|
|
|
l0562h:
|
|
|
- ld c,(hl) ;0562 get register
|
|
|
- inc hl ;0563 bump
|
|
|
- ld b,(hl) ;0564 get count
|
|
|
- inc hl ;0565 bump
|
|
|
- ld a,b ;0566
|
|
|
- and a ;0567
|
|
|
- jr nz,screenclearloop ;0568 if count not 0 loop $-8
|
|
|
- jp (hl) ;056a
|
|
|
+ ld c,(hl) ;0562 Get I/O port number from table
|
|
|
+ inc hl ;0563 Move to count byte
|
|
|
+ ld b,(hl) ;0564 Get byte count
|
|
|
+ inc hl ;0565 Move to data
|
|
|
+ ld a,b ;0566 Test count
|
|
|
+ and a ;0567 Check if zero
|
|
|
+ jr nz,screenclearloop ;0568 If not zero, output data block
|
|
|
+ jp (hl) ;056a Jump to next routine
|
|
|
+
|
|
|
screenclearnetry2:
|
|
|
- ld de,03100h ;056b
|
|
|
- ld a,00fh ;056e
|
|
|
- out (0b8h),a ;0570 CRT register select
|
|
|
- xor a ;0572
|
|
|
- out (0b9h),a ;0573 CRT data register
|
|
|
- in a,(0bbh) ;0575 ?????
|
|
|
- or a ;0577
|
|
|
- ret nz ;0578
|
|
|
- ld de,030a0h ;0579
|
|
|
- ret ;057c
|
|
|
+ ld de,03100h ;056b DE = 0x3100 (display line 1 start address)
|
|
|
+ ld a,00fh ;056e CRT register 15 (cursor position low byte)
|
|
|
+ out (0b8h),a ;0570 Select CRT register 15
|
|
|
+ xor a ;0572 A = 0 (cursor position = 0)
|
|
|
+ out (0b9h),a ;0573 Write cursor position to CRT
|
|
|
+ in a,(0bbh) ;0575 Read from port 0xBB (keyboard status?)
|
|
|
+ or a ;0577 Test status
|
|
|
+ ret nz ;0578 Return if non-zero (key pressed?)
|
|
|
+ ld de,030a0h ;0579 DE = 0x30A0 (alternate display position)
|
|
|
+ ret ;057c Return
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; DELAY LOOP ROUTINE
|
|
|
+; ================================================================================
|
|
|
+; Provides more precise timing delays using stack manipulation
|
|
|
+
|
|
|
delayloop:
|
|
|
- ld hl,04600h ;057d
|
|
|
+ ld hl,04600h ;057d HL = 17920 (delay counter)
|
|
|
+
|
|
|
l0580h:
|
|
|
- dec hl ;0580
|
|
|
- ex (sp),hl ;0581
|
|
|
- ex (sp),hl ;0582
|
|
|
- ex (sp),hl ;0583
|
|
|
- ex (sp),hl ;0584
|
|
|
- ld a,l ;0585
|
|
|
+ dec hl ;0580 Decrement counter
|
|
|
+ ex (sp),hl ;0581 Exchange HL with top of stack (add delay)
|
|
|
+ ex (sp),hl ;0582 Exchange back (more delay)
|
|
|
+ ex (sp),hl ;0583 Exchange again (even more delay)
|
|
|
+ ex (sp),hl ;0584 Exchange back (maximum delay per loop)
|
|
|
+ ld a,l ;0585 Test if HL reached zero
|
|
|
or h ;0586
|
|
|
- jr nz,l0580h ;0587
|
|
|
- ret ;0589
|
|
|
- pop ix ;058a
|
|
|
+ jr nz,l0580h ;0587 Continue loop until HL = 0
|
|
|
+ ret ;0589 Return after ~17920 * 4 clock cycles
|
|
|
+
|
|
|
+ pop ix ;058a Clean up stack (dead code?)
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; CRT CONTROLLER INITIALIZATION
|
|
|
+; ================================================================================
|
|
|
+; Complete CRT setup with buzzer control and I/O initialization
|
|
|
+
|
|
|
setupcrt:
|
|
|
- ld a,00fh ;058c
|
|
|
- out (0b8h),a ;058e CRT register select
|
|
|
- xor a ;0590
|
|
|
- out (0b9h),a ;0591 CRT data register
|
|
|
- in a,(0bbh) ;0593
|
|
|
- and a ;0595
|
|
|
- jr nz,l059ch ;0596
|
|
|
- ld a,081h ;0598
|
|
|
- out (0d4h),a ;059a Buzzer on
|
|
|
+ ld a,00fh ;058c CRT register 15 (cursor position low)
|
|
|
+ out (0b8h),a ;058e Select CRT register 15
|
|
|
+ xor a ;0590 A = 0 (cursor off)
|
|
|
+ out (0b9h),a ;0591 Write to CRT data register
|
|
|
+ in a,(0bbh) ;0593 Read keyboard/system status
|
|
|
+ and a ;0595 Test status
|
|
|
+ jr nz,l059ch ;0596 If non-zero, skip buzzer
|
|
|
+ ld a,081h ;0598 Buzzer control byte
|
|
|
+ out (0d4h),a ;059a Turn on buzzer/sound
|
|
|
+
|
|
|
l059ch:
|
|
|
- ld bc,006cch ;059c
|
|
|
- ld hl,005b8h ;059f
|
|
|
- otir ;05a2
|
|
|
- ld bc,0000h ;05a4
|
|
|
+ ld bc,006cch ;059c B=6 bytes, C=0xCC (I/O port for system control)
|
|
|
+ ld hl,005b8h ;059f Point to I/O initialization table
|
|
|
+ otir ;05a2 Output 6 bytes to port 0xCC (system setup)
|
|
|
+ ld bc,0000h ;05a4 BC = 0 (delay counter)
|
|
|
+
|
|
|
+ ; Delay loop for system settling
|
|
|
l05a7h:
|
|
|
- ex (sp),hl ;05a7
|
|
|
- ex (sp),hl ;05a8
|
|
|
- dec bc ;05a9
|
|
|
- ld a,b ;05aa
|
|
|
+ ex (sp),hl ;05a7 Exchange HL with stack top (timing delay)
|
|
|
+ ex (sp),hl ;05a8 Exchange back (more timing delay)
|
|
|
+ dec bc ;05a9 Decrement delay counter
|
|
|
+ ld a,b ;05aa Test if BC reached zero
|
|
|
or c ;05ab
|
|
|
- jr nz,l05a7h ;05ac
|
|
|
- ld a,080h ;05ae
|
|
|
- out (0d4h),a ;05b0 Buzzer off
|
|
|
- ld a,09fh ;05b2
|
|
|
- out (0cch),a ;05b4 ?????
|
|
|
- jp (ix) ;05b6
|
|
|
-l05b8h:
|
|
|
- adc a,(hl) ;05b8
|
|
|
- inc b ;05b9
|
|
|
- sub d ;05ba
|
|
|
- cp a ;05bb
|
|
|
- rst 18h ;05bc
|
|
|
- rst 38h ;05bd
|
|
|
+ jr nz,l05a7h ;05ac Continue delay loop
|
|
|
+ ld a,080h ;05ae Buzzer off command
|
|
|
+ out (0d4h),a ;05b0 Turn off buzzer
|
|
|
+ ld a,09fh ;05b2 System control value
|
|
|
+ out (0cch),a ;05b4 Final system control setup
|
|
|
+ jp (ix) ;05b6 Continue execution at IX
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; I/O INITIALIZATION TABLE
|
|
|
+; ================================================================================
|
|
|
+; 6-byte table for system controller setup (port 0xCC)
|
|
|
+
|
|
|
+IO_SETUP_TABLE:
|
|
|
+ defb 08eh ;05b8 I/O setup byte 1 (adc a,(hl) opcode)
|
|
|
+ defb 004h ;05b9 I/O setup byte 2 (inc b opcode)
|
|
|
+ defb 092h ;05ba I/O setup byte 3 (sub d opcode)
|
|
|
+ defb 0bfh ;05bb I/O setup byte 4 (cp a opcode)
|
|
|
+ defb 0dfh ;05bc I/O setup byte 5 (rst 18h opcode)
|
|
|
+ defb 0ffh ;05bd I/O setup byte 6 (rst 38h opcode)
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; MEMORY COPY ROUTINE WITH BANKING
|
|
|
+; ================================================================================
|
|
|
+; Copies data using banked memory (used during boot program loading)
|
|
|
+
|
|
|
l05beh:
|
|
|
- ld a,001h ;05be
|
|
|
- out (0c8h),a ;05c0 Map and system control
|
|
|
+ ld a,001h ;05be Memory bank 1
|
|
|
+ out (0c8h),a ;05c0 Select bank 1 for memory operations
|
|
|
+
|
|
|
l05c2h:
|
|
|
- ex af,af' ;05c2
|
|
|
- adc a,(hl) ;05c3
|
|
|
- ex af,af' ;05c4
|
|
|
- inc hl ;05c5
|
|
|
- dec de ;05c6
|
|
|
- ld a,e ;05c7
|
|
|
+ ex af,af' ;05c2 Save AF in alternate register
|
|
|
+ adc a,(hl) ;05c3 Load byte from source (HL)
|
|
|
+ ex af,af' ;05c4 Restore AF
|
|
|
+ inc hl ;05c5 Increment source pointer
|
|
|
+ dec de ;05c6 Decrement byte counter
|
|
|
+ ld a,e ;05c7 Test if DE reached zero
|
|
|
or d ;05c8
|
|
|
- jr nz,l05c2h ;05c9
|
|
|
- out (0c8h),a ;05cb Map and system control
|
|
|
- jp l02ech ;05cd
|
|
|
- cp 002h ;05d0
|
|
|
- ld a,001h ;05d2
|
|
|
- out (0c8h),a ;05d4 Map and system control
|
|
|
- jr nz,l05f5h ;05d6
|
|
|
- ld a,(0ff81h) ;05d8
|
|
|
- ld (0022h),a ;05db
|
|
|
- ld a,c ;05de
|
|
|
- sub 010h ;05df
|
|
|
- jr c,l05f5h ;05e1
|
|
|
- ld c,a ;05e3
|
|
|
- jr z,l05eeh ;05e4
|
|
|
- ld a,(0ff8fh) ;05e6
|
|
|
- cp 095h ;05e9
|
|
|
- jr nz,l05eeh ;05eb
|
|
|
- inc c ;05ed
|
|
|
+ jr nz,l05c2h ;05c9 Continue copy loop if more bytes
|
|
|
+ out (0c8h),a ;05cb A=0, restore normal memory bank
|
|
|
+ jp l02ech ;05cd Jump back to boot execution routine
|
|
|
+
|
|
|
+;
|
|
|
+; ANALYSIS OF ALTERNATIVE BOOT PATH (0x05D0-0x0616):
|
|
|
+; ==================================================
|
|
|
+;
|
|
|
+; This represents a remarkable discovery of the Monroe OC8820's dual-OS boot capability.
|
|
|
+; The system implements support for two operating systems through calculated
|
|
|
+; indirect jumps, creating a sophisticated OS-selection boot system.
|
|
|
+;
|
|
|
+; OPERATING SYSTEM BOOT MODES:
|
|
|
+; ----------------------------
|
|
|
+; Mode 0/1: Standard boot path - Monroe OS8 (Monroe's proprietary operating system)
|
|
|
+; Mode 2: CP/M boot path - Industry standard OS for business applications
|
|
|
+; Mode 2+: Advanced Monroe OS8 features and configurations
|
|
|
+;
|
|
|
+; DUAL-OS ENTRY MECHANISM:
|
|
|
+; ------------------------
|
|
|
+; 1. Boot disk contains OS identification in banked memory (0xFF80-0xFF92 range)
|
|
|
+; 2. Main boot code reads OS type and calculates appropriate boot vector
|
|
|
+; 3. Address calculation: Base(4) + OS_Parameter + AdvancedFeatures = OS_BootVector
|
|
|
+; 4. Target address stored in IX via push BC/pop IX mechanism
|
|
|
+; 5. Later jp (ix) instruction jumps to OS-specific initialization code
|
|
|
+;
|
|
|
+; OS CONFIGURATION DATA STRUCTURE (in banked memory):
|
|
|
+; --------------------------------------------------
|
|
|
+; 0xFF80: Base OS configuration flag (combined with runtime parameters)
|
|
|
+; 0xFF81: OS-specific configuration byte (CP/M BIOS params or Monroe OS8 settings)
|
|
|
+; 0xFF8D: 4-byte OS parameter block #1 (disk geometry, memory layout)
|
|
|
+; 0xFF8F: OS validation signature (0x95 = validated Monroe OS8 disk with advanced features)
|
|
|
+; 0xFF91: OS boot data byte (entry points, system calls)
|
|
|
+; 0xFF92: OS boot data byte (additional OS parameters)
|
|
|
+;
|
|
|
+; CP/M vs MONROE OS8 BOOT DIFFERENTIATION:
|
|
|
+; ----------------------------------------
|
|
|
+; - If mode ≠ 2: Monroe OS8 boot (standard proprietary OS)
|
|
|
+; - If mode = 2 and parameter < 16: CP/M boot (industry standard)
|
|
|
+; - If mode = 2 and parameter ≥ 16: Check for Monroe OS8 advanced features
|
|
|
+; - If signature = 0x95: Monroe OS8 with advanced features (+1 offset)
|
|
|
+; - Final jump target = 4 + (OS_parameter-16) + advanced_features_bonus
|
|
|
+;
|
|
|
+; The final jp (iy) transfers control to the selected OS kernel!
|
|
|
+;
|
|
|
+;; ================================================================================
|
|
|
+; Entry point: 0x05D0 (reached via jp (ix) with calculated address from 0x05F2-0x05F3)
|
|
|
+; This represents a sophisticated secondary boot path for handling different system configurations
|
|
|
+;
|
|
|
+; Entry conditions:
|
|
|
+; - A register contains boot mode indicator
|
|
|
+; - C register contains configuration parameter
|
|
|
+; - System expects specific memory layout in banked memory
|
|
|
+
|
|
|
+l05d0h:
|
|
|
+ cp 002h ;05d0 Compare A with 2 (OS boot mode check: 2 = CP/M selection)
|
|
|
+ ld a,001h ;05d2 Load memory bank 1 selector
|
|
|
+ out (0c8h),a ;05d4 Switch to memory bank 1 for OS-specific operations
|
|
|
+ jr nz,l05f5h ;05d6 If A≠2, use Monroe OS8 (native OS), skip CP/M setup
|
|
|
+
|
|
|
+ ; CP/M specific initialization (A was equal to 2)
|
|
|
+ ld a,(0ff81h) ;05d8 Load CP/M configuration byte from boot disk
|
|
|
+ ld (0022h),a ;05db Store CP/M config in system variable (BIOS parameters)
|
|
|
+ ld a,c ;05de Get CP/M parameter from C register
|
|
|
+ sub 010h ;05df Subtract 16 (check if parameter >= 16 for advanced CP/M)
|
|
|
+ jr c,l05f5h ;05e1 If C<16, use basic CP/M boot, jump to common path
|
|
|
+ ld c,a ;05e3 Update C with adjusted value (C = C-16)
|
|
|
+ jr z,l05eeh ;05e4 If result is zero (C was exactly 16), basic advanced CP/M
|
|
|
+
|
|
|
+ ; Advanced Monroe OS8 features when booting from CP/M mode
|
|
|
+ ld a,(0ff8fh) ;05e6 Load validation signature from boot disk
|
|
|
+ cp 095h ;05e9 Compare with Monroe OS8 advanced feature signature 0x95
|
|
|
+ jr nz,l05eeh ;05eb If not Monroe OS8 signature, use standard CP/M boot
|
|
|
+ inc c ;05ed Valid Monroe OS8 features: increment C (Monroe-specific CP/M extensions)
|
|
|
+
|
|
|
l05eeh:
|
|
|
- ld a,004h ;05ee
|
|
|
- add a,c ;05f0
|
|
|
- ld c,a ;05f1
|
|
|
- push bc ;05f2
|
|
|
- pop ix ;05f3
|
|
|
+ ; Calculate OS-specific jump target address
|
|
|
+ ld a,004h ;05ee Base offset = 4
|
|
|
+ add a,c ;05f0 Add OS-derived offset to base
|
|
|
+ ld c,a ;05f1 C now contains calculated OS boot vector offset
|
|
|
+ push bc ;05f2 Push BC to stack
|
|
|
+ pop ix ;05f3 Pop into IX - now IX = OS boot vector (B×256 + OS_offset)
|
|
|
+ ; This creates the target address for OS-specific initialization
|
|
|
+
|
|
|
l05f5h:
|
|
|
- ld a,(0ff80h) ;05f5
|
|
|
- or c ;05f8
|
|
|
- ld c,a ;05f9
|
|
|
- ld a,(0ff91h) ;05fa
|
|
|
- ld (de),a ;05fd
|
|
|
- inc de ;05fe
|
|
|
- push bc ;05ff
|
|
|
- ld bc,00004h ;0600
|
|
|
- ldir ;0603
|
|
|
- ld de,00023h ;0605
|
|
|
- ld hl,0ff8dh ;0608
|
|
|
- ld a,(0ff92h) ;060b
|
|
|
- ld (de),a ;060e
|
|
|
- inc de ;060f
|
|
|
- ld bc,00004h ;0610
|
|
|
- ldir ;0613
|
|
|
- pop bc ;0615
|
|
|
- jp (iy) ;0616
|
|
|
- dec b ;0618
|
|
|
- add a,b ;0619
|
|
|
- dec b ;061a
|
|
|
- nop ;061b
|
|
|
+ ; Common path for both operating systems (Monroe OS8 and CP/M)
|
|
|
+ ; OS-specific data preparation and parameter setup
|
|
|
+ ld a,(0ff80h) ;05f5 Load base OS configuration from boot disk
|
|
|
+ or c ;05f8 Combine with OS-specific offset parameter
|
|
|
+ ld c,a ;05f9 Store combined OS configuration
|
|
|
+ ld a,(0ff91h) ;05fa Load OS boot parameter 1 from disk (entry points, BIOS vectors)
|
|
|
+ ld (de),a ;05fd Store to OS parameter area (DE points to system area)
|
|
|
+ inc de ;05fe Advance destination pointer
|
|
|
+
|
|
|
+ ; Copy 4-byte OS parameter block from boot disk
|
|
|
+ push bc ;05ff Save BC (OS configuration)
|
|
|
+ ld bc,00004h ;0600 Set count = 4 bytes
|
|
|
+ ldir ;0603 Copy 4 bytes: Monroe OS8 or CP/M system parameters
|
|
|
+
|
|
|
+ ; Set up for second OS parameter block copy
|
|
|
+ ld de,00023h ;0605 DE = destination address 0x0023 (OS parameter area)
|
|
|
+ ld hl,0ff8dh ;0608 HL = source in banked memory 0xFF8D (OS data block 2)
|
|
|
+ ld a,(0ff92h) ;060b Load OS boot parameter 2 (system vectors, disk geometry)
|
|
|
+ ld (de),a ;060e Store at 0x0023
|
|
|
+ inc de ;060f DE = 0x0024
|
|
|
+
|
|
|
+ ; Copy second 4-byte OS parameter block
|
|
|
+ ld bc,00004h ;0610 Set count = 4 bytes
|
|
|
+ ldir ;0613 Copy 4 bytes: Monroe OS8 system tables or CP/M BIOS tables
|
|
|
+
|
|
|
+ pop bc ;0615 Restore BC (OS configuration)
|
|
|
+ jp (iy) ;0616 Jump to selected OS kernel entry point! (Monroe OS8 or CP/M)
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; DATA TABLE AND DISK CONTROLLER INITIALIZATION
|
|
|
+; ================================================================================
|
|
|
+ defb 005h ;0618 Controller parameter 1
|
|
|
+ defb 080h ;0619 Controller parameter 2 (0x80 = enable flag?)
|
|
|
+ defb 005h ;061a Controller parameter 3
|
|
|
+ defb 000h ;061b Controller parameter 4 (terminator?)
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; DISK CONTROLLER SETUP AND STATUS CHECK ROUTINE
|
|
|
+; ================================================================================
|
|
|
+; Initializes the disk controller and waits for ready status
|
|
|
+; Uses the 4-byte parameter table above (0x0618-0x061B)
|
|
|
+; Returns: Carry set if timeout/error, clear if success
|
|
|
+
|
|
|
sub_061ch:
|
|
|
- ld bc,002a3h ;061c
|
|
|
- ld hl,00618h ;061f
|
|
|
- otir ;0622
|
|
|
- ld b,0ffh ;0624
|
|
|
+ ld bc,002a3h ;061c B=2 bytes, C=0xA3 (port number for disk controller)
|
|
|
+ ld hl,00618h ;061f HL points to controller parameter table above
|
|
|
+ otir ;0622 Output 2 bytes from (HL) to port 0xA3, auto-increment HL
|
|
|
+ ld b,0ffh ;0624 B = 255 (timeout counter for controller ready)
|
|
|
+
|
|
|
l0626h:
|
|
|
- in a,(079h) ;0626
|
|
|
- cp 0c7h ;0628
|
|
|
- jr z,l0630h ;062a
|
|
|
- djnz l0626h ;062c
|
|
|
- scf ;062e
|
|
|
- ret ;062f
|
|
|
+ ; Wait for disk controller ready status
|
|
|
+ in a,(079h) ;0626 Read disk controller status port
|
|
|
+ cp 0c7h ;0628 Compare with ready status value 0xC7
|
|
|
+ jr z,l0630h ;062a If ready (0xC7), continue with operation
|
|
|
+ djnz l0626h ;062c Decrement timeout counter, loop if not expired
|
|
|
+ scf ;062e Set carry flag (timeout error)
|
|
|
+ ret ;062f Return with error
|
|
|
+
|
|
|
l0630h:
|
|
|
- call reading ;0630
|
|
|
- ret c ;0633
|
|
|
- in a,(0ffh) ;0634
|
|
|
- rra ;0636
|
|
|
- rra ;0637
|
|
|
- and 007h ;0638
|
|
|
- ld hl,007e2h ;063a
|
|
|
- jr z,l064fh ;063d
|
|
|
- ld hl,007d6h ;063f
|
|
|
- dec a ;0642
|
|
|
- jr z,l0648h ;0643
|
|
|
- ld hl,007cah ;0645
|
|
|
+ ; Controller is ready - execute read operation
|
|
|
+ call reading ;0630 Execute disk read command
|
|
|
+ ret c ;0633 Return if read error occurred
|
|
|
+
|
|
|
+ ; Analyze controller response for configuration
|
|
|
+ in a,(0ffh) ;0634 Read controller configuration register
|
|
|
+ rra ;0636 Rotate right (check bit 0)
|
|
|
+ rra ;0637 Rotate right again (check bit 1)
|
|
|
+ and 007h ;0638 Mask to get lower 3 bits (configuration value 0-7)
|
|
|
+
|
|
|
+ ; *** BOOT DEVICE SELECTION LOGIC ***
|
|
|
+ ; Configuration value determines boot device priority:
|
|
|
+ ; 0 = Default (floppy-only system)
|
|
|
+ ; 1 = Hard disk + floppy system (hard disk priority)
|
|
|
+ ; 2+ = Advanced hard disk system (hard disk with extended features)
|
|
|
+
|
|
|
+ ld hl,007e2h ;063a Default: point to floppy-only configuration table
|
|
|
+ jr z,l064fh ;063d If value=0, use floppy-only mode, skip device selection
|
|
|
+ ld hl,007d6h ;063f Point to hard disk + floppy configuration table
|
|
|
+ dec a ;0642 Decrement configuration value
|
|
|
+ jr z,l0648h ;0643 If value was 1, use hard disk + floppy mode
|
|
|
+ ld hl,007cah ;0645 Point to advanced hard disk configuration (value ≥ 2)
|
|
|
+
|
|
|
l0648h:
|
|
|
- call sub_076bh ;0648
|
|
|
- call reading ;064b
|
|
|
- ret c ;064e
|
|
|
+ call sub_076bh ;0648 Execute configuration-specific routine
|
|
|
+ call reading ;064b Execute another disk read
|
|
|
+ ret c ;064e Return if error
|
|
|
+
|
|
|
l064fh:
|
|
|
- ld de,0ff8dh ;064f
|
|
|
- ld bc,00004h ;0652
|
|
|
- ldir ;0655
|
|
|
- jp l077fh ;0657
|
|
|
+ ; Copy configuration data to system memory
|
|
|
+ ld de,0ff8dh ;064f DE = destination in banked memory (system parameters)
|
|
|
+ ld bc,00004h ;0652 BC = 4 bytes to copy
|
|
|
+ ldir ;0655 Copy 4 bytes from (HL) to system memory
|
|
|
+ jp l077fh ;0657 Jump to next stage of disk initialization
|
|
|
+; ================================================================================
|
|
|
+; DISK COMMAND EXECUTION ROUTINE
|
|
|
+; ================================================================================
|
|
|
+; Executes specific floppy disk commands (0x10, 0x11) used during boot sequence
|
|
|
+; This routine handles low-level disk operations like recalibrate and seek
|
|
|
+; Input: C = disk command (0x10 = recalibrate, 0x11 = seek/position)
|
|
|
+; Output: Carry flag set if error, clear if success
|
|
|
+
|
|
|
sub_065ah:
|
|
|
- push bc ;065a
|
|
|
- pop ix ;065b
|
|
|
- ld a,010h ;065d
|
|
|
- sub c ;065f
|
|
|
- jr z,l0664h ;0660
|
|
|
- ld a,020h ;0662
|
|
|
+ push bc ;065a Save BC register
|
|
|
+ pop ix ;065b IX = BC (save original command for later use)
|
|
|
+ ld a,010h ;065d A = 0x10 (base command value)
|
|
|
+ sub c ;065f A = 0x10 - C (calculate command offset)
|
|
|
+ jr z,l0664h ;0660 If C=0x10 (recalibrate), use A=0 parameter
|
|
|
+ ld a,020h ;0662 A = 0x20 (seek command parameter)
|
|
|
+
|
|
|
l0664h:
|
|
|
- ld hl,0ff83h ;0664
|
|
|
- ld b,004h ;0667
|
|
|
- ld (hl),008h ;0669
|
|
|
- inc hl ;066b
|
|
|
- ld (hl),a ;066c
|
|
|
+ ; Build disk command parameter block
|
|
|
+ ld hl,0ff83h ;0664 Point to disk parameter buffer in banked memory
|
|
|
+ ld b,004h ;0667 B = 4 (number of parameters to set)
|
|
|
+ ld (hl),008h ;0669 Store 0x08 (command type/drive select)
|
|
|
+ inc hl ;066b Move to next parameter slot
|
|
|
+ ld (hl),a ;066c Store command-specific parameter (0x00 or 0x20)
|
|
|
+
|
|
|
l066dh:
|
|
|
- inc hl ;066d
|
|
|
- ld (hl),000h ;066e
|
|
|
- djnz l066dh ;0670
|
|
|
- call reading ;0672
|
|
|
- ret c ;0675
|
|
|
- call moveoutreseta ;0676
|
|
|
- call reading2 ;0679
|
|
|
- and 002h ;067c
|
|
|
- ret z ;067e
|
|
|
- scf ;067f
|
|
|
- ret ;0680
|
|
|
-l0681h:
|
|
|
- push bc ;0681
|
|
|
- call screenclearnetry2 ;0682
|
|
|
- rst 10h ;0685
|
|
|
-
|
|
|
-; BLOCK 'ERROR1' (start 0x0686 end 0x06af)
|
|
|
+ ; Clear remaining parameters
|
|
|
+ inc hl ;066d Move to next parameter slot
|
|
|
+ ld (hl),000h ;066e Clear parameter (set to 0x00)
|
|
|
+ djnz l066dh ;0670 Clear remaining 3 parameters (total 6 bytes)
|
|
|
+
|
|
|
+ ; Execute the disk command
|
|
|
+ call reading ;0672 Execute the prepared disk command
|
|
|
+ ret c ;0675 Return immediately if command failed
|
|
|
+ call moveoutreseta ;0676 Move/output result data
|
|
|
+ call reading2 ;0679 Read final status
|
|
|
+ and 002h ;067c Check bit 1 (error flag)
|
|
|
+ ret z ;067e Return success if bit 1 clear
|
|
|
+ scf ;067f Set carry flag (error)
|
|
|
+ ret ;0680 Return with error
|
|
|
+; ================================================================================
|
|
|
+; CRITICAL DISK ERROR HANDLER
|
|
|
+; ================================================================================
|
|
|
+; Handles severe disk system errors that prevent successful boot
|
|
|
+; This is called when disk controller hardware fails or becomes unresponsive
|
|
|
+; Displays Error #1 message and enters service mode
|
|
|
+
|
|
|
+print_error1:
|
|
|
+ push bc ;0681 Save BC register state
|
|
|
+ call screenclearnetry2 ;0682 Clear screen and setup error display
|
|
|
+ rst 10h ;0685 RST 10h: Display error message (points to message below)
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; ERROR #1 MESSAGE DATA - CRITICAL DISK SYSTEM ERROR
|
|
|
+; ================================================================================
|
|
|
+; "Error 1: Disk system error, Call Service" - 40 characters
|
|
|
+; This indicates hardware-level disk controller failure requiring service
|
|
|
+
|
|
|
ERROR1_start:
|
|
|
- defb 028h ;0686
|
|
|
- defb 045h ;0687 count 40
|
|
|
- defb 072h ;0688 Error 1: Disk system error, Call Service
|
|
|
- defb 072h ;0689
|
|
|
- defb 06fh ;068a
|
|
|
- defb 072h ;068b
|
|
|
- defb 020h ;068c
|
|
|
- defb 031h ;068d
|
|
|
- defb 03ah ;068e
|
|
|
- defb 020h ;068f
|
|
|
- defb 044h ;0690
|
|
|
- defb 069h ;0691
|
|
|
- defb 073h ;0692
|
|
|
- defb 06bh ;0693
|
|
|
- defb 020h ;0694
|
|
|
- defb 073h ;0695
|
|
|
- defb 079h ;0696
|
|
|
- defb 073h ;0697
|
|
|
- defb 074h ;0698
|
|
|
- defb 065h ;0699
|
|
|
- defb 06dh ;069a
|
|
|
- defb 020h ;069b
|
|
|
- defb 065h ;069c
|
|
|
- defb 072h ;069d
|
|
|
- defb 072h ;069e
|
|
|
- defb 06fh ;069f
|
|
|
- defb 072h ;06a0
|
|
|
- defb 02ch ;06a1
|
|
|
- defb 020h ;06a2
|
|
|
- defb 043h ;06a3
|
|
|
- defb 061h ;06a4
|
|
|
- defb 06ch ;06a5
|
|
|
- defb 06ch ;06a6
|
|
|
- defb 020h ;06a7
|
|
|
- defb 053h ;06a8
|
|
|
- defb 065h ;06a9
|
|
|
- defb 072h ;06aa
|
|
|
- defb 076h ;06ab
|
|
|
-l06ach:
|
|
|
- defb 069h ;06ac
|
|
|
- defb 063h ;06ad
|
|
|
- defb 065h ;06ae
|
|
|
+ defb 028h ;0686 Message length: 40 characters
|
|
|
+ defb 045h ;0687 'E'
|
|
|
+ defb 072h ;0688 'r'
|
|
|
+ defb 072h ;0689 'r'
|
|
|
+ defb 06fh ;068a 'o'
|
|
|
+ defb 072h ;068b 'r'
|
|
|
+ defb 020h ;068c ' '
|
|
|
+ defb 031h ;068d '1'
|
|
|
+ defb 03ah ;068e ':'
|
|
|
+ defb 020h ;068f ' '
|
|
|
+ defb 044h ;0690 'D'
|
|
|
+ defb 069h ;0691 'i'
|
|
|
+ defb 073h ;0692 's'
|
|
|
+ defb 06bh ;0693 'k'
|
|
|
+ defb 020h ;0694 ' '
|
|
|
+ defb 073h ;0695 's'
|
|
|
+ defb 079h ;0696 'y'
|
|
|
+ defb 073h ;0697 's'
|
|
|
+ defb 074h ;0698 't'
|
|
|
+ defb 065h ;0699 'e'
|
|
|
+ defb 06dh ;069a 'm'
|
|
|
+ defb 020h ;069b ' '
|
|
|
+ defb 065h ;069c 'e'
|
|
|
+ defb 072h ;069d 'r'
|
|
|
+ defb 072h ;069e 'r'
|
|
|
+ defb 06fh ;069f 'o'
|
|
|
+ defb 072h ;06a0 'r'
|
|
|
+ defb 02ch ;06a1 ','
|
|
|
+ defb 020h ;06a2 ' '
|
|
|
+ defb 043h ;06a3 'C'
|
|
|
+ defb 061h ;06a4 'a'
|
|
|
+ defb 06ch ;06a5 'l'
|
|
|
+ defb 06ch ;06a6 'l'
|
|
|
+ defb 020h ;06a7 ' '
|
|
|
+ defb 053h ;06a8 'S'
|
|
|
+ defb 065h ;06a9 'e'
|
|
|
+ defb 072h ;06aa 'r'
|
|
|
+ defb 076h ;06ab 'v'
|
|
|
+ defb 069h ;06ac 'i'
|
|
|
+ defb 063h ;06ad 'c'
|
|
|
+ defb 065h ;06ae 'e'
|
|
|
ERROR1_end:
|
|
|
- call delayloop ;06af
|
|
|
- call delayloop ;06b2
|
|
|
- call delayloop ;06b5
|
|
|
- call setupclearscreen2 ;06b8
|
|
|
- call readydisk ;06bb
|
|
|
- pop bc ;06be
|
|
|
- scf ;06bf
|
|
|
- ret ;06c0
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; ERROR RECOVERY AND SYSTEM RESTART
|
|
|
+; ================================================================================
|
|
|
+; After displaying the error, system performs cleanup and restart sequence
|
|
|
+
|
|
|
+error1_recovery:
|
|
|
+ call delayloop ;06af Delay to allow user to read error message
|
|
|
+ call delayloop ;06b2 Additional delay for visibility
|
|
|
+ call delayloop ;06b5 Final delay before restart attempt
|
|
|
+ call setupclearscreen2 ;06b8 Clear screen and reinitialize display system
|
|
|
+ call readydisk ;06bb Attempt to ready disk system for retry
|
|
|
+ pop bc ;06be Restore BC register from stack
|
|
|
+ scf ;06bf Set carry flag (indicate error condition)
|
|
|
+ ret ;06c0 Return with error status
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; DISK SECTOR READ WITH RETRY LOGIC
|
|
|
+; ================================================================================
|
|
|
+; Advanced disk read routine with automatic retry and error recovery
|
|
|
+; Input: D = sector count, BC = parameters, HL = buffer pointer
|
|
|
+; Output: Carry set if unrecoverable error, clear if success
|
|
|
+
|
|
|
l06c1h:
|
|
|
- call sub_04c7h ;06c1
|
|
|
- ld a,b ;06c4
|
|
|
- ld (0ff85h),a ;06c5
|
|
|
- ld a,c ;06c8
|
|
|
- ld (0ff86h),a ;06c9
|
|
|
+ call sub_04c7h ;06c1 Setup disk operation parameters
|
|
|
+ ld a,b ;06c4 Get B register (track/cylinder)
|
|
|
+ ld (0ff85h),a ;06c5 Store track parameter in system memory
|
|
|
+ ld a,c ;06c8 Get C register (sector/head)
|
|
|
+ ld (0ff86h),a ;06c9 Store sector parameter in system memory
|
|
|
+
|
|
|
l06cch:
|
|
|
- ld a,d ;06cc
|
|
|
- ld (0ff87h),a ;06cd
|
|
|
- push bc ;06d0
|
|
|
- push hl ;06d1
|
|
|
- call reading ;06d2
|
|
|
- jp c,l06fbh ;06d5
|
|
|
- ld hl,0ff83h ;06d8
|
|
|
- ld bc,00678h ;06db
|
|
|
+ ld a,d ;06cc Get D register (sector count)
|
|
|
+ ld (0ff87h),a ;06cd Store sector count parameter
|
|
|
+ push bc ;06d0 Save BC registers (track/sector info)
|
|
|
+ push hl ;06d1 Save HL registers (buffer pointer)
|
|
|
+ call reading ;06d2 Execute disk read command
|
|
|
+ jp c,l06fbh ;06d5 If read error, jump to cleanup and return
|
|
|
+
|
|
|
+ ; Successful read - transfer parameter data
|
|
|
+ ld hl,0ff83h ;06d8 Point to disk parameter buffer
|
|
|
+ ld bc,00678h ;06db B=6 bytes to transfer, C=0x78 (I/O port for data)
|
|
|
+
|
|
|
l06deh:
|
|
|
- in a,(079h) ;06de
|
|
|
- and 041h ;06e0
|
|
|
- jr nz,l06deh ;06e2
|
|
|
- outi ;06e4
|
|
|
- jr nz,l06deh ;06e6
|
|
|
- out (07ah),a ;06e8
|
|
|
- nop ;06ea
|
|
|
+ ; Wait for controller ready and transfer data
|
|
|
+ in a,(079h) ;06de Read disk controller status port
|
|
|
+ and 041h ;06e0 Check bits 6 and 0 (ready and data request flags)
|
|
|
+ jr nz,l06deh ;06e2 Wait until controller indicates ready for transfer
|
|
|
+ outi ;06e4 Transfer byte: output (HL) to port C, increment HL, decrement B
|
|
|
+ jr nz,l06deh ;06e6 Continue until all 6 parameter bytes transferred
|
|
|
+ out (07ah),a ;06e8 Write final control byte to data port 0x7A
|
|
|
+ nop ;06ea Short timing delay for controller
|
|
|
+
|
|
|
l06ebh:
|
|
|
- in a,(079h) ;06eb
|
|
|
- and 044h ;06ed
|
|
|
- jr nz,l06ebh ;06ef
|
|
|
- out (07bh),a ;06f1
|
|
|
- call reading2 ;06f3
|
|
|
- and 002h ;06f6
|
|
|
- call nz,sub_06ffh ;06f8
|
|
|
+ ; Wait for final status and complete operation
|
|
|
+ in a,(079h) ;06eb Read disk controller status
|
|
|
+ and 044h ;06ed Check bits 6 and 2 (completion status flags)
|
|
|
+ jr nz,l06ebh ;06ef Wait for completion status change
|
|
|
+ out (07bh),a ;06f1 Write completion status to control port 0x7B
|
|
|
+ call reading2 ;06f3 Read final operation status
|
|
|
+ and 002h ;06f6 Check bit 1 (error indication)
|
|
|
+ call nz,sub_06ffh ;06f8 If error bit set, call error recovery routine
|
|
|
+
|
|
|
l06fbh:
|
|
|
- pop hl ;06fb
|
|
|
- pop bc ;06fc
|
|
|
- inc bc ;06fd
|
|
|
- ret ;06fe
|
|
|
+ ; Cleanup and return
|
|
|
+ pop hl ;06fb Restore HL registers (buffer pointer)
|
|
|
+ pop bc ;06fc Restore BC registers (track/sector)
|
|
|
+ inc bc ;06fd Increment BC to next sector position
|
|
|
+ ret ;06fe Return to caller
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; ADVANCED DISK ERROR RECOVERY ROUTINE
|
|
|
+; ================================================================================
|
|
|
+; Sophisticated error recovery with retry logic and validation
|
|
|
+; Called when initial read fails - attempts recovery and validation
|
|
|
+; Returns: Carry set if unrecoverable, clear if recovery successful
|
|
|
+
|
|
|
sub_06ffh:
|
|
|
- call reading ;06ff
|
|
|
- ret c ;0702
|
|
|
- ld a,003h ;0703
|
|
|
- call moveout ;0705
|
|
|
- ld bc,00478h ;0708
|
|
|
- ld hl,0ff89h ;070b
|
|
|
+ call reading ;06ff Attempt another disk read operation
|
|
|
+ ret c ;0702 Return immediately if read still failing
|
|
|
+ ld a,003h ;0703 A = 3 (retry/recovery command code)
|
|
|
+ call moveout ;0705 Execute move/output operation with retry command
|
|
|
+ ld bc,00478h ;0708 B=4 bytes to read, C=0x78 (I/O data port)
|
|
|
+ ld hl,0ff89h ;070b Point to error recovery buffer in system memory
|
|
|
+
|
|
|
l070eh:
|
|
|
- in a,(079h) ;070e
|
|
|
- cp 00fh ;0710
|
|
|
- jr nz,l070eh ;0712
|
|
|
- ini ;0714
|
|
|
- jr nz,l070eh ;0716
|
|
|
- call reading2 ;0718
|
|
|
- ld a,(0ff89h) ;071b
|
|
|
- sub 098h ;071e
|
|
|
- ret z ;0720
|
|
|
- scf ;0721
|
|
|
- ret ;0722
|
|
|
+ ; Read recovery data from controller
|
|
|
+ in a,(079h) ;070e Read disk controller status port
|
|
|
+ cp 00fh ;0710 Compare with 0x0F (ready for data transfer)
|
|
|
+ jr nz,l070eh ;0712 Wait until controller indicates ready (status = 0x0F)
|
|
|
+ ini ;0714 Input byte: read from port C to (HL), increment HL, decrement B
|
|
|
+ jr nz,l070eh ;0716 Continue until all 4 recovery bytes read
|
|
|
+ call reading2 ;0718 Read final status after recovery attempt
|
|
|
+ ld a,(0ff89h) ;071b Get first byte from recovery buffer
|
|
|
+ sub 098h ;071e Compare with expected recovery value 0x98
|
|
|
+ ret z ;0720 Return success (Z flag) if recovery data matches
|
|
|
+ scf ;0721 Set carry flag (recovery failed)
|
|
|
+ ret ;0722 Return with unrecoverable error status
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; LOW-LEVEL DISK CONTROLLER COMMUNICATION ROUTINES
|
|
|
+; ================================================================================
|
|
|
+; Core routines for sending commands and reading status from disk controller
|
|
|
+
|
|
|
reading:
|
|
|
- in a,(079h) ;0723
|
|
|
- and 080h ;0725
|
|
|
- scf ;0727
|
|
|
- ret z ;0728
|
|
|
- ld a,001h ;0729
|
|
|
- out (079h),a ;072b
|
|
|
- ld b,0ffh ;072d
|
|
|
+ ; Initiate disk read command with timeout protection
|
|
|
+ in a,(079h) ;0723 Read disk controller status port
|
|
|
+ and 080h ;0725 Check bit 7 (controller ready flag)
|
|
|
+ scf ;0727 Set carry flag (assume error initially)
|
|
|
+ ret z ;0728 Return with error if controller not ready
|
|
|
+ ld a,001h ;0729 A = 1 (start read command)
|
|
|
+ out (079h),a ;072b Send start command to disk controller
|
|
|
+ ld b,0ffh ;072d B = 255 (timeout counter - ~255 loop iterations)
|
|
|
+
|
|
|
l072fh:
|
|
|
- in a,(079h) ;072f
|
|
|
- and 080h ;0731
|
|
|
- ret z ;0733
|
|
|
- djnz l072fh ;0734
|
|
|
- scf ;0736
|
|
|
- ret ;0737
|
|
|
+ ; Wait for command completion with timeout
|
|
|
+ in a,(079h) ;072f Read controller status port
|
|
|
+ and 080h ;0731 Check ready bit (bit 7)
|
|
|
+ ret z ;0733 Return success (carry clear) if ready bit cleared
|
|
|
+ djnz l072fh ;0734 Decrement timeout counter and continue waiting
|
|
|
+ scf ;0736 Set carry flag (timeout error)
|
|
|
+ ret ;0737 Return with timeout error
|
|
|
+
|
|
|
reading2:
|
|
|
- in a,(079h) ;0738
|
|
|
- and 044h ;073a
|
|
|
- jr nz,reading2 ;073c
|
|
|
- in a,(078h) ;073e
|
|
|
- ld b,a ;0740
|
|
|
+ in a,(079h) ;0738 Read disk controller status
|
|
|
+ and 044h ;073a Check bits 6 and 2 (busy/status flags)
|
|
|
+ jr nz,reading2 ;073c Wait until both flags clear
|
|
|
+ in a,(078h) ;073e Read result from data port
|
|
|
+ ld b,a ;0740 Save result in B
|
|
|
+
|
|
|
l0741h:
|
|
|
- in a,(079h) ;0741
|
|
|
- and 042h ;0743
|
|
|
- jr nz,l0741h ;0745
|
|
|
- in a,(078h) ;0747
|
|
|
- ld a,b ;0749
|
|
|
- ret ;074a
|
|
|
+ in a,(079h) ;0741 Read controller status again
|
|
|
+ and 042h ;0743 Check bits 6 and 1 (different status bits)
|
|
|
+ jr nz,l0741h ;0745 Wait until these flags clear
|
|
|
+ in a,(078h) ;0747 Read final data byte
|
|
|
+ ld a,b ;0749 Restore original result to A
|
|
|
+ ret ;074a Return with status in A
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; DISK COMMAND OUTPUT ROUTINES
|
|
|
+; ================================================================================
|
|
|
+; Send command sequences to disk controller
|
|
|
+
|
|
|
moveoutreseta:
|
|
|
- ld a,000h ;074b
|
|
|
+ ld a,000h ;074b A = 0 (reset command)
|
|
|
+
|
|
|
moveout:
|
|
|
- call sub_0760h ;074d
|
|
|
- ld a,(0ff84h) ;0750
|
|
|
- call sub_0760h ;0753
|
|
|
- ld a,000h ;0756
|
|
|
- ld b,004h ;0758
|
|
|
+ call sub_0760h ;074d Send A to disk controller
|
|
|
+ ld a,(0ff84h) ;0750 Get stored command parameter
|
|
|
+ call sub_0760h ;0753 Send parameter to controller
|
|
|
+ ld a,000h ;0756 A = 0 (padding/terminator)
|
|
|
+ ld b,004h ;0758 B = 4 (send 4 zero bytes)
|
|
|
+
|
|
|
l075ah:
|
|
|
- call sub_0760h ;075a
|
|
|
- djnz l075ah ;075d
|
|
|
- ret ;075f
|
|
|
+ call sub_0760h ;075a Send zero byte to controller
|
|
|
+ djnz l075ah ;075d Repeat 4 times
|
|
|
+ ret ;075f Return
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; LOW-LEVEL DISK CONTROLLER I/O
|
|
|
+; ================================================================================
|
|
|
+; Fundamental routine for sending bytes to disk controller
|
|
|
+
|
|
|
sub_0760h:
|
|
|
- push af ;0760
|
|
|
+ push af ;0760 Save byte to send
|
|
|
+
|
|
|
l0761h:
|
|
|
- in a,(079h) ;0761
|
|
|
- and 041h ;0763
|
|
|
- jr nz,l0761h ;0765
|
|
|
- pop af ;0767
|
|
|
- out (078h),a ;0768
|
|
|
- ret ;076a
|
|
|
+ in a,(079h) ;0761 Read controller status
|
|
|
+ and 041h ;0763 Check bits 6 and 0 (ready/busy flags)
|
|
|
+ jr nz,l0761h ;0765 Wait until controller ready to receive
|
|
|
+ pop af ;0767 Restore byte to send
|
|
|
+ out (078h),a ;0768 Send byte to controller data port
|
|
|
+ ret ;076a Return
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; DISK CONTROLLER DATA TRANSFER
|
|
|
+; ================================================================================
|
|
|
+; Transfers data block from controller
|
|
|
+
|
|
|
sub_076bh:
|
|
|
- ld a,00ch ;076b
|
|
|
- call moveout ;076d
|
|
|
- ld bc,00878h ;0770
|
|
|
+ ld a,00ch ;076b A = 0x0C (data transfer command)
|
|
|
+ call moveout ;076d Send command to controller
|
|
|
+ ld bc,00878h ;0770 B=8 bytes, C=0x78 (data port)
|
|
|
+
|
|
|
l0773h:
|
|
|
- in a,(079h) ;0773
|
|
|
- cp 007h ;0775
|
|
|
- jr nz,l0773h ;0777
|
|
|
- outi ;0779
|
|
|
- jr nz,l0773h ;077b
|
|
|
- jr reading2 ;077d
|
|
|
+ in a,(079h) ;0773 Read controller status
|
|
|
+ cp 007h ;0775 Compare with 0x07 (data ready)
|
|
|
+ jr nz,l0773h ;0777 Wait until data ready
|
|
|
+ outi ;0779 Input byte: (HL) ← (C), HL++, B--
|
|
|
+ jr nz,l0773h ;077b Continue until 8 bytes transferred
|
|
|
+ jr reading2 ;077d Jump to read final status
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; DISK ERROR RECOVERY AND ALTERNATE ROUTINES
|
|
|
+; ================================================================================
|
|
|
+
|
|
|
l077fh:
|
|
|
- ld a,0e4h ;077f
|
|
|
- call steproutine ;0781
|
|
|
- ret z ;0784
|
|
|
- jp l0681h ;0785
|
|
|
+ ld a,0e4h ;077f A = 0xE4 (error recovery command)
|
|
|
+ call steproutine ;0781 Execute step/recovery routine
|
|
|
+ ret z ;0784 Return if successful
|
|
|
+ jp print_error1 ;0785 Jump to disk error handler
|
|
|
+
|
|
|
l0788h:
|
|
|
- call reading ;0788
|
|
|
- ret c ;078b
|
|
|
- ld a,001h ;078c
|
|
|
- call steproutine ;078e
|
|
|
- ret z ;0791
|
|
|
- jr l079dh ;0792
|
|
|
+ call reading ;0788 Attempt disk read
|
|
|
+ ret c ;078b Return if error
|
|
|
+ ld a,001h ;078c A = 0x01 (step command)
|
|
|
+ call steproutine ;078e Execute step routine
|
|
|
+ ret z ;0791 Return if successful
|
|
|
+ jr print_error3 ;0792 Jump to alternate error handling
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; DISK STEP/SEEK ROUTINE
|
|
|
+; ================================================================================
|
|
|
+; Executes disk step commands (seek operations)
|
|
|
+
|
|
|
steproutine:
|
|
|
- call moveout ;0794
|
|
|
- call reading2 ;0797
|
|
|
- and 002h ;079a
|
|
|
- ret ;079c
|
|
|
-l079dh:
|
|
|
- call screenclearnetry2 ;079d
|
|
|
- rst 10h ;07a0
|
|
|
+ call moveout ;0794 Send step command to controller
|
|
|
+ call reading2 ;0797 Read controller status
|
|
|
+ and 002h ;079a Check bit 1 (error flag)
|
|
|
+ ret ;079c Return with Z flag set if no error
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; DISK MALFUNCTION ERROR HANDLER
|
|
|
+; ================================================================================
|
|
|
+
|
|
|
+print_error3:
|
|
|
+ call screenclearnetry2 ;079d Clear screen and setup display
|
|
|
+ rst 10h ;07a0 RST 10h: Display error message
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; ERROR #3 MESSAGE DATA - DISK MALFUNCTION
|
|
|
+; ================================================================================
|
|
|
|
|
|
; BLOCK 'ERROR3' (start 0x07a1 end 0x07c9)
|
|
|
ERROR3_start:
|
|
|
- defb 027h ;07a1 count 39
|
|
|
- defb 045h ;07a2 Error 3: Disk Malfunction, Call Service
|
|
|
- defb 072h ;07a3
|
|
|
- defb 072h ;07a4
|
|
|
- defb 06fh ;07a5
|
|
|
- defb 072h ;07a6
|
|
|
- defb 020h ;07a7
|
|
|
- defb 033h ;07a8
|
|
|
- defb 03ah ;07a9
|
|
|
- defb 020h ;07aa
|
|
|
- defb 044h ;07ab
|
|
|
- defb 069h ;07ac
|
|
|
- defb 073h ;07ad
|
|
|
- defb 06bh ;07ae
|
|
|
- defb 020h ;07af
|
|
|
- defb 04dh ;07b0
|
|
|
- defb 061h ;07b1
|
|
|
- defb 06ch ;07b2
|
|
|
- defb 066h ;07b3
|
|
|
- defb 075h ;07b4
|
|
|
- defb 06eh ;07b5
|
|
|
- defb 063h ;07b6
|
|
|
- defb 074h ;07b7
|
|
|
- defb 069h ;07b8
|
|
|
- defb 06fh ;07b9
|
|
|
- defb 06eh ;07ba
|
|
|
- defb 02ch ;07bb
|
|
|
- defb 020h ;07bc
|
|
|
- defb 043h ;07bd
|
|
|
- defb 061h ;07be
|
|
|
- defb 06ch ;07bf
|
|
|
- defb 06ch ;07c0
|
|
|
- defb 020h ;07c1
|
|
|
- defb 053h ;07c2
|
|
|
- defb 065h ;07c3
|
|
|
- defb 072h ;07c4
|
|
|
- defb 076h ;07c5
|
|
|
- defb 069h ;07c6
|
|
|
- defb 063h ;07c7
|
|
|
- defb 065h ;07c8
|
|
|
+ defb 027h ;07a1 Message length: 39 characters
|
|
|
+ defb 045h ;07a2 'E' - "Error #3: Disk Malfunction, Call Service"
|
|
|
+ defb 072h ;07a3 'r'
|
|
|
+ defb 072h ;07a4 'r'
|
|
|
+ defb 06fh ;07a5 'o'
|
|
|
+ defb 072h ;07a6 'r'
|
|
|
+ defb 020h ;07a7 ' '
|
|
|
+ defb 033h ;07a8 '3'
|
|
|
+ defb 03ah ;07a9 ':'
|
|
|
+ defb 020h ;07aa ' '
|
|
|
+ defb 044h ;07ab 'D'
|
|
|
+ defb 069h ;07ac 'i'
|
|
|
+ defb 073h ;07ad 's'
|
|
|
+ defb 06bh ;07ae 'k'
|
|
|
+ defb 020h ;07af ' '
|
|
|
+ defb 04dh ;07b0 'M'
|
|
|
+ defb 061h ;07b1 'a'
|
|
|
+ defb 06ch ;07b2 'l'
|
|
|
+ defb 066h ;07b3 'f'
|
|
|
+ defb 075h ;07b4 'u'
|
|
|
+ defb 06eh ;07b5 'n'
|
|
|
+ defb 063h ;07b6 'c'
|
|
|
+ defb 074h ;07b7 't'
|
|
|
+ defb 069h ;07b8 'i'
|
|
|
+ defb 06fh ;07b9 'o'
|
|
|
+ defb 06eh ;07ba 'n'
|
|
|
+ defb 02ch ;07bb ','
|
|
|
+ defb 020h ;07bc ' '
|
|
|
+ defb 043h ;07bd 'C'
|
|
|
+ defb 061h ;07be 'a'
|
|
|
+ defb 06ch ;07bf 'l'
|
|
|
+ defb 06ch ;07c0 'l'
|
|
|
+ defb 020h ;07c1 ' '
|
|
|
+ defb 053h ;07c2 'S'
|
|
|
+ defb 065h ;07c3 'e'
|
|
|
+ defb 072h ;07c4 'r'
|
|
|
+ defb 076h ;07c5 'v'
|
|
|
+ defb 069h ;07c6 'i'
|
|
|
+ defb 063h ;07c7 'c'
|
|
|
+ defb 065h ;07c8 'e'
|
|
|
ERROR3_end:
|
|
|
- halt ;07c9
|
|
|
+ halt ;07c9 System halt - requires service intervention
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; DATA TABLES AND CONSTANTS
|
|
|
+; ================================================================================
|
|
|
+; Various data tables used by system routines
|
|
|
+
|
|
|
l07cah:
|
|
|
- ld bc,00432h ;07ca
|
|
|
- ld bc,00031h ;07cd
|
|
|
- ld b,b ;07d0
|
|
|
- dec bc ;07d1
|
|
|
- ld b,000h ;07d2
|
|
|
- sub l ;07d4
|
|
|
- rst 38h ;07d5
|
|
|
-l07d6h:
|
|
|
- ld bc,00232h ;07d6
|
|
|
- ld bc,00031h ;07d9
|
|
|
- ld b,b ;07dc
|
|
|
- dec bc ;07dd
|
|
|
- ld b,000h ;07de
|
|
|
- ld c,d ;07e0
|
|
|
- rst 38h ;07e1
|
|
|
+ defb 001h ;07ca Data table entry 1
|
|
|
+ defb 032h ;07cb Data table entry 2
|
|
|
+ defb 004h ;07cc Data table entry 3
|
|
|
+ defb 001h ;07cd Data table entry 4
|
|
|
+ defb 031h ;07ce Data table entry 5
|
|
|
+ defb 000h ;07cf Data table entry 6
|
|
|
+ defb 040h ;07d0 Data byte
|
|
|
+ defb 00bh ;07d1 Data byte
|
|
|
+ defb 006h ;07d2 Data byte
|
|
|
+ defb 000h ;07d3 Data byte
|
|
|
+ defb 095h ;07d4 Data byte
|
|
|
+ defb 0ffh ;07d5 Data byte
|
|
|
+ defb 001h ;07d6 Data byte
|
|
|
+l07d7h:
|
|
|
+ defb 032h ;07d7 Data byte
|
|
|
+ defb 002h ;07d8 Data byte
|
|
|
+ defb 001h ;07d9 Data byte
|
|
|
+ defb 031h ;07da Data table entry 1
|
|
|
+ defb 000h ;07db Data table entry 1
|
|
|
+ defb 040h ;07dc Data table entry 2
|
|
|
+ defb 00bh ;07dd Data table entry 2
|
|
|
+ defb 006h ;07de Data byte
|
|
|
+ defb 000h ;07df Data byte
|
|
|
+ defb 04ah ;07e0 Data byte
|
|
|
+ defb 0ffh ;07e1 Data byte
|
|
|
+
|
|
|
l07e2h:
|
|
|
- nop ;07e2
|
|
|
- nop ;07e3
|
|
|
- ld c,d ;07e4
|
|
|
- rst 38h ;07e5
|
|
|
- rst 38h ;07e6
|
|
|
- rst 38h ;07e7
|
|
|
- rst 38h ;07e8
|
|
|
- rst 38h ;07e9
|
|
|
- rst 38h ;07ea
|
|
|
- rst 38h ;07eb
|
|
|
- rst 38h ;07ec
|
|
|
- rst 38h ;07ed
|
|
|
- rst 38h ;07ee
|
|
|
- rst 38h ;07ef
|
|
|
- rst 38h ;07f0
|
|
|
- rst 38h ;07f1
|
|
|
- rst 38h ;07f2
|
|
|
- rst 38h ;07f3
|
|
|
- rst 38h ;07f4
|
|
|
- rst 38h ;07f5
|
|
|
- rst 38h ;07f6
|
|
|
- rst 38h ;07f7
|
|
|
- rst 38h ;07f8
|
|
|
- rst 38h ;07f9
|
|
|
- rst 38h ;07fa
|
|
|
- rst 38h ;07fb
|
|
|
- rst 38h ;07fc
|
|
|
- rst 38h ;07fd
|
|
|
- rst 38h ;07fe
|
|
|
- rst 38h ;07ff
|
|
|
+ defb 000h ;07e2 Data byte 'Q'
|
|
|
+ defb 000h ;07e3 Data byte (NOP padding)
|
|
|
+ defb 04ah ;07e4 Data byte (NOP padding)
|
|
|
+l07e5h:
|
|
|
+ defb 0ffh ;07e5 Data byte 'J'
|
|
|
+
|
|
|
+; ROM unused space filled with RST 38h (0FFh) - typical EPROM pattern
|
|
|
+
|
|
|
+ defb 0ffh ;07e6 Unused ROM space
|
|
|
+ defb 0ffh ;07e7 Unused ROM space
|
|
|
+ defb 0ffh ;07e8 Unused ROM space
|
|
|
+ defb 0ffh ;07e9 Unused ROM space
|
|
|
+ defb 0ffh ;07ea Unused ROM space
|
|
|
+ defb 0ffh ;07eb Unused ROM space
|
|
|
+ defb 0ffh ;07ec Unused ROM space
|
|
|
+ defb 0ffh ;07ed Unused ROM space
|
|
|
+ defb 0ffh ;07ee Unused ROM space
|
|
|
+ defb 0ffh ;07ef Unused ROM space
|
|
|
+ defb 0ffh ;07f0 Unused ROM space
|
|
|
+ defb 0ffh ;07f1 Unused ROM space
|
|
|
+ defb 0ffh ;07f2 Unused ROM space
|
|
|
+ defb 0ffh ;07f3 Unused ROM space
|
|
|
+ defb 0ffh ;07f4 Unused ROM space
|
|
|
+ defb 0ffh ;07f5 Unused ROM space
|
|
|
+ defb 0ffh ;07f6 Unused ROM space
|
|
|
+ defb 0ffh ;07f7 Unused ROM space
|
|
|
+ defb 0ffh ;07f8 Unused ROM space
|
|
|
+ defb 0ffh ;07f9 Unused ROM space
|
|
|
+ defb 0ffh ;07fa Unused ROM space
|
|
|
+ defb 0ffh ;07fb Unused ROM space
|
|
|
+ defb 0ffh ;07fc Unused ROM space
|
|
|
+ defb 0ffh ;07fd Unused ROM space
|
|
|
+ defb 0ffh ;07fe Unused ROM space
|
|
|
+ defb 0ffh ;07ff End of 2K ROM - TMS2516 EPROM
|
|
|
+
|
|
|
+; ================================================================================
|
|
|
+; END OF ROM - MONROE OC8820 BOOT ROM R3.00C
|
|
|
+; ================================================================================
|
|
|
+; Total ROM size: 2048 bytes (0x0000-0x07FF)
|
|
|
+; Boot process complete - system transfers control to OS at 0xFFA6
|
|
|
+; ================================================================================
|