diff --git a/boot/boot.z80 b/boot/boot.z80 index 71d84af..d0ad06a 100644 --- a/boot/boot.z80 +++ b/boot/boot.z80 @@ -1,4 +1,4 @@ -_start: +_gtart: ld sp,0 ; Initialize the stack ld a,0x4 ; Find a generic storage card call find_first_card diff --git a/config.toml b/config.toml new file mode 100644 index 0000000..dbbf4ec --- /dev/null +++ b/config.toml @@ -0,0 +1,14 @@ +[[cards]] +type = "rom" +image = "rom.bin" + +[[cards]] +type = "term" + +[[cards]] +type = "ram" +num_pages = 128 # 512 KiB + +[[cards]] +type = "storage" +image = "os.dsk" diff --git a/file_structures b/file_structures new file mode 100644 index 0000000..f619595 --- /dev/null +++ b/file_structures @@ -0,0 +1,15 @@ +VFS messages: +register_fs(mb_no: MailboxID, name: &str) -> bool +mount(dev_path: &str, mount_path: &str, fs: &str) -> bool +open(path: &str, mode: &str) -> (MailboxID, u32) + +FS Api: +// Optional mailbox is redirect mailbox - direct file API calls there for provided FD +open(path: &str, mode: &str) -> (Option, u32) + +File Api: +read(fd: u32, pos: usize, len: usize) -> Vec + +DevFS: +register_dev(mb_no: MailboxID, name: &str, kind: u8) -> bool + diff --git a/init.z80 b/init.z80 index fb20523..99439bc 100644 --- a/init.z80 +++ b/init.z80 @@ -4,8 +4,6 @@ _start: call find_disk /* ld hl, test_string */ /* call print */ -/* call get_free_mailbox ; Initialize a mailbox */ -/* ld (mailbox_num), hl */ call get_free_frame ; Set up a frame to load programs into at 0x8000 ld b, c ld e, l @@ -13,6 +11,11 @@ ld d, h ld c, 8 bp_call_sf: call set_frame +; ld iy, vfs_name ; Load and run the initrd driver +; call run_file +; vfs_loaded: +; call yield ; Yield to let the initrd driver initialize +; vfs_returned: ld iy, initrd_driver_name ; Load and run the initrd driver call run_file initrd_driver_loaded: @@ -21,47 +24,108 @@ initrd_driver_returned: ld iy, initrd_fs_name ; Load and run the initrd fs driver call run_file initrd_fs_loaded: +fs_init_wait_loop: call yield ; Yield to let the initrd driver initialize -/* call get_free_frame ; Set up a message frame at 0xA000 */ -/* ld b, c */ -/* push hl */ -/* pop de */ -/* ld c, 0xA */ -/* call set_frame */ -; Set up a read message to the driver starting at 0x80 and reading -; 0x200 bytes -/* ld a, 0x80 */ -/* ld (0xA000), a */ -/* ld a, 0x00 */ -/* ld (0xA001), a */ -/* ld a, 0x00 */ -/* ld (0xA002), a */ -/* ld a, 0x2 */ -/* 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 */ +yield_done: +call get_free_mailbox ; Initialize a mailbox +ld (mailbox_num), hl +ld de, 1 +call proc_map_get +ld a, l +cp 0 +jp z, fs_init_wait_loop +fs_ready: +call get_free_frame ; Set up a message frame at 0xA000 +ld a, c +ld (msg_phys_addr), a +ld (msg_phys_addr+1), hl +ld b, c +push hl +pop de +ld c, 0xA +call set_frame +frame_done: +; Set up an open message to the initrd FS for "init.elf" +ld hl, (mailbox_num) +ld (0xA000), hl +ld a, 0x0 ; Open operation +ld (0xA002), a +ld a, 0x69 ; i +ld (0xA003), a +ld a, 0x6e ; n +ld (0xA004), a +ld a, 0x69 ; i +ld (0xA005), a +ld a, 0x74 ; t +ld (0xA006), a +ld a, 0x2e ; . +ld (0xA007), a +ld a, 0x65 ; e +ld (0xA008), a +ld a, 0x6c ; l +ld (0xA009), a +ld a, 0x66 ; f +ld (0xA00a), a +ld a, 0x0 ; NUL +ld (0xA00b), a +push de +push bc +ld de, 1 ; Get the mailbox number for the initrd driver +call proc_map_get +pmg_done: +pop bc +pop de +ld c, b ; Send the message +ld ix, 0x0000 +call mb_send loop: call yield -jp loop +loop_yield_done: +ld hl, (mailbox_num) +call mb_read ; Read a message +mb_read_done: +ld a, b ; Loop if there is no message +cp 0 +jp nz, loop +ld a, (0xA001) +ld c, a +open_done: +; Set up a read message to the initrd FS for init.elf starting at 0x10 and reading 0x50 bytes +ld hl, (mailbox_num) +ld (0xA000), hl +ld a, 0x1 ; Read operation +ld (0xA002), a +ld a, c ; FD +ld (0xA003), a +ld hl, 0x10 +ld (0xA004), hl ; File offset +ld hl, 0x50 +ld (0xA006), hl ; Read length +ld de, 1 ; Get the mailbox number for the initrd driver +call proc_map_get +read_pmg_done: +ld a, (msg_phys_addr) +ld c, a +ld de, (msg_phys_addr+1) +ld ix, 0x0000 +call mb_send +read_loop: +call yield +read_loop_yield_done: +ld hl, (mailbox_num) +call mb_read ; Read a message +read_mb_read_done: +ld a, b ; Loop if there is no message +cp 0 +jp nz, read_loop + +halt mailbox_num: .ds.b 2 +msg_phys_addr: .ds.b 3 + +vfs_name: .asciz "vfs.elf" initrd_driver_name: .asciz "initrd_driver.elf" initrd_fs_name: .asciz "initrd_fs.elf" diff --git a/initrd_driver.z80 b/initrd_driver.z80 index 610bf4c..d03e042 100644 --- a/initrd_driver.z80 +++ b/initrd_driver.z80 @@ -2,20 +2,22 @@ _start: call find_disk -ld a, 7 -call 0xdffd +call get_free_mailbox push hl ld de, 0 -ld a, 8 -call 0xdffd +pms_call: +call proc_map_set pop hl ld (mailbox_num), hl msg_loop: call yield yield_back: ld hl, (mailbox_num) -ld a, 6 -call 0xdffd +call mb_read +mb_read_done: +ld a, b +cp 1 +jp z, msg_loop msg_read: push bc push de @@ -23,6 +25,7 @@ push hl ld b, c ld c, 0xB call set_frame +set_frame_done: ld a, h or 0xB0 ld h, a @@ -33,17 +36,17 @@ 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 -jp read_bytes -ld hl, (0xB004) ; Load destination mailbox into HL +call read_bytes +pop hl pop ix pop de pop bc ld a, 5 call 0xdffd -halt jp msg_loop -halt read_buf: .ds.b 512 @@ -67,24 +70,61 @@ ld a, (start_byte) ; A = 255 - offset + 1 (256-offset) ld b, a ld a, 0xFF sub b -inc a 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 -inc a 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 @@ -98,6 +138,10 @@ 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 diff --git a/initrd_fs.z80 b/initrd_fs.z80 index 96dfd12..3401847 100644 --- a/initrd_fs.z80 +++ b/initrd_fs.z80 @@ -1,47 +1,61 @@ .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 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 +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, 0xA000 +ld hl, 0x8000 initrd_read_loop: push bc push de push hl -ld hl, 0x8000 +; 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, (0x8000) +ld a, (0xA000) +cp 0 +jp z, initrd_read_done ld c, a -ld hl, 0x8001 +ld hl, 0xA001 ; Read the name + null terminator into the mapping list ldir ld a, (hl) ld (de), a inc hl -pop de -ld a, e + 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) +ld a, (hl) ; Write the file legth to the mapping list ld (de), a inc hl inc de @@ -49,11 +63,19 @@ ld a, (hl) ld (de), a inc hl inc de -ld l, e +ld l, e ld h, d -pop de +pop iy +; SECH pop bc -ld (hl), e +; (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 @@ -61,9 +83,9 @@ ld (hl), c inc hl ; Advance to the next header ld b, 0 ; Load the filename length in BC -ld a, (0x8000) +ld a, (0xA000) ld c, a -ld hl, 0x8004 +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 @@ -73,37 +95,161 @@ 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 ; Read a message and place it at 0xB000 +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 - -ld hl, (0xB004) ; Load destination mailbox into HL +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 -halt jp msg_loop -halt +; 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 0x8000 +; 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 @@ -115,23 +261,48 @@ ld a, 0x00 ld (0xA002), a ld a, 0x1 ld (0xA003), a -ld hl, (mailbox_num) +ld hl, (sec_read_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 +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, (mailbox_num) +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, loop -read_sector_done: +jp nz, read_bytes_loop +read_bytes_done: ret diff --git a/kernel/ipc.z80 b/kernel/ipc.z80 index f659296..d7d51d0 100644 --- a/kernel/ipc.z80 +++ b/kernel/ipc.z80 @@ -154,6 +154,9 @@ ld (mb_free_list), a ld a, (ix + 1) ld (mb_free_list + 1), a ld hl, (temp) +xor a +ld (temp), a +ld (temp + 1), a ret ; Clobbers A, BC, DE, and IX diff --git a/kernel/main.z80 b/kernel/main.z80 index 4040eca..efdd2cc 100644 --- a/kernel/main.z80 +++ b/kernel/main.z80 @@ -105,6 +105,7 @@ djnz page_alloc_loop pop de pop ix pop iy +load_seg: ;Zero out the segments place in memory ld c, (ix+20) ; Load the byte counter with the number of bytes to zero out ld b, (ix+21) diff --git a/kernel/pmem.z80 b/kernel/pmem.z80 index 8ff44d6..87f673d 100644 --- a/kernel/pmem.z80 +++ b/kernel/pmem.z80 @@ -56,6 +56,7 @@ get_ram_bmap: ld a, h or 0xE0 ld h, a + grb_512k_done: ret grb_large_card: ex af, af' @@ -65,6 +66,7 @@ get_ram_bmap: ld e, d call set_frame ld hl, 0xE000 + grb_large_done: ret ; Get a free frame of RAM @@ -221,6 +223,8 @@ init_if1_end: /* cp c */ jp nz, init_if2_end ld (hl), 0xFF +inc hl +ld (hl), 0xFF init_if2_end: ld a, (first_ram_card) ld b, a diff --git a/kernel/proc_map.z80 b/kernel/proc_map.z80 index 390d6a7..36882fa 100644 --- a/kernel/proc_map.z80 +++ b/kernel/proc_map.z80 @@ -8,6 +8,17 @@ call get_free_frame ld a, c ld (map_frame), a ld (map_frame+1), hl +ld c, 0xE +ld a, (map_frame) +ld b, a +ld de, (map_frame+1) +call set_frame +xor a +ld (0xE000), a +ld hl, 0xE000 +ld de, 0xE001 +ld bc, 4096-1 +ldir ret ; Clobbers A, BC, HL, IX @@ -24,7 +35,7 @@ pop de pop hl add hl, hl ld a, h -or 0xE +or 0xE0 ld h, a ld (hl), e inc hl @@ -43,7 +54,7 @@ call set_frame pop hl add hl, hl ld a, h -or 0xE +or 0xE0 ld h, a ld e, (hl) inc hl diff --git a/kernel/tasking.z80 b/kernel/tasking.z80 index 2b178d9..e82a8f9 100644 --- a/kernel/tasking.z80 +++ b/kernel/tasking.z80 @@ -129,20 +129,13 @@ schedule_process: jp nz, block1 jp end1 block1: - push bc push hl - pop bc - call get_process_ptr push bc - pop iy - pop bc - push bc - /* ld (iy+7), c */ - /* ld (iy+8), b */ call get_process_ptr push bc pop ix pop bc + pop hl ld (ix+5), l ld (ix+6), h ld (ready_to_run_head), bc @@ -158,6 +151,7 @@ end1: jp block3 block2: ld (ready_to_run_head), bc + ld (ready_to_run_tail), bc ret block3: ld (current_process), bc @@ -194,6 +188,7 @@ end3: push iy ld bc, (current_process) call get_process_ptr + yield_store_pm_gpp_done: push bc pop ix ld de, 11 @@ -211,51 +206,39 @@ yield_list_manip: ; Get next process into ix, unlink it from the ; ready to run list, and link the current process in ; Logic: - ; next_process = ready_to_run_head -> pid - ; if (current_process->pid == 1) { - ; ready_to_run_head = 0 + ; next_process = ready_to_run_head + ; if (current_process == 1) { + ; ready_to_run_head = 0 + ; ready_to_run_tail = 0 ; } else { - ; current_process->next = ready_to_run_head->next - ; ready_to_run_head = current_process + ; ready_to_run_head = ready_to_run_head->next + ; current_process->next = 0 + ; if (ready_to_run_head==0) { + ; ready_to_run_head=current_process; + ; ready_to_run_tail=current_process; + ; } else { + ; ready_to_run_tail->next = current_process + ; ready_to_run_tail = current_process; + ; } ; } ; current_process = next_process - ld ix, (ready_to_run_head) - push ix - pop bc - call get_process_ptr -ylm_gpp_done: - push bc - pop ix - ld e, (ix+9) - ld d, (ix+10) - ld l, (ix+5) - ld h, (ix+6) - push hl - push de - push ix + call pop_rtr_head ld bc, (current_process) - call get_process_ptr -ylm_gpp2_done: - pop ix - pop de - pop hl - push bc - pop iy - ld a, (iy + 9) + ld a, c cp 1 - jp nz, else4 - xor a - ld (ready_to_run_head), a - ld (ready_to_run_head+1), a - jp end4 -else4: - ld (iy+5), l - ld (iy+6), h - ld bc, (current_process) - ld (ready_to_run_head), bc -end4: + jp z, ylm_skip_link + push de + call push_rtr_tail + pop de +ylm_skip_link: ld (current_process), de yield_sp_page_set: + push de + pop bc + call get_process_ptr +y_sp_ps_gpp_done: + push bc + pop ix push ix ld de, 11 add ix, de @@ -303,7 +286,85 @@ yield_sp_load: pop af ret +;Gets the ID of the head of the ready to run list in DE and removes the element from the list +;Logic: + ; bc = *ready_to_run_head; + ; ix = get_process_ptr(bc); + ; ready_to_run_head = ix->next; + ; if (ready_to_run_head==0) { + ; ready_to_run_tail=0; + ; } + ; return bc; +pop_rtr_head: + ld bc, (ready_to_run_head) + push bc + call get_process_ptr +pop_rh_gpp_done: + push bc + pop ix + pop de + ld l, (ix+5) + ld h, (ix+6) + ld (ready_to_run_head), hl + ld a, l + cp 0 + jp nz, pop_rh_ok + ld a, h + cp 0 + jp nz, pop_rh_ok + ld (ready_to_run_tail), hl +pop_rh_ok: + ret + +;Pushes the process with the ID in BC onto the ready to run list +; Clobbers A, DE, HL, and IX +; Logic: + ; if (*ready_to_run_tail == 0) { + ; *ready_to_run_tail = bc + ; *ready_to_run_head = bc + ; } else { + ; ix = get_process_ptr(bc); + ; ix->next = 0; + ; ix = get_process_ptr(*ready_to_run_tail); + ; ix->next = bc; + ; *ready_to_run_tail=bc; + ; } +push_rtr_tail: + ld hl, (ready_to_run_tail) + ld a, l + cp 0 + jp nz, push_rtr_tail_nz + ld a, h + cp 0 + jp nz, push_rtr_tail_nz + ld (ready_to_run_head), bc + ld (ready_to_run_tail), bc + ret +push_rtr_tail_nz: + push bc + call get_process_ptr +push_rtr_gpp_done: + push bc + pop ix + ld (ix+5), 0 + ld (ix+6), 0 + ld bc, (ready_to_run_tail) + call get_process_ptr +push_rtr_gpp2_done: + push bc + pop ix + pop bc + ld (ix+5), c + ld (ix+6), b + ld (ready_to_run_tail), bc + ret + + + + + ready_to_run_head: .ds.b 2 +ready_to_run_tail: .ds.b 2 current_process: .ds.b 2 next_pid: .dc.w 1 process_allocation_bitmap: .ds.b 128 diff --git a/rom.elf b/rom.elf new file mode 100755 index 0000000..21545bf Binary files /dev/null and b/rom.elf differ diff --git a/vfs.z80 b/vfs.z80 new file mode 100644 index 0000000..18c8a45 --- /dev/null +++ b/vfs.z80 @@ -0,0 +1,220 @@ +.global _start + +_start: +call get_free_frame +ld b, c +ld e, l +ld d, h +ld c, 0x9 +call set_frame +call get_free_frame +ld a, c +ld (send_page_addr), a +ld (send_page_addr+1), hl +ld b, c +ld e, l +ld d, h +ld c, 0x8 +call set_frame +ld hl, 0x9000 +ld de, 0x9001 +ld bc, 0x1000 +ld (hl), 0x0 +ldir +call get_free_mailbox +push hl +ld de, 1 +call proc_map_set +pop hl +ld (vfs_mailbox_num), hl +call get_free_mailbox +ld (fs_mailbox_num), hl +msg_loop: +call yield +yield_back: +ld hl, (vfs_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, register_fs +cp 0x1 +jp z, mount +operation_done: +pop hl +pop ix +pop de +pop bc +call mb_send +jp msg_loop + +register_fs: +ld a, (fs_count) +ld l, a +ld h, 0x0 +add hl, hl +add hl, hl +add hl, hl +add hl, hl +ld de, data_fs_offset +add hl, de +ld de, 0x9000 +add hl, de +push hl +pop de +ld hl, 0xB003 +ld bc, 16 +ldir +ld a, (fs_count) +inc a +ld (fs_count), a +ret + +; String pointer 1 in IX, 2 in IY +; Return in A +strcmp: +strcmp_loop: +ld a, (iy) +ld b, a +ld a, (ix) +cp b +jp nz, strcmp_loopend +cp 0 +ret z +inc ix +inc iy +jp strcmp_loop +strcmp_loopend: +ld a, (iy) +ld b, a +ld a, (ix) +sub b +ret + + +mount: +ld a, (mount_count) +ld l, 0x0 +ld h, a +ld de, data_mount_offset +add hl, de +ld de, 0x9000 +add hl, de +push hl +pop de +push de +ld hl, 0xB003 +ld bc, 252 +ldir +ld a, (mount_count) +inc a +ld (mount_count), a +; FS type at 0xB1FF +ld a, (fs_count) +ld b, a +ld hl, data_fs_offset + 0x9000 +ld de, 0x10 +mount_loop1: +push hl +pop ix +ld iy, 0xB0FF +push bc +call strcmp +pop bc +cp 0 +jp mount_loop1_done +add hl, de +djnz mount_loop1 +mount_loop1_done: +ld de, 14 +add hl, de +pop ix +ld de, 252 +add ix, de +ld e, (hl) +inc hl +ld d, (hl) +ld (ix), e +ld (ix+1), d +push ix +ld a, 0x2 +ld (0x8000), a +ld hl, 0xB0FF +ld de, 0x8001 +ld bc, 256 +ldir +ld a, (send_page_addr) +ld c, a +ld de, (send_page_addr+1) +ld ix, 0x0 +call mb_send +mount_wait_loop: +call yield +ld hl, (fs_mailbox_num) +call mb_read ; Read a message +ld a, b ; Loop if there is no message +cp 0 +jp nz, mount_wait_loop +pop ix +ld a, (0x8000) +ld (ix+2), a +ld a, (0x8001) +ld (ix+3), a + +ret + +; String pointer 1 in IX, 2 in IY +; Return in A +vfsstrcmp: +vfsstrcmp_loop: +ld a, (iy) +ld b, a +ld a, (ix) +cp b +cp 0 +ret z +jp nz, vfsstrcmp_loopend +inc ix +inc iy +jp vfsstrcmp_loop +vfsstrcmp_loopend: +ld a, (iy) +ld b, a +ld a, (ix) +sub b +ret + + + + +vfs_mailbox_num: .ds.b 2 +fs_mailbox_num: .ds.b 2 + +send_page_addr: .ds.b 3 + +fs_count: .ds.b 1 +mount_count: .ds.b 1 + +.equ data_fs_offset, 0x0 +.equ data_mount_offset, 0x200 +.equ fs_name_offset, 0x0 +.equ fs_pid_offset, 0xE +.equ mount_path_offset, 0x0 +.equ mount_fs_pid_offset, 0xFD +.equ mount_fs_id_offset, 0xFF