.global _start _start: call find_disk ld a, 7 call 0xdffd push hl ld de, 0 ld a, 8 call 0xdffd pop hl ld (mailbox_num), hl msg_loop: call yield yield_back: ld hl, (mailbox_num) ld a, 6 call 0xdffd msg_read: push bc push de push hl ld b, c ld c, 0xB call set_frame ld a, h or 0xB0 ld h, a ld c, (hl) inc hl ld b, (hl) inc hl ld e, (hl) inc hl ld d, (hl) ld hl, 0xB000 jp read_bytes ld hl, (0xB004) ; Load destination mailbox into HL pop ix pop de pop bc ld a, 5 call 0xdffd halt jp msg_loop halt read_buf: .ds.b 512 ;Given a starting byte number in BC, a byte count in DE, and a destination address in HL, reads those bytes off the disk read_bytes: ld (start_byte), bc ld (byte_count), de ld (dest_addr), hl ld c, 0 ld d, 0 ld e, b ld hl, sec_buf call read_sector ld hl, sec_buf ld b, 0 ; Load BC with lower byte of start_byte (sector offset) ld a, (start_byte) ld c, a add hl, bc ; Add the offset to the buffer address ld de, (dest_addr) ld a, (start_byte) ; A = 255 - offset + 1 (256-offset) ld b, a ld a, 0xFF sub b inc a ld b, 0 ; Load bc with the value in A ld c, a ldir start_sec_trns_done: ld (dest_addr), de ld a, (start_byte) ; A = 255 - offset + 1 (256-offset) ld b, a ld a, 0xFF sub b inc a ld b, 0 ; Load bc with the value in A ld c, a ld hl, (byte_count) scf ccf sbc hl, bc ld (rem_bytes), hl ld b, h ld c, 0 ld d, 0 ld a, (start_byte+1) inc a ld e, a ld hl, (dest_addr) sector_loop: push bc call read_sector inc de pop bc djnz sector_loop ld (dest_addr), hl ld hl, (sec_buf) call read_sector ld hl, (sec_buf) ld de, (dest_addr) ld b, 0 ld a, (rem_bytes) ld c, a ldir read_bytes_done: ret start_byte: .ds.b 2 byte_count: .ds.b 2 dest_addr: .ds.b 2 rem_bytes: .ds.b 2 sec_buf: .ds.b 256 ; Given a sector number in C:DE and a buffer address in HL, reads the sector off disk. ; Clobbers A, BC, HL read_sector: push bc ld c,0xFF ; Force the top half of the IO address to be the id of the card, ld a, (disk_num) ; so the block transfer instructions can be used out (c), a pop bc ld a, c ld c, 0 out (c), e inc c out (c), d inc c out (c), a ld b, 0x0 ; Setup a transfer of 256 bytes (1 sector) at a time ld c, 0x3 ; from the storage device's data port inir ld c,0xFF ; Unforce the top half of the IO address in a,(c) read_sec_done: ret .global find_disk ; Clobbers A and HL find_disk: ld b,0x4 call find_first_card ld a, l ld (disk_num), a ret disk_num: .ds.b 1 mailbox_num: .ds.b 2 /* Start sector: Start byte / 256 */ /* Offset in start sector: Start byte % 256 */ /* Rem bytes: Byte count - (256 - Offset in start sector) */ /* Middle sectors start: start sector + 1 */ /* Middle sectors count: Rem bytes / 256 */ /* End sector: Middle sectors start + Middle sectors count */ /* End sector copy length: Rem bytes % 256 */