OBJS=emu-main.o clock.o bus.o cpu.o \
rom.o cartridge.o 6502core.o debug.o ram.o \
- ppu.o
+ ppu.o dma.o ioapu.o
# kbhit.o
--- /dev/null
+#ifndef __apu_h__
+#define __apu_h__
+
+void set_apu_addr(unsigned short addr);
+unsigned char get_apu_data(void);
+void set_apu_data(unsigned char data);
+
+void set_apu_start(int ce);
+
+#endif /*__apu_h__*/
+
#include "rom.h"
#include "ram.h"
#include "ppu.h"
+#include "apu.h"
unsigned char dbg_rom_get_byte(unsigned short offset);
unsigned short dbg_rom_get_short(unsigned short offset);
* */
#define IO_PPU_BIT 0x2000
-#define IO_APU_BIT 0x6000
+#define IO_APU_BIT 0x4000
#define ROM_BIT 0x8000
#define RAM_MASK 0x07FF
* */
void start_bus(void) {
//dprint("start bus %04x, addr&ppu: %x\n", addr_bus, addr_bus & IO_PPU_BIT);
+ pin_status.ready = 0;
if (addr_bus & ROM_BIT) {
/*case rom*/
- pin_status.ready = 0;
set_rom_ce_pin(TRUE);
}
- else if ((addr_bus & IO_APU_BIT) == IO_APU_BIT) {
+ else if (addr_bus & IO_APU_BIT) {
+ set_apu_start(TRUE);
}
else if (addr_bus & IO_PPU_BIT) {
/*case ppu*/
- pin_status.ready = 0;
set_ppu_ce_pin(TRUE);
}
else {
/*case ram*/
- pin_status.ready = 0;
set_ram_ce_pin(TRUE);
}
}
if (!pin_status.ready) {
fprintf(stderr, "pin not ready!!!!\n");
}
+
//dprint("end bus\n");
if (addr_bus & ROM_BIT) {
set_rom_ce_pin(FALSE);
}
- else if ((addr_bus & IO_APU_BIT) == IO_APU_BIT) {
+ else if (addr_bus & IO_APU_BIT) {
+ set_apu_start(FALSE);
}
else if (addr_bus & IO_PPU_BIT) {
set_ppu_ce_pin(FALSE);
if (addr & ROM_BIT) {
set_rom_addr(addr & ROM_MASK);
}
- else if ((addr & IO_APU_BIT) == IO_APU_BIT) {
+ else if (addr & IO_APU_BIT) {
+ //dprint("bus addr ioapu...\n");
+ set_apu_addr(addr & IO_APU_MASK);
}
else if (addr & IO_PPU_BIT) {
set_ppu_addr(addr & IO_PPU_MASK);
critical_error = TRUE;
//no write to ROM
}
- else if ((addr_bus & IO_APU_BIT) == IO_APU_BIT) {
+ else if (addr_bus & IO_APU_BIT) {
+ set_apu_data(data);
}
else if (addr_bus & IO_PPU_BIT) {
set_ppu_data(data);
if (addr_bus & ROM_BIT) {
data_bus = get_rom_data();
}
- else if ((addr_bus & IO_APU_BIT) == IO_APU_BIT) {
+ else if (addr_bus & IO_APU_BIT) {
+ data_bus = get_apu_data();
}
else if (addr_bus & IO_PPU_BIT) {
data_bus = get_ppu_data();
pin_status.rw = rw;
}
+int get_rw_pin(void) {
+ return pin_status.rw;
+}
+
/*nmi interrupt*/
void set_nmi_pin(int val) {
pin_status.nmi = val;
if (addr & ROM_BIT) {
return dbg_rom_get_byte(addr & ROM_MASK);
}
- else if ((addr & IO_APU_BIT) == IO_APU_BIT) {
+ else if (addr & IO_APU_BIT) {
return 0;
}
else if (addr & IO_PPU_BIT) {
if (addr & ROM_BIT) {
return dbg_rom_get_short(addr & ROM_MASK);
}
- else if ((addr & IO_APU_BIT) == IO_APU_BIT) {
+ else if (addr & IO_APU_BIT) {
return 0;
}
else if (addr & IO_PPU_BIT) {
--- /dev/null
+
+#include "tools.h"
+
+static unsigned char sprite_dma_reg;
+
+void set_dma_data(unsigned char data) {
+ dprint("set_dma_data: %02x\n", data);
+ sprite_dma_reg = data;
+}
+
+int init_dma(void) {
+
+ sprite_dma_reg = 0;
+ return TRUE;
+}
+
+void clean_dma(void) {
+
+}
+
int init_bus(void);
int init_debug(void);
int init_ppu(void);
+int init_apu(void);
+int init_dma(void);
void clean_bus(void);
void clean_debug(void);
void clean_ppu(void);
+void clean_apu(void);
+void clean_dma(void);
void reset_cpu(void);
int load_cartridge(const char* cartridge);
return FALSE;
}
+ ret = init_apu();
+ if (!ret) {
+ fprintf(stderr, "apu init err.\n");
+ return FALSE;
+ }
+
+ ret = init_dma();
+ if (!ret) {
+ fprintf(stderr, "dma init err.\n");
+ return FALSE;
+ }
+
ret = init_cpu();
if (!ret) {
fprintf(stderr, "cpu init err.\n");
static void clean_datas(void) {
dprint("clean data...\n");
clean_clock();
+ clean_dma();
clean_rom();
clean_ram();
clean_ppu();
+ clean_apu();
clean_bus();
clean_debug();
--- /dev/null
+#include "tools.h"
+#include "apu.h"
+
+static unsigned short apu_addr;
+static unsigned char apu_data;
+
+#define APU_IO_SIZE 0x20
+
+/*
+ * apucore r/w func ptr.
+ * */
+void set_dma_data(unsigned char data);
+void release_bus(void);
+int get_rw_pin(void);
+
+typedef void (apu_write_t)(unsigned char);
+typedef unsigned char (apu_read_t)(void);
+
+static apu_write_t *apu_write_func[APU_IO_SIZE];
+static apu_read_t *apu_read_func[APU_IO_SIZE];
+
+void set_apu_addr(unsigned short addr) {
+ dprint("set_apu_addr: %02x\n", addr);
+ apu_addr = addr;
+}
+
+unsigned char get_apu_data(void) {
+ return apu_data;
+}
+
+void set_apu_data(unsigned char data) {
+ dprint("set_apu_data: %02x\n", data);
+ apu_data = data;
+}
+
+void set_apu_start(int ce) {
+ //let ram i/o on the bus.
+ if (ce) {
+ if (get_rw_pin()) {
+ //write cycle
+ apu_write_func[apu_addr](apu_data);
+ }
+ else {
+ //read cycle
+ apu_data = apu_read_func[apu_addr]();
+ }
+ release_bus();
+ }
+}
+
+
+/*dummy I/O func*/
+static void null_write(unsigned char d){}
+static unsigned char null_read(void){return 0;}
+
+int init_apu(void) {
+ int i;
+ apu_addr = 0;
+ apu_data = 0;
+
+ //fill null function
+ for (i = 0; i < APU_IO_SIZE; i++) {
+ apu_write_func[i] = null_write;
+ }
+ for (i = 0; i < APU_IO_SIZE; i++) {
+ apu_read_func[i] = null_read;
+ }
+ //dma func
+ apu_write_func[0x14] = set_dma_data;
+
+ return TRUE;
+}
+
+void clean_apu(void) {
+}
+
struct sprite_attr sa;
unsigned char x, y, tile;
+ //sprite priority:
+ //draw lowest priority first,
+ //high priority late. highest priority comes top.
if (foreground) {
for (i = 0; i < SPRITE_CNT; i++) {
- spr_ram_data_get(i, &x, &y, &tile, &sa);
+ spr_ram_data_get(SPRITE_CNT - 1 - i, &x, &y, &tile, &sa);
if (sa.priority)
set_sprite(x, y, tile, sa);
}
}
else {
for (i = 0; i < SPRITE_CNT; i++) {
- spr_ram_data_get(i, &x, &y, &tile, &sa);
+ spr_ram_data_get(SPRITE_CNT - 1 - i, &x, &y, &tile, &sa);
if (!sa.priority)
set_sprite(x, y, tile, sa);
}