.global _start _start: call find_disk call get_free_mailbox push hl ld de, 0 pms_call: call proc_map_set pop hl ld (mailbox_num), hl msg_loop: call yield yield_back: ld hl, (mailbox_num) call mb_read mb_read_done: ld a, b cp 1 jp z, msg_loop msg_read: push bc push de push hl ld b, c ld c, 0xB call set_frame set_frame_done: 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, (0xB004) ; Load destination mailbox into HL and save it on the stack push hl ld hl, 0xB000 call read_bytes pop hl pop ix pop de pop bc ld a, 5 call 0xdffd jp msg_loop 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 ld b, 0 ; Load bc with the value in A ld c, a inc bc push de ld de, (byte_count) ld a, b cp d jp c, count_ok_1 ld a, c cp e jp c, count_ok_1 push de pop bc count_ok_1: pop de ld a, b cp 0 jp nz, nz_ok ld a, c cp 0 jp nz, nz_ok jp no_transfer nz_ok: ldir no_transfer: 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 ld b, 0 ; Load bc with the value in A ld c, a inc bc push de ld de, (byte_count) ld a, b cp d jp c, count_ok_2 ld a, c cp e jp c, count_ok_2 push de pop bc count_ok_2: pop de ld hl, (byte_count) scf ccf sbc hl, bc ld (rem_bytes), hl ld a, h cp 0 jp z, no_transfer_2 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 no_transfer_2: ld a, (rem_bytes) cp 0 jp z, read_bytes_done 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 */