aprentice
Moderator
KaioShin said:Apprentice I tried it with your emu and this is what I get:
BTW: I like this distorted Logo, so I made it my Avatar![]()
did you load a game and not the bootrom itself?
KaioShin said:Apprentice I tried it with your emu and this is what I get:
BTW: I like this distorted Logo, so I made it my Avatar![]()
HyperHacker said:The bootROM reads the Nintendo logo at $104. You need to load an actual game, then write the bootROM over the first $100 bytes. (Then when it writes 01 to $FF50, copy the start of the ROM back into that area. This is done right at $FE, so you don't need to perform a jump or anything.) If the logo or header checksum don't match it just goes into a jr-loop ($18, $FE), so you might be able to trap that and force-jump it out of the loop (modify PC manually), so that it still boots if the header is invalid.
aprentice said:did you load a game and not the bootrom itself?
bcrew1375 said:Tetris stays on the first text screen for about 5 seconds.
bcrew1375 said:KaioShin: The 3-5 bits are interrupt enable registers. 3 is for H-Blank, 4 is for V-Blank, 5 is for OAM. They request an LCDC interrupt depending on the mode. So, if bit 3 is on when the mode changes to H-Blank, an LCDC interrupt is requested. You would then treat it the same as an LY Coincidence interrupt.
if LCD is On
{
lcd-=cycles;
special handle of vblank for LY increment
if lcd<=0
{
//handling of all modes, and of couse lcd+=next mode ticks
}
}
if(cpu.LCDon)
{
cpu.count_stat-=cpu.cycles;
if(cpu.count_stat<=0)
{
switch(IOReg_STAT&0x03)
{
case 0:{ // HBlank
// --------------------------------
// increment LY each loop
IOReg_LY++;
// LY/LYC Coincidence???
if(IOReg_LYC==IOReg_LY) // LY compare
{
// set coincidence flag
IOReg_STAT|=BIT_2;
// request interrupt
if(IOReg_STAT&BIT_6) reqINT(BIT_1);
}else{
// reset coincidence flag
IOReg_STAT&=0xFB;
}
// time for vblank???
if(IOReg_LY>144){
vid.SetSTATMode(MODE_VBLANK);
cpu.count_stat+=CYCLES_VBLANK;
cpu.vblank_wait=1;
if(IOReg_STAT&BIT_3) reqINT(BIT_1);
}else{ // time for mode2, OAM transfer???
vid.SetSTATMode(MODE_OAMTRANSFER);
cpu.count_stat+=CYCLES_OAMTRANSFER;
if(!(IOReg_STAT&BIT_6) && IOReg_LYC && (IOReg_STAT&BIT_5))
reqINT(BIT_1); // fixes joust, altered space, homm
}
}break;
case 1:{ // VBlank
// --------------------------------
if(cpu.vblank_wait)
{
cpu.count_stat+=CYCLES_VBLANK;
reqINT(BIT_0);
if(IOReg_STAT&BIT_4)
reqINT(BIT_1);
if((IOReg_STAT&BIT_6) && (IOReg_STAT&BIT_2))
reqINT(BIT_1);
// ----------
// joypad interrupt shit here
// ----------
cpu.vblank_wait=0;
}
if(IOReg_LY<153){
++IOReg_LY;
if(IOReg_LY>=153) cpu.count_stat+=24;
else cpu.count_stat+=CYCLES_VBLANK;
}else{
// update user input
EventSDL();
// reset the LY register
IOReg_LY=0;
// goto mode2, oam transfer
vid.SetSTATMode(MODE_OAMTRANSFER);
cpu.count_stat+=CYCLES_OAMTRANSFER;
}
// LY/LYC Coincidence???
if(IOReg_LYC==IOReg_LY) // LY compare
{
// set coincidence flag
IOReg_STAT|=BIT_2;
// request interrupt
if(IOReg_STAT&BIT_6) reqINT(BIT_1);
}else{
// reset coincidence flag
IOReg_STAT&=0xFB;
}
}break;
case 2:{ // Searching OAM...
// --------------------------------
cpu.count_stat+=CYCLES_OAMTRANSFER;
cpu.draw_wait = 12;
// next mode...
vid.SetSTATMode(MODE_TRANSFER);
cpu.count_stat+=CYCLES_TRANSFER;
break;}
case 3:{ // Transfer
// --------------------------------
cpu.count_stat+=CYCLES_TRANSFER;
// next mode..
vid.SetSTATMode(MODE_HBLANK);
cpu.count_stat+=CYCLES_HBLANK;
if(IOReg_STAT&BIT_4)
reqINT(BIT_1);
break;}
}
}
if(cpu.draw_wait)
{
cpu.draw_wait -= cpu.cycles;
if(cpu.draw_wait <= 0)
{
cpu.draw_wait = 0;
if(IOReg_LY < 144)
{
vid.DrawScanline();
}
}
}
}
void VIDEO::SetSTATMode(int mode)
{
IOReg_STAT=(IOReg_STAT&0xFC)|mode; //Clear and set bits 0,1
switch(mode)
{
case 0: //HBlank
dbg_lcdc_phase=1;
if(IOReg_STAT&0x08) IOReg_IF|=BIT_1;
break;
case 1: //VBlank
dbg_lcdc_phase=4;
if(IOReg_STAT&0x10) IOReg_IF|=BIT_1;
break;
case 2: //OAM
dbg_lcdc_phase=2;
if(IOReg_STAT&0x20) IOReg_IF|=BIT_1;
break;
case 3: //Transfer
dbg_lcdc_phase=3;
//if(cpu.hdma&0x80) hdma_hblank();
break;
}
}