OBJ = \
- unagi.o driver_onajimi.o script.o header.o \
+ unagi.o script.o header.o \
+ driver_master.o driver_onajimi.o driver_hongkongfc.o \
file.o textutil.o giveio.o unagi.res.o
OBJ_HK = giveio.o driver_hongkongfc.o
TARGET = unagi.exe
#---- depend file ----
driver_hongkongfc.o: driver_hongkongfc.c type.h paralellport.h \
- hard_hongkongfc.h giveio.h
+ driver_master.h driver_hongkongfc.h hard_hongkongfc.h
+driver_master.o: driver_master.c driver_master.h type.h driver_onajimi.h \
+ driver_hongkongfc.h
driver_onajimi.o: driver_onajimi.c type.h paralellport.h hard_onajimi.h \
- driver_onajimi.h
+ driver_master.h driver_onajimi.h
file.o: file.c file.h type.h
giveio.o: giveio.c giveio.h
header.o: header.c type.h file.h header.h
-script.o: script.c type.h file.h driver_onajimi.h giveio.h textutil.h \
+script.o: script.c type.h file.h driver_master.h giveio.h textutil.h \
header.h script.h
textutil.o: textutil.c type.h textutil.h
-unagi.o: unagi.c type.h driver_onajimi.h giveio.h file.h script.h
+unagi.o: unagi.c type.h driver_master.h giveio.h file.h script.h
#include "type.h"
#include "paralellport.h"
+#include "driver_master.h"
+#include "driver_hongkongfc.h"
#include "hard_hongkongfc.h"
-//#include "hongkongfc.h"
enum{
PORT_CONTROL_MASK_XOR = 0x03, //bit01 invert
(1 << BITNUM_CPU_RW)
);
-void hk_cpu_read(long address, long length, u8 *data)
+static void hk_init(void)
+{
+}
+
+static void hk_cpu_read(long address, long length, u8 *data)
{
//fc bus ½é´ü²½
data_port_latch(DATA_SELECT_CONTROL, BUS_CONTROL_CPU_READ);
}
}
-void hk_ppu_read(long address, long length, u8 *data)
+static void hk_ppu_read(long address, long length, u8 *data)
{
data_port_latch(DATA_SELECT_CONTROL, BUS_CONTROL_PPU_READ);
address &= ADDRESS_MASK_A0toA12; //PPU charcter data area mask
}
}
-void hk_cpu_write(long address, long data)
+static void hk_cpu_write(long address, long data)
{
int c = BUS_CONTROL_BUS_WRITE;
//Á´¤Æ¤Î¥Ð¥¹¤ò»ß¤á¤ë
data_port_latch(DATA_SELECT_CONTROL, BITNUM_WRITEDATA_OUTPUT);
}
-void hk_ppu_write(long address, long data)
+static void hk_ppu_write(long address, long data)
{
int c = BUS_CONTROL_BUS_WRITE;
c = bit_clear(c, BITNUM_CPU_M2); //¤¿¤Ö¤ó¤¤¤ë
data_port_latch(DATA_SELECT_CONTROL, BUS_CONTROL_BUS_WRITE);
}
+const struct driver DRIVER_HONGKONGFC = {
+ name: "hongkongfc",
+ init: hk_init,
+ cpu_read: hk_cpu_read,
+ ppu_read: hk_ppu_read,
+ cpu_write: hk_cpu_write,
+ ppu_write: hk_ppu_write
+};
+
+#ifdef TEST
#include "giveio.h"
#include <stdio.h>
#include <stdlib.h>
}
return 0;
}
+#endif
--- /dev/null
+#ifndef _DRIVER_HONGKONGFC_H_
+#define _DRIVER_HONGKONGFC_H_
+const struct driver DRIVER_HONGKONGFC;
+#endif
--- /dev/null
+#include <string.h>
+#include "driver_master.h"
+#include "driver_onajimi.h"
+#include "driver_hongkongfc.h"
+
+const struct driver *driver_get(const char *name)
+{
+ if(strcmp(name, DRIVER_ONAJIMI.name) == 0){
+ return &DRIVER_ONAJIMI;
+ }else if(strcmp(name, DRIVER_HONGKONGFC.name) == 0){
+ return &DRIVER_HONGKONGFC;
+ }
+ return NULL;
+}
--- /dev/null
+#ifndef _DRIVER_MASTER_H_
+#define _DRIVER_MASTER_H_
+#include "type.h"
+struct driver{
+ void (*init)(void);
+ void (*cpu_read)(long address, long length, u8 *data);
+ void (*ppu_read)(long address, long length, u8 *data);
+ void (*cpu_write)(long address, long data);
+ void (*ppu_write)(long address, long data);
+ const char *name;
+};
+const struct driver *driver_get(const char *name);
+#endif
famicom ROM cartridge dump program - unagi
emuste.net ¤Ç¤ª¤Ê¤¸¤ß¤Î¤â¤Î¤Î¥Ï¡¼¥É¥É¥é¥¤¥Ð
-todo:
-* Ê̤Υϡ¼¥É¥¦¥§¥¢¤ËÂбþ¤·¤¿¾ì¹ç¤Ï PORT_DATA ¤«¤é wait ¤Þ¤Ç¤ò¥Ø¥Ã¥À¤Ë¤Þ¤È¤á¤ë
-
+memo:
+* -O0 ¤Ê¤é inline asm ¤Ç¤âÈ¿±þ¤Ç¤¤ë¤¬¡¢-O2 ¤À¤ÈÆ°¤«¤Ê¤¤
+ * ͽÁÛ¤ËÈ¿¤·¤Æ out ¤ÏÆ°¤¯¤¬¡¢ in ¤Ë wait ¤¬É¬Íפߤ¿¤¤
+* gcc ¤Î¥¢¥»¥ó¥Ö¥é¤Ï x86 ¤Ç¤¢¤í¤¦¤È src,dst ¤Î½ç¤Çȿž¤·¤Æ¤¤¤ë
+* http://download.intel.com/jp/developer/jpdoc/IA32_Arh_Dev_Man_Vol2A_i.pdf
+ * out,in ¤Î¥¢¥É¥ì¥¹¤Ë dx ¤ò»È¤ï¤Ê¤¤¤È 8bit ¥¢¥É¥ì¥¹¤Ë¤Ê¤ë
+ * out,in ¤Î¥Ç¡¼¥¿¤Ï¥ì¥¸¥¹¥¿¤Ç¥Ç¡¼¥¿Éý¤¬ÊѤï¤ë al:8bit, ax:16bit, eax:32bit
*/
#include "type.h"
#include "paralellport.h"
#include "hard_onajimi.h"
+#include "driver_master.h"
#include "driver_onajimi.h"
static inline void bus_control(int data)
control = bit_set(control, BITNUM_CPU_M2);
}
-void cpu_read(long address, long length, u8 *data)
+static void cpu_read(long address, long length, u8 *data)
{
int control = BUS_CONTROL_CPU_READ;
if(address & ADDRESS_MASK_A15){
fc_bus_read(address, length, data, control, M2_CONTROL_TRUE);
}
-void ppu_read(long address, long length, u8 *data)
+static void ppu_read(long address, long length, u8 *data)
{
fc_bus_read(address, length, data, BUS_CONTROL_PPU_READ, M2_CONTROL_FALSE);
}
H:1, L:0, x:ROMareaaccess»þ0, ¤½¤ì°Ê³°1
*/
-void cpu_write(long address, long data)
+static void cpu_write(long address, long data)
{
int control = BUS_CONTROL_BUS_WRITE;
//addressÀßÄê + Á´¤Æ¤Î¥Ð¥¹¤ò»ß¤á¤ë
bus_control(BUS_CONTROL_BUS_WRITE);
}
-void ppu_write(long address, long data)
+static void ppu_write(long address, long data)
{
int control = BUS_CONTROL_BUS_WRITE;
bus_control(control);
bus_control(BUS_CONTROL_BUS_WRITE);
}
+
+const struct driver DRIVER_ONAJIMI = {
+ name: "onajimi",
+ init: reader_init,
+ cpu_read: cpu_read,
+ ppu_read: ppu_read,
+ cpu_write: cpu_write,
+ ppu_write: ppu_write
+};
#ifndef _DRIVER_ONAJIMI_H_
#define _DRIVER_ONAJIMI_H_
-
-void reader_init(void);
-void cpu_read(long address, long length, u8 *data);
-void ppu_read(long address, long length, u8 *data);
-void cpu_write(long address, long data);
-void ppu_write(long address, long data);
+const struct driver DRIVER_ONAJIMI;
#endif
--- /dev/null
+#ifndef _PARALELL_PORT_INLINE_H_
+#define _PARALELL_PORT_INLINE_H_
+/*
+famicom ROM cartridge dump program - unagi
+¥Ñ¥é¥ì¥ë¥Ý¡¼¥È¶¦ÍÄêµÁ
+*/
+//#include <dos.h> ?
+//#include <windows.h>
+#define ASM_ENABLE (0)
+enum{
+ PORT_DATA = 0x0378,
+ PORT_BUSY,
+ PORT_CONTROL
+};
+enum{
+ ADDRESS_MASK_A0toA12 = 0x1fff,
+ ADDRESS_MASK_A0toA14 = 0x7fff,
+ ADDRESS_MASK_A15 = 0x8000
+};
+
+#if ASM_ENABLE==0
+void _outp(int, int);
+int _inp(int);
+#endif
+
+/*
+static inline ¤Ï¶¦Í¥Þ¥¯¥í°·¤¤
+*/
+static inline int bit_set(int data, const int bit)
+{
+ data |= 1 << bit;
+ return data;
+}
+
+static inline int bit_clear(int data, const int bit)
+{
+ data &= ~(1 << bit);
+ return data;
+}
+
+static inline void wait(void)
+{
+ //const long waittime = 100000;
+ //SleepEx(20,TRUE);
+}
+
+#endif
#include <string.h>
#include "type.h"
#include "file.h"
-#include "driver_onajimi.h"
+#include "driver_master.h"
#include "giveio.h"
#include "textutil.h"
#include "header.h"
*/
enum {PPU_TEST_RAM, PPU_TEST_ROM};
const u8 PPU_TEST_DATA[] = "PPU_TEST_DATA";
-/*static*/ int ppu_ramtest(void)
+#if DEBUG==0
+static
+#endif
+int ppu_ramtest(const struct driver *d)
{
const int length = sizeof(PPU_TEST_DATA);
const long testaddr = 123;
int i = length;
long address = testaddr;
while(i != 0){
- ppu_write(address++, 0);
+ d->ppu_write(address++, 0);
i--;
}
}
//ppu test data write
{
- const u8 *d;
+ const u8 *data;
int i = length;
long address = testaddr;
- d = PPU_TEST_DATA;
+ data = PPU_TEST_DATA;
while(i != 0){
- ppu_write(address++, (long) *d);
- d++;
+ d->ppu_write(address++, (long) *data);
+ data++;
i--;
}
}
u8 writedata[length];
- ppu_read(testaddr, length, writedata);
+ d->ppu_read(testaddr, length, writedata);
if(memcmp(writedata, PPU_TEST_DATA, length) == 0){
return PPU_TEST_RAM;
}
checksum_print(m->data, length);
}
-static void execute_cpu_ramrw(const struct memory *w, struct memory *r, int mode, long address, long length)
+static void execute_cpu_ramrw(const struct driver *d, const struct memory *w, struct memory *r, int mode, long address, long length)
{
if(mode == MODE_RAM_WRITE){
const u8 *writedata;
long l = length;
writedata = w->data;
while(l != 0){
- cpu_write(a++, *writedata);
+ d->cpu_write(a++, *writedata);
writedata += 1;
l--;
}
}
- cpu_read(address, length, r->data);
+ d->cpu_read(address, length, r->data);
if(mode == MODE_RAM_DUMP){
return;
}
static int execute(const struct script *s, struct romimage *r)
{
+ const struct driver *d;
+ d = driver_get("hongkongfc");
+ if(d == NULL){
+ printf("execute error: driver not found.\n");
+ return NG;
+ }
const int gg = giveio_start();
switch(gg){
case GIVEIO_OPEN:
case GIVEIO_START:
case GIVEIO_WIN95:
- reader_init();
+ d->init();
break;
default:
case GIVEIO_ERROR:
if(is_region_cpuram(addr)){
m = &cpu_ram_read;
}
- cpu_read(addr, length, m->data);
+ d->cpu_read(addr, length, m->data);
read_result_print(m, length);
m->data += length;
m->offset += length;
case SCRIPT_OPCODE_CPU_WRITE:{
long data;
expression_calc(&s->expression, &data);
- cpu_write(s->value[0], data);
+ d->cpu_write(s->value[0], data);
}
break;
case SCRIPT_OPCODE_CPU_RAMRW:{
const long length = s->value[1];
- execute_cpu_ramrw(&cpu_ram_write, &cpu_ram_read, r->mode, s->value[0], length);
+ execute_cpu_ramrw(d, &cpu_ram_write, &cpu_ram_read, r->mode, s->value[0], length);
read_result_print(&cpu_ram_read, length);
cpu_ram_read.data += length;
cpu_ram_read.offset += length;
}
break;
case SCRIPT_OPCODE_PPU_RAMTEST:
- if(ppu_ramtest() == PPU_TEST_RAM){
+ if(ppu_ramtest(d) == PPU_TEST_RAM){
printf("PPU_RAMTEST: charcter RAM found\n");
r->ppu_rom.size = 0;
end = 0;
/*for mmc2,4 protect.
¤³¤Î¤È¤¤Ï1byteÆɤ߹þ¤ó¤Ç¡¢¤½¤ÎÆâÍƤϥХåե¡¤Ë¤¤¤ì¤Ê¤¤*/
u8 dummy;
- ppu_read(address, 1, &dummy);
+ d->ppu_read(address, 1, &dummy);
}else{
- ppu_read(address, length, ppu_rom.data);
+ d->ppu_read(address, length, ppu_rom.data);
read_result_print(&ppu_rom, length);
}
ppu_rom.data += length;
break;
case SCRIPT_OPCODE_PPU_WRITE:
if(OP_PPU_WRITE_ENABLE == 1){
- ppu_write(s->value[0], s->value[1]);
+ d->ppu_write(s->value[0], s->value[1]);
}
break;
case SCRIPT_OPCODE_STEP_START:
#ifndef _SCRIPT_H_
#define _SCRIPT_H_
-int ppu_ramtest(void);
+#if DEBUG==1
+#include "driver_master.h"
+int ppu_ramtest(const struct driver *d);
+#endif
void script_load(const char *inmode, const char *scriptfile, const char *targetfile, const int test_only);
struct st_variable{
#include <stdio.h>
#include <stdlib.h>
#include "type.h"
-#include "driver_onajimi.h"
+#include "driver_master.h"
#include "giveio.h"
#include "file.h"
#include "script.h"
#if DEBUG==1
-static void backupram_test(const char *file)
+static void test(const char *drivername, const char *file)
{
+ const struct driver *d;
+ d = driver_get(drivername);
+ if(d == NULL){
+ printf("execute error: driver not found.\n");
+ return;
+ }
const int gg = giveio_start();
switch(gg){
case GIVEIO_OPEN:
case GIVEIO_START:
case GIVEIO_WIN95:
- reader_init();
+ d->init();
break;
default:
case GIVEIO_ERROR:
switch(file[0]){
case 'p':
- printf("%d\n", ppu_ramtest());
+ printf("%d\n", ppu_ramtest(d));
break;
case 'b':{
const int testbufsize = 0x100;
u8 testbuf[testbufsize];
int i;
- cpu_read(0x6000, testbufsize, testbuf);
+ d->cpu_read(0x6000, testbufsize, testbuf);
for(i=0;i<0x10;i++){
printf("%02x ", testbuf[i]);
}
{
switch(c){
#if DEBUG==1
- case 2:
- backupram_test(v[1]);
+ case 3:
+ test(v[1], v[2]);
break;
#endif
case 4: