140 lines
2.1 KiB
Z80 Assembly
140 lines
2.1 KiB
Z80 Assembly
.global _start
|
|
_start:
|
|
call get_free_mailbox ; Get a mailbox
|
|
push hl
|
|
ld de, 1
|
|
call get_free_frame ; Set up a frame to send messages at 0x8000
|
|
ld b, c
|
|
ld e, l
|
|
ld d, h
|
|
ld c, 0x8
|
|
call set_frame
|
|
call get_free_frame ; Set up a frame for the file mapping at 0xA000
|
|
ld b, c
|
|
ld e, l
|
|
ld d, h
|
|
ld c, 0xA
|
|
call set_frame
|
|
ld c, 0
|
|
ld de, 1
|
|
ld hl, 0xA000
|
|
initrd_read_loop:
|
|
push bc
|
|
push de
|
|
push hl
|
|
ld hl, 0x8000
|
|
call read_sector
|
|
pop de
|
|
push de
|
|
ld b, 0 ; Load the filename length in BC
|
|
ld a, (0x8000)
|
|
ld c, a
|
|
inc hl
|
|
ldir
|
|
ld a, (hl)
|
|
ld (de), a
|
|
inc hl
|
|
pop de
|
|
ld a, e
|
|
add a, 0x20
|
|
ld e, a
|
|
ld a, d
|
|
adc a, 0x0
|
|
ld d, a
|
|
ld a, (hl)
|
|
ld (de), a
|
|
inc hl
|
|
inc de
|
|
ld a, (hl)
|
|
ld (de), a
|
|
inc hl
|
|
inc de
|
|
ld l, e
|
|
ld h, d
|
|
pop de
|
|
pop bc
|
|
ld (hl), e
|
|
inc hl
|
|
ld (hl), d
|
|
inc hl
|
|
ld (hl), c
|
|
inc hl
|
|
; Advance to the next header
|
|
ld b, 0 ; Load the filename length in BC
|
|
ld a, (0x8000)
|
|
ld c, a
|
|
ld hl, 0x8004
|
|
add hl, bc ; Add the filename length to get the pointer to the
|
|
; # of blocks in the file in HL
|
|
ld c, (hl) ; Read the # of blocks into BC
|
|
inc hl
|
|
ld b, (hl)
|
|
ld l, c ; Move it into HL
|
|
ld h, b
|
|
inc hl ; Add 1 to account for the header sector
|
|
pop bc
|
|
add hl, de ; 24-bit add of HL to C:DE
|
|
ld e, l
|
|
ld d, h
|
|
ld a, c
|
|
adc a, 0
|
|
ld c, a
|
|
jp initrd_read_loop
|
|
call proc_map_set ; Register ourselves as ID 1
|
|
pop hl
|
|
ld (mailbox_num), hl
|
|
msg_loop:
|
|
call yield
|
|
ld hl, (mailbox_num)
|
|
call mb_read ; Read a message and place it at 0xB000
|
|
push bc
|
|
push de
|
|
push hl
|
|
ld b, c
|
|
ld c, 0xB
|
|
call set_frame
|
|
|
|
ld hl, (0xB004) ; Load destination mailbox into HL
|
|
pop ix
|
|
pop de
|
|
pop bc
|
|
call mb_send
|
|
halt
|
|
jp msg_loop
|
|
halt
|
|
|
|
mailbox_num: .ds.b 2
|
|
|
|
; Given a sector number in C:DE, reads the sector off disk into 0x8000
|
|
read_sector:
|
|
; Set up a read message to the driver starting at the sector in register E and reading
|
|
; 0x100 bytes
|
|
ld a, 0x0
|
|
ld (0xA000), a
|
|
ld a, e
|
|
ld (0xA001), a
|
|
ld a, 0x00
|
|
ld (0xA002), a
|
|
ld a, 0x1
|
|
ld (0xA003), a
|
|
ld hl, (mailbox_num)
|
|
ld (0xA004), hl
|
|
push de
|
|
push bc
|
|
ld de, 0 ; Get the mailbox number for the initrd driver
|
|
call proc_map_get
|
|
pop bc
|
|
pop de
|
|
ld c, b ; Send the message
|
|
ld ix, 0x0000
|
|
call mb_send
|
|
loop:
|
|
call yield
|
|
ld hl, (mailbox_num)
|
|
call mb_read ; Read a message
|
|
ld a, b ; Loop if there is no message
|
|
cp 0
|
|
jp nz, loop
|
|
read_sector_done:
|
|
ret
|