From: astoria-d Date: Fri, 15 Mar 2013 06:18:22 +0000 (+0900) Subject: ppu ok. X-Git-Tag: motonesemu-0.1.0 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=a3c26535aa9b8c05cd769470d4aa8993cd56d75d;p=motonesemu%2Fmotonesemu.git ppu ok. now hello world works on the emulator!! --- diff --git a/emulator/clock.h b/emulator/clock.h index 910ed6e..d43f001 100644 --- a/emulator/clock.h +++ b/emulator/clock.h @@ -1,9 +1,6 @@ #ifndef __clock_h__ #define __clock_h__ -#include -#include - typedef int (clock_func_t) (void); int init_clock(void); @@ -21,7 +18,7 @@ int start_cpu_clock(void); //#undef DEB_SLOW #ifdef DEB_SLOW -#define CPU_CLOCK_FREQ 100L +#define CPU_CLOCK_FREQ 500000L #else #define CPU_CLOCK_FREQ 1789773L #endif diff --git a/emulator/cpu.c b/emulator/cpu.c index 898bbda..7338c3a 100644 --- a/emulator/cpu.c +++ b/emulator/cpu.c @@ -1,6 +1,5 @@ #include #include -#include #include #include #include "tools.h" diff --git a/emulator/ppu.c b/emulator/ppu.c index 0bbf429..559b761 100644 --- a/emulator/ppu.c +++ b/emulator/ppu.c @@ -116,7 +116,6 @@ static void null_write(unsigned char d){} static unsigned char null_read(void){return 0;} static void *ppu_loop(void* arg) { - struct timespec ts = {CPU_CLOCK_SEC, CPU_CLOCK_NSEC / 10}; while (!ppu_end_loop) { sem_wait(&ppu_sem_id); if (ppu_pin.ce) { @@ -128,7 +127,6 @@ static void *ppu_loop(void* arg) { //read cycle ppu_data = ppucore_read_func[ppu_addr](); } - nanosleep(&ts, NULL); release_bus(); } } diff --git a/emulator/ppucore/ppucore.c b/emulator/ppucore/ppucore.c index ea6cd15..e226647 100644 --- a/emulator/ppucore/ppucore.c +++ b/emulator/ppucore/ppucore.c @@ -149,8 +149,8 @@ unsigned char ppu_status_get(void) { return ret; } -void sprite_addr_set(unsigned char data) { - sprite_ram_addr_reg = data; +void sprite_addr_set(unsigned char addr) { + sprite_ram_addr_reg = addr; } void sprite_data_set(unsigned char data) { @@ -161,14 +161,16 @@ void ppu_scroll_set(unsigned char data) { scroll_reg = data; } -void ppu_vram_addr_set(unsigned char data) { +void ppu_vram_addr_set(unsigned char half_addr) { + //dprint("vram addr:%04x\n", half_addr); if (vram_addr_reg.cnt++ == 0) - vram_addr_reg.addr.b.low = data; + vram_addr_reg.addr.b.hi = half_addr; else - vram_addr_reg.addr.b.hi = data; + vram_addr_reg.addr.b.low = half_addr; } void ppu_vram_data_set(unsigned char data) { + //dprint("vram data:%04x\n", data); vram_data_reg = data; vram_data_set(vram_addr_reg.addr.s, data); diff --git a/emulator/ppucore/ppucore.h b/emulator/ppucore/ppucore.h index 0eceee4..7790d3a 100644 --- a/emulator/ppucore/ppucore.h +++ b/emulator/ppucore/ppucore.h @@ -20,10 +20,10 @@ void ppu_ctrl1_set(unsigned char data); void ppu_ctrl2_set(unsigned char data); -void sprite_addr_set(unsigned char data); +void sprite_addr_set(unsigned char addr); void sprite_data_set(unsigned char data); void ppu_scroll_set(unsigned char data); -void ppu_vram_addr_set(unsigned char data); +void ppu_vram_addr_set(unsigned char half_addr); void ppu_vram_data_set(unsigned char data); unsigned char ppu_status_get(void); diff --git a/emulator/ppucore/vram.c b/emulator/ppucore/vram.c index 443fc21..93f7584 100644 --- a/emulator/ppucore/vram.c +++ b/emulator/ppucore/vram.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "tools.h" #include "ppucore.h" @@ -40,7 +41,7 @@ void set_bgtile(int tile_id); #define NAME_TBL_SIZE V_SCREEN_TILE_SIZE * H_SCREEN_TILE_SIZE #define ATTR_TBL_SIZE (VIRT_SCREEN_TILE_SIZE * VIRT_SCREEN_TILE_SIZE \ / ATTR_GROUP_UNIT / ATTR_UNIT_PER_BYTE) -#define PALETTE_TBL_SIZE 16 +#define PALETTE_TBL_SIZE 0x10 #define SPRITE_RAM_SIZE 0xff #define PATTERN_ADDR_MASK (PATTERN_TBL_SIZE - 1) @@ -50,8 +51,7 @@ void set_bgtile(int tile_id); #define PPU_ADDR_MASK (0x4000 - 1) #define PALETTE_START 0x3F00 -#define NAME_ATTR_MASK1 (0x3000 - 1) -#define NAME_ATTR_MASK2 (0x0400 - 1) +#define NAME_ATTR_MASK 0x2FFF #define PALETTE_SPRITE_BIT 0x10 #define NAME0_START PATTERN_TBL_SIZE * 2 @@ -167,37 +167,42 @@ static void spr_ram_tbl_set(unsigned short offset, unsigned char data) { void vram_data_set(unsigned short addr, unsigned char data) { + //mirror 0x4000 up addr. addr &= PPU_ADDR_MASK; if (addr < 2 * PATTERN_TBL_SIZE) { //do nothing. pattern table is read only. } else if (addr >= PALETTE_START) { + // bg/sprite palette table. if (addr & PALETTE_SPRITE_BIT) - bg_palette_tbl_set(addr & PALETTE_TBL_ADDR_MASK, data); + spr_palette_tbl_set(addr & PALETTE_TBL_ADDR_MASK, data); else bg_palette_tbl_set(addr & PALETTE_TBL_ADDR_MASK, data); } else { - if (addr < NAME0_START) { + // name/attr table. + // mask 0x3000 up addr. + addr &= NAME_ATTR_MASK; + if (addr < ATTR0_START) { name_tbl_set(0, addr - NAME0_START, data); } - else if (addr < ATTR0_START) { + else if (addr < NAME1_START) { attr_tbl_set(0, addr - ATTR0_START, data); } - else if (addr < NAME1_START) { + else if (addr < ATTR1_START) { name_tbl_set(1, addr - NAME1_START, data); } - else if (addr < ATTR1_START) { + else if (addr < NAME2_START) { attr_tbl_set(1, addr - ATTR1_START, data); } - else if (addr < NAME2_START) { + else if (addr < ATTR2_START) { name_tbl_set(2, addr - NAME2_START, data); } - else if (addr < ATTR2_START) { + else if (addr < NAME3_START) { attr_tbl_set(2, addr - ATTR2_START, data); } - else if (addr < NAME3_START) { + else if (addr < ATTR3_START) { name_tbl_set(3, addr - NAME3_START, data); } else { @@ -218,30 +223,31 @@ unsigned char vram_data_get(unsigned short addr) { } else if (addr >= PALETTE_START) { if (addr & PALETTE_SPRITE_BIT) - return bg_palette_tbl_get(addr & PALETTE_TBL_ADDR_MASK); + return spr_palette_tbl_get(addr & PALETTE_TBL_ADDR_MASK); else return bg_palette_tbl_get(addr & PALETTE_TBL_ADDR_MASK); } else { - if (addr < NAME0_START) { + addr &= NAME_ATTR_MASK; + if (addr < ATTR0_START) { return name_tbl_get(0, addr - NAME0_START); } - else if (addr < ATTR0_START) { + else if (addr < NAME1_START) { return attr_tbl_get(0, addr - ATTR0_START); } - else if (addr < NAME1_START) { + else if (addr < ATTR1_START) { return name_tbl_get(1, addr - NAME1_START); } - else if (addr < ATTR1_START) { + else if (addr < NAME2_START) { return attr_tbl_get(1, addr - ATTR1_START); } - else if (addr < NAME2_START) { + else if (addr < ATTR2_START) { return name_tbl_get(2, addr - NAME2_START); } - else if (addr < ATTR2_START) { + else if (addr < NAME3_START) { return attr_tbl_get(2, addr - ATTR2_START); } - else if (addr < NAME3_START) { + else if (addr < ATTR3_START) { return name_tbl_get(3, addr - NAME3_START); } else { @@ -253,8 +259,100 @@ unsigned char vram_data_get(unsigned short addr) { /* VRAM manipulation... */ +//#define PPU_TEST +#ifdef PPU_TEST +/* + * ppu test function + * */ +static void test_ppu(void) { + int i; + unsigned char plt[32] = { + 0x0f, 0x00, 0x10, 0x20, + 0x0f, 0x06, 0x16, 0x26, + 0x0f, 0x08, 0x18, 0x28, + 0x0f, 0x0a, 0x1a, 0x2a, + + 0x0f, 0x00, 0x10, 0x20, + 0x0f, 0x06, 0x16, 0x26, + 0x0f, 0x08, 0x18, 0x28, + 0x0f, 0x0a, 0x1a, 0x2a, + }; + +/* + //palette tbl + for (i = 0; i < 16; i++) + vram_data_set(0x3f00 + i, plt[i]); + for (i = 0; i < 16; i++) + vram_data_set(0x3f10 + i, plt[i + 16]); +*/ + //name tbl + for (i = 0; i < 960; i++) + vram_data_set(0x2000 + i, 0); + +/* +*/ + //attr tbl + for (i = 0; i < 64; i++) + vram_data_set(0x23c0 + i, 0); + + vram_data_set(0x2000 + 205, 'D'); + vram_data_set(0x2000 + 206, 'e'); + vram_data_set(0x2000 + 207, 'e'); + vram_data_set(0x2000 + 208, '!'); + vram_data_set(0x2000 + 209, '!'); + //205 = palette gp2 00011011b + //205 = 11 + vram_data_set(0x23c0 + 11, 0x1b); + + //other test. + vram_data_set(0x2000 + 300, 1); + vram_data_set(0x2000 + 0, 0x65); + /* + * */ + + set_monocolor(FALSE); + + for (i = 0; i < 960; i++) + set_bgtile(i); + + //sprite test + struct sprite_attr sa; + sa.palette = 2; + sa.priority = 1; + sa.flip_h = 0; + sa.flip_v = 0; + set_sprite(30, 100, 'd', sa); + sa.flip_h = 1; + set_sprite(50, 100, 'd', sa); + sa.flip_v = 1; + set_sprite(70, 105, 'd', sa); + + /* + vga_xfer(); +*/ + +//void dump_vram(int type, int bank, unsigned short addr, int size); +/* + dump_vram(VRAM_DUMP_TYPE_PTN, 0, 0, 0x100); + dump_vram(VRAM_DUMP_TYPE_NAME, 0, 0, 300); + dump_vram(VRAM_DUMP_TYPE_ATTR, 0, 0, 64); + dump_vram(VRAM_DUMP_TYPE_PLT, 0, 0, 16); +*/ +} +static int first_time = TRUE; +#endif /* PPU_TEST */ + int show_background(void) { int i; + +#ifdef PPU_TEST + if (first_time) { + test_ppu(); + first_time = FALSE; + } + return TRUE; +#endif /*PPU_TEST */ + for (i = 0; i < H_SCREEN_TILE_SIZE * V_SCREEN_TILE_SIZE; i++) { #warning update bg must be more efficient. update only changed tile. set_bgtile(i); @@ -443,6 +541,16 @@ int vram_init(void) { if (spr_palette_tbl == NULL) return FALSE; + memset(pattern_tbl0, 0, PATTERN_TBL_SIZE); + memset(pattern_tbl1, 0, PATTERN_TBL_SIZE); + memset(sprite_ram, 0, SPRITE_RAM_SIZE); + memset(name_tbl0, 0, NAME_TBL_SIZE); + memset(name_tbl1, 0, NAME_TBL_SIZE); + memset(attr_tbl0, 0, ATTR_TBL_SIZE); + memset(attr_tbl1, 0, ATTR_TBL_SIZE); + memset(bg_palette_tbl, 0, PALETTE_TBL_SIZE); + memset(spr_palette_tbl, 0, PALETTE_TBL_SIZE); + return TRUE; } diff --git a/emulator/ram.c b/emulator/ram.c index 1bfaec0..91efad6 100644 --- a/emulator/ram.c +++ b/emulator/ram.c @@ -56,19 +56,16 @@ void set_ram_ce_pin(int ce) { static void *ram_loop(void* arg) { //ram data load delay is 1/10 (dummy interval) - struct timespec ts = {CPU_CLOCK_SEC, CPU_CLOCK_NSEC / 10}; while (!ram_end_loop) { sem_wait(&ram_sem_id); if (ram_pin_status.ce) { if (ram_pin_status.oe) { //read cycle - nanosleep(&ts, NULL); ram_data = ram_buffer[ram_addr]; } else if (ram_pin_status.we) { //write cycle - nanosleep(&ts, NULL); ram_buffer[ram_addr] = ram_data; } release_bus(); diff --git a/emulator/rom.c b/emulator/rom.c index b0cabce..f54d57a 100644 --- a/emulator/rom.c +++ b/emulator/rom.c @@ -54,12 +54,10 @@ void set_rom_ce_pin(int ce) { static void *rom_loop(void* arg) { //rom data load delay is 1/10 (dummy interval) - struct timespec ts = {CPU_CLOCK_SEC, CPU_CLOCK_NSEC / 10}; while (!rom_end_loop) { sem_wait(&rom_sem_id); if (rom_pin_status.ce) { - nanosleep(&ts, NULL); rom_data = rom_buffer[rom_addr]; release_bus(); }