section .text,text dc.l fakestack, _start public _start _start: move.w #$1, 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 #$10000, 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 #$8100, a1 bsr.w find_all_ram_cards move.l #$8100, a0 bsr.w sort_ram_cards move.w #$4, 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 #$0, ($F3,a2) ; Disable the ROM move.l #$1, (a3) ; Enable the RAM at base $0 cmpi.l #$1000000, d2 bcs.b sp_ok move.l #$ff0000, d2 sp_ok: move.l d2, a7 ; Load sector 0 to $0 move.l #$0, ($0,a4) ; Set the sector number to 0 move.l #$1, ($4,a4) ; Set the sector count to 1 move.l #$0, ($C,a4) ; Set the destination address to $0 move.w #$1, ($8,a4) ; Send a DMA read command jmp ($0).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 #$ff0000, a0 ; a0 holds the address of the current card ffc_loop: lea ($100,a0), a0 ; adda.l #$100,a0 ; Move to the next card move.w ($fe,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 #$0, d0 ; d0 holds the size of the largest RAM card found move.w #$0, a0 ; a0 holds the address of the largest RAM card found move.l #$ff0000, a1 ; a1 holds the address of the current card flr_loop: lea ($100,a1), a1 ; adda.l #$100,a0 ; Move to the next card move.w ($fe,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 #$2, d1 ; If the card isn't a RAM card, skip it bne.b flr_loop move.l ($4,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: dc.l 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 #$ff0000, a0 ; a0 holds the address of the current card. farc_loop: lea ($100,a0), a0 ; adda.l #$100,a0 ; Move to the next card move.w ($fe,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 #$2, 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 ($4,a2), d3 move.l (4,a1), a2 ; Read the second card's size move.l ($4,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 ($4,a1), d4 ; Read the second value move.l d3, ($4,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