1
2 #include "shared.h"
3 #include <string.h>
4
5 /*--------------------------------------------------------------------------*/
6 /* Init, reset, shutdown functions */
7 /*--------------------------------------------------------------------------*/
8
pce_init(void)9 int pce_init(void)
10 {
11 return (1);
12 }
13
pce_reset(FESTALON_HES * hes)14 void pce_reset(FESTALON_HES *hes)
15 {
16 memset(&hes->ctrl, 0, sizeof(hes->ctrl));
17 memset(hes->ram, 0, sizeof(hes->ram));
18 bank_reset(hes);
19 h6280_reset(hes->h6280, hes, hes->ram, hes->read_ptr, hes->write_ptr);
20 }
21
pce_shutdown(void)22 void pce_shutdown(void)
23 {
24 }
25
26 /*--------------------------------------------------------------------------*/
27 /* Hardware page handlers */
28 /*--------------------------------------------------------------------------*/
29
io_page_w(FESTALON_HES * hes,int address,int data)30 void io_page_w(FESTALON_HES *hes, int address, int data)
31 {
32 switch(address & 0x1C00)
33 {
34 case 0x0000: /* VDC */
35 if(address <= 0x0003)
36 {
37 vdc_w(hes, address, data);
38 return;
39 }
40 break;
41
42 case 0x0400: /* VCE */
43 break;
44
45 case 0x0800: /* PSG */
46 if(address <= 0x0809)
47 {
48 psg_w(hes, address, data);
49 return;
50 }
51 break;
52
53 case 0x0C00: /* Timer */
54 if(address == 0x0C00 || address == 0x0C01)
55 {
56 H6280_timer_w(hes->h6280, address & 1, data);
57 return;
58 }
59 break;
60
61 case 0x1000: /* I/O */
62 if(address == 0x1000)
63 {
64 input_w(hes, data);
65 return;
66 }
67 break;
68
69 case 0x1400: /* IRQ control */
70 if(address == 0x1402 || address == 0x1403)
71 {
72 H6280_irq_status_w(hes->h6280, address & 1, data);
73 return;
74 }
75 break;
76
77 case 0x1800: /* CD-ROM */
78 return;
79
80 case 0x1C00: /* Expansion */
81 break;
82 }
83 }
84
85
io_page_r(FESTALON_HES * hes,int address)86 int io_page_r(FESTALON_HES *hes, int address)
87 {
88 switch(address & 0x1C00)
89 {
90 case 0x0000: /* VDC */
91 if(address <= 0x0003)
92 {
93 return (vdc_r(hes, address));
94 }
95 break;
96
97 case 0x0400: /* VCE */
98 return (0x00);
99
100 case 0x0800: /* PSG */
101 break;
102
103 case 0x0C00: /* Timer */
104 if(address == 0x0C00 || address == 0x0C01)
105 {
106 return (H6280_timer_r(hes->h6280, address & 1));
107 }
108 break;
109
110 case 0x1000: /* I/O */
111 if(address == 0x1000)
112 {
113 return (input_r(hes));
114 }
115 break;
116
117 case 0x1400: /* IRQ control */
118 if(address == 0x1402 || address == 0x1403)
119 {
120 return (H6280_irq_status_r(hes->h6280, address & 1));
121 }
122 break;
123
124 case 0x1800: /* CD-ROM */
125 break;
126
127 case 0x1C00: /* Expansion */
128 return(hes->IBP[address&0x1FFF]);
129 break;
130 }
131 return (UNMAPPED_IO);
132 }
133
134
135 /*--------------------------------------------------------------------------*/
136 /* Memory pointer management */
137 /*--------------------------------------------------------------------------*/
138
139 /* Reset all pointers */
bank_reset(FESTALON_HES * hes)140 void bank_reset(FESTALON_HES *hes)
141 {
142 int i;
143
144 /* Return value for unmapped reads */
145 memset(hes->dummy_read, UNMAPPED_MEM, sizeof(hes->dummy_read));
146
147 /* Set all 256 banks to unused */
148 for(i = 0; i < 0x100; i += 1)
149 {
150 hes->bank_map[i].read = hes->dummy_read;
151 hes->bank_map[i].write = hes->dummy_write;
152 }
153
154 /* ROM */
155 for(i = 0; i < 0x80; i += 1)
156 {
157 hes->bank_map[0x00 + i].read = &hes->rom[(i << 13)];
158 }
159
160 /* Work RAM (+ SGX) */
161 for(i = 0; i < 4; i += 1)
162 {
163 hes->bank_map[0xF8+i].write = &hes->ram[i << 13];
164 hes->bank_map[0xF8+i].read = &hes->ram[i << 13];
165 }
166
167 /* I/O area */
168 hes->bank_map[0xFF].read = hes->IBP;
169 hes->bank_map[0xFF].write = NULL;
170
171 /* Set up logical mapping */
172 for(i = 0; i < 8; i += 1)
173 {
174 hes->read_ptr[i] = hes->bank_map[0].read; /* ROM bank #0 */
175 hes->write_ptr[i] = hes->bank_map[0].write; /* Ignored */
176 }
177 }
178
179 /* Set a memory pointer to a certain bank */
bank_set(FESTALON_HES * hes,int bank,int value)180 void bank_set(FESTALON_HES *hes, int bank, int value)
181 {
182 hes->read_ptr[bank] = hes->bank_map[value].read;
183 hes->write_ptr[bank] = hes->bank_map[value].write;
184 }
185
186 /*--------------------------------------------------------------------------*/
187 /* Input routines */
188 /*--------------------------------------------------------------------------*/
189
input_w(FESTALON_HES * hes,uint8 data)190 void input_w(FESTALON_HES *hes, uint8 data)
191 {
192 /* New state of SEL and CLR lines */
193 int new_sel = (data >> 0) & 1;
194 int new_clr = (data >> 1) & 1;
195
196 /* Shift in new bits */
197 hes->ctrl.sel = (hes->ctrl.sel << 1) | (new_sel);
198 hes->ctrl.clr = (hes->ctrl.clr << 1) | (new_clr);
199 }
200
input_r(FESTALON_HES * hes)201 uint8 input_r(FESTALON_HES *hes)
202 {
203 uint8 temp = 0xFF;
204
205 if((hes->ctrl.sel & 1) == 0) temp >>= 4;
206 temp &= 0x0F;
207 return (temp);
208 }
209