SEGA CD Mode 1

Ask anything your want about Mega/SegaCD programming.

Moderator: Mask of Destiny

TascoDLX
Very interested
Posts: 262
Joined: Tue Feb 06, 2007 8:18 pm

Post by TascoDLX » Tue Jan 03, 2012 1:31 pm

Nemesis wrote:I've tested the flux rom, and it can't boot a laseractive either. It starts, but none of the controls work, and it doesn't manage to read the track list.
Of course it doesn't. Flux has no idea where the subcpu bios is in the LaserActive boot rom.
Nemesis wrote:Best as I can figure, the sub-cpu does boot and start running code, but it can't talk to the CD hardware, and seems to lock up, or wait forever for some state which the hardware never reaches.
Well, it will loop until the subbios passes checksum. Note, you can disable checksum by writing #$0000 to $00018E of the subcpu bios. Other than that, it's probably a problem with the CDD, or some horrible hardware problem causing an exception.

Before you load up the subcpu bios and your SP, you should force a reset on the gate array. This is in the manual. Here's how you do it:

Code: Select all

move.w #$FF00, $A12002
move.b #$03, $A12001
move.b #$02, $A12001
move.b #$00, $A12001
EXACTLY like that. This will force the system to reset the entire gate array. Then go about loading it as you were. It should work.

If you're feeling crafty, you could hack the subbios to verify that comm is working. Really, you just replace the bios with a short little program that writes to the comm area and, if it shows up on the main side, it works.
Nemesis wrote:Oh, and since we've been talking about the LaserActive, I should note that the LaserActive bios has half disabled mode 1 boot support. The bios still has the code to test for a mode 1 boot cart, and jump to 0x400200 to boot it, but the code which loads the sub-cpu program has been removed. This means you should be able to boot the system, but you won't be able to load a sub-cpu program automatically on boot up.
Yes, that's it. Same with the model 2 bios, etc. Theoretically, this means you can't skip the region protection without "hacking" your way into the bios, like Flux does (like Pier Solar does).
Chilly Willy wrote:I noticed that "attempt to run special cart at 0x400200" as well, but put it down to a BRAM cart that needed custom read/write code.
Yes, they are not related, but about the BRAM cart: I'm surprised no one has tried to make a BRAM cart with a custom handler (at least I haven't heard any mention of one). The documentation is pretty good and you can do a lot to extend the storage. I think installing a custom handler is possible on most if not every bios.

Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Wed Jan 04, 2012 11:20 am

Ok, some quick updates:

Your boot loader code now works on a LaserActive Chilly Willy, with some modifications. Loading the MegaLD sub-cpu bios first is not required, but doing a full clear of, at the very least, the first page of program ram is required, otherwise the sub-cpu bios hangs on initialization. I also added in the forced reset of the gate array, as per what TascoDLX posted, as I noticed in my disassembly of the MegaLD bios that it always does this when loading the sub-cpu bios. One modification you also need to make to your bootloader is with the timeout setting waiting for the sub-cpu to initialize. Your value of 20000 iterations isn't long enough for the LaserActive, the hardware seems slower to initialize than other systems. My tests show that it never seems to reach 200000 iterations, but I made modifications to your code to make it try and continue regardless. I'd suggest doing something like that for "production" code, since there may be other hardware quirks or delays which can cause much longer initialization times, which we aren't aware of yet.

I've also been writing my own mode 1 boot loader for the MegaCD, since before this thread was created, and as of tonight, I have it working as well. I've managed to get my dumping program working for normal MegaCD disks when booting from the cart, and I'm making very good progress with dumping MegaLD disks. At this stage, I can open the LD drive tray and load a new disk, I just need to work out the bios command to read data from the disk. The command I thought was for reading data starts the first video track playing when I call it. I'll do more analysis of the MegaLD sub-cpu bios tomorrow and try and figure out the right command.

Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Wed Jan 04, 2012 11:22 am

Oh, I should add, I'll be posting all the source for the working boot loaders soon, I just need to clean them up a bit more first. They've got my debug code and old bits of junk scattered all through them. I'll post the cleaned up proven working code as soon as I have it ready.

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Wed Jan 04, 2012 7:08 pm

Great news! I knew the community would work out any issues once SOMETHING was released. :D

I mostly put the timeout in my code for debug purposes. I figured it was probably "wrong" as it timed out on me a few times until I got to the value it currently is. I figured it would not be included in a "real" app, or made bigger for worst case situations.

EDIT: Nemesis, try this out to see if it works on the LA. It has the changes you talked about. It also has a big comment on the fact that the timeout shouldn't be needed, but is currently 10 times what the LA seems to need.

http://www.mediafire.com/download.php?ab0n2vukcu9aobl

TascoDLX
Very interested
Posts: 262
Joined: Tue Feb 06, 2007 8:18 pm

Post by TascoDLX » Wed Jan 04, 2012 10:22 pm

Nemesis wrote:Loading the MegaLD sub-cpu bios first is not required, but doing a full clear of, at the very least, the first page of program ram is required, otherwise the sub-cpu bios hangs on initialization.
Here's your bug confirmation:

The model 1 bios decompresses the subcpu bios to a full 22KB, with 14 trailing zero bytes. Range is $000000 thru $0057FF.

The laseractive bios decompresses the subcpu (CD) bios without the 14 trailing zero bytes. Range is $000000 thru $0057F1.

Since the checksum is calculated from $000200 thru $0057FF, those 14 zero bytes are fairly important. You probably don't need to clear any more than that as far as the bios is concerned.
Nemesis wrote:At this stage, I can open the LD drive tray and load a new disk, I just need to work out the bios command to read data from the disk. The command I thought was for reading data starts the first video track playing when I call it.
If you want more extensive notes on the LD bios, I might be able to help. The stuff I posted in the other thread is pretty condensed.

Chilly:

From your revised code,

Code: Select all

	/*
	 * 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);
That brings up an interesting point. I don't know if the reset sequence has any timing requirements. The manual seems to indicate that the assembly sequence is the only way to do it, so it's hard to say whether or not this is effective. It may be something to test at some point in the future. Also in question is whether or not this is actually neccessary from a hard reset. Maybe not a big deal at this point, but something to keep an eye on.

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Wed Jan 04, 2012 10:44 pm

Thanks for pointing that out - if it doesn't work for Nemesis on his LA, I'll make that part assembly and try again.

As to why you need to clear the ram, that's one of those "whoopsi!" events. :lol: Seriously, checking the checksum over a range not covered by the archived code? How hard would it have been to add 14 zeroes COMPRESSED to the compressed bios? Someone did the compressed block and then probably didn't notice their error because the clearing code covered for them.

Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Wed Jan 04, 2012 11:11 pm

TascoDLX wrote:The model 1 bios decompresses the subcpu bios to a full 22KB, with 14 trailing zero bytes. Range is $000000 thru $0057FF.

The laseractive bios decompresses the subcpu (CD) bios without the 14 trailing zero bytes. Range is $000000 thru $0057F1.

Since the checksum is calculated from $000200 thru $0057FF, those 14 zero bytes are fairly important. You probably don't need to clear any more than that as far as the bios is concerned.
Aha, good to know. I was wondering what the cause was.
TascoDLX wrote:
Nemesis wrote: At this stage, I can open the LD drive tray and load a new disk, I just need to work out the bios command to read data from the disk. The command I thought was for reading data starts the first video track playing when I call it.
If you want more extensive notes on the LD bios, I might be able to help. The stuff I posted in the other thread is pretty condensed.
More notes would be great, the more the better. That said, I think I've found the cause of my troubles. I think you're right about 0x0120 being the code for the ROMREAD function, but they've changed the arguments. The function now needs a mode flag as a parameter to select between ROMREAD, ROMREADN, and ROMREADE, and there's only a single entry point.

I've made and been using an LDBIOS.INC file for my code, which I've based on the official CDBIOS.INC file from Sega's SDK. Here's my notes for the ROMREAD function on the LaserActive, as I typed them up this morning:

Code: Select all

;----------------------------------------------------------------------- 
; BIOS_ROMREAD - Begins reading data from the CDROM at the designated 
; logical sector. The read continues until either no more data is
; received, the specified number of sectors have been read, or the
; target sector has been reached, dependending on the value specified in
; the ROMREADMODE flag.
; 
; input: 
;   d0.w  ROMREADMODE flag. If invalid, acts as if d1 != 0.
;   d1.b  Video playback flag? Seems to start video playing if not equal to 0.
;   a0.l  The way this is interpreted depends on the value of d0
;     d0.w = ROMREADMODE_D ($120):
;       a0.l  address of a 32 bit logical sector number to read from
;     d0.w = ROMREADMODE_N ($121):
;       a0.l  address of a 32 bit sector number and 32 bit sector count 
;           dc.l    $00000001   ; First sector to read 
;           dc.l    $00001234   ; Number of sectors to read 
;     d0.w = ROMREADMODE_E ($122):
;       a0.l  address of table of 32 bit logical sector numbers 
;           dc.l    $00000001   ; First sector to read 
;           dc.l    $00000123   ; Last sector to read 
; 
; returns: 
;   cc  Command has been executed 
;   cs  Failure (Arguments were invalid) 
;   d1.w Result: 
;           $0000 = Command has been executed 
;           $0100 = Failure (Arguments were invalid) 
;----------------------------------------------------------------------- 
I'm going to try running my dumping program again this evening using these results, and see if I can successfully read data off the disk.
Chilly Willy wrote:Thanks for pointing that out - if it doesn't work for Nemesis on his LA, I'll make that part assembly and try again.

As to why you need to clear the ram, that's one of those "whoopsi!" events. :lol: Seriously, checking the checksum over a range not covered by the archived code? How hard would it have been to add 14 zeroes COMPRESSED to the compressed bios? Someone did the compressed block and then probably didn't notice their error because the clearing code covered for them.
Well, I've noticed both the LaserActive bios and the standard MegaCD bioses clear the entire range of program memory in all 4 banked pages on doing a reset, it just happens in slightly different places in the code. That was probably just a bug they never knew was there, because they were always clearing the memory from day one. I'm doing a full clear of all 4 memory pages in my boot code, just in case.

In terms of bugs, I've also noticed there was code that was supposed to clear the full word ram when doing a reset, but it was completely broken in all the 1.X MegaCD bios versions, including on the LaserActive. Check the subroutine at 0x79C in the v1.00 USA SegaCD bios. Not only were they testing $A12002 (the write protect register) instead of $A12003 when trying to check if the word ram mode and assignment status, they also wrote the clear data to (a0) instead of (a0)+, so at best, it would only have cleared the first long-word of the word ram. They didn't fix this until the v2.XX bios versions. I'm sure there are more than a few other bugs in there.
TascoDLX wrote:...I don't know if the reset sequence has any timing requirements...
I want to do more testing on that later too, I suspect the timing isn't important, just the order. If I was to speculate, I'd say that internally, a reset is performed if the device responsible sees the sequence of writes 0x03, 0x02, 0x00 to register 0xA12001, while the write protect flags are all set. I suspect doing repeated writes of 0x03, 0x02, 0x00 will continue to perform a reset, as long as the write protect flags all remain set, and I suspect doing full word-wide writes of 0xFF03, 0xFF02, 0xFF00 to 0xA12000 would work too. This is all speculation though.

Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Thu Jan 05, 2012 12:42 am

My notes above on the ROMREAD function in the LaserActive is wrong. There is one entry point for all the ROMREAD functions, but there's no mode parameter in D0. D0 is of couse the function code itself, so all the testing of D0 is just testing the function code, to check if it's 0x120, 0x121, or 0x122, to select between ROMREAD, ROMREADN, and ROMREADE after the entry point to the handler function. There is an extra parameter, D1, however, which needs to be set to 0. I didn't do this in my code previously, so I'm still hopeful I'll find it works correctly just by clearing D1 before the call.

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Thu Jan 05, 2012 4:29 am

Have you had a chance to try my last code? I wanted to update my threads if it worked on your LA. Thanks.

Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Thu Jan 05, 2012 10:20 am

Have you had a chance to try my last code? I wanted to update my threads if it worked on your LA. Thanks.
Just tested it then, yep, works great. :)

My reading of the MegaLD disk is not going quite so well. I didn't spot that the d1 register is actually the return from a subroutine call, which is checking and interacting with the MegaLD hardware registers at 0xFDFE**, and that call is returning an error. Seems like I need to do something else to setup the hardware for a read before calling the ROMREAD bios functions. Need to do more investigation...

TascoDLX
Very interested
Posts: 262
Joined: Tue Feb 06, 2007 8:18 pm

Post by TascoDLX » Thu Jan 05, 2012 12:55 pm

Nemesis wrote:Seems like I need to do something else to setup the hardware for a read before calling the ROMREAD bios functions.
Did you call DRVINIT first, and did it succeed without error?

There's some other stuff you can try calling beforehand that may or may not be helpful:

Code: Select all

jsr $5f22 : d0.w = #$011F, d1.b = #$01
jsr $5f22 : d0.w = #$0161, d1.b = #$01
jsr $5f22 : d0.w = #$012E, d1.b = #$01
If any of these calls set the carry flag, just retry it.

This is all just a guess based on some of the bios code. Not that I know what any of these calls do. I thought that 0161 sets PSC (Picture Stop Cancel), so that seems interesting.

EDIT:

Also maybe...

Code: Select all

jsr $5f22 : d0.w = #$012F, d1.b = #$04
after DRVINIT succeeds.

If you want to continue this part of the discussion in the LaserActive thread, that'd be fine. I think we've veered a little OT.
Last edited by TascoDLX on Fri Jan 06, 2012 6:07 am, edited 1 time in total.

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Thu Jan 05, 2012 4:47 pm

Nemesis wrote:
Have you had a chance to try my last code? I wanted to update my threads if it worked on your LA. Thanks.
Just tested it then, yep, works great. :)
Thanks. :D

Ti_
Very interested
Posts: 97
Joined: Tue Aug 30, 2011 7:50 am
Contact:

Post by Ti_ » Wed Mar 14, 2012 7:56 am

Kega Fusion 3.64 DMA from ROM stop working when loading Audio CD.
It's a bug or feature?

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Wed Mar 14, 2012 8:25 pm

Depends on if Snake wants to fix it or not... if he will, it's a bug, if not, it's a feature. :wink: :lol:

Fusion also doesn't do mode 1 in 32X cart mode, which also needs fixing.

Ti_
Very interested
Posts: 97
Joined: Tue Aug 30, 2011 7:50 am
Contact:

Post by Ti_ » Wed Mar 14, 2012 9:22 pm

Chilly Willy wrote:Depends on if Snake wants to fix it or not... if he will, it's a bug, if not, it's a feature. :wink: :lol:

Fusion also doesn't do mode 1 in 32X cart mode, which also needs fixing.
I've also tested netplay bugged in that mode, games no resets at start..
so..looks like there's no way to play with mode1.

Can you ask Steve Snake to fix it? or 3.64 is final version?
p.s. and also will be fine to add option to unlock more than 20 sprites per scanline.

Post Reply