emu/rom.68k
2022-10-09 12:14:49 -05:00

79 lines
3.1 KiB
Plaintext

.long 0, start
start:
move.w #fakestack, a7
move.b #0x1, d0 ; Find the ROM card
bra.b find_first_card
romfindret:
move.l a0, a6 ; Save the ROM card IO base in a6 for later
lea (0xEE, a6), a7 ; Set up the stack at the end of the ROM's IO space RAM
bsr.b find_largest_ram ; Find the largest RAM card and put the IO base in a5
move.l a0, a5
move.l d0, d7
move.b #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 a6, 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 (a6) ; Jump to the ramcode
stop #0x2700
ramcode:
move.b #0x0, (0xFE, a6) ; Disable the ROM
move.l #0x1, (a5) ; Enable the RAM at base 0x0
move.l d7, a7
; Load sector 0 to 0x0
move.l #0x0, (a4) ; Set the sector number to 0
; Transfer 0x100 (256) bytes from the storage card's data register to 0x0
move.w #0x0, a1 ; Load a1, the destination address register, with 0x0
move.w #0xFF, d0 ; Load d0 with the sector size - 1.
sector_loop:
move.b (4, a4), (a1)+ ; Transfer a byte of sector data to the destination
dbra d0, sector_loop ; Loop back if there is more to transfer
jmp (0x0).W ; Jump to the loaded sector
stop #0x2700
ramcode_end:
; 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
; Finds the largest RAM card, and returns it's IO base address in a0 and size in d0, or 0 if not found
; Clobbers d1, a1
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.b (0xff, 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.b #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
ble.b flr_loop
move.l d1, d0 ; Store the sise and address of the new latgest card in s0 and a0
move.l a1, a0
bra.b flr_loop ; Loop back and check the next card
flr_done:
rts
fakestack:
.long romfindret