CDROM reading issue after subcpu halt

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 Feb 13, 2007 4:35 am

Fonzie wrote:After not receiving reply from the bios, the CDD stops to work... Thanks to the method of steve, i fixed the problem (partialy since it shows a "open tray" on KEGA, seems wierd).
That's pretty much how I thought it would look.

I suggest that you test this on a model 1 Mega-CD because it may in fact eject the disc -- it's just the way the bios works. If this happens, we may be able to come up with a workaround.

Fonzie
Genny lover
Posts: 323
Joined: Tue Aug 29, 2006 11:17 am
Contact:

Post by Fonzie » Tue Feb 13, 2007 10:34 am

Yeah, Kega say "disc ejected"...
I cannot check on model1 hardware.

Steve told me that it would be cause of some data left in the CDD registers...
Any idea how to fix that?


I mean, i'm sure some games use the subcpu Halt function, how they do? :D héhé

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

Post by TascoDLX » Tue Feb 13, 2007 6:49 pm

Before we go nuts...
Fonzie wrote:

Code: Select all

else if(command==0x0402)//UnHalting perparation requested
{
      scpu_interruptmask[0]=interruptmask;

      pc=(unsigned char*)0xFF8037;
      *pc=0x0;
      for(i=0;i<32;i++){asm("nop");}
      *pc=0x4; //Kick start CDD!
}
Try kick starting the CDD *before* unmasking interrupts and let me know if you get the same result.

Fonzie
Genny lover
Posts: 323
Joined: Tue Aug 29, 2006 11:17 am
Contact:

Post by Fonzie » Tue Feb 13, 2007 9:30 pm

Ok :)

Code: Select all

pc=(unsigned char*)0xFF8037;
*pc=0x0;
for(i=0;i<32;i++){asm("nop");}
*pc=0x4; //Kick start CDD!
for(i=0;i<32;i++){asm("nop");}
scpu_interruptmask[0]=interruptmask;
I tried that, kega still says "tray opened", "tray closed"... I cannot check on real hardware actualy.
Before we go nuts...
You are already bored? :) :D

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

Post by TascoDLX » Tue Feb 13, 2007 10:55 pm

Fonzie wrote:I tried that, kega still says "tray opened", "tray closed"... I cannot check on real hardware actualy.
Before we go nuts...
You are already bored? :) :D
Quite the contrary... this is where the fun begins.

The cause seems to be an abrupt change in the CDD status. I don't know the exact status after a CDD reset but we might be able to keep the bios from freaking out. Hopefully we won't have to hack into the bios.

Here's something to try. Before trying the following, the drive needs to be paused with ROMPAUSEON to where CDBSTAT returns 0505 (paused in data mode). If CDBSTAT reads as stopped [0000], this probably won't work.

Before disabling interrupts:

- call CDBPAUSE with value 0
- call CDBSTAT until drive is stopped (status == 0000)
- disable interrupts immediately
- call CDBPAUSE with value 4500 [decimal] <restores the default value>

You can then halt and do whatever you need. After you unhalt the subcpu, just do as before: kick start the CDD then unmask interrupts. You can try it without the kick start but I think we figured out that it needs to be reset.

Good luck. It gets messy from here on out. :)

Fonzie
Genny lover
Posts: 323
Joined: Tue Aug 29, 2006 11:17 am
Contact:

Post by Fonzie » Thu Feb 15, 2007 11:12 pm

Quite the contrary... this is where the fun begins.
Héhé :D we should make a "wecome to the nuts level membership" in this board.

I'm going to try this soon :) Thx a lot :)

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

Post by TascoDLX » Wed Feb 28, 2007 7:25 am

*bump* :wink:

Fonzie
Genny lover
Posts: 323
Joined: Tue Aug 29, 2006 11:17 am
Contact:

Post by Fonzie » Sun Mar 11, 2007 4:49 pm

Sure, I don't forget... But I actualy have a bug around Lzss decoding... A bug that only happen on real hardware (and on a C code).

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

Post by TascoDLX » Sun Mar 11, 2007 9:54 pm

OK... let me know if I can help.

Fonzie
Genny lover
Posts: 323
Joined: Tue Aug 29, 2006 11:17 am
Contact:

Post by Fonzie » Sat Mar 31, 2007 7:55 pm

Ok, i started to apply your code, digging in some old sega archive to know the cdbpause process...

I found this :
; BIOS_CDBPAUSE - Sets the delay time before the BIOS switches from
; pause to standby. Normal ranges for this delay time are $1194 - $FFFE.
; A delay of $FFFF prevents the drive from stopping, but can damage the
; drive if used improperly.
;
; input:
; d1.w 16 bit delay time
;
; returns:
; nothing
Do you mean you want to stop the cdrom drive spinning (standby) before halting?
Because, i may call halt quite oftenly so going to simple pause mode is ok but going to standby mode each time may slowdown a lot or even hang the hardware.

There is really no other solution? In fact, actualy, it works good in model2 hardware and gens.. only say "tray opened" on kega (and model1 hardware?) after the kick start...

Thank you very much

Fonzie

Fonzie
Genny lover
Posts: 323
Joined: Tue Aug 29, 2006 11:17 am
Contact:

Post by Fonzie » Mon Apr 02, 2007 8:37 pm

Ok, I had to ask to the master of the masters ^^ Steve Snake :P
There were an easy solution, I explain:
The cdd have several registers (10 of them) that have data inside... When you kick start, it will imediately take this garbage data for "commands" and it appeared that one register had a "open tray" command left inside... The trick is to set all the registers to 0 (0 = no command), so when kicking start, nothing happen.

I did not check yet if its ok on real hardware, but now kega no more say "tray opened"... I'm so happy :D Thank you all. Big thanks to you, Tasco and a big kiss to Steve for the info :'D

Code: Select all

                        else if(command==0x0402)//UnHalting perparation requested
                          {
                            scpu_interruptmask[0]=interruptmask;
                            pc=(unsigned char*)0xFF8037;
                            *pc=0x0;
                            for(i=0;i<32;i++){asm("nop");}
                            pc=(uchar*) 0xff8038;
 
                            for(i=0;i<0xa;i++){*pc=0;pc++;}//Clear all nasty cdd commands

                            *pc=0x4; //Kick start CDD!
                            for(i=0;i<32;i++){asm("nop");}
                          }

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

Post by TascoDLX » Tue Apr 03, 2007 5:07 am

Great news!

Pretty simple explanation: a status byte turns into a command byte. Though it does seem like a Kega bug as I wouldn't expect the actual hardware to process this phony command. But maybe it does -- just seems kinda quirky.

BTW, your code is getting sloppy:

Code: Select all

                        else if(command==0x0402)//UnHalting perparation requested
                          {
                            scpu_interruptmask[0]=interruptmask;
                            pc=(unsigned char*)0xFF8037;
                            *pc=0x0;
                            for(i=0;i<32;i++){asm("nop");}
                            pc=(uchar*) 0xff8038;
 
                            for(i=0;i<0xa;i++){*pc=0;pc++;}//Clear all nasty cdd commands

                            *pc=0x4; //Kick start CDD!
                            for(i=0;i<32;i++){asm("nop");}
                          } 
Naturally, you should unmask the interrupts *after* you kick start the CDD. Also (I really shouldn't have to point this out)...

Code: Select all

                            pc=(uchar*) 0xff8038;
 
                            for(i=0;i<0xa;i++){*pc=0;pc++;}//Clear all nasty cdd commands

                            *pc=0x4; //Kick start CDD!
Well, it's pretty obvious.

Fonzie
Genny lover
Posts: 323
Joined: Tue Aug 29, 2006 11:17 am
Contact:

Post by Fonzie » Tue Apr 03, 2007 7:22 am

tss tss ;) yeah, shame on me, just call this an half kick start ;) ...
I fixed it , and of course, the tray-open error appeared again... I'm so stupid and sad..
I tried to clear before, right between, with delay or not... no luck..
(I really shouldn't have to point this out)..
No, nice you did... With pointers, i always do the most dumb errors...
I have an issue in my megacart firmware that i could never fix, probably a pointer thing again...


Thx

Fonz

Fonzie
Genny lover
Posts: 323
Joined: Tue Aug 29, 2006 11:17 am
Contact:

Post by Fonzie » Tue Apr 03, 2007 9:06 pm

Okay, Defintively fixed ^^

Code: Select all

                        else if(command==0x0402)//UnHalting perparation requested
                          {
                            scpu_interruptmask[0]=interruptmask;
                           // pc=(unsigned char*)0xFF8037;
                           // *pc=0x0;
                            for(i=0;i<32;i++){asm("nop");}
                            pc=(uchar*) 0xff8038;
                            for(i=0;i<0xc;i++){*pc=0;pc++;}//Clear all nasty cdc commands
                            pc=(unsigned char*)0xFF8037;
                            *pc=0x4; //Kick start CDD!
                            for(i=0;i<32;i++){asm("nop");}
                          }
Writting 0 apparently drives the hardware mad because he absolutely want to open the tray for no reason... Still no clue how the cdd is kicked start in that way but it work and that's all ^^

I checked on kega, gens and hardware model2... Should be fine :)

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

Post by TascoDLX » Wed Apr 04, 2007 12:31 am

Just to be certain, you might wanna try:

Code: Select all

                           pc = (unsigned char*)0xFF8037;
                           *pc &= 0xFB;

Code: Select all

                            pc = (unsigned char*)0xFF8037;
                            *pc |= 0x04; //Kick start CDD!
But, hey, as long as it works... :D

Post Reply