309 lines
4.7 KiB
Z80 Assembly
309 lines
4.7 KiB
Z80 Assembly
.global _start
|
|
_start:
|
|
call get_free_mailbox ; Get a mailbox
|
|
ld (sec_read_mailbox_num), hl
|
|
call get_free_mailbox ; Get a mailbox
|
|
ld (mailbox_num), hl
|
|
ld de, 1
|
|
call get_free_frame ; Set up a frame to send messages at 0xA000
|
|
ld a, c
|
|
ld (msg_frame_phys), a
|
|
ld a, l
|
|
ld (msg_frame_phys+1), a
|
|
ld a, h
|
|
ld (msg_frame_phys+2), a
|
|
ld b, c
|
|
ld e, l
|
|
ld d, h
|
|
ld c, 0xA
|
|
call set_frame
|
|
call get_free_frame ; Set up a frame for the file mapping at 0x8000
|
|
ld b, c
|
|
ld e, l
|
|
ld d, h
|
|
ld c, 0x8
|
|
call set_frame
|
|
ld c, 0
|
|
ld de, 1
|
|
ld hl, 0x8000
|
|
initrd_read_loop:
|
|
push bc
|
|
push de
|
|
push hl
|
|
; FM SECL SECH
|
|
ld hl, 0xA000
|
|
call read_sector
|
|
pop de
|
|
push de
|
|
; FM SECL SECH
|
|
ld b, 0 ; Load the filename length in BC
|
|
ld a, (0xA000)
|
|
cp 0
|
|
jp z, initrd_read_done
|
|
ld c, a
|
|
ld hl, 0xA001 ; Read the name + null terminator into the mapping list
|
|
ldir
|
|
ld a, (hl)
|
|
ld (de), a
|
|
inc hl
|
|
pop de ; Restore the value of DE before reading the name in
|
|
; SECL SECH
|
|
dbg_label:
|
|
ld a, e ; Add 0x20 to DE
|
|
add a, 0x20
|
|
ld e, a
|
|
ld a, d
|
|
adc a, 0x0
|
|
ld d, a
|
|
ld a, (hl) ; Write the file legth to the mapping list
|
|
ld (de), a
|
|
inc hl
|
|
inc de
|
|
ld a, (hl)
|
|
ld (de), a
|
|
inc hl
|
|
inc de
|
|
ld l, e
|
|
ld h, d
|
|
pop iy
|
|
; SECH
|
|
pop bc
|
|
; (EMPTY)
|
|
push de
|
|
; FM
|
|
push bc
|
|
; SECH FM
|
|
ld e, iyl
|
|
ld d, iyh
|
|
ld (hl), e ; Write the starting block of the file to the mapping list
|
|
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, (0xA000)
|
|
ld c, a
|
|
ld hl, 0xA004
|
|
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
|
|
; FM
|
|
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
|
|
pop hl
|
|
; (empty)
|
|
inc hl
|
|
inc hl
|
|
inc hl
|
|
jp initrd_read_loop
|
|
initrd_read_done:
|
|
ld de, 1
|
|
ld hl, (mailbox_num)
|
|
pms_call:
|
|
call proc_map_set ; Register ourselves as ID 1
|
|
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 hl, (0xB000) ; Load destination mailbox into HL and save it on the stack
|
|
push hl
|
|
ld hl, 0xB002
|
|
; Handling code goes here
|
|
ld a, (hl)
|
|
inc hl
|
|
cp 0x0
|
|
jp z, open
|
|
cp 0x1
|
|
jp z, read
|
|
operation_done:
|
|
pop hl
|
|
pop ix
|
|
pop de
|
|
pop bc
|
|
call mb_send
|
|
jp msg_loop
|
|
|
|
; de = start of file map list
|
|
; c = 0
|
|
; while (1) {
|
|
; if (*de == 0) {
|
|
; (0xB000) = 1;
|
|
; return
|
|
; }
|
|
; if (strcmp(de, 0xB003) == 0) {
|
|
; (0xB000) = 0;
|
|
; (0xB001) = c;
|
|
; return;
|
|
; }
|
|
; }
|
|
open:
|
|
ld de, 0x8000
|
|
ld c, 0
|
|
open_find_loop:
|
|
ld a, (de)
|
|
cp 0
|
|
jp nz, open_not_end
|
|
ld a, 1
|
|
ld (0xB000), a
|
|
jp operation_done
|
|
open_not_end:
|
|
ld ix, 0xB003
|
|
push de
|
|
pop iy
|
|
call strcmp
|
|
cp 0
|
|
jp nz, open_not_match
|
|
ld a, 0
|
|
ld (0xB000), a
|
|
ld a, c
|
|
ld (0xB001), a
|
|
jp operation_done
|
|
open_not_match:
|
|
inc c
|
|
push de
|
|
pop hl
|
|
ld de, 0x25
|
|
add hl, de
|
|
push hl
|
|
pop de
|
|
jp open_find_loop
|
|
|
|
read:
|
|
ld a, (0xB003)
|
|
ld l, a
|
|
ld h, 0
|
|
push hl
|
|
pop ix
|
|
add hl, hl
|
|
add hl, hl
|
|
push hl
|
|
pop de
|
|
add ix, de
|
|
add hl, hl
|
|
add hl, hl
|
|
add hl, hl
|
|
push hl
|
|
pop de
|
|
add ix, de
|
|
ld de, 0x8020
|
|
add ix, de
|
|
ld d, (ix+2)
|
|
ld e, 0x0
|
|
ld hl, (0xB004)
|
|
add hl, de
|
|
ld bc, 0x100
|
|
add hl, bc
|
|
ld c, l
|
|
ld b, h
|
|
ld de, (0xB006)
|
|
call read_bytes
|
|
ld de, 0xB000
|
|
ld hl, 0xA000
|
|
ld bc, (0xB006)
|
|
ldir
|
|
jp operation_done
|
|
|
|
|
|
|
|
strcmp:
|
|
strcmp_loop:
|
|
ld a, (ix+0)
|
|
ld b, (iy+0)
|
|
cp b
|
|
jp nz, strcmp_different
|
|
cp 0
|
|
ret z
|
|
inc ix
|
|
inc iy
|
|
jp strcmp_loop
|
|
strcmp_different:
|
|
ld a, 1
|
|
ret
|
|
|
|
sec_read_mailbox_num: .ds.b 2
|
|
mailbox_num: .ds.b 2
|
|
msg_frame_phys: .ds.b 3
|
|
|
|
; Given a sector number in C:DE, reads the sector off disk into 0xA000
|
|
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, (sec_read_mailbox_num)
|
|
ld (0xA004), hl
|
|
ld de, 0 ; Get the mailbox number for the initrd driver
|
|
call proc_map_get
|
|
read_sec_pmg_done:
|
|
ld a, (msg_frame_phys)
|
|
ld c, a
|
|
ld de, (msg_frame_phys + 1)
|
|
ld ix, 0
|
|
call mb_send
|
|
read_sec_msg_sent:
|
|
loop:
|
|
call yield
|
|
ld hl, (sec_read_mailbox_num)
|
|
read_sector_done:
|
|
ret
|
|
|
|
|
|
; Given a byte offset in BC, and a byte length in DE no more than 0x1000, reads the data off disk into 0xA000
|
|
read_bytes:
|
|
; Set up a read message to the driver starting at the sector in register E and reading
|
|
; 0x100 bytes
|
|
ld (0xA000), bc
|
|
ld (0xA002), de
|
|
ld hl, (sec_read_mailbox_num)
|
|
ld (0xA004), hl
|
|
ld de, 0 ; Get the mailbox number for the initrd driver
|
|
call proc_map_get
|
|
read_bytes_pmg_done:
|
|
ld a, (msg_frame_phys)
|
|
ld c, a
|
|
ld de, (msg_frame_phys + 1)
|
|
ld ix, 0
|
|
call mb_send
|
|
read_bytes_msg_sent:
|
|
read_bytes_loop:
|
|
call yield
|
|
ld hl, (sec_read_mailbox_num)
|
|
|
|
call mb_read ; Read a message
|
|
ld a, b ; Loop if there is no message
|
|
cp 0
|
|
jp nz, read_bytes_loop
|
|
read_bytes_done:
|
|
ret
|