132 lines
5.0 KiB
Plaintext
132 lines
5.0 KiB
Plaintext
.long fakestack, _start
|
|
.global _start
|
|
_start:
|
|
move.w #0x1, d0 | Find the ROM card
|
|
bra.b find_first_card
|
|
romfindret:
|
|
move.l a0, a2 | Save the ROM card IO base in a6 for later
|
|
move.l #0x10000, a7 | Set up the stack at the end of the ROM card's RAM
|
|
bsr.w find_largest_ram | Find the largest RAM card and put the IO base in a3
|
|
move.l a0, a3
|
|
move.l d0, d2
|
|
move.l #0x8100, a1
|
|
bsr.w find_all_ram_cards
|
|
move.l #0x8100, a0
|
|
bsr.w sort_ram_cards
|
|
move.w #0x4, d0 | Find a storage card and put the IO base in a4
|
|
bsr.b find_first_card
|
|
move.l a0, a4
|
|
| Transfer the bootsector load code to the ROM's
|
|
| built in RAM at the start of it's IO space
|
|
move.w #(ramcode_end - ramcode), d0 | Put the length of the ramcode in d0
|
|
move.w #ramcode, a0 | Put the address of the ramcode in a0
|
|
move.l a2, a1 | Put the start of the ROM's IO space RAM in a0
|
|
ramcode_loop:
|
|
move.b (a0)+, (a1)+ | Transfer a byte of ramcode to the ROM's IO space RAM
|
|
dbra d0, ramcode_loop | Loop back if there is more to transfer
|
|
jmp (a2) | Jump to the ramcode
|
|
|
|
ramcode:
|
|
move.b #0x0, (0xF3, a2) | Disable the ROM
|
|
move.l #0x1, (a3) | Enable the RAM at base 0x0
|
|
cmpi.l #0x1000000, d2
|
|
bcs.b sp_ok
|
|
move.l #0xff0000, d2
|
|
sp_ok:
|
|
move.l d2, a7
|
|
| Load sector 0 to 0x0
|
|
move.l #0x0, (0x0, a4) | Set the sector number to 0
|
|
move.l #0x1, (0x4, a4) | Set the sector count to 1
|
|
move.l #0x0, (0xC, a4) | Set the destination address to 0x0
|
|
move.w #0x1, (0x8, a4) | Send a DMA read command
|
|
jmp (0x0).W | Jump to the loaded sector
|
|
ramcode_end:
|
|
|
|
nop | Padding to make sure ramcode_end and find_first_card are different
|
|
|
|
| Finds the first card with the type in d0.w, and returns it's IO base address in a0, or 0 if not found
|
|
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.w (0xfe, 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.w 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
|
|
|
|
| Finds the largest RAM card, and returns it's IO base address in a0 and size in d0, or 0 if not found
|
|
find_largest_ram:
|
|
move.l #0x0, d0 | d0 holds the size of the largest RAM card found
|
|
move.w #0x0, a0 | a0 holds the address of the largest RAM card found
|
|
move.l #0xff0000, a1 | a1 holds the address of the current card
|
|
flr_loop:
|
|
lea (0x100,a1), a1 | adda.l #$100,a0 ; Move to the next card
|
|
move.w (0xfe, a1), d1 | Load the type of the card into d1
|
|
beq.b flr_done | If the type is 0 (empty slot), we have scanned all cards, so exit the loop
|
|
cmp.w #0x2, d1 | If the card isn't a RAM card, skip it
|
|
bne.b flr_loop
|
|
move.l (0x4, a1), d1 | Load the card's size into d1
|
|
cmp.l d0, d1 | If the current size is less than the largest size found, go back to the start of the loop
|
|
bls.b flr_loop
|
|
move.l d1, d0 | Store the size and address of the new largest card in d0 and a0
|
|
move.l a1, a0
|
|
bra.b flr_loop | Loop back and check the next card
|
|
flr_done:
|
|
rts
|
|
fakestack:
|
|
.long romfindret
|
|
|
|
| 1KB buffer in a1
|
|
| Returns list length in d0
|
|
find_all_ram_cards:
|
|
move.b #0, d0 | d0 holds the number of RAM cards found.
|
|
move.l #0xff0000, a0 | a0 holds the address of the current card.
|
|
farc_loop:
|
|
lea (0x100, a0), a0 | adda.l #$100,a0 ; Move to the next card
|
|
move.w (0xfe, a0), d1 | Load the type of the card into d1
|
|
beq.b farc_done | If the type is 0 (empty slot), we have scanned all cards, so exit the loop
|
|
cmp.w #0x2, d1 | If the card isn't a RAM card, skip it
|
|
bne.b farc_loop
|
|
move.l a0, (a1)+ | Write the IO base address into the buffer and advance the buffer pointer
|
|
addq.b #1, d0 | Increment the count of found RAM cards
|
|
bra.b farc_loop | Loop back and check the next card
|
|
farc_done:
|
|
move.l #0, (a1) | Write a null terminator on the end of the list
|
|
rts
|
|
|
|
| optimized bubble sort to sort RAM cards by size
|
|
| Buffer in a0
|
|
| Length in d0
|
|
sort_ram_cards:
|
|
movem.l d2-d4/a2, -(a7) | Save calle-preserved registers
|
|
src_outer_loop:
|
|
move.b #0, d1 | d1 = newlen
|
|
move.b #1, d2 | d2 = i
|
|
move.l a0, a1 | a1 holds the pointer to the current pair
|
|
src_inner_loop:
|
|
cmp.b d0, d2 | if i >= length, exit the inner loop
|
|
bge.b src_inner_loop_done
|
|
move.l (a1), a2 | Read the first card's size
|
|
move.l (0x4, a2), d3
|
|
move.l (4, a1), a2 | Read the second card's size
|
|
move.l (0x4, a2), d4
|
|
cmp.l d3, d4 | if d4 <= d3, branch to src_pair_sorted
|
|
bls.b src_pair_sorted
|
|
move.l (a1), d3 | Read the first value
|
|
move.l (0x4, a1), d4 | Read the second value
|
|
move.l d3, (0x4, a1) | Write the first value where the second value was
|
|
move.l d4, (a1)+ | Write the second value where the first value was and increment a1 for the next pair
|
|
move.b d2, d1 | i = newlem
|
|
src_pair_sorted:
|
|
addq.b #1, d2 | i++
|
|
bra.b src_inner_loop
|
|
src_inner_loop_done:
|
|
move.b d1, d0 | len = newlen
|
|
cmp #1, d0 | if n > 1, branch to outer loop
|
|
bgt.b src_outer_loop
|
|
movem.l (a7)+, d2-d4/a2 | Restore calle-preserved registers
|
|
rts
|