2 famicom ROM cartridge dump program - unagi
3 emuste.net ¤Ç¤ª¤Ê¤¸¤ß¤Î¤â¤Î¤Î¥Ï¡¼¥É¥É¥é¥¤¥Ð
6 * Ê̤Υϡ¼¥É¥¦¥§¥¢¤ËÂбþ¤·¤¿¾ì¹ç¤Ï PORT_DATA ¤«¤é wait ¤Þ¤Ç¤ò¥Ø¥Ã¥À¤Ë¤Þ¤È¤á¤ë
9 * -O0 ¤Ê¤é inline asm ¤Ç¤âÈ¿±þ¤Ç¤¤ë¤¬¡¢-O2 ¤À¤ÈÆ°¤«¤Ê¤¤
10 * ͽÁÛ¤ËÈ¿¤·¤Æ out ¤ÏÆ°¤¯¤¬¡¢ in ¤Ë wait ¤¬É¬Íפߤ¿¤¤
11 * gcc ¤Î¥¢¥»¥ó¥Ö¥é¤Ï x86 ¤Ç¤¢¤í¤¦¤È src,dst ¤Î½ç¤Çȿž¤·¤Æ¤¤¤ë
12 * http://download.intel.com/jp/developer/jpdoc/IA32_Arh_Dev_Man_Vol2A_i.pdf
13 * out,in ¤Î¥¢¥É¥ì¥¹¤Ë dx ¤ò»È¤ï¤Ê¤¤¤È 8bit ¥¢¥É¥ì¥¹¤Ë¤Ê¤ë
14 * out,in ¤Î¥Ç¡¼¥¿¤Ï¥ì¥¸¥¹¥¿¤Ç¥Ç¡¼¥¿Éý¤¬ÊѤï¤ë al:8bit, ax:16bit, eax:32bit
17 //#include <windows.h>
19 #include "hard_onajimi.h"
20 #include "driver_onajimi.h"
22 #define ASM_ENABLE (0)
29 ADDRESS_MASK_A0toA14 = 0x7fff,
30 ADDRESS_MASK_A15 = 0x8000
37 static inline int bit_set(int data, const int bit)
43 static inline int bit_clear(int data, const int bit)
49 static inline void wait(void)
51 //const long waittime = 100000;
55 static inline void bus_control(int data)
58 _outp(PORT_DATA, data);
64 :: "i"(PORT_DATA), "q"(data): "%edx", "%eax"
74 static inline void address_control(int data)
79 _outp(PORT_CONTROL, data);
85 :: "i"(PORT_CONTROL), "q"(data): "%edx", "%eax"
91 /* address control data & function */
92 static long past_address = 0;
94 static void address_reset(void)
96 address_control(ADDRESS_RESET);
97 address_control(ADDRESS_ENABLE);
102 H->L ¤Çaddressincrement
104 static inline void address_increment(int data)
106 data = bit_set(data, BITNUM_ADDRESS_INCREMENT);
109 data = bit_clear(data, BITNUM_ADDRESS_INCREMENT);
112 past_address &= ADDRESS_MASK_A0toA14;
115 static void address_set(long address, int control)
117 address &= ADDRESS_MASK_A0toA14;
118 long increment_count = address - past_address;
119 if(increment_count < 0){
121 increment_count = address;
124 while(increment_count != 0){
125 address_increment(control);
126 increment_count -= 1;
134 static inline int data_bit_get(void)
139 " xorl %%eax,%%eax\n"
143 :"=q"(data) : "i"(PORT_STATUS) :"%edx", "%eax"
146 int data = _inp(PORT_STATUS);
156 static void data_shift(int control)
158 control = bit_clear(control, BITNUM_DATA_SHIFT_RIGHT);
159 bus_control(control);
160 control = bit_set(control, BITNUM_DATA_SHIFT_RIGHT);
161 bus_control(control);
164 /*ºÇ¾å°Ìbit¤«¤é½çÈ֤ˤȤë*/
165 static u8 data_get(int control)
169 //fcbus 8bit data load, shift count reset
170 control = bit_set(control, BITNUM_DATA_DIRECTION);
173 control = bit_clear(control, BITNUM_DATA_DIRECTION);
174 bus_control(control);
175 for(i = 0; i < 8; i++){
176 data |= (data_bit_get() << i);
182 //¤³¤³¤Î data ¤Ï 0 or 1
183 static inline int writedata_set(long data)
186 return data << BITNUM_DATA_WRITE_DATA;
189 static void data_set(int control, long data)
192 for(i = 0; i < 8; i++){
193 control = bit_clear(control, BITNUM_DATA_WRITE_DATA);
194 control |= writedata_set(data >> i);
195 bus_control(control);
200 static const int BUS_CONTROL_INIT = (
201 ADDRESS_NOP | DATA_SHIFT_NOP |
202 (DATA_DIRECTION_READ << BITNUM_DATA_DIRECTION) |
203 (PPU_DISABLE << BITNUM_PPU_SELECT) |
204 (PPU_WRITE__CPU_DISABLE << BITNUM_CPU_M2) |
205 (CPU_RAM_SELECT << BITNUM_CPU_RAMROM_SELECT) |
206 (CPU_READ << BITNUM_CPU_RW)
208 void reader_init(void)
210 bus_control(BUS_CONTROL_INIT);
214 static const int BUS_CONTROL_CPU_READ = (
215 ADDRESS_NOP | DATA_SHIFT_NOP |
216 (DATA_DIRECTION_READ << BITNUM_DATA_DIRECTION) |
217 (PPU_DISABLE << BITNUM_PPU_SELECT) |
218 (PPU_READ__CPU_ENABLE << BITNUM_CPU_M2) | //H
219 (CPU_RAM_SELECT << BITNUM_CPU_RAMROM_SELECT) |
220 (CPU_READ << BITNUM_CPU_RW)
223 static const int BUS_CONTROL_PPU_READ = (
224 ADDRESS_NOP | DATA_SHIFT_NOP |
225 (DATA_DIRECTION_READ << BITNUM_DATA_DIRECTION) |
226 (PPU_READ__CPU_ENABLE << BITNUM_CPU_M2) |
227 (PPU_ENABLE << BITNUM_PPU_SELECT) |
228 (CPU_RAM_SELECT << BITNUM_CPU_RAMROM_SELECT) |
229 (CPU_READ << BITNUM_CPU_RW)
232 static const int BUS_CONTROL_BUS_WRITE = (
233 ADDRESS_NOP | DATA_SHIFT_NOP |
234 (DATA_DIRECTION_WRITE << BITNUM_DATA_DIRECTION) |
235 (PPU_READ__CPU_ENABLE << BITNUM_CPU_M2) |
236 (PPU_DISABLE << BITNUM_PPU_SELECT) |
237 (CPU_RAM_SELECT << BITNUM_CPU_RAMROM_SELECT) |
238 (CPU_READ << BITNUM_CPU_RW)
242 M2_CONTROL_TRUE, M2_CONTROL_FALSE
245 static void fc_bus_read(long address, long length, u8 *data, int control, int m2_control)
247 address_set(address, control);
248 if(m2_control == M2_CONTROL_TRUE){
249 control = bit_clear(control, BITNUM_CPU_M2);
250 bus_control(control); //H->L: mapper ¤¬¥¢¥É¥ì¥¹¤ò¼è¤Ã¤Æ¤¯¤ë
253 if(m2_control == M2_CONTROL_TRUE){
254 //L->H: mapper ¤¬ data ¤ò½Ð¤¹
255 control = bit_set(control, BITNUM_CPU_M2);
257 *data = data_get(control);
258 if(m2_control == M2_CONTROL_TRUE){
260 control = bit_clear(control, BITNUM_CPU_M2);
261 bus_control(control);
263 control = bit_set(control, BITNUM_CPU_M2);
265 address_increment(control);
267 if(m2_control == M2_CONTROL_TRUE){
268 //H->L: mapper ¤¬¥¢¥É¥ì¥¹¤ò¼è¤Ã¤Æ¤¯¤ë
269 control = bit_clear(control, BITNUM_CPU_M2);
270 bus_control(control);
276 control = bit_set(control, BITNUM_CPU_M2);
279 void cpu_read(long address, long length, u8 *data)
281 int control = BUS_CONTROL_CPU_READ;
282 if(address & ADDRESS_MASK_A15){
283 control = bit_clear(control, BITNUM_CPU_RAMROM_SELECT);
285 fc_bus_read(address, length, data, control, M2_CONTROL_TRUE);
288 void ppu_read(long address, long length, u8 *data)
290 fc_bus_read(address, length, data, BUS_CONTROL_PPU_READ, M2_CONTROL_FALSE);
301 1 H->L bus:data set, mapper:address get
302 2 L->H bus:data write
303 3 H->L mapper: data write enable
304 4 L->H mapper: data get, bus:close
306 H:1, L:0, x:ROMareaaccess»þ0, ¤½¤ì°Ê³°1
308 void cpu_write(long address, long data)
310 int control = BUS_CONTROL_BUS_WRITE;
311 //addressÀßÄê + Á´¤Æ¤Î¥Ð¥¹¤ò»ß¤á¤ë
312 address_set(address, control);
314 control = bit_clear(control, BITNUM_CPU_M2);
315 //printf("%02x ", (int) data);
316 data_set(control, data);
318 control = bit_clear(control, BITNUM_CPU_RW);
319 //bus_control(control); //
320 control = bit_set(control, BITNUM_CPU_M2);
321 //bus_control(control); //
322 if(address & ADDRESS_MASK_A15){
323 control = bit_clear(control, BITNUM_CPU_RAMROM_SELECT);
325 bus_control(control);
326 control = bit_clear(control, BITNUM_CPU_M2);
327 bus_control(control);
328 bus_control(BUS_CONTROL_BUS_WRITE);
331 void ppu_write(long address, long data)
333 int control = BUS_CONTROL_BUS_WRITE;
335 address_set(address, control);
336 bus_control(control);
337 data_set(control, data);
338 control = bit_clear(control, BITNUM_PPU_RW);
339 control = bit_clear(control, BITNUM_PPU_SELECT); //mmc1 ¤Ï¤Ê¤¯¤Æ¤â¤¤¤±¤ë¤¬ mmc3 ¤Ë¤ÏɬÍ×
340 bus_control(control);
341 bus_control(BUS_CONTROL_BUS_WRITE);