.global _start _start: call get_free_mailbox ; Get a mailbox sr_mb_got: ld (sec_read_mailbox_num), hl call get_free_mailbox ; Get a mailbox mb_got: 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 hl, 0xA000 ld a, (msg_frame_phys) ld c, a ld de, (msg_frame_phys+1) call libvfs_init 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 rl_read_sector_done: 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 length 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 hl, (mailbox_num) ld ix, initrd_fs_name call libvfs_register_fs 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 cp 0x2 jp z, mount operation_done: pop hl pop ix pop de pop bc call mb_send jp msg_loop mount: jp operation_done ; 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, c ld (0xB000), a ld a, 0 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, (0xB005) add hl, de ld bc, 0x100 add hl, bc ld c, l ld b, h ld de, (0xB007) call read_bytes ld de, 0xB000 ld hl, 0xA000 ld bc, (0xB007) 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 initrd_fs_name: .asciz "initrd"