2 famicom ROM cartridge utility - unagi
5 Copyright (C) 2008 ±·³«È¯¶¨Æ±Áȹç
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_CPU_OPEN, ADDRESS_CPU_CLOSE};
69 static inline void address_set(long address)
71 long address_h = address >> 8;
72 long address_l = address & 0xff;
73 data_port_latch(DATA_SELECT_A15toA8, address_h);
74 data_port_latch(DATA_SELECT_A7toA0, address_l);
77 static inline u8 data_port_get(long address, int bus)
81 data_port_latch(DATA_SELECT_CONTROL, bus);
83 port_control_write(DATA_SELECT_BREAK_DATA << BITNUM_CONTROL_DATA_SELECT, PORT_CONTROL_WRITE);
84 int s = DATA_SELECT_READ << BITNUM_CONTROL_DATA_SELECT;
85 s = bit_set(s, BITNUM_CONTROL_DATA_LATCH);
86 port_control_write(s, PORT_CONTROL_READ);
87 return (u8) _inp(PORT_DATA);
91 ËÜÂÎ A23-A16 port ¤Ë latch ¤µ¤»¤¿¤¢¤È¤Ë¡¢
92 fc adapater ÆâÉô¤Ë¤µ¤é¤Ë latch ¤µ¤»¤ë¡£
94 static void data_port_set(int c, long data)
96 data_port_latch(DATA_SELECT_WRITEDATA, data);
97 data_port_latch(DATA_SELECT_CONTROL, c);
98 c = bit_set(c, BITNUM_WRITEDATA_LATCH);
99 data_port_latch(DATA_SELECT_CONTROL, c);
102 // /A15 ¤À¤±¤ò»ÈÍѤ¹¤ë
103 static const int BUS_CONTROL_CPU_READ = (
104 (1 << BITNUM_PPU_OUTPUT) |
105 (1 << BITNUM_PPU_RW) |
106 (1 << BITNUM_PPU_SELECT) |
107 (1 << BITNUM_WRITEDATA_OUTPUT) |
108 (0 << BITNUM_WRITEDATA_LATCH) |
109 (1 << BITNUM_CPU_M2) |
112 static const int BUS_CONTROL_PPU_READ = (
113 (0 << BITNUM_PPU_OUTPUT) |
114 (1 << BITNUM_PPU_RW) |
115 (0 << BITNUM_PPU_SELECT) |
116 (1 << BITNUM_WRITEDATA_OUTPUT) |
117 (0 << BITNUM_WRITEDATA_LATCH) |
118 (1 << BITNUM_CPU_M2) |
121 //static const int BUS_CONTROL_BUS_STANDBY = BUS_CONTROL_CPU_READ; //¥¨¥é¡¼¤Ë¤Ê¤ë
122 #define BUS_CONTROL_BUS_STANDBY BUS_CONTROL_CPU_READ
124 namcot ¤Î SRAM ÉÕ¥«¡¼¥È¥ê¥Ã¥¸¤Ï¦Õ2¤ò0x80²ó¾å¤²¤ë¤È½ÐÎϤ¬°ÂÄꤹ¤ë
126 ÉÔ°ÂÄê»þ¤Ï CPU ¤È PPU ¤Î data ¤¬º®¹ç¤µ¤ì¤Æ¤¤¤ëʪ¤¬¤Ç¤Æ¤¤¤ëµ¤¤¬¤¹¤ë
128 static void hk_init(void)
130 int c = BUS_CONTROL_CPU_READ;
133 c = bit_set(c, BITNUM_CPU_M2);
134 data_port_latch(DATA_SELECT_CONTROL, c);
135 c = bit_clear(c, BITNUM_CPU_M2);
136 data_port_latch(DATA_SELECT_CONTROL, c);
141 static void hk_cpu_read(long address, long length, u8 *data)
144 data_port_latch(DATA_SELECT_CONTROL, BUS_CONTROL_CPU_READ);
145 //A15 ¤òȿž¤·¡¢ /ROMCS ¤Ë¤·¤¿¤â¤Î¤òÅϤ¹
146 address ^= ADDRESS_MASK_A15;
148 *data = data_port_get(address, 0);
155 //patch. charcter ¤Î½ñ¤¹þ¤ß¤Î°ÂÄ꤬²þÁ±¤µ¤ì¤¿¤éºï½ü¤¹¤ë
156 int hongkong_flash_patch = 0;
157 static void hk_ppu_read(long address, long length, u8 *data)
159 if(hongkong_flash_patch == 0){
160 data_port_latch(DATA_SELECT_CONTROL, BUS_CONTROL_BUS_STANDBY);
162 data_port_latch(DATA_SELECT_CONTROL, BUS_CONTROL_PPU_READ);
165 address &= ADDRESS_MASK_A0toA12; //PPU charcter data area mask
166 address |= ADDRESS_MASK_A15; //CPU area disk
168 if(hongkong_flash_patch == 0){
169 *data = data_port_get(address, BUS_CONTROL_PPU_READ);
171 *data = data_port_get(address, 0);
176 if(hongkong_flash_patch == 0){
177 data_port_latch(DATA_SELECT_CONTROL, BUS_CONTROL_BUS_STANDBY);
182 static inline void cpu_romcs_set(long address)
184 data_port_latch(DATA_SELECT_A15toA8, address >> 8);
187 static void hk_cpu_write_6502(long address, long length, const uint8_t *data)
190 int c = BUS_CONTROL_BUS_STANDBY;
192 data_port_latch(DATA_SELECT_CONTROL, c);
193 // /rom ¤ò H ¤Ë¤·¤Æ¥Ð¥¹¤ò»ß¤á¤ë
194 address_set(address | ADDRESS_MASK_A15);
196 //¦Õ2 = L, R/W=L, address set, data set
197 c = bit_clear(c, BITNUM_CPU_M2);
198 data_port_set(c, *data); //latch¤Ï¤³¤Î´Ø¿ôÆâÉô¤Ç¹Ô¤¦
199 if(address & ADDRESS_MASK_A15){
200 cpu_romcs_set(address & ADDRESS_MASK_A0toA14);
202 c = bit_clear(c, BITNUM_CPU_RW);
203 data_port_latch(DATA_SELECT_CONTROL, c);
206 c = bit_set(c, BITNUM_CPU_M2);
207 c = bit_clear(c, BITNUM_WRITEDATA_OUTPUT);
208 data_port_latch(DATA_SELECT_CONTROL, c);
210 //¦Õ2 = L, H ¤Ë¤¹¤ë¤Þ¤Ç R/W, address, Data ¤ò͸ú¾õÂ֤ˤ¹¤ë
211 c = bit_clear(c, BITNUM_CPU_M2);
212 data_port_latch(DATA_SELECT_CONTROL, c);
214 //¦Õ2 = H, R/W = H, address disable, data out disable
215 if(address & ADDRESS_MASK_A15){
216 //address & ADDRESS_MASK_A15 ¤ÇÆ°¤¤¤Æ¤¿..?
217 cpu_romcs_set(address | ADDRESS_MASK_A15);
219 data_port_latch(DATA_SELECT_CONTROL, BUS_CONTROL_BUS_STANDBY);
226 //onajimi ¤À¤È /CS ¤È /OE ¤¬Æ±¤¸¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤¬¡¢hongkong¤À¤È»ß¤á¤é¤ì¤ë¡£½ñ¤¹þ¤ß»þ¤Ë output enable ¤Ï H ¤Ç¤¢¤ë¤Ù¤¡£
227 static void hk_ppu_write(long address, long length, const uint8_t *data)
230 int c = BUS_CONTROL_BUS_STANDBY;
231 c = bit_clear(c, BITNUM_CPU_M2); //¤¿¤Ö¤ó¤¤¤ë
232 //c = bit_clear(c, BITNUM_CPU_RW);
233 data_port_latch(DATA_SELECT_CONTROL, c);
234 //cpu rom ¤ò»ß¤á¤¿¥¢¥É¥ì¥¹¤òÅϤ¹
235 address_set((address & ADDRESS_MASK_A0toA12) | ADDRESS_MASK_A15);
236 data_port_set(c, *data);
237 // data_port_latch(DATA_SELECT_CONTROL, c);
239 c = bit_clear(c, BITNUM_PPU_SELECT);
240 data_port_latch(DATA_SELECT_CONTROL, c);
242 c = bit_clear(c, BITNUM_WRITEDATA_OUTPUT);
243 c = bit_clear(c, BITNUM_PPU_RW);
244 data_port_latch(DATA_SELECT_CONTROL, c);
246 c = bit_set(c, BITNUM_PPU_RW);
247 data_port_latch(DATA_SELECT_CONTROL, c);
249 // c = bit_set(c, BITNUM_WRITEDATA_OUTPUT);
250 data_port_latch(DATA_SELECT_CONTROL, BUS_CONTROL_BUS_STANDBY);
259 static const int FLASH_CPU_WRITE = (
260 (1 << BITNUM_PPU_OUTPUT) |
261 (1 << BITNUM_PPU_RW) |
262 (1 << BITNUM_PPU_SELECT) |
263 (1 << BITNUM_WRITEDATA_OUTPUT) |
264 (0 << BITNUM_WRITEDATA_LATCH) |
265 (0 << BITNUM_CPU_M2) |
269 static void hk_cpu_flash_write(long address, long data)
271 int c = FLASH_CPU_WRITE;
273 data_port_latch(DATA_SELECT_CONTROL, c);
274 address_set(address | ADDRESS_MASK_A15);
275 data_port_set(c, data);
278 During the byte-load cycle, the addresses are latched by the falling
279 edge of either CE or WE,whichever occurs last. The data are latched
280 by the rising edge of either CE or WE, whicheveroccurs first.
282 #CS or #WE ¤¬¹ß¤ê¤¿¤È¤¤Ë address latch
283 #CS or #WE ¤¬¾å¤¬¤Ã¤¿¤È¤¤Ë data latch
285 hongkong ·Ï¤Ï address ¤È /ROMCS ¤¬Æ±¤¸¥Ð¥¤¥È¤Ç¡¢ /CS À©¸æ¤Ë¤¹¤ë¤È
286 hongkong ¥Ç¡¼¥¿Ç˲õ+¥¢¥É¥ì¥¹ÉÔ°ÂÄê¤Ë¤Ê¤ë¤Î¤Ç¡¢/WE À©¸æ¤Ë¤·¤Ê¤¤¤ÈÆ°¤«¤Ê¤¤¡£
289 cpu_romcs_set(address & ADDRESS_MASK_A0toA14);
291 c = bit_clear(c, BITNUM_WRITEDATA_OUTPUT);
292 c = bit_clear(c, BITNUM_CPU_RW);
293 // c = bit_clear(c, BITNUM_CPU_M2);
294 data_port_latch(DATA_SELECT_CONTROL, c);
296 data_port_latch(DATA_SELECT_CONTROL, FLASH_CPU_WRITE);
298 cpu_romcs_set(address | ADDRESS_MASK_A15);
302 const struct reader_driver DRIVER_HONGKONGFC = {
303 .name = "hongkongfc",
304 .open_or_close = paralellport_open_or_close,
306 .cpu_read = hk_cpu_read,
307 .ppu_read = hk_ppu_read,
308 .cpu_write_6502 = hk_cpu_write_6502,
309 .ppu_write = hk_ppu_write,
311 .cpu_flash_config = NULL, .cpu_flash_erase = NULL, .cpu_flash_program = NULL,
312 .ppu_flash_config = NULL, .ppu_flash_erase = NULL, .ppu_flash_program = NULL
319 static void data_show(u8 *d, int length)
325 switch(offset & 0xf){
336 printf("%02x%c", *d, safix);
342 printf("sum 0x%06x", sum);
345 int main(int c, char **v)
347 const int gg = giveio_start();
355 printf("Can't Access Direct IO %d\n", gg);
359 long d = strtol(v[2], NULL, 0x10);
363 data_port_latch(DATA_SELECT_CONTROL, BUS_CONTROL_BUS_STANDBY);
364 port_control_write(DATA_SELECT_WRITE << BITNUM_CONTROL_DATA_SELECT, PORT_CONTROL_WRITE);
368 data_port_latch(DATA_SELECT_CONTROL, BUS_CONTROL_CPU_READ);
369 address_set(d ^ ADDRESS_MASK_A15);
370 port_control_write(DATA_SELECT_BREAK_DATA << BITNUM_CONTROL_DATA_SELECT, PORT_CONTROL_WRITE);
371 port_control_write(DATA_SELECT_READ << BITNUM_CONTROL_DATA_SELECT, PORT_CONTROL_READ);
372 printf("%02x\n", _inp(PORT_DATA));
375 const long length = 0x1000;
377 hk_cpu_read(d, length, data);
378 data_show(data, length);
382 data_port_latch(DATA_SELECT_CONTROL, BUS_CONTROL_PPU_READ);
383 address_set(d | ADDRESS_MASK_A15, ADDRESS_RESET);
384 port_control_write(DATA_SELECT_READ << BITNUM_CONTROL_DATA_SELECT, PORT_CONTROL_READ);
385 printf("%02x\n", _inp(PORT_DATA));
388 const long length = 0x200;
390 hk_ppu_read(d, length, data);
391 data_show(data, length);
396 if(gg != GIVEIO_WIN95){
397 giveio_stop(GIVEIO_STOP);