#include <stdlib.h>
#include <time.h>
#include <string.h>
-#include <pthread.h>
-#include <semaphore.h>
#include "clock.h"
#include "tools.h"
+#include "vga.h"
+#include "ppucore.h"
-int ppucore_init(void);
+void set_vga_base(unsigned char* base);
+void *vga_shm_get(void);
+void vga_shm_free(void* addr);
+void release_bus(void);
struct ppu_cpu_pin {
unsigned int ce :1; /*chip enable*/
unsigned int vblank :1; /*connected to nmi*/
};
-struct ppu_register {
- unsigned char control1; /*write only*/
- unsigned char control2; /*write only*/
- unsigned char status; /*read only*/
- unsigned char sprite_addr;
- unsigned char sprite_data;
- unsigned char scroll;
- unsigned char vram_addr;
- unsigned char vram_data;
-};
-
struct ppu_cart_pin {
unsigned int rd :1; /*read*/
unsigned int wr :1; /*write.*/
static struct ppu_cpu_pin ppu_pin;
static struct ppu_cart_pin cart_pin;
-struct ppu_register ppu_reg;
+static unsigned short ppu_addr;
+static unsigned char ppu_data;
+
+static unsigned char* vga_shared_buf;
-static pthread_t ppu_thread_id;
-static int ppu_end_loop;
-static sem_t ppu_sem_id;
/*
- * JAPAN/US uses NTSC standard.
- *
- * NTSC:
- * ---------------------------------------------------------
- * Frames per second 60
- * Time per frame (milliseconds) 16.67
- * Scanlines per frame (of which is V-Blank) 262 (20)
- * CPU cycles per scanline 113.33
- * Resolution 256 x 224
- * CPU speed 1.79 MHz
- *
- * PPU clock 21.48 Mhz
+ * ppucore r/w func ptr.
* */
+typedef void (ppu_write_t)(unsigned char);
+typedef unsigned char (ppu_read_t)(void);
+
+static void null_write(unsigned char);
+static unsigned char null_read(void);
+
+static ppu_write_t *ppucore_write_func[8] = {
+ ppu_ctrl1_set,
+ ppu_ctrl2_set,
+ null_write,
+ sprite_data_set,
+ sprite_addr_set,
+ ppu_scroll_set,
+ ppu_vram_addr_set,
+ ppu_vram_data_set
+};
+
+static ppu_read_t *ppucore_read_func[8] = {
+ null_read,
+ null_read,
+ ppu_status_get,
+ null_read,
+ null_read,
+ null_read,
+ null_read,
+ ppu_vram_data_get
+};
-void set_ppu_addr(unsigned char data) {
+/*
+* JAPAN/US uses NTSC standard.
+*
+* NTSC:
+* ---------------------------------------------------------
+* Frames per second 60
+* Time per frame (milliseconds) 16.67
+* Scanlines per frame (of which is V-Blank) 262 (20)
+* CPU cycles per scanline 113.33
+* Resolution 256 x 224
+* CPU speed 1.79 MHz
+*
+* PPU clock 21.48 Mhz
+* */
+
+void set_ppu_addr(unsigned short addr) {
+ ppu_addr = addr;
}
unsigned char get_ppu_data(void) {
- return 0;
+ return ppu_data;
}
void set_ppu_data(unsigned char data) {
+ ppu_data = data;
}
-static void *ppu_loop(void* arg) {
- //struct timespec ts = {CPU_CLOCK_SEC, CPU_CLOCK_NSEC / 10};
+/*
+ * write: rw = 1
+ * read: rw = 0
+ * */
+void set_ppu_rw_pin(int rw) {
+ ppu_pin.rw = rw;
+}
- while (!ppu_end_loop) {
- sem_wait(&ppu_sem_id);
- ;
+void set_ppu_ce_pin(int ce) {
+ ppu_pin.ce = ce;
+ //let ram i/o on the bus.
+ if (ce) {
+ if (ppu_pin.rw) {
+ //write cycle
+ ppucore_write_func[ppu_addr](ppu_data);
+ }
+ else {
+ //read cycle
+ ppu_data = ppucore_read_func[ppu_addr]();
+ }
+ release_bus();
}
- return NULL;
}
+/*dummy I/O func*/
+static void null_write(unsigned char d){}
+static unsigned char null_read(void){return 0;}
+
int init_ppu(void) {
int ret;
- pthread_attr_t attr;
-
- ppu_end_loop = FALSE;
- memset(&ppu_reg, 0, sizeof(ppu_reg));
ppu_pin.ce = 0;
ppu_pin.rw = 0;
cart_pin.rd = 0;
cart_pin.wr = 0;
- ret = ppucore_init();
- if (ret == FALSE) {
- return FALSE;
- }
+ ppu_addr = 0;
+ ppu_data = 0;
- ret = sem_init(&ppu_sem_id, 0, 0);
- if (ret != RT_OK) {
+ /* get vga shared memory */
+ if((vga_shared_buf = (unsigned char*)vga_shm_get()) == NULL)
+ {
+ fprintf(stderr, "error attaching shared memory.\n");
return FALSE;
}
- ret = pthread_attr_init(&attr);
- if (ret != RT_OK) {
- return FALSE;
- }
+ memset(vga_shared_buf, 0, VGA_SHM_SIZE);
+ set_vga_base((unsigned char*)vga_shared_buf);
- ppu_thread_id = 0;
- ret = pthread_create(&ppu_thread_id, &attr, ppu_loop, NULL);
- if (ret != RT_OK) {
+ ret = ppucore_init();
+ if (ret == FALSE) {
return FALSE;
}
}
void clean_ppu(void) {
- void* ret;
-
- ppu_end_loop = TRUE;
- sem_post(&ppu_sem_id);
- pthread_join(ppu_thread_id, &ret);
-
- sem_destroy(&ppu_sem_id);
- dprint("ppu thread joined.\n");
-
+ clean_ppucore();
+ vga_shm_free(vga_shared_buf);
}