os-z80/initrd_fs.z80

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
ld hl, 0x8001
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