CDROM reading issue after subcpu halt
Moderator: Mask of Destiny
CDROM reading issue after subcpu halt
Héhé I canned FMV for now and tried to fix tavern rpg engine...
The major point is that the maincpu engine halt the subcpu to read/write to its ram (i cannot use the flip flop word ram, since its 100% full).
Okay, it appear to work pretty good on real hardware exept one thing:
When I halt/unhalt even once the subcpu, any attempt to read data off the disc hang (the red led stays on after halt).
Of course, sub cpu still run and can execute any type of "non-loading" commands
I tried to add a delay before each "halt", i also tried to disactivate Vint before "halting" but nothing really happen, still hang. So i suspected it could be cause of the crazy segacd bios... I added debug code everywhere (10KB of debug code out of 58KB) for almost all things... And figured out that subcpu hang at this point (when trying to read data again):
mcd_wait_cdc_stat();
And the code is :
/*
###################################################################
Wait CDC_STAT ARRIVE TO 1 O_o
CDC stat^^
entry : _CDBIOS
IN: d0.w : Function Number (cdcstat)
Out:cscc
Break : do/d1/a0/a1
Func :
CDCSTAT 00008AH Check if prepared data here or not
*/
.align 4
.globl mcd_wait_cdc_stat
mcd_wait_cdc_stat:
Check:
move.w #0x8A, %d0
jsr 0x5f22
bcs Check
rts
I assume that halting subcpu break something , so the wait_cdc_stat function loop forever or even hang inside the segacd bios...
I cross finguer that it simply loop forever...
Also, for segacd specialists, what should i do after detecting the error? I already tried to CDROM_stop and read again without success...
Thx a lot
Fonzie
The major point is that the maincpu engine halt the subcpu to read/write to its ram (i cannot use the flip flop word ram, since its 100% full).
Okay, it appear to work pretty good on real hardware exept one thing:
When I halt/unhalt even once the subcpu, any attempt to read data off the disc hang (the red led stays on after halt).
Of course, sub cpu still run and can execute any type of "non-loading" commands
I tried to add a delay before each "halt", i also tried to disactivate Vint before "halting" but nothing really happen, still hang. So i suspected it could be cause of the crazy segacd bios... I added debug code everywhere (10KB of debug code out of 58KB) for almost all things... And figured out that subcpu hang at this point (when trying to read data again):
mcd_wait_cdc_stat();
And the code is :
/*
###################################################################
Wait CDC_STAT ARRIVE TO 1 O_o
CDC stat^^
entry : _CDBIOS
IN: d0.w : Function Number (cdcstat)
Out:cscc
Break : do/d1/a0/a1
Func :
CDCSTAT 00008AH Check if prepared data here or not
*/
.align 4
.globl mcd_wait_cdc_stat
mcd_wait_cdc_stat:
Check:
move.w #0x8A, %d0
jsr 0x5f22
bcs Check
rts
I assume that halting subcpu break something , so the wait_cdc_stat function loop forever or even hang inside the segacd bios...
I cross finguer that it simply loop forever...
Also, for segacd specialists, what should i do after detecting the error? I already tried to CDROM_stop and read again without success...
Thx a lot
Fonzie
A couple thoughts:
Does your function keep looping or does it never return from the BIOS? Either way, the BIOS could be getting corrupted. Maybe you could try masking all interrupts on the subcpu before the halt.
Are you stopping the CD before the halt and restarting afterwards? If you're not stopping, it could be as easy as calling for a ROMPAUSE beforehand.
Does your function keep looping or does it never return from the BIOS? Either way, the BIOS could be getting corrupted. Maybe you could try masking all interrupts on the subcpu before the halt.
Are you stopping the CD before the halt and restarting afterwards? If you're not stopping, it could be as easy as calling for a ROMPAUSE beforehand.
Thx Tasco
I added PauseON and PauseOFF functions and it hang 50% of the time, again it ends in the wait_cdc_stat function... Even if i try to read again, it do very random result.
The first 3 loadings are ok... the 4th one got hang / corrupt 75% of time and the 5th one (after an halt/unhalt) hang 100% time.
hang = keeps looping in the wait_cdc_stat
It keeps looping in wait_cdc_stat... I tried to add a delay + init all stuff if delay over... Work very randomely and loop forever for the 5th loading everytime.
There is something extremely wrong somewhere in my process... absolutely... Maybe i call too many bios functions too fast... But there is no delay given in the documentation.
Well, i start to think (i was already thinking) that this f****g hardware isn't for me...
I added PauseON and PauseOFF functions and it hang 50% of the time, again it ends in the wait_cdc_stat function... Even if i try to read again, it do very random result.
The first 3 loadings are ok... the 4th one got hang / corrupt 75% of time and the 5th one (after an halt/unhalt) hang 100% time.
hang = keeps looping in the wait_cdc_stat
It keeps looping in wait_cdc_stat... I tried to add a delay + init all stuff if delay over... Work very randomely and loop forever for the 5th loading everytime.
There is something extremely wrong somewhere in my process... absolutely... Maybe i call too many bios functions too fast... But there is no delay given in the documentation.
Well, i start to think (i was already thinking) that this f****g hardware isn't for me...
Thx a lot Tasco .
I cleaned all my code, used CDBSTAT after every bios call to check that bios isn't busy anymore and bios achieved the function i want to
I now always pause_ON after each load and start a new READ (since pause_off seems to hang/loop at wait_cdb_stat).
It work perfect on Gens, but i got better result in real hardware
Now each loading (before subcpu halt) is 100% secure/reliable. With incredible speed However, it hang after I halt/unhalt the subcpu, here (in one of those two loops, situated at the begining of the loading function).
mcd_comreg_write(0xA1,0x14);
mcd_cd_rom_read(sectorfrom);
while((mcd_get_cdb_stat()&0x8000)==0x8000){}//Wait no more busy
while((mcd_get_cdb_stat()&0xFF)!=1){}//Wait reading again
So, the halt thing seems to hang something in the bios (even if the bios paused the read and said "i'm no more doing anything".
Any new idea? Should i add CDBCHK too?
I'm quite happy all appear fine with pause_on Still hang after a halt but quite happy ;P
I cleaned all my code, used CDBSTAT after every bios call to check that bios isn't busy anymore and bios achieved the function i want to
I now always pause_ON after each load and start a new READ (since pause_off seems to hang/loop at wait_cdb_stat).
It work perfect on Gens, but i got better result in real hardware
Now each loading (before subcpu halt) is 100% secure/reliable. With incredible speed However, it hang after I halt/unhalt the subcpu, here (in one of those two loops, situated at the begining of the loading function).
mcd_comreg_write(0xA1,0x14);
mcd_cd_rom_read(sectorfrom);
while((mcd_get_cdb_stat()&0x8000)==0x8000){}//Wait no more busy
while((mcd_get_cdb_stat()&0xFF)!=1){}//Wait reading again
So, the halt thing seems to hang something in the bios (even if the bios paused the read and said "i'm no more doing anything".
Any new idea? Should i add CDBCHK too?
I'm quite happy all appear fine with pause_on Still hang after a halt but quite happy ;P
-
- Very interested
- Posts: 616
- Joined: Thu Nov 30, 2006 6:30 am
Is there some way to temporarily disable interrupt generation from the CDC? If I had to take a wild guess, I'd say that the CDC has problems if it doesn't get a proper IRQ acknowledgement and I would imagine that the 68K doesn't generate an IRQ ack signal when it's halted. Since the CDC (or whatever logic handles interrupts generated by the CDC anyway) never got an ack for the original IRQ it's possible it won't generate any more. I seem to remember that most of the CD BIOS functions wait for data from the interrupt handlers. If the interrupts never fire, they'll hang forever.
I'm not sure if this is actually the case though. I've never done any low level interaction with the CD hardware so I'm not really in a position to test my hypothesis.
I'm not sure if this is actually the case though. I've never done any low level interaction with the CD hardware so I'm not really in a position to test my hypothesis.
-
- Very interested
- Posts: 616
- Joined: Thu Nov 30, 2006 6:30 am
Perhaps messing with this will get you your results. There's certainly plenty of room for it to not work even if the problem is interupt related, but it's worth a shot.Fonzie wrote:Yeah, there is an interupt masker
Yeah, every 1/75th of a second when you're reading data off the drive. Not sure what other interupts it generates though.And yeah, i confirm that the CDC generate interupts every few ms...
It's possible at least.Nice you think a interupt disknowledge could hang CDC Sounds good to me...
You mean 75 frames, and yes it is. It's a CDC decoder interrupt (CDC interrupt in the tech manual). Even if it keeps generating interrupts when the drive is paused, these interrupts can be disabled directly on the CDC.ob1 wrote:Aren't these interrupts frame interrupts ? Not frame as a frame per image, but frame as in the CD-audio specification ? A CD-audio is 73'59"and 74 frames. Each second is divided in 74 frame.Mask of Destiny wrote:Yeah, every 1/75th of a second when you're reading data off the drive.
Could it be ?
One of the other interrupts comes from the CDD and is the source of communication between the drive and bios. I'd guess the CDD is freaking out because it's left waiting for the subcpu. You can turn off this communication but I don't know if you can turn it back on... safely. I hope it doesn't come to that.
The other interrupt is the subcode interrupt but we shouldn't have to worry about that.
Ok, working now ... Yeppee
The trick :
-Mask all interupts before halting (writting 0xFFFF to the mask register, need to be verified because the documentation seems to sux).
-After unhalt, kick start the CDD.
It works on model2 hardware... however, it is unsure that it is perfect because kega shows a "open tray" icon everytime I kick start the cdd.
Thank a lot guys And my master, steve
Now need to fix other bugs (my maincpu code related)
The trick :
-Mask all interupts before halting (writting 0xFFFF to the mask register, need to be verified because the documentation seems to sux).
-After unhalt, kick start the CDD.
It works on model2 hardware... however, it is unsure that it is perfect because kega shows a "open tray" icon everytime I kick start the cdd.
Thank a lot guys And my master, steve
Now need to fix other bugs (my maincpu code related)
-
- Very interested
- Posts: 616
- Joined: Thu Nov 30, 2006 6:30 am
Save the (byte) value at $FF8033, write 0x7E to $FF8033, and, after the unhalt, restore the original value to $FF8033.Fonzie wrote:-Mask all interupts before halting (writting 0xFFFF to the mask register, need to be verified because the documentation seems to sux).
I'd really like to see the code.Fonzie wrote:-After unhalt, kick start the CDD.
Yeah, i'm writting 0xFFFF instead of 0x7E , but it is same result
Thank you for the confirmation.
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).
Here is my code for Halt/Unhalt preparation process Subcpu side of course.
Enjoy!
After kick start, the CDD appear to work again, no more hang héhé, magic
Thank you for the confirmation.
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).
Here is my code for Halt/Unhalt preparation process Subcpu side of course.
Code: Select all
if(command==0x0401)//Halting perparation requested
{
interruptmask=scpu_interruptmask[0];
scpu_interruptmask[0]=0xFFFF;
}
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!
}
After kick start, the CDD appear to work again, no more hang héhé, magic