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 | |
23 | static uint8 chrcmd[8], prg0, prg1, brk, mirr; |
24 | static uint8 reg[8], cmd; |
25 | static uint8 IRQCount,IRQLatch,IRQa; |
26 | static uint8 IRQReload; |
27 | static 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 | |
43 | static 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 | |
61 | static 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 | |
74 | static 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 | |
121 | static 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 | |
141 | static void StateRestore(int version) |
142 | { |
143 | Sync(); |
144 | } |
145 | |
146 | static void UNLSL1632Power(void) |
147 | { |
148 | setprg16(0xC000,~0); |
149 | SetReadHandler(0x8000,0xFFFF,CartBR); |
150 | SetWriteHandler(0x8000,0xFFFF,UNLSL1632CMDWrite); |
151 | } |
152 | |
153 | void UNLSL1632_Init(CartInfo *info) |
154 | { |
155 | info->Power=UNLSL1632Power; |
156 | GameHBIRQHook2=UNLSL1632IRQHook; |
157 | GameStateRestore=StateRestore; |
158 | AddExState(&StateRegs, ~0, 0, 0); |
159 | } |