diff --git a/Tupfile b/Tupfile index fa72de8..2ba3c0a 100644 --- a/Tupfile +++ b/Tupfile @@ -3,10 +3,10 @@ export RUSTUP_HOME RUSTC_FLAGS = -C debuginfo=0 -C opt-level=3 --edition 2021 -LDLIBS = libs/*.o +LDLIBS = libs/libvfs/libvfs.a libs/libstd/libstd.a : foreach *.z80 |> !as |> -: foreach *.o | libs/*.o |> !ld |> %B.elf +: foreach *.o | $(LDLIBS) |> !ld |> %B.elf : initrd_maker.rs |> rustc $(RUSTC_FLAGS) -o %o %f |> bin/%B : kernel/kernel.elf *.elf | bin/initrd_maker |> bin/initrd_maker %f |> initrd diff --git a/Tuprules.tup b/Tuprules.tup index aad321d..8c5c553 100644 --- a/Tuprules.tup +++ b/Tuprules.tup @@ -2,4 +2,4 @@ LDFLAGS = -n !as = |> z80-elf-as $(ASFLAGS) -o %o %f |> %B.o -!ld = |> z80-elf-ld $(LDFLAGS) -o %o $(LDLIBS) %f |> +!ld = |> z80-elf-ld $(LDFLAGS) -o %o %f $(LDLIBS) |> diff --git a/boot/boot.z80 b/boot/boot.z80 index d0ad06a..71d84af 100644 --- a/boot/boot.z80 +++ b/boot/boot.z80 @@ -1,4 +1,4 @@ -_gtart: +_start: ld sp,0 ; Initialize the stack ld a,0x4 ; Find a generic storage card call find_first_card diff --git a/init.z80 b/init.z80 index c7b974e..e65faa0 100644 --- a/init.z80 +++ b/init.z80 @@ -2,8 +2,6 @@ _start: call find_disk -/* ld hl, test_string */ -/* call print */ call get_free_frame ; Set up a frame to load programs into at 0x8000 ld b, c ld e, l @@ -11,25 +9,28 @@ ld d, h ld c, 8 bp_call_sf: call set_frame -call get_free_mailbox ; Initialize a mailbox -ld (mailbox_num), hl ld iy, vfs_name ; Load and run the VFS call run_file vfs_loaded: call yield ; Yield to let the VFS initialize vfs_returned: -ld iy, test_fs_name ; Load and run the test fs +ld iy, initrd_driver_name ; Load and run the initrd driver call run_file -test_fs_loaded: -test_fs_init_wait_loop: -call yield ; Yield to let the test fs initialize +initrd_driver_loaded: +initrd_driver_init_wait_loop: +call yield ; Yield to let the initrd driver initialize +ld iy, initrd_fs_name ; Load and run the initrd fs +call run_file +initrd_fs_loaded: +initrd_fs_init_wait_loop: +call yield ; Yield to let the initrd fs initialize yield_done: -ld de, 3 +ld de, 1 call proc_map_get ld a, l cp 0 -jp z, test_fs_init_wait_loop -test_fs_initialized: +jp z, initrd_fs_init_wait_loop +initrd_fs_initialized: call get_free_frame ; Set up a message frame at 0xA000 ld a, c ld (msg_phys_addr), a @@ -40,87 +41,42 @@ pop de ld c, 0xA call set_frame frame_done: -; Set up a mount message to the VFS for "" on "/" with fs "a" at mailbox 1 -ld hl, (mailbox_num) -ld (0xA000), hl -ld a, 0x1 ; Mount operation -ld (0xA002), a -ld a, 0x2F ; '/' -ld (0xA003), a -ld a, 0x0 ; '\0' -ld (0xA004), a -ld a, 0x0 ; '\0' -ld (0xA0FF), a -ld a, 0x61 ; 'a' -ld (0xA1FF), a -ld a, 0x0 ; '\0' -ld (0xA200), a -push de -push bc -ld de, 2 ; Get the mailbox number for the VFS -call proc_map_get -mount_pmg_done: -pop bc -pop de -ld c, b ; Send the message -ld ix, 0x0000 -call mb_send -mount_loop: -call yield -mount_loop_yield_done: -ld hl, (mailbox_num) -call mb_read ; Read a message -mount_mb_read_done: -ld a, b ; Loop if there is no message -cp 0 -jp nz, mount_loop -mount_done: -; Set up an open message to the VFS for "/test" -ld hl, (mailbox_num) -ld (0xA000), hl -ld a, 0x2 ; Open operation -ld (0xA002), a -ld a, 0x2F ; '/' -ld (0xA003), a -ld a, 0x74 ; 't' -ld (0xA004), a -ld a, 0x65 ; 'e' -ld (0xA005), a -ld a, 0x73 ; 's' -ld (0xA006), a -ld a, 0x74 ; 't' -ld (0xA007), a -ld a, 0x0 ; '\0' -ld (0xA008), a -push de -push bc -ld de, 2 ; Get the mailbox number for the VFS -call proc_map_get -open_pmg_done: -pop bc -pop de -ld ix, 0x0000 ; Send the message -call mb_send -open_loop: -call yield -open_loop_yield_done: -ld hl, (mailbox_num) -call mb_read ; Read a message -open_mb_read_done: -ld a, b ; Loop if there is no message -cp 0 -jp nz, open_loop -open_done: -halt +ld hl, 0xA000 +ld a, (msg_phys_addr) +ld c, a +ld de, (msg_phys_addr+1) +call libvfs_init -mailbox_num: .ds.b 2 +; Mount the initrd at "/" +ld bc, null_string +ld de, root_path +ld hl, initrd_string +call libvfs_mount + +; Open "/test_fs.elf" +ld hl, test_fs_path +ld de, file_struct +call libvfs_open + +; Read 0x100 bytes at 0x0 +ld hl, file_struct +ld bc, 0x100 +ld de, 0x0 +call libvfs_read +halt 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" +initrd_string: .asciz "initrd" test_fs_name: .asciz "test_fs.elf" +root_path: .asciz "/" +test_fs_path: .asciz "/test_fs.elf" +null_string: .asciz "" + +file_struct: .ds.b 4 ; Loads and starts the ELF file with the name pointed to by IY run_file: @@ -256,6 +212,8 @@ ld iy, proc_pagemap call new_process ret +msg_frame_phys: +.ds.b 3 proc_pagemap: .ds.b 36 diff --git a/initrd_fs.z80 b/initrd_fs.z80 index 3401847..c3d6bfb 100644 --- a/initrd_fs.z80 +++ b/initrd_fs.z80 @@ -1,8 +1,11 @@ .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 @@ -23,6 +26,11 @@ 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 @@ -33,6 +41,7 @@ push hl ; FM SECL SECH ld hl, 0xA000 call read_sector +rl_read_sector_done: pop de push de ; FM SECL SECH @@ -55,7 +64,7 @@ ld e, a ld a, d adc a, 0x0 ld d, a -ld a, (hl) ; Write the file legth to the mapping list +ld a, (hl) ; Write the file length to the mapping list ld (de), a inc hl inc de @@ -109,6 +118,9 @@ 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: @@ -140,6 +152,8 @@ cp 0x0 jp z, open cp 0x1 jp z, read +cp 0x2 +jp z, mount operation_done: pop hl pop ix @@ -148,6 +162,9 @@ pop bc call mb_send jp msg_loop +mount: +jp operation_done + ; de = start of file map list ; c = 0 ; while (1) { @@ -178,9 +195,9 @@ pop iy call strcmp cp 0 jp nz, open_not_match -ld a, 0 -ld (0xB000), a ld a, c +ld (0xB000), a +ld a, 0 ld (0xB001), a jp operation_done open_not_match: @@ -214,17 +231,17 @@ ld de, 0x8020 add ix, de ld d, (ix+2) ld e, 0x0 -ld hl, (0xB004) +ld hl, (0xB005) add hl, de ld bc, 0x100 add hl, bc ld c, l ld b, h -ld de, (0xB006) +ld de, (0xB007) call read_bytes ld de, 0xB000 ld hl, 0xA000 -ld bc, (0xB006) +ld bc, (0xB007) ldir jp operation_done @@ -306,3 +323,5 @@ cp 0 jp nz, read_bytes_loop read_bytes_done: ret + +initrd_fs_name: .asciz "initrd" diff --git a/kernel/ipc.z80 b/kernel/ipc.z80 index d7d51d0..b5fbba2 100644 --- a/kernel/ipc.z80 +++ b/kernel/ipc.z80 @@ -6,6 +6,11 @@ mb_send: push de push bc push ix +ld a, l +cp 0 +jp nz, not_init +; halt +not_init: call get_mb_ptr pop ix pop bc diff --git a/libs/Tupfile b/libs/libstd/Tupfile similarity index 55% rename from libs/Tupfile rename to libs/libstd/Tupfile index a3b1c94..4a66c18 100644 --- a/libs/Tupfile +++ b/libs/libstd/Tupfile @@ -1,3 +1,4 @@ include_rules : foreach *.z80 |> !as |> +: *.o |> ar rs %o %f |> libstd.a diff --git a/libs/strings.z80 b/libs/libstd/strings.z80 similarity index 60% rename from libs/strings.z80 rename to libs/libstd/strings.z80 index cd3c85f..222b086 100644 --- a/libs/strings.z80 +++ b/libs/libstd/strings.z80 @@ -9,3 +9,13 @@ ret z inc bc inc hl jp strlen_loop + +; Copies the string in HL to DE +.global strcpy +strcpy: +push hl +call strlen +inc bc +pop hl +ldir +ret diff --git a/libs/syscalls.z80 b/libs/libstd/syscalls.z80 similarity index 100% rename from libs/syscalls.z80 rename to libs/libstd/syscalls.z80 diff --git a/libs/libvfs/Tupfile b/libs/libvfs/Tupfile new file mode 100644 index 0000000..1c4910a --- /dev/null +++ b/libs/libvfs/Tupfile @@ -0,0 +1,4 @@ +include_rules + +: foreach *.z80 |> !as |> +: *.o |> ar rs %o %f |> libvfs.a diff --git a/libs/libvfs/vfs.z80 b/libs/libvfs/vfs.z80 new file mode 100644 index 0000000..e308a09 --- /dev/null +++ b/libs/libvfs/vfs.z80 @@ -0,0 +1,202 @@ +.global libvfs_init +; Pointer to message frame in HL +; Physical address of message frame in C:DE +; Clobbers A, BC, DE, HL, IX +libvfs_init: +ld (msg_frame_ptr), hl +ld a, c +ld (msg_frame_phys), a +ld (msg_frame_phys+1), de +call get_free_mailbox ; Initialize a mailbox +ld (mailbox_num), hl +ret + +.global libvfs_register_fs +; Registers a FS with the VFS +; Mailbox in HL, pointer to name in IX +; Clobbers A, BC, DE, HL, IX, IY +libvfs_register_fs: +push hl +ld iy, (msg_frame_ptr) +ld hl, (mailbox_num) +ld (iy), l +ld (iy+1), h +ld a, 0x0 ; Register FS operation +ld (iy+2), a +ld bc, 7 +push ix +pop hl +ld d, iyh +ld e, 0x3 +call strcpy +pop hl +ld (iy+0x11), l +ld (iy+0x12), h +ld de, 2 ; Get the mailbox number for the VFS +call proc_map_get +pmg_done: +ld a, (msg_frame_phys) +ld c, a +ld de, (msg_frame_phys+1) +ld ix, 0x0000 +call mb_send +reg_fs_loop: +call yield +loop_yield_done: +ld hl, (mailbox_num) +call mb_read ; Read a message +reg_fs_mb_read_done: +ld a, b ; Loop if there is no message +cp 0 +jp nz, reg_fs_loop +ret + +.global libvfs_mount +; Mounts a FS +; Device string in BC +; Path string in DE +; FS name string in HL +; Clobbers A, BC, DE, HL, IX, IY +libvfs_mount: +push hl +push bc +push de +ld iy, (msg_frame_ptr) +ld hl, (mailbox_num) +ld (iy), l +ld (iy+1), h +ld a, 0x1 ; Mount operation +ld (iy+2), a +ld d, iyh +ld e, 0x3 +pop hl +call strcpy +ld d, iyh +ld e, 0xFF +pop hl +call strcpy +ld d, iyh +inc d +ld e, 0xFF +pop hl +call strcpy +ld de, 2 ; Get the mailbox number for the VFS +call proc_map_get +mount_pmg_done: +; Send the message +ld a, (msg_frame_phys) +ld c, a +ld de, (msg_frame_phys+1) +ld ix, 0x0000 +call mb_send +mount_loop: +call yield +mount_loop_yield_done: +ld hl, (mailbox_num) +call mb_read ; Read a message +mount_mb_read_done: +ld a, b ; Loop if there is no message +cp 0 +jp nz, mount_loop +mount_done: +ret + +.global libvfs_open +; Opens a file +; Path in HL +; Pointer to 4-byte buffer in DE (file info saved there) +; FD returned in DE, MBID of FS in HL +; Clobbers A, BC, DE, HL, IX, IY +libvfs_open: +push de +push hl +ld iy, (msg_frame_ptr) +ld hl, (mailbox_num) +ld (iy), l +ld (iy+1), h +ld a, 0x2 ; Open operation +ld (iy+2), a +ld d, iyh +ld e, 0x3 +pop hl +call strcpy +ld de, 2 ; Get the mailbox number for the VFS +call proc_map_get +open_pmg_done: +; Send the message +ld a, (msg_frame_phys) +ld c, a +ld de, (msg_frame_phys+1) +ld ix, 0x0000 +call mb_send +open_loop: +call yield +open_loop_yield_done: +ld hl, (mailbox_num) +call mb_read ; Read a message +open_mb_read_done: +ld a, b ; Loop if there is no message +cp 0 +jp nz, open_loop +open_done: +ld hl, (msg_frame_ptr) +pop de +ld bc, 4 +ldir +ret + +.global libvfs_read +; Reads data from an open file +; Pointer to file struct in HL +; Data length in BC +; Offset in DE +; Buffer returned in HL +; BUFFER INVALIDATED WHEN MESSAGE IS NEXT SENT +; WITH FRAME GIVEN ON INIT +libvfs_read: +push hl +ld iy, (msg_frame_ptr) +ld hl, (mailbox_num) +ld (iy), l +ld (iy+1), h +pop hl +ld a, 0x1 ; Read operation +ld (iy+2), a +ld a, (hl) +ld (iy+3), c +inc hl +ld a, (hl) +ld (iy+4), b +inc hl +ld (iy+5), e +ld (iy+6), d +ld (iy+7), c +ld (iy+8), b +; Send the message +ld c, (hl) +inc hl +ld b, (hl) +push bc +pop hl +ld a, (msg_frame_phys) +ld c, a +ld de, (msg_frame_phys+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 +read_done: +ld hl, (msg_frame_ptr) +ret + +.bss +mailbox_num: .ds.b 2 +msg_frame_ptr: .ds.b 2 +msg_frame_phys: .ds.b 3 diff --git a/rom.elf b/rom.elf deleted file mode 100755 index 21545bf..0000000 Binary files a/rom.elf and /dev/null differ diff --git a/test_fs.z80 b/test_fs.z80 index 08e6656..cd606a1 100644 --- a/test_fs.z80 +++ b/test_fs.z80 @@ -82,7 +82,6 @@ call mb_send jp msg_loop open: -halt ld a, 0xAA ld (0xB000), a ld a, 0x55