78 lines
3.2 KiB
Plaintext
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
|
|
|