Compare commits
16 Commits
Author | SHA1 | Date | |
---|---|---|---|
74ba1c2e0f | |||
561a73e02e | |||
7787315906 | |||
9841b30ca8 | |||
3efad948f2 | |||
164fdaa8f1 | |||
1f91beae5e | |||
5633e6154a | |||
6223392b9d | |||
e49c2e2047 | |||
5a0f1c7e46 | |||
bea0c3979f | |||
787be520e9 | |||
779624e340 | |||
27fce6feeb | |||
ebbb0b19ed |
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,3 +0,0 @@
|
||||
*.bin
|
||||
*.elf
|
||||
*.o
|
7
Tupfile
Normal file
7
Tupfile
Normal file
@ -0,0 +1,7 @@
|
||||
.gitignore
|
||||
LDFLAGS = -z max-page-size=1 --orphan-handling=error -T rom.ld
|
||||
ASFLAGS = -m68010 -spaces -Felf -ldots -align -quiet
|
||||
|
||||
: rom.68k |> vasmm68k_mot $(ASFLAGS) -o %o %f |> rom.o
|
||||
: rom.o |> m68k-elf-ld $(LDFLAGS) -o %o %f |> rom.elf
|
||||
: rom.elf |> m68k-elf-objcopy -O binary %f %o |> rom.bin
|
0
Tupfile.ini
Normal file
0
Tupfile.ini
Normal file
4
abi_ref
Normal file
4
abi_ref
Normal file
@ -0,0 +1,4 @@
|
||||
d0, d1, a0, and a1 are caller preserved
|
||||
d2-d7 and a2-a5 are callee preserved
|
||||
a6 is frame pointer
|
||||
a7 is stack pointer
|
@ -1,5 +0,0 @@
|
||||
#! /bin/bash -x
|
||||
m68k-elf-as -m68010 --register-prefix-optional -o rom.o rom.68k
|
||||
m68k-elf-ld -z max-page-size=1 -T rom.ld -o rom.elf rom.o
|
||||
m68k-elf-objcopy -O binary rom.elf rom.bin
|
||||
|
165
rom.68k
165
rom.68k
@ -1,79 +1,132 @@
|
||||
.long fakestack, start
|
||||
start:
|
||||
move.b #0x1, d0 | Find the ROM card
|
||||
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, a6 | Save the ROM card IO base in a6 for later
|
||||
lea (0xF0, 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
|
||||
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 a6, a1 | Put the start of the ROM's IO space RAM in a0
|
||||
; 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 (a6) | Jump to the ramcode
|
||||
stop #0x2700
|
||||
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, (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
|
||||
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
|
||||
nop ; Padding to make sure ramcode_end and find_first_card are different
|
||||
|
||||
| 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
|
||||
; 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
|
||||
move.l #$ff0000, 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
|
||||
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
|
||||
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
|
||||
; 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
|
||||
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 (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
|
||||
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 (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 size and address of the new largest card in d0 and a0
|
||||
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
|
||||
bra.b flr_loop ; Loop back and check the next card
|
||||
flr_done:
|
||||
rts
|
||||
fakestack:
|
||||
.long romfindret
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user