OSDN Git Service

stop using separate threads for cpu and rom, ram, ppu due to performance issue..
[motonesemu/motonesemu.git] / emulator / ppu.c
index 5f8f91b..c519299 100644 (file)
@@ -2,13 +2,16 @@
 #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*/
@@ -16,17 +19,6 @@ struct ppu_cpu_pin {
     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.*/
@@ -34,78 +26,122 @@ struct ppu_cart_pin {
 
 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;
     }
 
@@ -113,15 +149,8 @@ int init_ppu(void) {
 }
 
 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);
 }