os/boot/boot.68k
2022-10-09 15:30:21 -05:00

78 lines
3.2 KiB
Plaintext

.global _start
_start:
move.b #0x4, %d0
bsr.w find_first_card
| Load the header sector for the kernel binary
move.l #0x1, (%a0) | Set the sector number to 1
| Transfer 0x100 (256) bytes from the storage card's data register to 0x100
move.w #0x100, %a1 | Load a1, the destination address register, with 0x100
move.w #0xFF, %d0 | Load d0 with the sector size - 1.
hdr_sector_loop:
move.b (4, %a0), (%a1)+ | Transfer a byte of sector data to the destination
dbra %d0, hdr_sector_loop | Loop back if there is more to transfer
move.w (0x102), %d0 | Load d0 with the number of sectors for the kernel - 1
subq #0x1, %d0
| load the ELF kernel binary off the disk
move.l #0x2, (%a0) | Set the sector number to 2
| Transfer 0x100 (256) * d0 bytes from the storage card's data register to 0xA000
move.l #0xA000, %a1 | Load a1, the destination address register, with 0xA000
sectors_loop:
move.w #0xFF, %d1 | Load d0 with the sector size - 1.
sector_loop:
move.b (4, %a0), (%a1)+ | Transfer a byte of sector data to the destination
dbra %d1, sector_loop | Loop back if there is more to transfer
dbra %d0, sectors_loop | Loop back if there are more sectors to transfer
move.l (0xA01C), %d0 | Load the offset of the program headers in the file
move.l #0xA000, %a0 | Put the address of the program headers in a0
adda.w %d0, %a0
move.w (0xA02C), %d0 | Put the number of program headers - 1 in d0
subq #0x1, %d0
phead_loop:
move.l (%a0), %d1 | If the type of the program header isn't 1 (LOAD), skip the header
cmpi.l #0x1, %d1
bne.b next_seg
| Zero the destination memory of the program header
move.l (20, %a0), %d1 | Put the memory size of the program header - 1 in d1
subq #0x1, %d1
move.l (8, %a0), %a1 | Put the starting memory address of the program header in a1
zero_loop:
move.b #0, (%a1)+ | Zero a byte of the destination memory
dbra %d1, zero_loop | Loop back if there is more to zero
| Copy the data of the program header from the loaded file into position
move.l (16, %a0), %d1 | Put the file size of the program header - 1 in d1
subq #0x1, %d1
move.l (4, %a0), %a1 | Put the address of the start of the loaded program header's data in a1
adda.l #0xA000, %a1
move.l (8, %a0), %a2 | Put the starting memory address of the program header in a2
load_loop:
move.b (%a1)+, (%a2)+ | Copy a byte of data into position
dbra %d1, load_loop | Loop back if there is more to copy
next_seg:
lea (0x20, %a0), %a0 | Advance a0 to point to the next program header
dbra %d0, phead_loop | If there are more program headers, loop back
move.l (0xA018), %a0 | Load the entry point of the program into a0
jmp (%a0) | Jump to the entry point of the program
| Finds the first card with the type in d0.b, and returns it's IO base address in a0, or 0 if not found
| Clobbers d1
find_first_card:
move.l #0xff0000, %a0 | a0 holds the address of the current card
ffc_loop:
lea (0x100, %a0), %a0 | adda.l #$100, %a0 | Move to the next card
move.b (0xff, %a0), %d1 | Load the type of the card into d1
beq.b ffc_done | If the type is 0 (empty slot), we have scanned all cards, so exit the loop
cmp.b %d0, %d1 | If the card is the type we want, return with the address in a0
beq.b ffc_done
bra.b ffc_loop | Loop back and check the next card
ffc_done:
rts
.if . != 256
.org 255
.byte 0
.endif