2023-01-29 11:03:53 -06:00
|
|
|
.global _start
|
|
|
|
|
|
|
|
_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
|
|
|
|
ld d, h
|
|
|
|
ld c, 8
|
|
|
|
bp_call_sf:
|
|
|
|
call set_frame
|
2023-09-17 11:02:33 -05:00
|
|
|
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:
|
2023-01-29 11:03:53 -06:00
|
|
|
ld iy, initrd_driver_name ; Load and run the initrd driver
|
|
|
|
call run_file
|
|
|
|
initrd_driver_loaded:
|
|
|
|
call yield ; Yield to let the initrd driver initialize
|
|
|
|
initrd_driver_returned:
|
|
|
|
ld iy, initrd_fs_name ; Load and run the initrd fs driver
|
|
|
|
call run_file
|
|
|
|
initrd_fs_loaded:
|
2023-09-03 10:03:51 -05:00
|
|
|
fs_init_wait_loop:
|
2023-01-29 11:03:53 -06:00
|
|
|
call yield ; Yield to let the initrd driver initialize
|
2023-09-03 10:03:51 -05:00
|
|
|
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:
|
2023-09-17 11:02:33 -05:00
|
|
|
; Set up a register FS message to the VFS for "a" at mailbox 1
|
2023-09-03 10:03:51 -05:00
|
|
|
ld hl, (mailbox_num)
|
|
|
|
ld (0xA000), hl
|
2023-09-17 11:02:33 -05:00
|
|
|
ld a, 0x0 ; Register FS operation
|
2023-09-03 10:03:51 -05:00
|
|
|
ld (0xA002), a
|
2023-09-17 11:02:33 -05:00
|
|
|
ld a, 0x61 ; 'a'
|
2023-09-03 10:03:51 -05:00
|
|
|
ld (0xA003), a
|
2023-09-17 11:02:33 -05:00
|
|
|
ld a, 0x0 ; '\0'
|
2023-09-03 10:03:51 -05:00
|
|
|
ld (0xA004), a
|
2023-09-17 11:02:33 -05:00
|
|
|
ld a, 0x1
|
|
|
|
ld (0xA011), a
|
|
|
|
ld a, 0x0
|
|
|
|
ld (0xA012), a
|
2023-09-03 10:03:51 -05:00
|
|
|
push de
|
|
|
|
push bc
|
2023-09-17 11:02:33 -05:00
|
|
|
ld de, 2 ; Get the mailbox number for the VFS
|
2023-09-03 10:03:51 -05:00
|
|
|
call proc_map_get
|
|
|
|
pmg_done:
|
|
|
|
pop bc
|
|
|
|
pop de
|
|
|
|
ld c, b ; Send the message
|
|
|
|
ld ix, 0x0000
|
|
|
|
call mb_send
|
2023-01-29 11:03:53 -06:00
|
|
|
loop:
|
|
|
|
call yield
|
2023-09-03 10:03:51 -05:00
|
|
|
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
|
2023-09-17 11:02:33 -05:00
|
|
|
register_done:
|
|
|
|
; Set up a mount message to the VFS for "" on "/" with fs "a" at mailbox 1
|
2023-09-03 10:03:51 -05:00
|
|
|
ld hl, (mailbox_num)
|
|
|
|
ld (0xA000), hl
|
2023-09-17 11:02:33 -05:00
|
|
|
ld a, 0x1 ; Mount operation
|
2023-09-03 10:03:51 -05:00
|
|
|
ld (0xA002), a
|
2023-09-17 11:02:33 -05:00
|
|
|
ld a, 0x2F ; '/'
|
2023-09-03 10:03:51 -05:00
|
|
|
ld (0xA003), a
|
2023-09-17 11:02:33 -05:00
|
|
|
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
|
2023-09-03 10:03:51 -05:00
|
|
|
call proc_map_get
|
2023-09-17 11:02:33 -05:00
|
|
|
mount_pmg_done:
|
|
|
|
pop bc
|
|
|
|
pop de
|
|
|
|
ld c, b ; Send the message
|
2023-09-03 10:03:51 -05:00
|
|
|
ld ix, 0x0000
|
|
|
|
call mb_send
|
2023-09-17 11:02:33 -05:00
|
|
|
mount_loop:
|
2023-09-03 10:03:51 -05:00
|
|
|
call yield
|
2023-09-17 11:02:33 -05:00
|
|
|
mount_loop_yield_done:
|
2023-09-03 10:03:51 -05:00
|
|
|
ld hl, (mailbox_num)
|
|
|
|
call mb_read ; Read a message
|
2023-09-17 11:02:33 -05:00
|
|
|
mount_mb_read_done:
|
2023-09-03 10:03:51 -05:00
|
|
|
ld a, b ; Loop if there is no message
|
|
|
|
cp 0
|
2023-09-17 11:02:33 -05:00
|
|
|
jp nz, loop
|
|
|
|
ld a, (0xA001)
|
|
|
|
ld c, a
|
|
|
|
mount_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
|
|
|
|
; 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
|
2023-09-03 10:03:51 -05:00
|
|
|
|
|
|
|
halt
|
2023-01-29 11:03:53 -06:00
|
|
|
|
|
|
|
mailbox_num: .ds.b 2
|
|
|
|
|
2023-09-03 10:03:51 -05:00
|
|
|
msg_phys_addr: .ds.b 3
|
|
|
|
|
|
|
|
vfs_name: .asciz "vfs.elf"
|
2023-01-29 11:03:53 -06:00
|
|
|
initrd_driver_name: .asciz "initrd_driver.elf"
|
|
|
|
initrd_fs_name: .asciz "initrd_fs.elf"
|
|
|
|
|
|
|
|
; Loads and starts the ELF file with the name pointed to by IY
|
|
|
|
run_file:
|
|
|
|
call read_file
|
|
|
|
ld hl, 0x8000
|
|
|
|
push hl
|
|
|
|
pop iy
|
|
|
|
ld l, (iy+0x1C) ; Load IX with the start of the program headers in memory
|
|
|
|
ld h, (iy+0x1D) ; Load IX with the start of the program headers in memory
|
|
|
|
push hl
|
|
|
|
pop ix
|
|
|
|
push iy
|
|
|
|
pop bc
|
|
|
|
add ix, bc
|
|
|
|
ld a, (iy+0x2C) ; load B with the number of program headers
|
|
|
|
ld b, a
|
|
|
|
phead_loop:
|
|
|
|
ld a, (ix+0)
|
|
|
|
cp 1
|
|
|
|
jp NZ, next_seg
|
|
|
|
push bc
|
|
|
|
ld c, (ix+20)
|
|
|
|
ld b, (ix+21)
|
|
|
|
; b = if c > 0 || b & 0xF > 0 {
|
|
|
|
; (b & 0xF0) + 0x10
|
|
|
|
; } else {
|
|
|
|
; b & 0xF0
|
|
|
|
; } >> 4
|
|
|
|
ld a, c
|
|
|
|
cp 0
|
|
|
|
jp z, cmp2
|
|
|
|
jp blk1
|
|
|
|
cmp2:
|
|
|
|
ld a, b
|
|
|
|
and 0xF
|
|
|
|
cp 0
|
|
|
|
jp z, blk2
|
|
|
|
blk1:
|
|
|
|
ld a, b
|
|
|
|
and 0xF0
|
|
|
|
add a, 0x10
|
|
|
|
ld b, a
|
|
|
|
jp end1
|
|
|
|
blk2:
|
|
|
|
ld a, b
|
|
|
|
and 0xF0
|
|
|
|
ld b, a
|
|
|
|
end1:
|
|
|
|
srl b
|
|
|
|
srl b
|
|
|
|
srl b
|
|
|
|
srl b
|
|
|
|
ld c, (ix+9)
|
|
|
|
srl c
|
|
|
|
srl c
|
|
|
|
srl c
|
|
|
|
srl c
|
|
|
|
push iy
|
|
|
|
push ix
|
|
|
|
push de
|
|
|
|
ld a, c
|
|
|
|
sla a
|
|
|
|
add a, c
|
|
|
|
ld c, a
|
|
|
|
ld b, 0
|
|
|
|
map_seg_frame:
|
|
|
|
ld ix, proc_pagemap
|
|
|
|
add ix, bc
|
|
|
|
push ix
|
|
|
|
ld a, 1
|
|
|
|
call 0xdffd
|
|
|
|
pop ix
|
|
|
|
seg_frame_found:
|
|
|
|
ld (ix+0), c
|
|
|
|
ld (ix+1), l
|
|
|
|
ld (ix+2), h
|
|
|
|
ld b, c
|
|
|
|
ld e, l
|
|
|
|
ld d, h
|
|
|
|
ld c, 7
|
|
|
|
call set_frame
|
|
|
|
/* ld b, c */
|
|
|
|
/* ld d, h */
|
|
|
|
/* ld e, l */
|
|
|
|
/* pop hl */
|
|
|
|
/* ld c, l */
|
|
|
|
/* push hl */
|
|
|
|
/* call set_frame */
|
|
|
|
/* pop bc */
|
|
|
|
/* inc c */
|
|
|
|
/* djnz page_alloc_loop */
|
|
|
|
pop de
|
|
|
|
pop ix
|
|
|
|
pop iy
|
|
|
|
seg_load:
|
|
|
|
;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)
|
|
|
|
ld e, (ix+8) ; Load the destination & source address register with the destination location of the segment in memory
|
|
|
|
ld d, (ix+9)
|
|
|
|
ld a, d
|
|
|
|
and 0xF
|
|
|
|
or 0x70
|
|
|
|
ld d, a
|
|
|
|
ld h, d
|
|
|
|
ld l, e
|
|
|
|
ld (hl), 0 ; Zero out the first byte in the segment ( Acts as a 'seed' for the zeroing )
|
|
|
|
ldir
|
|
|
|
ld c, (ix+16) ; Load the byte counter with the number of bytes to transfer
|
|
|
|
ld b, (ix+17)
|
|
|
|
ld l, (ix+4) ; Load the source address register with the memory address if the segment data
|
|
|
|
ld h, (ix+5)
|
|
|
|
push iy
|
|
|
|
pop de
|
|
|
|
add hl, de
|
|
|
|
ld e, (ix+8) ; Load the destination & source address register with the destination location of the segment in memory
|
|
|
|
ld d, (ix+9)
|
|
|
|
ld a, d
|
|
|
|
and 0xF
|
|
|
|
or 0x70
|
|
|
|
ld d, a
|
|
|
|
ldir; Do the transfer
|
|
|
|
pop bc
|
|
|
|
next_seg:
|
|
|
|
ld de, 32
|
|
|
|
add ix, de
|
|
|
|
dec b
|
|
|
|
ld a, b
|
|
|
|
jp nz, phead_loop
|
|
|
|
ld l, (iy+0x18) ; Load HL with the program entry point
|
|
|
|
ld h, (iy+0x19) ; Load HL with the program entry point
|
|
|
|
ld iy, proc_pagemap
|
|
|
|
call new_process
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
proc_pagemap:
|
|
|
|
.ds.b 36
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
|
; Reads a file off the disk to 0x8000 in memory
|
|
|
|
; Pointer to file name in iy
|
|
|
|
read_file:
|
|
|
|
ld c, 0
|
|
|
|
ld de, 1
|
|
|
|
ri_find_loop:
|
|
|
|
ld hl, 0x8000
|
|
|
|
push bc
|
|
|
|
call read_sector
|
|
|
|
ri_find_read_done:
|
|
|
|
ld ix, 0x8001
|
|
|
|
push iy
|
|
|
|
call strcmp
|
|
|
|
pop iy
|
|
|
|
pop bc
|
|
|
|
jp z, ri_init_found
|
|
|
|
push bc
|
|
|
|
ld b, 0
|
|
|
|
ld a, (0x8000)
|
|
|
|
ld c, a
|
|
|
|
ld hl, 0x8004
|
|
|
|
add hl, bc
|
|
|
|
ld c, (hl)
|
|
|
|
inc hl
|
|
|
|
ld b, (hl)
|
|
|
|
ld l, c
|
|
|
|
ld h, b
|
|
|
|
inc hl
|
|
|
|
add hl, de
|
|
|
|
ld e, l
|
|
|
|
ld d, h
|
|
|
|
pop bc
|
|
|
|
ld a, c
|
|
|
|
adc a, 0
|
|
|
|
ld c, a
|
|
|
|
jp ri_find_loop
|
|
|
|
ri_init_found:
|
|
|
|
push bc
|
|
|
|
ld b, 0
|
|
|
|
ld a, (0x8000)
|
|
|
|
ld c, a
|
|
|
|
ld hl, 0x8004
|
|
|
|
add hl, bc
|
|
|
|
pop bc
|
|
|
|
ld b, (hl)
|
|
|
|
ld hl, 1
|
|
|
|
add hl, de
|
|
|
|
ld e, l
|
|
|
|
ld d, h
|
|
|
|
ld a, c
|
|
|
|
adc a, 0
|
|
|
|
ld c, a
|
|
|
|
ld hl, 0x8000
|
|
|
|
ri_read_loop:
|
|
|
|
push bc
|
|
|
|
call read_sector
|
|
|
|
pop bc
|
|
|
|
push hl
|
|
|
|
ld hl, 1
|
|
|
|
add hl, de
|
|
|
|
ld e, l
|
|
|
|
ld d, h
|
|
|
|
ld a, c
|
|
|
|
adc a, 0
|
|
|
|
ld c, a
|
|
|
|
pop hl
|
|
|
|
djnz ri_read_loop
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; Given a sector number in C:DE and a buffer address in HL, reads the sector off disk.
|
|
|
|
read_sector:
|
|
|
|
push bc
|
|
|
|
ld c,0xFF ; Force the top half of the IO address to be the id of the card,
|
|
|
|
ld a, (disk_num) ; so the block transfer instructions can be used
|
|
|
|
out (c), a
|
|
|
|
pop bc
|
|
|
|
ld a, c
|
|
|
|
ld c, 0
|
|
|
|
out (c), e
|
|
|
|
inc c
|
|
|
|
out (c), d
|
|
|
|
inc c
|
|
|
|
out (c), a
|
|
|
|
ld b, 0x0 ; Setup a transfer of 256 bytes (1 sector) at a time
|
|
|
|
ld c, 0x3 ; from the storage device's data port
|
|
|
|
inir
|
|
|
|
ld c,0xFF ; Unforce the top half of the IO address
|
|
|
|
in a,(c)
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
.global find_disk
|
|
|
|
; Clobbers A and HL
|
|
|
|
find_disk:
|
|
|
|
ld b,0x4
|
|
|
|
ld a, 10
|
|
|
|
call 0xdffd
|
|
|
|
ld a, l
|
|
|
|
ld (disk_num), a
|
|
|
|
ret
|
|
|
|
|
|
|
|
disk_num: .ds.b 1
|
|
|
|
|
|
|
|
|
|
|
|
/* initrd: */
|
|
|
|
/* .incbin "initrd" */
|
|
|
|
/* initrd_end: */
|
|
|
|
|
|
|
|
|