OSDN Git Service

stop using separate threads for cpu and rom, ram, ppu due to performance issue..
[motonesemu/motonesemu.git] / emulator / ppu.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <time.h>
4 #include <string.h>
5
6 #include "clock.h"
7 #include "tools.h"
8 #include "vga.h"
9 #include "ppucore.h"
10
11 void set_vga_base(unsigned char* base);
12 void *vga_shm_get(void);
13 void vga_shm_free(void* addr);
14 void release_bus(void);
15
16 struct ppu_cpu_pin {
17     unsigned int ce     :1;     /*chip enable*/
18     unsigned int rw     :1;     /*assert on write.*/
19     unsigned int vblank :1;     /*connected to nmi*/
20 };
21
22 struct ppu_cart_pin {
23     unsigned int rd     :1;     /*read*/
24     unsigned int wr     :1;     /*write.*/
25 };
26
27 static struct ppu_cpu_pin  ppu_pin;
28 static struct ppu_cart_pin cart_pin;
29
30 static unsigned short ppu_addr;
31 static unsigned char ppu_data;
32
33 static unsigned char* vga_shared_buf;
34
35
36 /*
37  * ppucore r/w func ptr.
38  * */
39 typedef void (ppu_write_t)(unsigned char);
40 typedef unsigned char (ppu_read_t)(void);
41
42 static void null_write(unsigned char);
43 static unsigned char null_read(void);
44
45 static ppu_write_t *ppucore_write_func[8] = {
46     ppu_ctrl1_set,
47     ppu_ctrl2_set,
48     null_write,
49     sprite_data_set,
50     sprite_addr_set,
51     ppu_scroll_set,
52     ppu_vram_addr_set,
53     ppu_vram_data_set
54 };
55
56 static ppu_read_t *ppucore_read_func[8] = {
57     null_read,
58     null_read,
59     ppu_status_get,
60     null_read,
61     null_read,
62     null_read,
63     null_read,
64     ppu_vram_data_get
65 };
66
67 /*
68 * JAPAN/US uses NTSC standard.
69
70 * NTSC: 
71 * ---------------------------------------------------------
72 * Frames per second                            60 
73 * Time per frame (milliseconds)                16.67 
74 * Scanlines per frame (of which is V-Blank)    262 (20) 
75 * CPU cycles per scanline                      113.33 
76 * Resolution                                   256 x 224 
77 * CPU speed                                    1.79 MHz 
78 *
79 * PPU clock                                    21.48 Mhz
80 * */
81
82 void set_ppu_addr(unsigned short addr) {
83     ppu_addr = addr;
84 }
85
86 unsigned char get_ppu_data(void) {
87     return ppu_data;
88 }
89
90 void set_ppu_data(unsigned char data) {
91     ppu_data = data;
92 }
93
94 /*
95  * write: rw = 1
96  * read: rw = 0
97  * */
98 void set_ppu_rw_pin(int rw) {
99     ppu_pin.rw = rw;
100 }
101
102 void set_ppu_ce_pin(int ce) {
103     ppu_pin.ce = ce;
104     //let ram i/o on the bus.
105     if (ce) {
106         if (ppu_pin.rw) {
107             //write cycle
108             ppucore_write_func[ppu_addr](ppu_data);
109         }
110         else {
111             //read cycle
112             ppu_data = ppucore_read_func[ppu_addr]();
113         }
114         release_bus();
115     }
116 }
117
118 /*dummy I/O func*/
119 static void null_write(unsigned char d){}
120 static unsigned char null_read(void){return 0;}
121
122 int init_ppu(void) {
123     int ret;
124
125     ppu_pin.ce = 0;
126     ppu_pin.rw = 0;
127     cart_pin.rd = 0;
128     cart_pin.wr = 0;
129
130     ppu_addr = 0;
131     ppu_data = 0;
132
133     /* get vga shared memory */
134     if((vga_shared_buf = (unsigned char*)vga_shm_get()) == NULL)
135     {
136         fprintf(stderr, "error attaching shared memory.\n");
137         return FALSE;
138     }
139
140     memset(vga_shared_buf, 0, VGA_SHM_SIZE);
141     set_vga_base((unsigned char*)vga_shared_buf);
142
143     ret = ppucore_init();
144     if (ret == FALSE) {
145         return FALSE;
146     }
147
148     return TRUE;
149 }
150
151 void clean_ppu(void) {
152     clean_ppucore();
153     vga_shm_free(vga_shared_buf);
154 }
155
156