2 famicom ROM cartridge utility - unagi
5 Copyright (C) 2008 sato_tiff
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * 74138 ¤Î channel select ¤À¤¬¡¢¥Ñ¥é¥ì¥ë¥Ý¡¼¥È¤Î¥Ç¡¼¥¿¤ÎÊý¸þ¤òÊѹ¹¤¹¤ë¤È¡¢ÆÃÄê¤Î¥Á¥ã¥ó¥Í¥ë¤Î¥Ç¡¼¥¿¤¬Ç˲õ¤µ¤ì¤ë
23 * Ç˲õ¤µ¤ì¤ë¤¬¡¢Ç˲õÀ褬ÀßÄê¤Ç¤¤ë¤é¤·¤¯¤½¤ì¤Ë¤·¤¿
26 #include "paralellport.h"
27 #include "reader_master.h"
28 #include "reader_hongkongfc.h"
29 #include "hard_hongkongfc.h"
32 PORT_CONTROL_MASK_XOR = 0x03, //bit01 invert
33 PORT_CONTROL_READ = 0,
37 static inline int busy_get(void)
39 int d = _inp(PORT_BUSY);
44 static inline void port_control_write(int s, int rw)
46 if(rw == PORT_CONTROL_READ){
48 s = bit_set(s, BITNUM_CONTROL_DIRECTION);
51 s = bit_clear(s, BITNUM_CONTROL_DIRECTION);
53 s = bit_clear(s, BITNUM_CONTROL_INTERRUPT);
54 s ^= PORT_CONTROL_MASK_XOR;
55 _outp(PORT_CONTROL, s);
58 static inline void data_port_latch(int select, long data)
60 select <<= BITNUM_CONTROL_DATA_SELECT;
61 select = bit_set(select, BITNUM_CONTROL_DATA_LATCH);
62 port_control_write(select, PORT_CONTROL_WRITE);
63 _outp(PORT_DATA, data);
64 select = bit_clear(select, BITNUM_CONTROL_DATA_LATCH);
65 port_control_write(select, PORT_CONTROL_WRITE);
68 enum{ADDRESS_RESET, ADDRESS_SET};
69 /*¤³¤ì¤â¥Ý¡¼¥ÈÇ˲õ¤¬µ¯¤³¤ë¤Î¤«¤Á¤ã¤ó¤ÈÆ°¤«¤Ê¤¤
70 static inline void address_set(long address, int reset)
72 static long last_address_h, last_address_l;
73 long address_h = address >> 8;
74 long address_l = address & 0xff;
75 if(reset == ADDRESS_RESET){
76 data_port_latch(DATA_SELECT_A15toA8, address_h);
77 data_port_latch(DATA_SELECT_A7toA0, address_l);
79 if(last_address_h != address_h){
80 data_port_latch(DATA_SELECT_A15toA8, address_h);
82 if(last_address_l != address_l){
83 data_port_latch(DATA_SELECT_A7toA0, address_l);
86 last_address_h = address_h;
87 last_address_l = address_l;
90 static inline void address_set(long address, int reset)
92 long address_h = address >> 8;
93 long address_l = address & 0xff;
94 data_port_latch(DATA_SELECT_A15toA8, address_h);
95 data_port_latch(DATA_SELECT_A7toA0, address_l);
97 static inline u8 data_port_get(long address, int bus, int m2)
101 //¦Õ2 control ¤òÆþ¤ì¤ë¤È²¿¸Î¤«CPU¥¢¥É¥ì¥¹ $8090 ¤Ç¥Ð¥ó¥¯¤¬ÀÚ¤êÂؤï¤ë???
103 if(address == (0x8090 ^ ADDRESS_MASK_A15)){
106 address_set(address, ADDRESS_SET);
107 if(m2 == M2_CONTROL_TRUE){
108 bus = bit_clear(bus, BITNUM_CPU_M2);
110 data_port_latch(DATA_SELECT_CONTROL, bus);
111 if(m2 == M2_CONTROL_TRUE){
112 bus = bit_set(bus, BITNUM_CPU_M2);
113 data_port_latch(DATA_SELECT_CONTROL, bus);
116 address_set(address, ADDRESS_SET);
118 port_control_write(DATA_SELECT_BREAK_DATA << BITNUM_CONTROL_DATA_SELECT, PORT_CONTROL_WRITE);
119 int s = DATA_SELECT_READ << BITNUM_CONTROL_DATA_SELECT;
120 s = bit_set(s, BITNUM_CONTROL_DATA_LATCH);
121 port_control_write(s, PORT_CONTROL_READ);
122 return (u8) _inp(PORT_DATA);
126 ËÜÂÎ A23-A16 port ¤Ë latch ¤µ¤»¤¿¤¢¤È¤Ë¡¢
127 fc adapater ÆâÉô¤Ë¤µ¤é¤Ë latch ¤µ¤»¤ë¡£
129 static void data_port_set(int c, long data)
131 data_port_latch(DATA_SELECT_WRITEDATA, data);
132 data_port_latch(DATA_SELECT_CONTROL, c);
133 c = bit_set(c, BITNUM_WRITEDATA_LATCH);
134 data_port_latch(DATA_SELECT_CONTROL, c);
137 // /A15 ¤À¤±¤ò»ÈÍѤ¹¤ë
138 static const int BUS_CONTROL_CPU_READ = (
139 (1 << BITNUM_PPU_OUTPUT) |
140 (1 << BITNUM_PPU_RW) |
141 (1 << BITNUM_PPU_SELECT) |
142 (1 << BITNUM_WRITEDATA_OUTPUT) |
143 (0 << BITNUM_WRITEDATA_LATCH) |
144 (1 << BITNUM_CPU_M2) |
147 static const int BUS_CONTROL_PPU_READ = (
148 (0 << BITNUM_PPU_OUTPUT) |
149 (1 << BITNUM_PPU_RW) |
150 (0 << BITNUM_PPU_SELECT) |
151 (1 << BITNUM_WRITEDATA_OUTPUT) |
152 (0 << BITNUM_WRITEDATA_LATCH) |
153 (0 << BITNUM_CPU_M2) |
156 //static const int BUS_CONTROL_BUS_WRITE = BUS_CONTROL_CPU_READ; //¥¨¥é¡¼¤Ë¤Ê¤ë
157 #define BUS_CONTROL_BUS_WRITE BUS_CONTROL_CPU_READ
159 namcot ¤Î SRAM ÉÕ¥«¡¼¥È¥ê¥Ã¥¸¤Ï¦Õ2¤ò0x80²ó¾å¤²¤ë¤È½ÐÎϤ¬°ÂÄꤹ¤ë
161 ÉÔ°ÂÄê»þ¤Ï CPU ¤È PPU ¤Î data ¤¬º®¹ç¤µ¤ì¤Æ¤¤¤ëʪ¤¬¤Ç¤Æ¤¤¤ëµ¤¤¬¤¹¤ë
163 static void hk_init(void)
165 int c = BUS_CONTROL_CPU_READ;
168 c = bit_set(c, BITNUM_CPU_M2);
169 data_port_latch(DATA_SELECT_CONTROL, c);
170 c = bit_clear(c, BITNUM_CPU_M2);
171 data_port_latch(DATA_SELECT_CONTROL, c);
175 address_set(0, ADDRESS_RESET);
179 static void hk_cpu_read(long address, long length, u8 *data)
182 data_port_latch(DATA_SELECT_CONTROL, BUS_CONTROL_CPU_READ);
183 //A15 ¤òȿž¤·¡¢ /ROMCS ¤Ë¤·¤¿¤â¤Î¤òÅϤ¹
184 address ^= ADDRESS_MASK_A15;
186 *data = data_port_get(address, BUS_CONTROL_CPU_READ, M2_CONTROL_FALSE);
193 static void hk_ppu_read(long address, long length, u8 *data)
195 data_port_latch(DATA_SELECT_CONTROL, BUS_CONTROL_PPU_READ);
196 address &= ADDRESS_MASK_A0toA12; //PPU charcter data area mask
197 address |= ADDRESS_MASK_A15; //CPU area disk
199 *data = data_port_get(address, BUS_CONTROL_PPU_READ, M2_CONTROL_FALSE);
206 static void hk_cpu_6502_write(long address, long data)
208 int c = BUS_CONTROL_BUS_WRITE;
210 data_port_latch(DATA_SELECT_CONTROL, c);
211 // /rom ¤ò H ¤Ë¤·¤Æ¥Ð¥¹¤ò»ß¤á¤ë
212 address_set(address | ADDRESS_MASK_A15, ADDRESS_SET);
214 //1 H->L bus:data set, mapper:address get
215 c = bit_clear(c, BITNUM_CPU_M2);
216 data_port_set(c, data); //latch¤Ï¤³¤Î´Ø¿ôÆâÉô¤Ç¹Ô¤¦
217 c = bit_clear(c, BITNUM_WRITEDATA_OUTPUT);
218 data_port_latch(DATA_SELECT_CONTROL, c);
219 //2 L->H bus:data write
220 //ROM Îΰè¤Î¾ì¹ç¤Ï¤³¤Î¥¿¥¤¥ß¥ó¥°¤Ç /rom ¤òÍî¤È¤¹
221 if(address & ADDRESS_MASK_A15){
222 address_set(address & ADDRESS_MASK_A0toA14, ADDRESS_SET);
224 c = bit_clear(c, BITNUM_CPU_RW);
225 c = bit_set(c, BITNUM_CPU_M2);
226 data_port_latch(DATA_SELECT_CONTROL, c);
227 //3 H->L mapper: data write enable
228 c = bit_clear(c, BITNUM_CPU_M2);
229 data_port_latch(DATA_SELECT_CONTROL, c);
230 //4 L->H mapper: data get, bus:close
231 if(address & ADDRESS_MASK_A15){
232 address_set(address | ADDRESS_MASK_A15, ADDRESS_SET);
234 data_port_latch(DATA_SELECT_CONTROL, BUS_CONTROL_BUS_WRITE);
237 //onajimi ¤À¤È /CS ¤È /OE ¤¬Æ±¤¸¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤¬¡¢hongkong¤À¤È»ß¤á¤é¤ì¤ë¡£½ñ¤¹þ¤ß»þ¤Ë output enable ¤Ï H ¤Ç¤¢¤ë¤Ù¤¡£
238 static void hk_ppu_write(long address, long data)
240 int c = BUS_CONTROL_BUS_WRITE;
241 c = bit_clear(c, BITNUM_CPU_M2); //¤¿¤Ö¤ó¤¤¤ë
242 data_port_latch(DATA_SELECT_CONTROL, c);
243 //cpu rom ¤ò»ß¤á¤¿¥¢¥É¥ì¥¹¤òÅϤ¹
244 address_set((address & ADDRESS_MASK_A0toA12) | ADDRESS_MASK_A15, ADDRESS_SET);
245 data_port_set(c, data);
246 c = bit_clear(c, BITNUM_WRITEDATA_OUTPUT);
248 c = bit_clear(c, BITNUM_PPU_RW);
249 data_port_latch(DATA_SELECT_CONTROL, c);
251 c = bit_clear(c, BITNUM_PPU_SELECT);
252 data_port_latch(DATA_SELECT_CONTROL, c);
254 c = bit_set(c, BITNUM_PPU_SELECT);
255 data_port_latch(DATA_SELECT_CONTROL, c);
257 data_port_latch(DATA_SELECT_CONTROL, BUS_CONTROL_BUS_WRITE);
260 static const int FLASH_CPU_WRITE = (
261 (1 << BITNUM_PPU_OUTPUT) |
262 (1 << BITNUM_PPU_RW) |
263 (1 << BITNUM_PPU_SELECT) |
264 (1 << BITNUM_WRITEDATA_OUTPUT) |
265 (0 << BITNUM_WRITEDATA_LATCH) |
266 (0 << BITNUM_CPU_M2) |
270 static void hk_cpu_flash_write(long address, long data)
272 int c = FLASH_CPU_WRITE;
274 data_port_latch(DATA_SELECT_CONTROL, c);
275 address_set(address | ADDRESS_MASK_A15, ADDRESS_SET);
276 data_port_set(c, data);
279 During the byte-load cycle, the addresses are latched by the falling
280 edge of either CE or WE,whichever occurs last. The data are latched
281 by the rising edge of either CE or WE, whicheveroccurs first.
285 #CS or #WE ¤¬¹ß¤ê¤¿¤È¤¤Ë address latch
286 #CS or #WE ¤¬¾å¤¬¤Ã¤¿¤È¤¤Ë data latch
288 c = bit_clear(c, BITNUM_WRITEDATA_OUTPUT);
290 c = bit_clear(c, BITNUM_CPU_RW);
291 // c = bit_clear(c, BITNUM_CPU_M2);
292 data_port_latch(DATA_SELECT_CONTROL, c);
294 address_set(address & ADDRESS_MASK_A0toA14, ADDRESS_SET);
296 address_set(address | ADDRESS_MASK_A15, ADDRESS_SET);
298 data_port_latch(DATA_SELECT_CONTROL, FLASH_CPU_WRITE);
301 const struct reader_driver DRIVER_HONGKONGFC = {
304 cpu_read: hk_cpu_read,
305 ppu_read: hk_ppu_read,
306 cpu_6502_write: hk_cpu_6502_write,
307 ppu_write: hk_ppu_write,
308 cpu_flash_write: hk_cpu_flash_write
315 static void data_show(u8 *d, int length)
321 switch(offset & 0xf){
332 printf("%02x%c", *d, safix);
338 printf("sum 0x%06x", sum);
341 int main(int c, char **v)
343 const int gg = giveio_start();
351 printf("Can't Access Direct IO %d\n", gg);
355 long d = strtol(v[2], NULL, 0x10);
359 data_port_latch(DATA_SELECT_CONTROL, BUS_CONTROL_BUS_WRITE);
360 port_control_write(DATA_SELECT_WRITE << BITNUM_CONTROL_DATA_SELECT, PORT_CONTROL_WRITE);
364 data_port_latch(DATA_SELECT_CONTROL, BUS_CONTROL_CPU_READ);
365 address_set(d ^ ADDRESS_MASK_A15, ADDRESS_RESET);
366 port_control_write(DATA_SELECT_BREAK_DATA << BITNUM_CONTROL_DATA_SELECT, PORT_CONTROL_WRITE);
367 port_control_write(DATA_SELECT_READ << BITNUM_CONTROL_DATA_SELECT, PORT_CONTROL_READ);
368 printf("%02x\n", _inp(PORT_DATA));
371 const long length = 0x1000;
373 hk_cpu_read(d, length, data);
374 data_show(data, length);
378 data_port_latch(DATA_SELECT_CONTROL, BUS_CONTROL_PPU_READ);
379 address_set(d | ADDRESS_MASK_A15, ADDRESS_RESET);
380 port_control_write(DATA_SELECT_READ << BITNUM_CONTROL_DATA_SELECT, PORT_CONTROL_READ);
381 printf("%02x\n", _inp(PORT_DATA));
384 const long length = 0x200;
386 hk_ppu_read(d, length, data);
387 data_show(data, length);
392 if(gg != GIVEIO_WIN95){
393 giveio_stop(GIVEIO_STOP);