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