ppu_ctrl1_set,
ppu_ctrl2_set,
null_write,
- sprite_data_set,
sprite_addr_set,
+ sprite_data_set,
ppu_scroll_set,
ppu_vram_addr_set,
ppu_vram_data_set
DUMMY_OBJS=dummy-driver2.o debug.o cartridge.o
OBJS=ppucore.o vram.o vscreen.o palette.o \
- vga_xfer.o
+ vga_xfer.o sprite.o
LIBS=-L../../libs -L./ -lmotones -pthread -lrt -lppucore
#include "vram.h"
#include "ppucore.h"
#include "vga_xfer.h"
+#include "sprite.h"
int vscreen_init(void);
void clean_vscreen(void);
void set_bg_pattern_bank(unsigned char bank);
void set_spr_pattern_bank(unsigned char bank);
void set_bg_name_tbl_base(unsigned char sw);
+void spr_ram_tbl_set(unsigned short offset, unsigned char data);
+int show_sprite(int foreground);
void dump_ppu_reg(void);
unsigned int cnt :1;
};
+struct ppu_scroll_reg {
+ unsigned char x;
+ unsigned char y;
+ unsigned int cnt :1;
+};
/*ppu core register instances*/
static struct ppu_ctrl_reg1 ctrl_reg1;
static struct ppu_ctrl_reg2 ctrl_reg2;
static struct ppu_status_reg status_reg;
static struct ppu_vram_addr_reg vram_addr_reg;
+static struct ppu_scroll_reg scroll_reg;
+static struct ppu_sprite_reg sprite_reg;
static unsigned char sprite_ram_addr_reg;
-static unsigned char sprite_ram_data_reg;
static unsigned char sprite_ram_dma_reg;
static unsigned char vram_data_reg;
-static unsigned char scroll_reg;
static unsigned char vram_dma_reg;
//value set by the ctrl_reg1.
clock_gettime(CLOCK_REALTIME, &begin);
if (ctrl_reg2.show_sprite) {
//sprite in the back
- ;
+ show_sprite(FALSE);
}
if (ctrl_reg2.show_bg/**/) {
//back ground image
}
if (ctrl_reg2.show_sprite) {
//foreground sprite
- ;
+ show_sprite(TRUE);
}
if (updated)
vga_xfer();
}
void sprite_addr_set(unsigned char addr) {
+ dprint("sprite_addr_set addr=%02x\n", addr);
sprite_ram_addr_reg = addr;
+ sprite_reg.cnt = 0;
}
void sprite_data_set(unsigned char data) {
- sprite_ram_data_reg = data;
+ dprint("sprite_data_set addr=%02x, data=%02x, cnt:%d\n",
+ sprite_ram_addr_reg, data, sprite_reg.cnt);
+ switch (sprite_reg.cnt) {
+ case 0:
+ default:
+ sprite_reg.y = data;
+ break;
+ case 1:
+ sprite_reg.index = data;
+ break;
+ case 2:
+ memcpy(&sprite_reg.sa, &data, sizeof(struct sprite_attr));
+ break;
+ case 3:
+ sprite_reg.x = data;
+ break;
+ }
+ spr_ram_tbl_set(sprite_ram_addr_reg + sprite_reg.cnt, data);
+ sprite_reg.cnt++;
}
void ppu_scroll_set(unsigned char data) {
- scroll_reg = data;
+ dprint("scroll set %s = %02x\n", (scroll_reg.cnt == 0 ? "x" : "y"), data);
+ if (scroll_reg.cnt++ == 0)
+ scroll_reg.x = data;
+ else
+ scroll_reg.y = data;
}
void ppu_vram_addr_set(unsigned char half_addr) {
memset(&ctrl_reg2, 0, sizeof(ctrl_reg1));
memset(&status_reg, 0, sizeof(status_reg));
memset(&vram_addr_reg, 0, sizeof(vram_addr_reg));
+ memset(&scroll_reg, 0, sizeof(scroll_reg));
+ memset(&sprite_reg, 0, sizeof(sprite_reg));
sprite_ram_addr_reg = 0;
- sprite_ram_data_reg = 0;
sprite_ram_dma_reg = 0;
vram_data_reg = 0;
- scroll_reg = 0;
vram_dma_reg = 0;
vram_read_cnt = 0;
if (!ret)
return FALSE;
+ ret = sprite_init();
+ if (!ret)
+ return FALSE;
+
ret = vscreen_init();
if (!ret)
return FALSE;
dprint("ppucore thread joined.\n");
clean_vram();
+ clean_sprite();
clean_vscreen();
}
--- /dev/null
+#include <stdlib.h>
+#include <string.h>
+
+#include "tools.h"
+#include "vga.h"
+#include "vram.h"
+#include "ppucore.h"
+#include "sprite.h"
+
+void palette_index_to_rgb15(unsigned char index, struct rgb15* rgb);
+
+
+static unsigned char * sprite_ram;
+
+void spr_ram_tbl_set(unsigned short offset, unsigned char data) {
+ sprite_ram[offset & SPR_RAM_ADDR_MASK] = data;
+}
+
+void spr_ram_data_get(unsigned char index, unsigned char *x, unsigned char *y,
+ unsigned char *tile_id, struct sprite_attr *sa) {
+ //index is multiple of 4.
+ index *= 4;
+ index &= SPR_RAM_ADDR_MASK;
+
+ *y = sprite_ram[index++];
+ *tile_id = sprite_ram[index++];
+ memcpy(sa, sprite_ram + index++, sizeof(struct sprite_attr));
+ *x = sprite_ram[index++];
+}
+
+int sprite_init(void) {
+ sprite_ram = malloc(SPRITE_RAM_SIZE);
+ if (sprite_ram == NULL)
+ return FALSE;
+ memset(sprite_ram, 0, SPRITE_RAM_SIZE);
+ return TRUE;
+}
+
+void clean_sprite(void) {
+ free(sprite_ram);
+}
+
unsigned int flip_v :1;
} __attribute__ ((packed));
+struct ppu_sprite_reg {
+ unsigned char y;
+ unsigned char index;
+ struct sprite_attr sa;
+ unsigned char x;
+ unsigned int cnt :2;
+};
+
+#define SPRITE_RAM_SIZE 0x100
+#define SPRITE_CNT (SPRITE_RAM_SIZE / 4)
+#define SPR_RAM_ADDR_MASK (SPRITE_RAM_SIZE - 1)
+
+int sprite_init(void);
+void clean_sprite(void);
+
#endif /*__sprite_h__*/
void set_bgtile(int tile_id);
/*vram definition*/
-static unsigned char * sprite_ram;
static unsigned char * bg_palette_tbl;
static unsigned char * spr_palette_tbl;
bg_palette_tbl[offset] = data;
}
-
-static unsigned char spr_ram_tbl_get(unsigned short offset) {
- return sprite_ram[offset];
-}
-
-static void spr_ram_tbl_set(unsigned short offset, unsigned char data) {
- sprite_ram[offset] = data;
-}
-
void vram_data_set(unsigned short addr, unsigned char data) {
#ifdef PPU_TEST
if (!first_time)
}
#endif /* PPU_TEST */
-int show_background(void) {
- int i;
-
-#ifdef PPU_TEST
- if (1 /*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++) {
- set_bgtile(i);
- }
- return TRUE;
-}
-
static int attr_index_to_gp(int tile_index) {
int tile_x, tile_y, gp_x, gp_y;
if (pattern_tbl1 == NULL)
return FALSE;
- sprite_ram = malloc(SPRITE_RAM_SIZE);
- if (sprite_ram == NULL)
- return FALSE;
-
name_tbl0 = malloc(NAME_TBL_SIZE);
if (name_tbl0 == 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);
free(pattern_tbl0);
free(pattern_tbl1);
- free(sprite_ram);
-
free(name_tbl0);
free(name_tbl1);
#define ATTR_TBL_SIZE (VIRT_SCREEN_TILE_SIZE * VIRT_SCREEN_TILE_SIZE \
/ ATTR_GROUP_UNIT / ATTR_UNIT_PER_BYTE)
#define PALETTE_TBL_SIZE 0x10
-#define SPRITE_RAM_SIZE 0xff
#define PATTERN_ADDR_MASK (PATTERN_TBL_SIZE - 1)
#define ATTR_TBL_ADDR_MASK (ATTR_TBL_SIZE - 1)
#define PALETTE_TBL_ADDR_MASK (PALETTE_TBL_SIZE - 1)
-#define SPR_RAM_ADDR_MASK (SPRITE_RAM_SIZE - 1)
#define PPU_ADDR_MASK (0x4000 - 1)
#define PALETTE_START 0x3F00
void load_attribute(unsigned char bank, int tile_index, struct palette *plt);
void load_pattern(unsigned char bank, unsigned char ptn_index, struct tile_2* pattern);
void load_spr_attribute(struct sprite_attr sa, struct palette *plt);
+void spr_ram_data_get(unsigned char index, unsigned char *x, unsigned char *y,
+ unsigned char *tile_id, struct sprite_attr *sa);
struct tile_rgb15_line {
struct rgb15 d[8];
set_data->l[i].d[7 - j] = plt.col[pi];
}
else {
- //TODO
- //for the time being, transparent bg color is black..
+ //TODO for the time being, transparent bg color is black..
+ /*
set_data->l[i].d[7 - j].r = 0;
set_data->l[i].d[7 - j].g = 0;
set_data->l[i].d[7 - j].b = 0;
+ */
}
}
}
}
+int show_background(void) {
+ int i;
+
+ for (i = 0; i < H_SCREEN_TILE_SIZE * V_SCREEN_TILE_SIZE; i++) {
+ set_bgtile(i);
+ }
+ return TRUE;
+}
+
+
void set_sprite(int x, int y, int tile_id, struct sprite_attr sa) {
struct palette plt;
struct tile_2 ptn;
}
}
+int show_sprite(int foreground) {
+ int i;
+ struct sprite_attr sa;
+ unsigned char x, y, tile;
+
+ if (foreground) {
+ for (i = 0; i < SPRITE_CNT; i++) {
+ spr_ram_data_get(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);
+ if (!sa.priority)
+ set_sprite(x, y, tile, sa);
+ }
+ }
+ return TRUE;
+}
+
+
void set_bg_pattern_bank(unsigned char bank) {
bg_pattern_bank = bank;
}