mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-09 06:36:59 +02:00
#407 32X use Chilly Willy's CRT code for Mars & Genesis, use preprocessor for asm files
This commit is contained in:
@@ -13,6 +13,7 @@ LDSCRIPTSDIR = $(ROOTDIR)/ldscripts
|
||||
SHPREFIX = $(ROOTDIR)/sh-elf/bin/sh-elf-
|
||||
SHCC = $(SHPREFIX)gcc
|
||||
SHXX = $(SHPREFIX)g++
|
||||
SHPP = $(SHPREFIX)cpp
|
||||
SHAS = $(SHPREFIX)as
|
||||
SHLD = $(SHPREFIX)ld
|
||||
SHOBJC = $(SHPREFIX)objcopy
|
||||
@@ -41,14 +42,13 @@ FILES_CC = $(foreach dir, $(SOURCES), $(wildcard $(dir)/*.c))
|
||||
FILES_XX = $(foreach dir, $(SOURCES), $(wildcard $(dir)/*.cpp))
|
||||
|
||||
LIBS = $(LIBPATH) -lm -lc -lgcc -lgcc-Os-4-200 -lnosys
|
||||
OBJS = $(BUILD)/sh2_crt0.o
|
||||
OBJS += $(addprefix $(BUILD)/, $(notdir $(FILES_AS:%.s=%.o)))
|
||||
OBJS = $(addprefix $(BUILD)/, $(notdir $(FILES_AS:%.s=%.o)))
|
||||
OBJS += $(addprefix $(BUILD)/, $(notdir $(FILES_CC:%.c=%.o)))
|
||||
OBJS += $(addprefix $(BUILD)/, $(notdir $(FILES_XX:%.cpp=%.o)))
|
||||
|
||||
.PHONY: dump clean
|
||||
|
||||
all: $(BUILD) m68k_crt0.bin m68k_crt1.bin $(TARGET).32x
|
||||
all: $(BUILD) m68k.bin $(TARGET).32x
|
||||
|
||||
dump:
|
||||
@[ -d dump ] || mkdir -p dump
|
||||
@@ -68,15 +68,15 @@ $(TARGET).32x: $(TARGET).elf
|
||||
$(TARGET).elf: $(OBJS)
|
||||
$(SHCC) $(SHLDFLAGS) $(OBJS) $(LIBS) -o $(TARGET).elf
|
||||
|
||||
%.bin: crt/%.s
|
||||
$(MDAS) $(MDASFLAGS) -o $(BUILD)/$@.o $<
|
||||
$(MDLD) $(MDLDFLAGS) -o $(BUILD)/$@ $(BUILD)/$@.o
|
||||
m68k.bin:
|
||||
make -C src-md
|
||||
|
||||
$(BUILD)/%.o: crt/%.s
|
||||
$(BUILD)/%.o: %.s
|
||||
$(SHAS) $(SHASFLAGS) $(INCPATH) -o $@ $<
|
||||
|
||||
$(BUILD)/%.o: asm/%.s
|
||||
$(SHAS) $(SHASFLAGS) $(INCPATH) -o $@ $<
|
||||
$(SHPP) $(INCPATH) -o $(BUILD)/$(notdir $<) $<
|
||||
$(SHAS) $(SHASFLAGS) $(INCPATH) -o $@ $(BUILD)/$(notdir $<)
|
||||
|
||||
$(BUILD)/%.o: %.c
|
||||
$(SHCC) $(SHCCFLAGS) $(INCPATH) -o $@ $<
|
||||
|
@@ -1,85 +0,0 @@
|
||||
| SEGA 32X support code for the 68000
|
||||
| by Chilly Willy
|
||||
| First part of rom header
|
||||
|
||||
.text
|
||||
|
||||
| Initial exception vectors. When the console is first turned on, it is
|
||||
| in MegaDrive mode. All vectors just point to the code to start up the
|
||||
| Mars adapter. After the adapter is enabled, none of these vectors will
|
||||
| appear as the adpater uses its own vector table to route exceptions to
|
||||
| the jump table. 0x3F0 is where the 68000 starts at for the 32X.
|
||||
|
||||
.long 0x01000000,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0
|
||||
.long 0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0
|
||||
.long 0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0
|
||||
.long 0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0
|
||||
.long 0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0
|
||||
.long 0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0
|
||||
.long 0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0
|
||||
.long 0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0
|
||||
|
||||
| Standard MegaDrive ROM header at 0x100
|
||||
|
||||
.ascii "SEGA 32X " /* First 4 bytes must be "SEGA" */
|
||||
.ascii "XProger (c)2022 " /* Copyright and date */
|
||||
.ascii "OpenLara Alpha " /* JP Name */
|
||||
.ascii "OpenLara Alpha " /* EN Name */
|
||||
.ascii "GM 14021968-01" /* Serial No. */
|
||||
.word 0x0000
|
||||
.ascii "J6 "
|
||||
.long 0x00000000,0x003FFFFF /* ROM start, end */
|
||||
.long 0x00FF0000,0x00FFFFFF /* RAM start, end */
|
||||
|
||||
| .ascii "RA" /* External RAM */
|
||||
| .byte 0xF8 /* don't clear + odd bytes */
|
||||
| .byte 0x20 /* SRAM */
|
||||
| .long 0x00200001,0x0020FFFF /* SRAM start, end */
|
||||
|
||||
.ascii " " /* no SRAM */
|
||||
|
||||
.ascii " "
|
||||
.ascii " "
|
||||
.ascii " "
|
||||
.ascii " "
|
||||
.ascii "F " /* enable any hardware configuration */
|
||||
|
||||
| Mars exception vector jump table at 0x200
|
||||
|
||||
jmp 0x880800.l /* reset = hot start */
|
||||
jsr 0x880806.l /* EX_BusError */
|
||||
jsr 0x880806.l /* EX_AddrError */
|
||||
jsr 0x880806.l /* EX_IllInstr */
|
||||
jsr 0x880806.l /* EX_DivByZero */
|
||||
jsr 0x880806.l /* EX_CHK */
|
||||
jsr 0x880806.l /* EX_TrapV */
|
||||
jsr 0x880806.l /* EX_Priviledge */
|
||||
jsr 0x880806.l /* EX_Trace */
|
||||
jsr 0x880806.l /* EX_LineA */
|
||||
jsr 0x880806.l /* EX_LineF */
|
||||
.space 72 /* reserved */
|
||||
jsr 0x880806.l /* EX_Spurious */
|
||||
jsr 0x880806.l /* EX_Level1 */
|
||||
jsr 0x880806.l /* EX_Level2 */
|
||||
jsr 0x880806.l /* EX_Level3 */
|
||||
jmp 0x88080C.l /* EX_Level4 HBlank */
|
||||
jsr 0x880806.l /* EX_Level5 */
|
||||
jmp 0x880812.l /* EX_Level6 VBlank */
|
||||
jsr 0x880806.l /* EX_Level7 */
|
||||
jsr 0x880806.l /* EX_Trap0 */
|
||||
jsr 0x880806.l /* EX_Trap1 */
|
||||
jsr 0x880806.l /* EX_Trap2 */
|
||||
jsr 0x880806.l /* EX_Trap3 */
|
||||
jsr 0x880806.l /* EX_Trap4 */
|
||||
jsr 0x880806.l /* EX_Trap5 */
|
||||
jsr 0x880806.l /* EX_Trap6 */
|
||||
jsr 0x880806.l /* EX_Trap7 */
|
||||
jsr 0x880806.l /* EX_Trap8 */
|
||||
jsr 0x880806.l /* EX_Trap9 */
|
||||
jsr 0x880806.l /* EX_TrapA */
|
||||
jsr 0x880806.l /* EX_TrapB */
|
||||
jsr 0x880806.l /* EX_TrapC */
|
||||
jsr 0x880806.l /* EX_TrapD */
|
||||
jsr 0x880806.l /* EX_TrapE */
|
||||
jsr 0x880806.l /* EX_TrapF */
|
||||
.space 166 /* reserved */
|
@@ -1,719 +0,0 @@
|
||||
! SEGA 32X support code for SH2
|
||||
! by Chilly Willy
|
||||
! Rom header and SH2 init/exception code - must be first in object list
|
||||
|
||||
.text
|
||||
|
||||
! Standard MD Header at 0x000
|
||||
|
||||
.incbin "build/m68k_crt0.bin", 0, 0x3C0
|
||||
|
||||
! Standard Mars Header at 0x3C0
|
||||
|
||||
.ascii "OpenLara " /* module name */
|
||||
.long 0x00000000 /* version */
|
||||
.long __text_size /* Source (in ROM) */
|
||||
.long 0x00000000 /* Destination (in SDRAM) */
|
||||
.long __data_size /* Size */
|
||||
.long 0x06000240 /* Master SH2 Jump */
|
||||
.long 0x06000244 /* Slave SH2 Jump */
|
||||
.long 0x06000000 /* Master SH2 VBR */
|
||||
.long 0x06000120 /* Slave SH2 VBR */
|
||||
|
||||
! Standard MD startup code at 0x3F0
|
||||
|
||||
.incbin "build/m68k_crt1.bin"
|
||||
|
||||
|
||||
.data
|
||||
|
||||
! Master Vector Base Table at 0x06000000
|
||||
|
||||
.long mstart /* Cold Start PC */
|
||||
.long 0x0603FC00 /* Cold Start SP */
|
||||
.long mstart /* Manual Reset PC */
|
||||
.long 0x0603FC00 /* Manual Reset SP */
|
||||
.long main_err /* Illegal instruction */
|
||||
.long 0x00000000 /* reserved */
|
||||
.long main_err /* Invalid slot instruction */
|
||||
.long 0x20100400 /* reserved */
|
||||
.long 0x20100420 /* reserved */
|
||||
.long main_err /* CPU address error */
|
||||
.long main_err /* DMA address error */
|
||||
.long main_err /* NMI vector */
|
||||
.long main_err /* User break vector */
|
||||
.space 76 /* reserved */
|
||||
.long main_err /* TRAPA #32 */
|
||||
.long main_err /* TRAPA #33 */
|
||||
.long main_err /* TRAPA #34 */
|
||||
.long main_err /* TRAPA #35 */
|
||||
.long main_err /* TRAPA #36 */
|
||||
.long main_err /* TRAPA #37 */
|
||||
.long main_err /* TRAPA #38 */
|
||||
.long main_err /* TRAPA #39 */
|
||||
.long main_err /* TRAPA #40 */
|
||||
.long main_err /* TRAPA #41 */
|
||||
.long main_err /* TRAPA #42 */
|
||||
.long main_err /* TRAPA #43 */
|
||||
.long main_err /* TRAPA #44 */
|
||||
.long main_err /* TRAPA #45 */
|
||||
.long main_err /* TRAPA #46 */
|
||||
.long main_err /* TRAPA #47 */
|
||||
.long main_err /* TRAPA #48 */
|
||||
.long main_err /* TRAPA #49 */
|
||||
.long main_err /* TRAPA #50 */
|
||||
.long main_err /* TRAPA #51 */
|
||||
.long main_err /* TRAPA #52 */
|
||||
.long main_err /* TRAPA #53 */
|
||||
.long main_err /* TRAPA #54 */
|
||||
.long main_err /* TRAPA #55 */
|
||||
.long main_err /* TRAPA #56 */
|
||||
.long main_err /* TRAPA #57 */
|
||||
.long main_err /* TRAPA #58 */
|
||||
.long main_err /* TRAPA #59 */
|
||||
.long main_err /* TRAPA #60 */
|
||||
.long main_err /* TRAPA #61 */
|
||||
.long main_err /* TRAPA #62 */
|
||||
.long main_err /* TRAPA #63 */
|
||||
.long main_irq /* Level 1 IRQ */
|
||||
.long main_irq /* Level 2 & 3 IRQ's */
|
||||
.long main_irq /* Level 4 & 5 IRQ's */
|
||||
.long main_irq /* PWM interupt */
|
||||
.long main_irq /* Command interupt */
|
||||
.long main_irq /* H Blank interupt */
|
||||
.long main_irq /* V Blank interupt */
|
||||
.long main_irq /* Reset Button */
|
||||
|
||||
! Slave Vector Base Table at 0x06000120
|
||||
|
||||
.long sstart /* Cold Start PC */
|
||||
.long 0x06040000 /* Cold Start SP */
|
||||
.long sstart /* Manual Reset PC */
|
||||
.long 0x06040000 /* Manual Reset SP */
|
||||
.long slav_err /* Illegal instruction */
|
||||
.long 0x00000000 /* reserved */
|
||||
.long slav_err /* Invalid slot instruction */
|
||||
.long 0x20100400 /* reserved */
|
||||
.long 0x20100420 /* reserved */
|
||||
.long slav_err /* CPU address error */
|
||||
.long slav_err /* DMA address error */
|
||||
.long slav_err /* NMI vector */
|
||||
.long slav_err /* User break vector */
|
||||
.space 76 /* reserved */
|
||||
.long slav_err /* TRAPA #32 */
|
||||
.long slav_err /* TRAPA #33 */
|
||||
.long slav_err /* TRAPA #34 */
|
||||
.long slav_err /* TRAPA #35 */
|
||||
.long slav_err /* TRAPA #36 */
|
||||
.long slav_err /* TRAPA #37 */
|
||||
.long slav_err /* TRAPA #38 */
|
||||
.long slav_err /* TRAPA #39 */
|
||||
.long slav_err /* TRAPA #40 */
|
||||
.long slav_err /* TRAPA #41 */
|
||||
.long slav_err /* TRAPA #42 */
|
||||
.long slav_err /* TRAPA #43 */
|
||||
.long slav_err /* TRAPA #44 */
|
||||
.long slav_err /* TRAPA #45 */
|
||||
.long slav_err /* TRAPA #46 */
|
||||
.long slav_err /* TRAPA #47 */
|
||||
.long slav_err /* TRAPA #48 */
|
||||
.long slav_err /* TRAPA #49 */
|
||||
.long slav_err /* TRAPA #50 */
|
||||
.long slav_err /* TRAPA #51 */
|
||||
.long slav_err /* TRAPA #52 */
|
||||
.long slav_err /* TRAPA #53 */
|
||||
.long slav_err /* TRAPA #54 */
|
||||
.long slav_err /* TRAPA #55 */
|
||||
.long slav_err /* TRAPA #56 */
|
||||
.long slav_err /* TRAPA #57 */
|
||||
.long slav_err /* TRAPA #58 */
|
||||
.long slav_err /* TRAPA #59 */
|
||||
.long slav_err /* TRAPA #60 */
|
||||
.long slav_err /* TRAPA #61 */
|
||||
.long slav_err /* TRAPA #62 */
|
||||
.long slav_err /* TRAPA #63 */
|
||||
.long slav_irq /* Level 1 IRQ */
|
||||
.long slav_irq /* Level 2 & 3 IRQ's */
|
||||
.long slav_irq /* Level 4 & 5 IRQ's */
|
||||
.long slav_irq /* PWM interupt */
|
||||
.long slav_irq /* Command interupt */
|
||||
.long slav_irq /* H Blank interupt */
|
||||
.long slav_irq /* V Blank interupt */
|
||||
.long slav_irq /* Reset Button */
|
||||
|
||||
! The main SH2 starts here at 0x06000240
|
||||
|
||||
mstart:
|
||||
bra mcont
|
||||
nop
|
||||
|
||||
! The slave SH2 starts here at 0x06000244
|
||||
|
||||
sstart:
|
||||
bra scont
|
||||
nop
|
||||
|
||||
! Each section of code below has its own data table so that the code
|
||||
! can be extended without worrying about the offsets becoming too big.
|
||||
! This results in duplicate entries, but not so many that we care. :)
|
||||
|
||||
mcont:
|
||||
! clear interrupt flags
|
||||
mov.l _master_int_clr,r1
|
||||
mov.w r0,@-r1 /* PWM INT clear */
|
||||
mov.w r0,@r1
|
||||
mov.w r0,@-r1 /* CMD INT clear */
|
||||
mov.w r0,@r1
|
||||
mov.w r0,@-r1 /* H INT clear */
|
||||
mov.w r0,@r1
|
||||
mov.w r0,@-r1 /* V INT clear */
|
||||
mov.w r0,@r1
|
||||
mov.w r0,@-r1 /* VRES INT clear */
|
||||
mov.w r0,@r1
|
||||
|
||||
mov.l _master_stk,r15
|
||||
! purge cache and turn it off
|
||||
mov.l _master_cctl,r0
|
||||
mov #0x10,r1
|
||||
mov.b r1,@r0
|
||||
|
||||
! clear bss
|
||||
mov #0,r0
|
||||
mov.l _master_bss_start,r1
|
||||
mov.l _master_bss_end,r2
|
||||
0:
|
||||
mov.l r0,@r1
|
||||
cmp/eq r1,r2
|
||||
bf/s 0b
|
||||
add #4,r1
|
||||
|
||||
! wait for 68000 to finish init
|
||||
mov.l _master_sts,r0
|
||||
mov.l _master_ok,r1
|
||||
1:
|
||||
mov.l @r0,r2
|
||||
nop
|
||||
nop
|
||||
cmp/eq r1,r2
|
||||
bt 1b
|
||||
|
||||
! let Slave SH2 run
|
||||
mov #0,r1
|
||||
mov.l r1,@(4,r0) /* clear slave status */
|
||||
|
||||
mov #0x80,r0
|
||||
mov.l _master_adapter,r1
|
||||
mov.b r0,@r1 /* set FM */
|
||||
mov #0x00,r0
|
||||
mov.b r0,@(1,r1) /* set int enables */
|
||||
mov #0x20,r0
|
||||
ldc r0,sr /* allow ints */
|
||||
|
||||
! purge cache, turn it on, and run main()
|
||||
mov.l _master_cctl,r0
|
||||
mov #0x11,r1
|
||||
mov.b r1,@r0
|
||||
mov.l _master_go,r0
|
||||
jmp @r0
|
||||
nop
|
||||
|
||||
.align 2
|
||||
_master_int_clr:
|
||||
.long 0x2000401E /* one word passed last int clr reg */
|
||||
_master_stk:
|
||||
.long 0x0603FC00 /* Cold Start SP */
|
||||
_master_sts:
|
||||
.long 0x20004020
|
||||
_master_ok:
|
||||
.ascii "M_OK"
|
||||
_master_adapter:
|
||||
.long 0x20004000
|
||||
_master_cctl:
|
||||
.long 0xFFFFFE92
|
||||
_master_go:
|
||||
.long _main
|
||||
|
||||
_master_bss_start:
|
||||
.long __bss_start
|
||||
_master_bss_end:
|
||||
.long __bss_end
|
||||
|
||||
scont:
|
||||
! clear interrupt flags
|
||||
mov.l _slave_int_clr,r1
|
||||
mov.w r0,@-r1 /* PWM INT clear */
|
||||
mov.w r0,@r1
|
||||
mov.w r0,@-r1 /* CMD INT clear */
|
||||
mov.w r0,@r1
|
||||
mov.w r0,@-r1 /* H INT clear */
|
||||
mov.w r0,@r1
|
||||
mov.w r0,@-r1 /* V INT clear */
|
||||
mov.w r0,@r1
|
||||
mov.w r0,@-r1 /* VRES INT clear */
|
||||
mov.w r0,@r1
|
||||
|
||||
mov.l _slave_stk,r15
|
||||
! wait for Master SH2 and 68000 to finish init
|
||||
mov.l _slave_sts,r0
|
||||
mov.l _slave_ok,r1
|
||||
1:
|
||||
mov.l @r0,r2
|
||||
nop
|
||||
nop
|
||||
cmp/eq r1,r2
|
||||
bt 1b
|
||||
|
||||
mov.l _slave_adapter,r1
|
||||
mov #0x00,r0
|
||||
mov.b r0,@(1,r1) /* set int enables (different from master despite same address!) */
|
||||
mov #0x20,r0
|
||||
ldc r0,sr /* allow ints */
|
||||
|
||||
! purge cache, turn it on, and run slave()
|
||||
mov.l _slave_cctl,r0
|
||||
mov #0x11,r1
|
||||
mov.b r1,@r0
|
||||
mov.l _slave_go,r0
|
||||
jmp @r0
|
||||
nop
|
||||
|
||||
.align 2
|
||||
_slave_int_clr:
|
||||
.long 0x2000401E /* one word passed last int clr reg */
|
||||
_slave_stk:
|
||||
.long 0x06040000 /* Cold Start SP */
|
||||
_slave_sts:
|
||||
.long 0x20004024
|
||||
_slave_ok:
|
||||
.ascii "S_OK"
|
||||
_slave_adapter:
|
||||
.long 0x20004000
|
||||
_slave_cctl:
|
||||
.long 0xFFFFFE92
|
||||
_slave_go:
|
||||
.long _slave
|
||||
|
||||
! Master exception handler
|
||||
|
||||
main_err:
|
||||
rte
|
||||
nop
|
||||
|
||||
! Master IRQ handler
|
||||
|
||||
main_irq:
|
||||
mov.l r0,@-r15
|
||||
|
||||
stc sr,r0 /* SR holds IRQ level in I3-I0 */
|
||||
shlr2 r0
|
||||
and #0x38,r0
|
||||
cmp/eq #0x28,r0
|
||||
bt main_h_irq
|
||||
cmp/eq #0x18,r0
|
||||
bt main_pwm_irq
|
||||
cmp/eq #0x30,r0
|
||||
bt main_v_irq
|
||||
cmp/eq #0x20,r0
|
||||
bt main_cmd_irq
|
||||
cmp/eq #0x38,r0
|
||||
bt main_vres_irq
|
||||
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
main_v_irq:
|
||||
mov.l r1,@-r15
|
||||
|
||||
mov.l mvi_mars_adapter,r1
|
||||
mov.w r0,@(0x16,r1) /* clear V IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
! handle V IRQ
|
||||
|
||||
mov.l @r15+,r1
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
.align 2
|
||||
mvi_mars_adapter:
|
||||
.long 0x20004000
|
||||
|
||||
main_h_irq:
|
||||
mov.l r1,@-r15
|
||||
|
||||
mov.l mhi_mars_adapter,r1
|
||||
mov.w r0,@(0x18,r1) /* clear H IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
! handle H IRQ
|
||||
|
||||
mov.l @r15+,r1
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
.align 2
|
||||
mhi_mars_adapter:
|
||||
.long 0x20004000
|
||||
|
||||
main_cmd_irq:
|
||||
mov.l r1,@-r15
|
||||
|
||||
mov.l mci_mars_adapter,r1
|
||||
mov.w r0,@(0x1A,r1) /* clear CMD IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
! handle CMD IRQ
|
||||
|
||||
mov.l @r15+,r1
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
.align 2
|
||||
mci_mars_adapter:
|
||||
.long 0x20004000
|
||||
|
||||
main_pwm_irq:
|
||||
mov.l r1,@-r15
|
||||
|
||||
mov.l mpi_mars_adapter,r1
|
||||
mov.w r0,@(0x1C,r1) /* clear PWM IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
! handle PWM IRQ
|
||||
|
||||
mov.l @r15+,r1
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
.align 2
|
||||
mpi_mars_adapter:
|
||||
.long 0x20004000
|
||||
|
||||
main_vres_irq:
|
||||
mov.l mvri_mars_adapter,r1
|
||||
mov.w r0,@(0x14,r1) /* clear VRES IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
mov #0x0F,r0
|
||||
shll2 r0
|
||||
shll2 r0
|
||||
ldc r0,sr /* disallow ints */
|
||||
|
||||
mov.l mvri_master_stk,r15
|
||||
mov.l mvri_master_vres,r0
|
||||
jmp @r0
|
||||
nop
|
||||
|
||||
.align 2
|
||||
mvri_mars_adapter:
|
||||
.long 0x20004000
|
||||
mvri_master_stk:
|
||||
.long 0x0603FC00 /* Cold Start SP */
|
||||
mvri_master_vres:
|
||||
.long main_reset
|
||||
|
||||
! Slave exception handler
|
||||
|
||||
slav_err:
|
||||
rte
|
||||
nop
|
||||
|
||||
! Slave IRQ handler
|
||||
|
||||
slav_irq:
|
||||
mov.l r0,@-r15
|
||||
|
||||
stc sr,r0 /* SR holds IRQ level I3-I0 */
|
||||
shlr2 r0
|
||||
and #0x38,r0
|
||||
cmp/eq #0x28,r0
|
||||
bt slav_h_irq
|
||||
cmp/eq #0x18,r0
|
||||
bt slav_pwm_irq
|
||||
cmp/eq #0x30,r0
|
||||
bt slav_v_irq
|
||||
cmp/eq #0x20,r0
|
||||
bt slav_cmd_irq
|
||||
cmp/eq #0x38,r0
|
||||
bt slav_vres_irq
|
||||
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
slav_v_irq:
|
||||
mov.l r1,@-r15
|
||||
|
||||
mov.l svi_mars_adapter,r1
|
||||
mov.w r0,@(0x16,r1) /* clear V IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
! handle V IRQ
|
||||
|
||||
mov.l @r15+,r1
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
.align 2
|
||||
svi_mars_adapter:
|
||||
.long 0x20004000
|
||||
|
||||
slav_h_irq:
|
||||
mov.l r1,@-r15
|
||||
|
||||
mov.l shi_mars_adapter,r1
|
||||
mov.w r0,@(0x18,r1) /* clear H IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
! handle H IRQ
|
||||
|
||||
mov.l @r15+,r1
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
.align 2
|
||||
shi_mars_adapter:
|
||||
.long 0x20004000
|
||||
|
||||
slav_cmd_irq:
|
||||
mov.l r1,@-r15
|
||||
|
||||
mov.l sci_mars_adapter,r1
|
||||
mov.w r0,@(0x1A,r1) /* clear CMD IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
! handle CMD IRQ
|
||||
|
||||
mov.l @r15+,r1
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
.align 2
|
||||
sci_mars_adapter:
|
||||
.long 0x20004000
|
||||
|
||||
slav_pwm_irq:
|
||||
mov.l r1,@-r15
|
||||
|
||||
mov.l spi_mars_adapter,r1
|
||||
mov.w r0,@(0x1C,r1) /* clear PWM IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
! handle PWM IRQ
|
||||
|
||||
mov.l @r15+,r1
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
.align 2
|
||||
spi_mars_adapter:
|
||||
.long 0x20004000
|
||||
|
||||
slav_vres_irq:
|
||||
mov.l svri_mars_adapter,r1
|
||||
mov.w r0,@(0x14,r1) /* clear VRES IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
mov #0x0F,r0
|
||||
shll2 r0
|
||||
shll2 r0
|
||||
ldc r0,sr /* disallow ints */
|
||||
|
||||
mov.l svri_slave_stk,r15
|
||||
mov.l svri_slave_vres,r0
|
||||
jmp @r0
|
||||
nop
|
||||
|
||||
.align 2
|
||||
svri_mars_adapter:
|
||||
.long 0x20004000
|
||||
svri_slave_stk:
|
||||
.long 0x06040000 /* Cold Start SP */
|
||||
svri_slave_vres:
|
||||
.long slav_reset
|
||||
|
||||
|
||||
! Fast memcpy function - copies longs, runs from sdram for speed
|
||||
! On entry: r4 = dst, r5 = src, r6 = len (in longs)
|
||||
|
||||
.align 4
|
||||
.global _fast_memcpy
|
||||
_fast_memcpy:
|
||||
mov.l @r5+,r3
|
||||
mov.l r3,@r4
|
||||
dt r6
|
||||
bf/s _fast_memcpy
|
||||
add #4,r4
|
||||
rts
|
||||
nop
|
||||
|
||||
! Fast memset function - sets long values, runs from sdram for speed
|
||||
! On entry: r4 = dst, r5 = value, r6 = len (in longs)
|
||||
|
||||
.align 4
|
||||
.global _fast_memset
|
||||
_fast_memset:
|
||||
mov.l r5,@r4
|
||||
dt r6
|
||||
bf/s _fast_memset
|
||||
add #4,r4
|
||||
rts
|
||||
nop
|
||||
|
||||
! Cache clear line function
|
||||
! On entry: r4 = ptr - should be 16 byte aligned
|
||||
|
||||
.align 4
|
||||
.global _CacheClearLine
|
||||
_CacheClearLine:
|
||||
mov.l _cache_flush,r0
|
||||
or r0,r4
|
||||
mov #0,r0
|
||||
mov.l r0,@r4
|
||||
rts
|
||||
nop
|
||||
|
||||
.align 2
|
||||
|
||||
_cache_flush:
|
||||
.long 0x40000000
|
||||
|
||||
! Cache control function
|
||||
! On entry: r4 = cache mode => 0x10 = CP, 0x08 = TW, 0x01 = CE
|
||||
|
||||
.align 4
|
||||
.global _CacheControl
|
||||
_CacheControl:
|
||||
mov.l _sh2_cctl,r0
|
||||
mov.b r4,@r0
|
||||
rts
|
||||
nop
|
||||
|
||||
.align 2
|
||||
|
||||
_sh2_cctl:
|
||||
.long 0xFFFFFE92
|
||||
|
||||
main_reset:
|
||||
! do any master SH2 specific reset code here
|
||||
|
||||
mov.l slav_st,r0
|
||||
mov.l slav_ok,r1
|
||||
0:
|
||||
mov.l @r0,r2
|
||||
nop
|
||||
nop
|
||||
cmp/eq r1,r2
|
||||
bf 0b /* wait for slave */
|
||||
|
||||
! recopy rom data to sdram
|
||||
|
||||
mov.l rom_header,r1
|
||||
mov.l @r1,r2 /* src relative to start of rom */
|
||||
mov.l @(4,r1),r3 /* dst relative to start of sdram */
|
||||
mov.l @(8,r1),r4 /* size (longword aligned) */
|
||||
mov.l rom_start,r1
|
||||
add r1,r2
|
||||
mov.l sdram_start,r1
|
||||
add r1,r3
|
||||
shlr2 r4 /* number of longs */
|
||||
add #-1,r4
|
||||
1:
|
||||
mov.l @r2+,r0
|
||||
mov.l r0,@r3
|
||||
add #4,r3
|
||||
dt r4
|
||||
bf 1b
|
||||
|
||||
mov.l main_st,r0
|
||||
mov.l main_ok,r1
|
||||
mov.l r1,@r0 /* tell everyone reset complete */
|
||||
|
||||
mov.l main_go,r0
|
||||
jmp @r0
|
||||
nop
|
||||
|
||||
slav_reset:
|
||||
! do any slave SH2 specific reset code here
|
||||
|
||||
mov.l slav_st,r0
|
||||
mov.l slav_ok,r1
|
||||
mov.l r1,@r0 /* tell master to start reset */
|
||||
|
||||
mov.l main_st,r0
|
||||
mov.l main_ok,r1
|
||||
0:
|
||||
mov.l @r0,r2
|
||||
nop
|
||||
nop
|
||||
cmp/eq r1,r2
|
||||
bf 0b /* wait for master to do the work */
|
||||
|
||||
mov.l slav_go,r0
|
||||
jmp @r0
|
||||
nop
|
||||
|
||||
.align 2
|
||||
main_st:
|
||||
.long 0x20004020
|
||||
main_ok:
|
||||
.ascii "M_OK"
|
||||
main_go:
|
||||
.long mstart
|
||||
rom_header:
|
||||
.long 0x220003D4
|
||||
rom_start:
|
||||
.long 0x22000000
|
||||
sdram_start:
|
||||
.long 0x26000000
|
||||
|
||||
slav_st:
|
||||
.long 0x20004024
|
||||
slav_ok:
|
||||
.ascii "S_OK"
|
||||
slav_go:
|
||||
.long sstart
|
||||
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
|
1272
src/platform/32x/crt0.s
Normal file
1272
src/platform/32x/crt0.s
Normal file
File diff suppressed because it is too large
Load Diff
46
src/platform/32x/src-md/Makefile
Normal file
46
src/platform/32x/src-md/Makefile
Normal file
@@ -0,0 +1,46 @@
|
||||
ifdef $(GENDEV)
|
||||
ROOTDIR = $(GENDEV)
|
||||
else
|
||||
ROOTDIR = /opt/toolchains/sega
|
||||
endif
|
||||
|
||||
PREFIX = $(ROOTDIR)/m68k-elf/bin/m68k-elf-
|
||||
CC = $(PREFIX)gcc
|
||||
AS = $(PREFIX)as
|
||||
LD = $(PREFIX)ld
|
||||
OBJC = $(PREFIX)objcopy
|
||||
|
||||
CC_VER := $(shell $(CC) -dumpversion)
|
||||
|
||||
LDSCRIPTSDIR = $(ROOTDIR)/ldscripts
|
||||
|
||||
LIBPATH = -L$(ROOTDIR)/m68k-elf/lib -L$(ROOTDIR)/m68k-elf/lib/gcc/m68k-elf/$(CC_VER) -L$(ROOTDIR)/m68k-elf/m68k-elf/lib
|
||||
INCPATH = -I$. -I$(ROOTDIR)/m68k-elf/include -I$(ROOTDIR)/m68k-elf/m68k-elf/include
|
||||
|
||||
CCFLAGS = -m68000 -Wall -O1 -c -fomit-frame-pointer
|
||||
ASFLAGS = -m68000 --register-prefix-optional
|
||||
LINKFLAGS = -T $(LDSCRIPTSDIR)/mars-md.ld -Wl,-Map=output.map -nostdlib
|
||||
|
||||
DD = dd
|
||||
RM = rm -f
|
||||
|
||||
TARGET = m68k
|
||||
LIBS = $(LIBPATH) -lc -lgcc -lnosys
|
||||
OBJS = crt0.o main.o kos.o cd.o
|
||||
|
||||
all: $(TARGET).bin
|
||||
|
||||
$(TARGET).bin: $(TARGET).elf
|
||||
$(OBJC) -O binary $< $(TARGET).bin
|
||||
|
||||
$(TARGET).elf: $(OBJS)
|
||||
$(CC) $(LINKFLAGS) $(OBJS) $(LIBS) -o $(TARGET).elf
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CCFLAGS) $(INCPATH) $< -o $@
|
||||
|
||||
%.o: %.s
|
||||
$(AS) $(ASFLAGS) $(INCPATH) $< -o $@
|
||||
|
||||
clean:
|
||||
$(RM) *.o *.bin *.elf output.map
|
183
src/platform/32x/src-md/cd.s
Normal file
183
src/platform/32x/src-md/cd.s
Normal file
@@ -0,0 +1,183 @@
|
||||
|
||||
.text
|
||||
|
||||
.global Sub_Start
|
||||
Sub_Start:
|
||||
|
||||
| Standard MegaCD Sub-CPU Program Header (copied to 0x6000)
|
||||
|
||||
SPHeader:
|
||||
.asciz "MAIN-SUBCPU"
|
||||
.word 0x0001,0x0000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long SPHeaderOffsets-SPHeader
|
||||
.long 0x00000000
|
||||
|
||||
SPHeaderOffsets:
|
||||
.word SPInit-SPHeaderOffsets
|
||||
.word SPMain-SPHeaderOffsets
|
||||
.word SPInt2-SPHeaderOffsets
|
||||
.word SPNull-SPHeaderOffsets
|
||||
.word 0x0000
|
||||
|
||||
| Sub-CPU Program Initialization (VBlank not enabled yet)
|
||||
|
||||
SPInit:
|
||||
move.b #'I,0x800F.w /* sub comm port = INITIALIZING */
|
||||
andi.b #0xE2,0x8003.w /* Priority Mode = off, 2M mode, Sub-CPU has access */
|
||||
rts
|
||||
|
||||
| Sub-CPU Program Main Entry Point (VBlank now enabled)
|
||||
|
||||
SPMain:
|
||||
move.w #0x0081,d0 /* CDBSTAT */
|
||||
jsr 0x5F22.w /* call CDBIOS function */
|
||||
move.w 0(a0),d0 /* BIOS status word */
|
||||
bmi.b 1f /* not ready */
|
||||
lsr.w #8,d0
|
||||
cmpi.b #0x40,d0
|
||||
beq.b 9f /* open */
|
||||
cmpi.b #0x10,d0
|
||||
beq.b 9f /* no disc */
|
||||
1:
|
||||
| Initialize Drive
|
||||
lea drive_init_parms(pc),a0
|
||||
move.w #0x0010,d0 /* DRVINIT */
|
||||
jsr 0x5F22.w /* call CDBIOS function */
|
||||
|
||||
move.w #0x0089,d0 /* CDCSTOP - stop reading data */
|
||||
jsr 0x5F22.w /* call CDBIOS function */
|
||||
9:
|
||||
move.b #0,0x800F.w /* sub comm port = READY */
|
||||
|
||||
| wait for command in main comm port
|
||||
WaitCmd:
|
||||
tst.b 0x800E.w
|
||||
beq.b WaitCmd
|
||||
cmpi.b #'D,0x800E.w
|
||||
beq GetDiscInfo
|
||||
cmpi.b #'T,0x800E.w
|
||||
beq GetTrackInfo
|
||||
cmpi.b #'P,0x800E.w
|
||||
beq PlayTrack
|
||||
cmpi.b #'S,0x800E.w
|
||||
beq StopPlaying
|
||||
cmpi.b #'Z,0x800E.w
|
||||
beq PauseResume
|
||||
cmpi.b #'C,0x800E.w
|
||||
beq CheckDisc
|
||||
move.b #'E,0x800F.w /* sub comm port = ERROR */
|
||||
WaitAck:
|
||||
tst.b 0x800E.w
|
||||
bne.b WaitAck /* wait for result acknowledged */
|
||||
move.b #0,0x800F.w /* sub comm port = READY */
|
||||
bra.b WaitCmd
|
||||
|
||||
GetDiscInfo:
|
||||
move.w #0x0081,d0 /* CDBSTAT */
|
||||
jsr 0x5F22.w /* call CDBIOS function */
|
||||
move.w 0(a0),0x8020.w /* BIOS status word */
|
||||
move.w 16(a0),0x8022.w /* First song number, Last song number */
|
||||
move.w 18(a0),0x8024.w /* Drive version, Flag */
|
||||
|
||||
move.b #'D,0x800F.w /* sub comm port = DONE */
|
||||
bra WaitAck
|
||||
|
||||
GetTrackInfo:
|
||||
move.w 0x8010.w,d1 /* track number */
|
||||
move.w #0x0083,d0 /* CDBTOCREAD */
|
||||
jsr 0x5F22.w /* call CDBIOS function */
|
||||
move.l d0,0x8020.w /* MMSSFFTN */
|
||||
move.b d1,0x8024.w /* track type */
|
||||
|
||||
move.b #'D,0x800F.w /* sub comm port = DONE */
|
||||
bra WaitAck
|
||||
|
||||
PlayTrack:
|
||||
move.w #0x0002,d0 /* MSCSTOP - stop playing */
|
||||
jsr 0x5F22.w /* call CDBIOS function */
|
||||
|
||||
move.w 0x8010.w,d1 /* track number */
|
||||
move.w #0x0011,d0 /* MSCPLAY - play from track on */
|
||||
move.b 0x8012.w,d2 /* flag */
|
||||
bmi.b 2f
|
||||
beq.b 1f
|
||||
move.w #0x0013,d0 /* MSCPLAYR - play with repeat */
|
||||
bra.b 2f
|
||||
1:
|
||||
move.w #0x0012,d0 /* MSCPLAY1 - play once */
|
||||
2:
|
||||
lea track_number(pc),a0
|
||||
move.w d1,(a0)
|
||||
jsr 0x5F22.w /* call CDBIOS function */
|
||||
|
||||
move.b #'D,0x800F.w /* sub comm port = DONE */
|
||||
bra WaitAck
|
||||
|
||||
StopPlaying:
|
||||
move.w #0x0002,d0 /* MSCSTOP - stop playing */
|
||||
jsr 0x5F22.w /* call CDBIOS function */
|
||||
|
||||
move.b #'D,0x800F.w /* sub comm port = DONE */
|
||||
bra WaitAck
|
||||
|
||||
PauseResume:
|
||||
move.w #0x0081,d0 /* CDBSTAT */
|
||||
jsr 0x5F22.w /* call CDBIOS function */
|
||||
move.b (a0),d0
|
||||
cmpi.b #1,d0
|
||||
beq.b 1f /* playing - pause playback */
|
||||
cmpi.b #5,d0
|
||||
beq.b 2f /* paused - resume playback */
|
||||
|
||||
move.b #'E,0x800F.w /* sub comm port = ERROR */
|
||||
bra WaitAck
|
||||
1:
|
||||
move.w #0x0003,d0 /* MSCPAUSEON - pause playback */
|
||||
jsr 0x5F22.w /* call CDBIOS function */
|
||||
|
||||
move.b #'D,0x800F.w /* sub comm port = DONE */
|
||||
bra WaitAck
|
||||
2:
|
||||
move.w #0x0004,d0 /* MSCPAUSEOFF - resume playback */
|
||||
jsr 0x5F22.w /* call CDBIOS function */
|
||||
|
||||
move.b #'D,0x800F.w /* sub comm port = DONE */
|
||||
bra WaitAck
|
||||
|
||||
CheckDisc:
|
||||
lea drive_init_parms(pc),a0
|
||||
move.w #0x0010,d0 /* DRVINIT */
|
||||
jsr 0x5F22.w /* call CDBIOS function */
|
||||
|
||||
move.w #0x0089,d0 /* CDCSTOP - stop reading data */
|
||||
jsr 0x5F22.w /* call CDBIOS function */
|
||||
|
||||
move.b #'D,0x800F.w /* sub comm port = DONE */
|
||||
bra WaitAck
|
||||
|
||||
|
||||
| Sub-CPU Program VBlank (INT02) Service Handler
|
||||
|
||||
SPInt2:
|
||||
rts
|
||||
|
||||
| Sub-CPU program Reserved Function
|
||||
|
||||
SPNull:
|
||||
rts
|
||||
|
||||
|
||||
| Sub-CPU variables
|
||||
|
||||
.align 2
|
||||
drive_init_parms:
|
||||
.byte 0x01, 0xFF /* first track (1), last track (all) */
|
||||
|
||||
track_number:
|
||||
.word 0
|
||||
|
||||
|
||||
.global Sub_End
|
||||
Sub_End:
|
@@ -1,119 +1,65 @@
|
||||
| SEGA 32X support code for the 68000
|
||||
| by Chilly Willy
|
||||
| Third part of rom header
|
||||
|
||||
.text
|
||||
|
||||
| Standard Mars startup code at 0x3F0 - this is included as binary as SEGA
|
||||
| uses this as a security key. US law allows us to include this as-is because
|
||||
| it's used for security. The interoperability clauses in the law state this
|
||||
| trumps copyright... and the Supreme Court agrees. :P
|
||||
| 0x880800 - entry point for reset/cold-start
|
||||
|
||||
.word 0x287C,0xFFFF,0xFFC0,0x23FC,0x0000,0x0000,0x00A1,0x5128
|
||||
.word 0x46FC,0x2700,0x4BF9,0x00A1,0x0000,0x7001,0x0CAD,0x4D41
|
||||
.word 0x5253,0x30EC,0x6600,0x03E6,0x082D,0x0007,0x5101,0x67F8
|
||||
.word 0x4AAD,0x0008,0x6710,0x4A6D,0x000C,0x670A,0x082D,0x0000
|
||||
.word 0x5101,0x6600,0x03B8,0x102D,0x0001,0x0200,0x000F,0x6706
|
||||
.word 0x2B78,0x055A,0x4000,0x7200,0x2C41,0x4E66,0x41F9,0x0000
|
||||
.word 0x04D4,0x6100,0x0152,0x6100,0x0176,0x47F9,0x0000,0x04E8
|
||||
.word 0x43F9,0x00A0,0x0000,0x45F9,0x00C0,0x0011,0x3E3C,0x0100
|
||||
.word 0x7000,0x3B47,0x1100,0x3B47,0x1200,0x012D,0x1100,0x66FA
|
||||
.word 0x7425,0x12DB,0x51CA,0xFFFC,0x3B40,0x1200,0x3B40,0x1100
|
||||
.word 0x3B47,0x1200,0x149B,0x149B,0x149B,0x149B,0x41F9,0x0000
|
||||
.word 0x04C0,0x43F9,0x00FF,0x0000,0x22D8,0x22D8,0x22D8,0x22D8
|
||||
.word 0x22D8,0x22D8,0x22D8,0x22D8,0x41F9,0x00FF,0x0000,0x4ED0
|
||||
.word 0x1B7C,0x0001,0x5101,0x41F9,0x0000,0x06BC,0xD1FC,0x0088
|
||||
.word 0x0000,0x4ED0,0x0404,0x303C,0x076C,0x0000,0x0000,0xFF00
|
||||
.word 0x8137,0x0002,0x0100,0x0000,0xAF01,0xD91F,0x1127,0x0021
|
||||
.word 0x2600,0xF977,0xEDB0,0xDDE1,0xFDE1,0xED47,0xED4F,0xD1E1
|
||||
.word 0xF108,0xD9C1,0xD1E1,0xF1F9,0xF3ED,0x5636,0xE9E9,0x9FBF
|
||||
.word 0xDFFF,0x4D41,0x5253,0x2049,0x6E69,0x7469,0x616C,0x2026
|
||||
.word 0x2053,0x6563,0x7572,0x6974,0x7920,0x5072,0x6F67,0x7261
|
||||
.word 0x6D20,0x2020,0x2020,0x2020,0x2020,0x2043,0x6172,0x7472
|
||||
.word 0x6964,0x6765,0x2056,0x6572,0x7369,0x6F6E,0x2020,0x2020
|
||||
.word 0x436F,0x7079,0x7269,0x6768,0x7420,0x5345,0x4741,0x2045
|
||||
.word 0x4E54,0x4552,0x5052,0x4953,0x4553,0x2C4C,0x5444,0x2E20
|
||||
.word 0x3139,0x3934,0x2020,0x2020,0x2020,0x2020,0x2020,0x2020
|
||||
.word 0x2020,0x2020,0x2020,0x2020,0x2020,0x2020,0x2020,0x2020
|
||||
.word 0x2020,0x2020,0x2020,0x524F,0x4D20,0x5665,0x7273,0x696F
|
||||
.word 0x6E20,0x312E,0x3000,0x48E7,0xC040,0x43F9,0x00C0,0x0004
|
||||
.word 0x3011,0x303C,0x8000,0x323C,0x0100,0x3E3C,0x0012,0x1018
|
||||
.word 0x3280,0xD041,0x51CF,0xFFF8,0x4CDF,0x0203,0x4E75,0x48E7
|
||||
.word 0x81C0,0x41F9,0x0000,0x063E,0x43F9,0x00C0,0x0004,0x3298
|
||||
.word 0x3298,0x3298,0x3298,0x3298,0x3298,0x3298,0x2298,0x3341
|
||||
.word 0xFFFC,0x3011,0x0800,0x0001,0x66F8,0x3298,0x3298,0x7000
|
||||
.word 0x22BC,0xC000,0x0000,0x7E0F,0x3340,0xFFFC,0x3340,0xFFFC
|
||||
.word 0x3340,0xFFFC,0x3340,0xFFFC,0x51CF,0xFFEE,0x22BC,0x4000
|
||||
.word 0x0010,0x7E09,0x3340,0xFFFC,0x3340,0xFFFC,0x3340,0xFFFC
|
||||
.word 0x3340,0xFFFC,0x51CF,0xFFEE,0x4CDF,0x0381,0x4E75,0x8114
|
||||
.word 0x8F01,0x93FF,0x94FF,0x9500,0x9600,0x9780,0x4000,0x0080
|
||||
.word 0x8104,0x8F02,0x48E7,0xC140,0x43F9,0x00A1,0x5180,0x08A9
|
||||
.word 0x0007,0xFF80,0x66F8,0x3E3C,0x00FF,0x7000,0x7200,0x337C
|
||||
.word 0x00FF,0x0004,0x3341,0x0006,0x3340,0x0008,0x4E71,0x0829
|
||||
.word 0x0001,0x000B,0x66F8,0x0641,0x0100,0x51CF,0xFFE8,0x4CDF
|
||||
.word 0x0283,0x4E75,0x48E7,0x8180,0x41F9,0x00A1,0x5200,0x08A8
|
||||
.word 0x0007,0xFF00,0x66F8,0x3E3C,0x001F,0x20C0,0x20C0,0x20C0
|
||||
.word 0x20C0,0x51CF,0xFFF6,0x4CDF,0x0181,0x4E75,0x41F9,0x00FF
|
||||
.word 0x0000,0x3E3C,0x07FF,0x7000,0x20C0,0x20C0,0x20C0,0x20C0
|
||||
.word 0x20C0,0x20C0,0x20C0,0x20C0,0x51CF,0xFFEE,0x3B7C,0x0000
|
||||
.word 0x1200,0x7E0A,0x51CF,0xFFFE,0x43F9,0x00A1,0x5100,0x7000
|
||||
.word 0x2340,0x0020,0x2340,0x0024,0x1B7C,0x0003,0x5101,0x2E79
|
||||
.word 0x0088,0x0000,0x0891,0x0007,0x66FA,0x7000,0x3340,0x0002
|
||||
.word 0x3340,0x0004,0x3340,0x0006,0x2340,0x0008,0x2340,0x000C
|
||||
.word 0x3340,0x0010,0x3340,0x0030,0x3340,0x0032,0x3340,0x0038
|
||||
.word 0x3340,0x0080,0x3340,0x0082,0x08A9,0x0000,0x008B,0x66F8
|
||||
.word 0x6100,0xFF12,0x08E9,0x0000,0x008B,0x67F8,0x6100,0xFF06
|
||||
.word 0x08A9,0x0000,0x008B,0x6100,0xFF3C,0x303C,0x0040,0x2229
|
||||
.word 0x0020,0x0C81,0x5351,0x4552,0x6700,0x0092,0x303C,0x0080
|
||||
.word 0x2229,0x0020,0x0C81,0x5344,0x4552,0x6700,0x0080,0x21FC
|
||||
.word 0x0088,0x02A2,0x0070,0x303C,0x0002,0x7200,0x122D,0x0001
|
||||
.word 0x1429,0x0080,0xE14A,0x8242,0x0801,0x000F,0x660A,0x0801
|
||||
.word 0x0006,0x6700,0x0058,0x6008,0x0801,0x0006,0x6600,0x004E
|
||||
.word 0x7020,0x41F9,0x0088,0x0000,0x3C28,0x018E,0x4A46,0x6700
|
||||
.word 0x0010,0x3429,0x0028,0x0C42,0x0000,0x67F6,0xB446,0x662C
|
||||
.word 0x7000,0x2340,0x0028,0x2340,0x002C,0x3E14,0x2C7C,0xFFFF
|
||||
.word 0xFFC0,0x4CD6,0x7FF9,0x44FC,0x0000,0x6014,0x43F9,0x00A1
|
||||
.word 0x5100,0x3340,0x0006,0x303C,0x8000,0x6004,0x44FC,0x0001
|
||||
.global _start
|
||||
_start:
|
||||
|
||||
| At this point (0x800), the Work RAM is clear, the VDP initialized, the
|
||||
| VRAM/VSRAM/CRAM cleared, the Z80 initialized, the 32X initialized,
|
||||
| both 32X framebuffers cleared, the 32X palette cleared, the SH2s
|
||||
| checked for a startup error, the adapter TV mode matches the MD TV
|
||||
| mode, and the ROM checksum checked. If any error is detected, the
|
||||
| carry is set, otherwise it is cleared. The 68000 main code is now
|
||||
| entered.
|
||||
| Clear Work RAM
|
||||
moveq #0,d0
|
||||
move.w #0x3FFF,d1
|
||||
suba.l a1,a1
|
||||
1:
|
||||
move.l d0,-(a1)
|
||||
dbra d1,1b
|
||||
|
||||
jmp __start+0x00880000+0x3F0
|
||||
| Copy initialized variables from ROM to Work RAM
|
||||
lea __text_end,a0
|
||||
move.w #__data_size,d0
|
||||
lsr.w #1,d0
|
||||
subq.w #1,d0
|
||||
2:
|
||||
move.w (a0)+,(a1)+
|
||||
dbra d0,2b
|
||||
|
||||
| 68000 General exception handler at 0x806
|
||||
lea __stack,sp /* set stack pointer to top of Work RAM */
|
||||
|
||||
jmp __except+0x00880000+0x3F0
|
||||
bsr init_hardware /* initialize the console hardware */
|
||||
|
||||
| 68000 Level 4 interrupt handler at 0x80C - HBlank IRQ
|
||||
jsr main /* call program main() */
|
||||
3:
|
||||
stop #0x2700
|
||||
bra.b 3b
|
||||
|
||||
jmp __hblank+0x00880000+0x3F0
|
||||
.align 64
|
||||
|
||||
| 68000 Level 6 interrupt handler at 0x812 - VBlank IRQ
|
||||
| 0x880840 - 68000 General exception handler
|
||||
|
||||
jmp __vblank+0x00880000+0x3F0
|
||||
|
||||
__except:
|
||||
move.l d0,-(sp)
|
||||
move.l 4(sp),d0 /* jump table return address */
|
||||
sub.w #0x206,d0 /* 0 = BusError, 6 = AddrError, etc */
|
||||
|
||||
| handle exception
|
||||
/* handle exception here */
|
||||
|
||||
move.l (sp)+,d0
|
||||
addq.l #4,sp /* pop jump table return address */
|
||||
rte
|
||||
|
||||
__hblank:
|
||||
.align 64
|
||||
|
||||
| 0x880880 - 68000 Level 4 interrupt handler - HBlank IRQ
|
||||
|
||||
rte
|
||||
|
||||
__vblank:
|
||||
.align 64
|
||||
|
||||
| 0x8808C0 - 68000 Level 6 interrupt handler - VBlank IRQ
|
||||
|
||||
move.l d0,-(sp)
|
||||
move.l 0xFF0FFC,d0
|
||||
move.l vblank,d0
|
||||
beq.b 1f
|
||||
move.l a0,-(sp)
|
||||
movea.l d0,a0
|
||||
@@ -123,14 +69,12 @@ __vblank:
|
||||
rte
|
||||
|
||||
|
||||
__start:
|
||||
move.b #0,0xA15107 /* clear RV - allow SH2 to access ROM */
|
||||
0:
|
||||
cmp.l #0x4D5F4F4B,0xA15120 /* M_OK */
|
||||
bne.b 0b /* wait for master ok */
|
||||
1:
|
||||
cmp.l #0x535F4F4B,0xA15124 /* S_OK */
|
||||
bne.b 1b /* wait for slave ok */
|
||||
| Initialize the MD side to a known state for the game
|
||||
|
||||
init_hardware:
|
||||
lea 0xC00004,a0
|
||||
move.w #0x8104,(a0) /* display off, vblank disabled */
|
||||
move.w (a0),d0 /* read VDP Status reg */
|
||||
|
||||
| init joyports
|
||||
move.b #0x40,0xA10009
|
||||
@@ -139,7 +83,6 @@ __start:
|
||||
move.b #0x40,0xA10005
|
||||
|
||||
| init MD VDP
|
||||
lea 0xC00004,a0
|
||||
move.w #0x8004,(a0) /* reg. 0 - Disable HBL INT */
|
||||
move.w #0x8174,(a0) /* reg. 1 - Enable display, VBL INT, DMA + 28 VCell size */
|
||||
move.w #0x8230,(a0) /* reg. 2 - Plane A =$30*$400=$C000 */
|
||||
@@ -160,21 +103,12 @@ __start:
|
||||
move.w #0x9100,(a0) /* reg 17 - window hpos */
|
||||
move.w #0x92FF,(a0) /* reg 18 - window vpos */
|
||||
|
||||
| Copy 68000 main loop to Work RAM to keep contention for the ROM with
|
||||
| SH2s to a minimum.
|
||||
lea __m68k_start(pc),a0
|
||||
lea 0x00FF1000,a1
|
||||
move.w #__m68k_end-__m68k_start-1,d0
|
||||
cpyloop:
|
||||
move.b (a0)+,(a1)+
|
||||
dbra d0,cpyloop
|
||||
|
||||
move.w #0,0xA15128 /* controller 1 */
|
||||
move.w #0,0xA1512A /* controller 2 */
|
||||
| look for mouse
|
||||
lea 0xA10003,a0
|
||||
0:
|
||||
bsr get_mky
|
||||
jsr get_mky
|
||||
cmpi.l #-2,d0
|
||||
beq.b 0b /* timeout */
|
||||
cmpi.l #-1,d0
|
||||
@@ -183,21 +117,84 @@ cpyloop:
|
||||
1:
|
||||
lea 2(a0),a0
|
||||
2:
|
||||
bsr get_mky
|
||||
jsr get_mky
|
||||
cmpi.l #-2,d0
|
||||
beq.b 2b /* timeout */
|
||||
cmpi.l #-1,d0
|
||||
beq.b 3f /* no mouse */
|
||||
move.w #0xF001,0xA1512A /* mouse in port 2 */
|
||||
3:
|
||||
move.l #0,0xA1512C /* clear the vblank count */
|
||||
|
||||
| jump to main loop in Work RAM
|
||||
jmp 0xFF1000.l
|
||||
| allow the 68k to access the FM chip
|
||||
move.w #0x0100,0xA11100 /* Z80 assert bus request */
|
||||
move.w #0x0100,0xA11200 /* Z80 deassert reset */
|
||||
|
||||
| this block of code must be pc relative as it's copied into Work RAM
|
||||
| wait on Mars side
|
||||
move.b #0,0xA15107 /* clear RV - allow SH2 to access ROM */
|
||||
0:
|
||||
cmp.l #0x4D5F4F4B,0xA15120 /* M_OK */
|
||||
bne.b 0b /* wait for master ok */
|
||||
1:
|
||||
cmp.l #0x535F4F4B,0xA15124 /* S_OK */
|
||||
bne.b 1b /* wait for slave ok */
|
||||
|
||||
__m68k_start:
|
||||
move.l #vert_blank,vblank /* set vertical blank interrupt handler */
|
||||
move.w #0x2000,sr /* enable interrupts */
|
||||
rts
|
||||
|
||||
|
||||
| void write_byte(void *dst, unsigned char val)
|
||||
.global write_byte
|
||||
write_byte:
|
||||
movea.l 4(sp),a0
|
||||
move.l 8(sp),d0
|
||||
move.b d0,(a0)
|
||||
rts
|
||||
|
||||
| void write_word(void *dst, unsigned short val)
|
||||
.global write_word
|
||||
write_word:
|
||||
movea.l 4(sp),a0
|
||||
move.l 8(sp),d0
|
||||
move.w d0,(a0)
|
||||
rts
|
||||
|
||||
| void write_long(void *dst, unsigned int val)
|
||||
.global write_long
|
||||
write_long:
|
||||
movea.l 4(sp),a0
|
||||
move.l 8(sp),d0
|
||||
move.l d0,(a0)
|
||||
rts
|
||||
|
||||
| unsigned char read_byte(void *src)
|
||||
.global read_byte
|
||||
read_byte:
|
||||
movea.l 4(sp),a0
|
||||
move.b (a0),d0
|
||||
rts
|
||||
|
||||
| unsigned short read_word(void *src)
|
||||
.global read_word
|
||||
read_word:
|
||||
movea.l 4(sp),a0
|
||||
move.w (a0),d0
|
||||
rts
|
||||
|
||||
| unsigned int read_long(void *src)
|
||||
.global read_long
|
||||
read_long:
|
||||
movea.l 4(sp),a0
|
||||
move.l (a0),d0
|
||||
rts
|
||||
|
||||
|
||||
.data
|
||||
|
||||
| Put remaining code in data section to lower bus contention for the rom.
|
||||
|
||||
.global do_main
|
||||
do_main:
|
||||
move.b #1,0xA15107 /* set RV */
|
||||
move.b #2,0xA130F1 /* SRAM disabled, write protected */
|
||||
move.b #0,0xA15107 /* clear RV */
|
||||
@@ -207,16 +204,11 @@ __m68k_start:
|
||||
move.w d0,0xA15100 /* set FM - allow SH2 access to MARS hw */
|
||||
move.l #0,0xA15120 /* let Master SH2 run */
|
||||
|
||||
lea vert_blank(pc),a0
|
||||
move.l a0,0xFF0FFC /* set vertical blank interrupt handler */
|
||||
move.w #0x2000,sr /* enable interrupts */
|
||||
|
||||
main_loop:
|
||||
move.w 0xA15120,d0 /* get COMM0 */
|
||||
bne.b handle_req
|
||||
|
||||
| any other 68000 tasks here
|
||||
|
||||
nop
|
||||
bra.b main_loop
|
||||
|
||||
| process request from Master SH2
|
||||
@@ -278,7 +270,56 @@ set_rom_bank:
|
||||
rts
|
||||
|
||||
start_music:
|
||||
tst.w cd_ok
|
||||
beq.b 2f /* couldn't init cd */
|
||||
tst.b cd_ok
|
||||
bne.b 0f /* disc found - try to play track */
|
||||
/* check for CD */
|
||||
10:
|
||||
move.b 0xA1200F,d1
|
||||
bne.b 10b /* wait until Sub-CPU is ready to receive command */
|
||||
move.b #'D,0xA1200E /* set main comm port to GetDiskInfo command */
|
||||
11:
|
||||
move.b 0xA1200F,d0
|
||||
beq.b 11b /* wait for acknowledge byte in sub comm port */
|
||||
move.b #0x00,0xA1200E /* acknowledge receipt of command result */
|
||||
|
||||
cmpi.b #'D,d0
|
||||
bne.b 2f /* couldn't get disk info */
|
||||
move.w 0xA12020,d0 /* BIOS status */
|
||||
cmpi.w #0x1000,d0
|
||||
bhs.b 2f /* open, busy, or no disc */
|
||||
move.b #1,cd_ok /* we have a disc - try to play track */
|
||||
0:
|
||||
move.b 0xA1200F,d1
|
||||
bne.b 0b /* wait until Sub-CPU is ready to receive command */
|
||||
|
||||
move.b d0,0xA12012 /* repeat flag */
|
||||
move.w 0xA15122,d0
|
||||
addq.w #1,d0
|
||||
move.w d0,0xA12010 /* track no. */
|
||||
move.b #'P,0xA1200E /* set main comm port to PlayTrack command */
|
||||
1:
|
||||
move.b 0xA1200F,d0
|
||||
beq.b 1b /* wait for acknowledge byte in sub comm port */
|
||||
move.b #0x00,0xA1200E /* acknowledge receipt of command result */
|
||||
2:
|
||||
move.w #0,0xA15120 /* done */
|
||||
bra main_loop
|
||||
|
||||
stop_music:
|
||||
tst.w cd_ok
|
||||
beq.b 2f
|
||||
0:
|
||||
move.b 0xA1200F,d1
|
||||
bne.b 0b /* wait until Sub-CPU is ready to receive command */
|
||||
|
||||
move.b #'S,0xA1200E /* set main comm port to StopPlayback command */
|
||||
1:
|
||||
move.b 0xA1200F,d0
|
||||
beq.b 1b /* wait for acknowledge byte in sub comm port */
|
||||
move.b #0x00,0xA1200E /* acknowledge receipt of command result */
|
||||
2:
|
||||
move.w #0,0xA15120 /* done */
|
||||
bra main_loop
|
||||
|
||||
@@ -347,10 +388,14 @@ vert_blank:
|
||||
bsr.b get_pad
|
||||
move.w d2,0xA1512A /* controller 2 current value */
|
||||
1:
|
||||
move.l 0xA1512C,d0
|
||||
addq.l #1,d0
|
||||
move.l d0,0xA1512C /* increment the vblank count */
|
||||
|
||||
tst.w gen_lvl2
|
||||
beq.b 2f
|
||||
lea 0xA12000,a0
|
||||
move.w (a0),d0
|
||||
ori.w #0x0100,d0
|
||||
move.w d0,(a0)
|
||||
2:
|
||||
move.l (sp)+,d2
|
||||
move.l (sp)+,d1
|
||||
movea.l (sp)+,a0
|
||||
@@ -543,6 +588,20 @@ mky_err:
|
||||
moveq #-1,d0
|
||||
rts
|
||||
|
||||
__m68k_end:
|
||||
|
||||
.align 4
|
||||
| Global variables for 68000
|
||||
|
||||
.align 4
|
||||
|
||||
vblank:
|
||||
dc.l 0
|
||||
|
||||
.global gen_lvl2
|
||||
gen_lvl2:
|
||||
dc.w 0
|
||||
|
||||
.global cd_ok
|
||||
cd_ok:
|
||||
dc.w 0
|
||||
|
||||
.align 4
|
110
src/platform/32x/src-md/kos.s
Normal file
110
src/platform/32x/src-md/kos.s
Normal file
@@ -0,0 +1,110 @@
|
||||
| ---------------------------------------------------------------------------
|
||||
| Kosinski decompression subroutine
|
||||
| void Kos_Decomp(uint8_t *src, uint8_t *dst)
|
||||
| Inputs:
|
||||
| 4(sp) = compressed data location
|
||||
| 8(sp) = destination
|
||||
| ---------------------------------------------------------------------------
|
||||
|
||||
.text
|
||||
|
||||
.global Kos_Decomp
|
||||
Kos_Decomp:
|
||||
movea.l 4(sp),a0
|
||||
movea.l 8(sp),a1
|
||||
movem.l d2-d6,-(sp)
|
||||
subq.l #2,sp /* make space for two bytes on the stack */
|
||||
move.b (a0)+,1(sp)
|
||||
move.b (a0)+,(sp)
|
||||
move.w (sp),d5 /* copy first description field */
|
||||
moveq #15,d4 /* 16 bits in a byte */
|
||||
|
||||
Kos_Decomp_Loop:
|
||||
lsr.w #1,d5 /* bit which is shifted out goes into C flag */
|
||||
move sr,d6
|
||||
dbra d4,Kos_Decomp_ChkBit
|
||||
move.b (a0)+,1(sp)
|
||||
move.b (a0)+,(sp)
|
||||
move.w (sp),d5 /* get next description field if needed */
|
||||
moveq #15,d4 /* reset bit counter */
|
||||
|
||||
Kos_Decomp_ChkBit:
|
||||
move d6,ccr /* was the bit set? */
|
||||
bcc.b Kos_Decomp_RLE /* if not, branch (C flag clear means bit was clear) */
|
||||
move.b (a0)+,(a1)+ /* otherwise, copy byte as-is */
|
||||
bra.b Kos_Decomp_Loop
|
||||
|
||||
| ---------------------------------------------------------------------------
|
||||
|
||||
Kos_Decomp_RLE:
|
||||
moveq #0,d3
|
||||
lsr.w #1,d5 /* get next bit */
|
||||
move sr,d6
|
||||
dbra d4,Kos_Decomp_ChkBit2
|
||||
move.b (a0)+,1(sp)
|
||||
move.b (a0)+,(sp)
|
||||
move.w (sp),d5
|
||||
moveq #15,d4
|
||||
|
||||
Kos_Decomp_ChkBit2:
|
||||
move d6,ccr /* was the bit set? */
|
||||
bcs.b Kos_Decomp_SeparateRLE /* if it was, branch */
|
||||
lsr.w #1,d5 /* bit which is shifted out goes into X flag */
|
||||
dbra d4,1f
|
||||
move.b (a0)+,1(sp)
|
||||
move.b (a0)+,(sp)
|
||||
move.w (sp),d5
|
||||
moveq #15,d4
|
||||
1:
|
||||
roxl.w #1,d3 /* get high repeat count bit (shift X flag in) */
|
||||
lsr.w #1,d5
|
||||
dbra d4,2f
|
||||
move.b (a0)+,1(sp)
|
||||
move.b (a0)+,(sp)
|
||||
move.w (sp),d5
|
||||
moveq #15,d4
|
||||
2:
|
||||
roxl.w #1,d3 /* get low repeat count bit */
|
||||
addq.w #1,d3 /* increment repeat count */
|
||||
moveq #-1,d2
|
||||
move.b (a0)+,d2 /* calculate offset */
|
||||
bra.b Kos_Decomp_RLELoop
|
||||
|
||||
| ---------------------------------------------------------------------------
|
||||
|
||||
Kos_Decomp_SeparateRLE:
|
||||
move.b (a0)+,d0 /* get first byte */
|
||||
move.b (a0)+,d1 /* get second byte */
|
||||
moveq #-1,d2
|
||||
move.b d1,d2
|
||||
lsl.w #5,d2
|
||||
move.b d0,d2 /* calculate offset */
|
||||
andi.w #7,d1 /* does a third byte need to be read? */
|
||||
beq.b Kos_Decomp_SeparateRLE2 /* if it does, branch */
|
||||
move.b d1,d3 /* copy repeat count */
|
||||
addq.w #1,d3 /* and increment it */
|
||||
|
||||
Kos_Decomp_RLELoop:
|
||||
move.b (a1,d2.w),d0
|
||||
move.b d0,(a1)+ /* copy appropriate byte */
|
||||
dbra d3,Kos_Decomp_RLELoop /* and repeat the copying */
|
||||
bra.b Kos_Decomp_Loop
|
||||
|
||||
| ---------------------------------------------------------------------------
|
||||
|
||||
Kos_Decomp_SeparateRLE2:
|
||||
move.b (a0)+,d1
|
||||
beq.b Kos_Decomp_Done /* 0 indicates end of compressed data */
|
||||
cmpi.b #1,d1
|
||||
beq.w Kos_Decomp_Loop /* 1 indicates a new description needs to be read */
|
||||
move.b d1,d3 /* otherwise, copy repeat count */
|
||||
bra.b Kos_Decomp_RLELoop
|
||||
|
||||
| ---------------------------------------------------------------------------
|
||||
|
||||
Kos_Decomp_Done:
|
||||
addq.l #2,sp /* restore stack pointer to original state */
|
||||
movem.l (sp)+,d2-d6
|
||||
rts
|
||||
|
||||
| End of function Kos_Decomp
|
130
src/platform/32x/src-md/main.c
Normal file
130
src/platform/32x/src-md/main.c
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* SEGA CD Mode 1 Support
|
||||
* by Chilly Willy
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
extern uint32_t vblank_vector;
|
||||
extern uint16_t gen_lvl2;
|
||||
extern uint16_t cd_ok;
|
||||
|
||||
extern uint32_t Sub_Start;
|
||||
extern uint32_t Sub_End;
|
||||
|
||||
extern void Kos_Decomp(uint8_t *src, uint8_t *dst);
|
||||
|
||||
extern void write_byte(unsigned int dst, unsigned char val);
|
||||
extern void write_word(unsigned int dst, unsigned short val);
|
||||
extern void write_long(unsigned int dst, unsigned int val);
|
||||
extern unsigned char read_byte(unsigned int src);
|
||||
extern unsigned short read_word(unsigned int src);
|
||||
extern unsigned int read_long(unsigned int src);
|
||||
|
||||
extern void do_main(void);
|
||||
|
||||
uint16_t InitCD(void)
|
||||
{
|
||||
char *bios;
|
||||
|
||||
/*
|
||||
* Check for CD BIOS
|
||||
* When a cart is inserted in the MD, the CD hardware is mapped to
|
||||
* 0x400000 instead of 0x000000. So the BIOS ROM is at 0x400000, the
|
||||
* Program RAM bank is at 0x420000, and the Word RAM is at 0x600000.
|
||||
*/
|
||||
bios = (char *)0x415800;
|
||||
if (memcmp(bios + 0x6D, "SEGA", 4))
|
||||
{
|
||||
bios = (char *)0x416000;
|
||||
if (memcmp(bios + 0x6D, "SEGA", 4))
|
||||
{
|
||||
// check for WonderMega/X'Eye
|
||||
if (memcmp(bios + 0x6D, "WONDER", 6))
|
||||
{
|
||||
bios = (char *)0x41AD00; // might also be 0x40D500
|
||||
// check for LaserActive
|
||||
if (memcmp(bios + 0x6D, "SEGA", 4))
|
||||
return 0; // no CD
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset the Gate Array - this specific sequence of writes is recognized by
|
||||
* the gate array as a reset sequence, clearing the entire internal state -
|
||||
* this is needed for the LaserActive
|
||||
*/
|
||||
write_word(0xA12002, 0xFF00);
|
||||
write_byte(0xA12001, 0x03);
|
||||
write_byte(0xA12001, 0x02);
|
||||
write_byte(0xA12001, 0x00);
|
||||
|
||||
/*
|
||||
* Reset the Sub-CPU, request the bus
|
||||
*/
|
||||
write_byte(0xA12001, 0x02);
|
||||
while (!(read_byte(0xA12001) & 2)) write_byte(0xA12001, 0x02); // wait on bus acknowledge
|
||||
|
||||
/*
|
||||
* Decompress Sub-CPU BIOS to Program RAM at 0x00000
|
||||
*/
|
||||
write_word(0xA12002, 0x0002); // no write-protection, bank 0, 2M mode, Word RAM assigned to Sub-CPU
|
||||
memset((char *)0x420000, 0, 0x20000); // clear program ram first bank - needed for the LaserActive
|
||||
Kos_Decomp((uint8_t *)bios, (uint8_t *)0x420000);
|
||||
|
||||
/*
|
||||
* Copy Sub-CPU program to Program RAM at 0x06000
|
||||
*/
|
||||
memcpy((char *)0x426000, (char *)&Sub_Start, (int)&Sub_End - (int)&Sub_Start);
|
||||
|
||||
write_byte(0xA1200E, 0x00); // clear main comm port
|
||||
write_byte(0xA12002, 0x2A); // write-protect up to 0x05400
|
||||
write_byte(0xA12001, 0x01); // clear bus request, deassert reset - allow CD Sub-CPU to run
|
||||
while (!(read_byte(0xA12001) & 1)) write_byte(0xA12001, 0x01); // wait on Sub-CPU running
|
||||
|
||||
/*
|
||||
* Set the vertical blank handler to generate Sub-CPU level 2 ints.
|
||||
* The Sub-CPU BIOS needs these in order to run.
|
||||
*/
|
||||
gen_lvl2 = 1; // generate Level 2 IRQ to Sub-CPU
|
||||
|
||||
/*
|
||||
* Wait for Sub-CPU program to set sub comm port indicating it is running -
|
||||
* note that unless there's something wrong with the hardware, a timeout isn't
|
||||
* needed... just loop until the Sub-CPU program responds, but 2000000 is about
|
||||
* ten times what the LaserActive needs, and the LA is the slowest unit to
|
||||
* initialize
|
||||
*/
|
||||
while (read_byte(0xA1200F) != 'I')
|
||||
{
|
||||
static int timeout = 0;
|
||||
timeout++;
|
||||
if (timeout > 2000000)
|
||||
{
|
||||
gen_lvl2 = 0;
|
||||
return 0; // no CD
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for Sub-CPU to indicate it is ready to receive commands
|
||||
*/
|
||||
while (read_byte(0xA1200F) != 0x00) ;
|
||||
|
||||
return 1; // CD ready to go!
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
cd_ok = 0; //InitCD();
|
||||
|
||||
/*
|
||||
* Main loop in ram - you need to have it in ram to avoid bus contention
|
||||
* for the rom with the SH2s.
|
||||
*/
|
||||
do_main(); // never returns
|
||||
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user