CD Initial Program (IP) trying to write to ROM

Ask anything your want about Mega/SegaCD programming.

Moderator: Mask of Destiny

Post Reply
DarkMorford
Interested
Posts: 15
Joined: Tue Mar 17, 2015 4:09 pm
Location: Redmond, WA

CD Initial Program (IP) trying to write to ROM

Post by DarkMorford » Wed Jul 22, 2015 8:51 pm

In working on my BIOS disassembly, I've started taking a look at some commercial software to see how they interact with it. I came across this curious bit of code in the IP of "Penn and Teller's Smoke & Mirrors," and I'm not quite sure what to make of it.

Code: Select all

loc_FF0000:
	; Disable all interrupts
	move #$2700, sr

	movea.l #GATE_ARRAY, a5
	move.w  #0,     GA_OFF_MAINCOMM(a5)
	move.w  #$FD0C, GA_OFF_HINT_VECTOR(a5)

	; Clear bytes $FF0FBE and byte_FF0FBF
	bsr.w sub_FF02D4

	; Clear RAM from long_FF0F80-$FF1000
	lea (long_FF0F80).l, a0
	move.w #$1F, d1
	moveq  #0,   d0

	@loc_FF0026:
		move.l d0, (a0)+
		dbf d1, @loc_FF0026

	; Get the status of controller #1
	move.w #$100, (Z80_BUSREQ).l
	move.w #$100, (Z80_RESET).l

	@loc_FF003C:
		btst  #0, (Z80_BUSREQ).l
		bne.s @loc_FF003C

	lea (JOYDATA1).l, a0
	bsr.w readJoypad

	move.w #0, (Z80_BUSREQ).l

	; Test A button on controller 1
	btst #6, d0

	move.b d0, ($108000).l

	lea (0).l, a0
	move.w (a0), d0
	addi.w #1, (a0)
	cmp.w  (a0), d0
	beq.w  loc_FF0150

	move.w d0, (a0)

	move.l #$210800C, (8).l
	move.l #$310800C, ($C).l
	move.l #$410800C, ($10).l
	move.l #$510800C, ($14).l
	move.l #$610800C, ($18).l
	move.l #$710800C, ($1C).l
	move.l #$810800C, ($20).l
	move.l #$910800C, ($24).l
	move.l #$108008,  ($80).l

	move.b d0, ($10F001).l

	move.w #$4E40, (loc_FF02AE).l

	<snip>
This is loaded into the main CPU's work RAM at 0xFF0000, and it runs from there.

The first half of that makes sense to me, but it gets all wonky after reading the controller port. It doesn't release the Z80 from its RESET state, checks for a button press and does nothing with it, writes to a couple of locations (0x108000 and 0x10F001) that are in "Reserved by system" address space, and tries to overwrite the vector table (which is part of the boot ROM and thus read-only) with locations that are not in the 68k's addressable space (e.g., 0x210800C is higher than the 68k's maximum of 0xFFFFFF).

Can any of you guys make sense of this? It's driving me up the wall...

Mask of Destiny
Very interested
Posts: 615
Joined: Thu Nov 30, 2006 6:30 am

Post by Mask of Destiny » Wed Jul 22, 2015 9:08 pm

I think the Z80's reset pin is active low, so writing a one is actually releasing reset not asserting it.

I would guess that the code that tries to write to address 0 is checking whether the code is running on some kind of development system on which the BIOS is actually RAM. You can see it attempt to increment the value at address 0 and then compares it to the value that was previously at address 0.

As for the large address thing, the 68000 completely ignores the upper 8 bits of an address, so 0x210800C is equivalent to 10800C

DarkMorford
Interested
Posts: 15
Joined: Tue Mar 17, 2015 4:09 pm
Location: Redmond, WA

Post by DarkMorford » Wed Jul 22, 2015 9:30 pm

Mask of Destiny wrote:I think the Z80's reset pin is active low, so writing a one is actually releasing reset not asserting it.
Ah, that's right. I keep forgetting that the bus-request and reset lines are opposites, and I was thrown off because it didn't follow the "normal" sequence for talking to the Z80.
I would guess that the code that tries to write to address 0 is checking whether the code is running on some kind of development system on which the BIOS is actually RAM. You can see it attempt to increment the value at address 0 and then compares it to the value that was previously at address 0.
That makes sense. If that's the case, it looks like it'll jump to loc_FF0150 of it detects that the BIOS is in fact ROM. And the code at that point makes sense to me again. ;)
As for the large address thing, the 68000 completely ignores the upper 8 bits of an address, so 0x210800C is equivalent to 10800C
D'oh! I knew that; I'm just so used to seeing FF in the high byte that it didn't click that this was the same thing. That said, 0x10800C is still in the "Reserved by system" address space, and it is trying to write the controller state to 0x108000 (also in reserved space) before doing the ROM/RAM check. I don't remember reading anything about that space mirroring a different section of RAM; is there something undocumented mapped in there?

Eke
Very interested
Posts: 884
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Fri Jul 24, 2015 11:03 am

DarkMorford wrote:That said, 0x10800C is still in the "Reserved by system" address space, and it is trying to write the controller state to 0x108000 (also in reserved space) before doing the ROM/RAM check. I don't remember reading anything about that space mirroring a different section of RAM; is there something undocumented mapped in there?
viewtopic.php?t=1276

0x10800C is same as 0x800C which is within BOOT ROM
on a dev unit, it's possible RAM is mapped there instead of ROM but it's unlikely the mirroring is different (expansion port and main ASIC only got VA1-VA17 + chip selects to distinguish between lower and upper 2MB area)

Post Reply