perfect vsync, bugfixes
[fceu.git] / boards / sl1632.c
CommitLineData
e2d0dd92 1/* FCE Ultra - NES/Famicom Emulator
2 *
3 * Copyright notice for this file:
4 * Copyright (C) 2005 CaH4e3
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "mapinc.h"
22
23static uint8 chrcmd[8], prg0, prg1, brk, mirr;
24static uint8 reg[8], cmd;
25static uint8 IRQCount,IRQLatch,IRQa;
26static uint8 IRQReload;
27static SFORMAT StateRegs[]=
28{
29 {reg, 8, "MMCREG"},
30 {&cmd, 1, "MMCCMD"},
31 {chrcmd, 8, "CHRCMD"},
32 {&prg0, 1, "PRG0"},
33 {&prg1, 1, "PRG1"},
34 {&brk, 1, "BRK"},
35 {&mirr, 1, "MIRR"},
36 {&IRQReload, 1, "IRQR"},
37 {&IRQCount, 1, "IRQC"},
38 {&IRQLatch, 1, "IRQL"},
39 {&IRQa, 1, "IRQA"},
40 {0}
41};
42
43static void Sync(void)
44{
45// if(brk&2)
46// {
47// setprg16(0x8000,~0);
48// setprg16(0xC000,~0);
49// }
50// else
51 {
52 setprg8(0x8000,prg0);
53 setprg8(0xA000,prg1);
54 }
55 int i;
56 for(i=0; i<8; i++)
57 setchr1(i<<10,chrcmd[i]);
58 setmirror(mirr^1);
59}
60
61static void Sync2(void)
62{
63 setprg8(0x8000,reg[6]&0x3F);
64 setprg8(0xA000,reg[7]&0x3F);
65 setchr2(0x0000,reg[0]>>1);
66 setchr2(0x8000,reg[1]>>1);
67 setchr1(0x1000,reg[2]);
68 setchr1(0x1400,reg[3]);
69 setchr1(0x1800,reg[4]);
70 setchr1(0x1C00,reg[5]);
71 setmirror(mirr^1);
72}
73
74static DECLFW(UNLSL1632CMDWrite)
75{
76 FCEU_printf("bs %04x %02x\n",A,V);
77// if((A&0xA131)==0xA131) brk=V;
78 if((A&0xA131)==0xA131) brk=V;
79 if(brk==2)
80 {
81 switch(A&0xE001)
82 {
83 case 0x8000: cmd=V&7; break;
84 case 0x8001: reg[cmd]=V; Sync(); break;
85 case 0xA000: mirr=V&1; break;
86 case 0xC000: IRQLatch=V; break;
87 case 0xC001: IRQReload=1; break;
88 case 0xE000: X6502_IRQEnd(FCEU_IQEXT); IRQa=0; break;
89 case 0xE001: IRQa=1; break;
90 }
91 Sync2();
92 }
93 else
94 {
95 switch(A&0xF003)
96 {
97 case 0x8000: prg0=V; break;
98 case 0xA000: prg1=V; break;
99 case 0x9000: mirr=V&1; break;
100 case 0xB000: chrcmd[0]=(chrcmd[0]&0xF0)|(V&0x0F); break;
101 case 0xB001: chrcmd[0]=(chrcmd[0]&0x0F)|(V<<4); break;
102 case 0xB002: chrcmd[1]=(chrcmd[1]&0xF0)|(V&0x0F); break;
103 case 0xB003: chrcmd[1]=(chrcmd[1]&0x0F)|(V<<4); break;
104 case 0xC000: chrcmd[2]=(chrcmd[2]&0xF0)|(V&0x0F); break;
105 case 0xC001: chrcmd[2]=(chrcmd[2]&0x0F)|(V<<4); break;
106 case 0xC002: chrcmd[3]=(chrcmd[3]&0xF0)|(V&0x0F); break;
107 case 0xC003: chrcmd[3]=(chrcmd[3]&0x0F)|(V<<4); break;
108 case 0xD000: chrcmd[4]=(chrcmd[4]&0xF0)|(V&0x0F); break;
109 case 0xD001: chrcmd[4]=(chrcmd[4]&0x0F)|(V<<4); break;
110 case 0xD002: chrcmd[5]=(chrcmd[5]&0xF0)|(V&0x0F); break;
111 case 0xD003: chrcmd[5]=(chrcmd[5]&0x0F)|(V<<4); break;
112 case 0xE000: chrcmd[6]=(chrcmd[6]&0xF0)|(V&0x0F); break;
113 case 0xE001: chrcmd[6]=(chrcmd[6]&0x0F)|(V<<4); break;
114 case 0xE002: chrcmd[7]=(chrcmd[7]&0xF0)|(V&0x0F); break;
115 case 0xE003: chrcmd[7]=(chrcmd[7]&0x0F)|(V<<4); break;
116 }
117 Sync();
118 }
119}
120
121static void UNLSL1632IRQHook(void)
122{
123 int count = IRQCount;
124 if((scanline==128)&&IRQa)X6502_IRQBegin(FCEU_IQEXT);
125 if(!count || IRQReload)
126 {
127 IRQCount = IRQLatch;
128 IRQReload = 0;
129 }
130 else
131 IRQCount--;
132 if(!IRQCount)
133 {
134 if(IRQa)
135 {
136 X6502_IRQBegin(FCEU_IQEXT);
137 }
138 }
139}
140
141static void StateRestore(int version)
142{
143 Sync();
144}
145
146static void UNLSL1632Power(void)
147{
148 setprg16(0xC000,~0);
149 SetReadHandler(0x8000,0xFFFF,CartBR);
150 SetWriteHandler(0x8000,0xFFFF,UNLSL1632CMDWrite);
151}
152
153void UNLSL1632_Init(CartInfo *info)
154{
155 info->Power=UNLSL1632Power;
156 GameHBIRQHook2=UNLSL1632IRQHook;
157 GameStateRestore=StateRestore;
158 AddExState(&StateRegs, ~0, 0, 0);
159}