OSDN Git Service

fa815af461d6a79db25cd1178bb04a98db7845e4
[csp-qt/common_source_project-fm7.git] / source / src / vm / mz3500 / main.cpp
1 /*
2         SHARP MZ-3500 Emulator 'EmuZ-3500'
3
4         Author : Takeda.Toshiya
5         Date   : 2010.08.31-
6
7         [ main ]
8 */
9
10 #include "main.h"
11 #include "../upd765a.h"
12 #include "../../fileio.h"
13
14 #define SET_BANK(s, e, w, r) { \
15         int sb = (s) >> 11, eb = (e) >> 11; \
16         for(int i = sb; i <= eb; i++) { \
17                 if((w) == wdmy) { \
18                         wbank[i] = wdmy; \
19                 } else { \
20                         wbank[i] = (w) + 0x800 * (i - sb); \
21                 } \
22                 if((r) == rdmy) { \
23                         rbank[i] = rdmy; \
24                 } else { \
25                         rbank[i] = (r) + 0x800 * (i - sb); \
26                 } \
27         } \
28 }
29
30 void MAIN::initialize()
31 {
32         // init memory
33         memset(ipl, 0xff, sizeof(ipl));
34         memset(ram, 0, sizeof(ram));
35         memset(common, 0, sizeof(common));
36         memset(basic, 0xff, sizeof(basic));
37         memset(ext, 0xff, sizeof(ext));
38         memset(rdmy, 0xff, sizeof(rdmy));
39         
40         // load rom images
41         FILEIO* fio = new FILEIO();
42         if(fio->Fopen(emu->bios_path(_T("IPL.ROM")), FILEIO_READ_BINARY)) {
43                 fio->Fread(ipl, sizeof(ipl), 1);
44                 fio->Fclose();
45         }
46         if(fio->Fopen(emu->bios_path(_T("BASIC.ROM")), FILEIO_READ_BINARY)) {
47                 fio->Fread(basic, sizeof(basic), 1);
48                 fio->Fclose();
49         }
50         delete fio;
51 }
52
53 void MAIN::reset()
54 {
55         // memory mapper
56         ms = ma = mo = 0;
57         me1 = me2 = true;
58         update_bank();
59         
60         // sub cpu
61         srqb = 2;
62         sres = 0;
63         sack = true;
64         srdy = false;
65         
66         // interrupt
67         intfd = int0 = int1 = int2 = int3 = int4 = false;
68         me = e1 = false;
69         inp = 0;
70         
71         // mfd
72         drq = index = false;
73 }
74
75 void MAIN::write_data8(uint32 addr, uint32 data)
76 {
77         addr &= 0xffff;
78         wbank[addr >> 11][addr & 0x7ff] = data;
79 }
80
81 uint32 MAIN::read_data8(uint32 addr)
82 {
83         addr &= 0xffff;
84         return rbank[addr >> 11][addr & 0x7ff];
85 }
86
87 void MAIN::write_io8(uint32 addr, uint32 data)
88 {
89         switch(addr & 0xff) {
90         case 0xec:      // mz3500sm p.17
91         case 0xed:
92         case 0xee:
93         case 0xef:
94                 int0 = false;
95                 update_irq();
96                 break;
97         case 0xf8:      // mz3500sm p.59
98         case 0xfa:
99                 if(data & 0x40) {
100                         for(int i = 0; i < 3; i++) {
101                                 if(data & (1 << i)) {
102 //                                      emu->out_debug_log("MAIN->FDC\tDRIVE=%d\n", i);
103                                         d_fdc->write_signal(SIG_UPD765A_DRVSEL, i, 3);
104                                         break;
105                                 }
106                         }
107                 }
108                 d_fdc->write_signal(SIG_UPD765A_MOTOR, data, 0x10);
109                 d_fdc->write_signal(SIG_UPD765A_TC, data, 0x20);
110                 motor = ((data & 0x10) != 0);
111                 me = ((data & 0x80) != 0);
112                 update_irq();
113                 break;
114         case 0xf9:      // mz3500sm p.59
115         case 0xfb:
116                 d_fdc->write_dma_io8(1, data);
117                 break;
118         case 0xfc:      // mz3500sm p.23
119                 if((srqb & 2) != (data & 2)) {
120 //                      emu->out_debug_log("MAIN->SUB\tBUSREQ=%d\n",(data&2)?1:0);
121                         d_subcpu->write_signal(SIG_CPU_BUSREQ, data, 2);
122                         srqb = data & 2;
123                 }
124                 e1 = ((data & 1) != 0);
125                 update_irq();
126                 break;
127         case 0xfd:      // mz3500sm p.23
128                 if(!(sres & 0x80) && (data & 0x80)) {
129 //                      emu->out_debug_log("MAIN->SUB\tRESET\n");
130                         d_subcpu->reset();
131                 }
132                 sres = data;
133                 ms = data & 3;
134                 update_bank();
135                 break;
136         case 0xfe:      // mz3500sm p.23
137                 mo = data & 7;
138                 ma = (data >> 4) & 0x0f;
139                 update_bank();
140                 break;
141         case 0xff:      // mz3500sm p.23
142                 me1 = ((data & 1) != 0);
143                 me2 = ((data & 2) != 0);
144 //              update_bank();
145                 break;
146         }
147 }
148
149 uint32 MAIN::read_io8(uint32 addr)
150 {
151         uint32 val = 0xff;
152         
153         switch(addr & 0xff) {
154         case 0xec:      // mz3500sm p.17
155         case 0xed:
156         case 0xee:
157         case 0xef:
158                 int0 = false;
159                 update_irq();
160                 break;
161         case 0xf8:      // mz3500sm p.59
162         case 0xfa:
163                 return 0xf8 | (drq ? 1 : 0) | (index ? 2 : 0) | (motor ? 4 : 0);
164         case 0xf9:      // mz3500sm p.59
165         case 0xfb:
166                 return d_fdc->read_dma_io8(1);
167         case 0xfd:      // mz3500sm p.23
168                 return sres;
169         case 0xfe:      // mz3500sm p.23,85-86
170                 return 0xe4;
171         case 0xff:      // mz3500sm p.23,85-86
172                 return 0xe0 | (srdy ? 0x10 : 0) | (sack ? 0 : 8) | (inp & 7);
173         }
174         return 0xff;
175 }
176
177 void MAIN::write_signal(int id, uint32 data, uint32 mask)
178 {
179         if(id == SIG_MAIN_SACK) {
180                 sack = ((data & mask) != 0);
181 //              emu->out_debug_log("SUB->MAIN\tSACK=%d\n",sack?1:0);
182         } else if(id == SIG_MAIN_SRDY) {
183                 srdy = ((data & mask) != 0);
184 //              emu->out_debug_log("SUB->MAIN\tSRDY=%d\n",srdy?1:0);
185         } else if(id == SIG_MAIN_INTFD) {
186                 intfd = ((data & mask) != 0);
187 //              emu->out_debug_log("FDC->MAIN\tINTFD=%d\n",intfd?1:0);
188                 update_irq();
189         } else if(id == SIG_MAIN_INT0) {
190                 int0 = ((data & mask) != 0);
191 //              emu->out_debug_log("SUB->MAIN\tINT0=%d\n",int0?1:0);
192                 update_irq();
193         } else if(id == SIG_MAIN_INT1) {
194                 int1 = ((data & mask) != 0);
195                 update_irq();
196         } else if(id == SIG_MAIN_INT2) {
197                 int2 = ((data & mask) != 0);
198                 update_irq();
199         } else if(id == SIG_MAIN_INT3) {
200                 int3 = ((data & mask) != 0);
201                 update_irq();
202         } else if(id == SIG_MAIN_INT4) {
203                 int4 = ((data & mask) != 0);
204                 update_irq();
205         } else if(id == SIG_MAIN_DRQ) {
206                 drq = ((data & mask) != 0);
207         } else if(id == SIG_MAIN_INDEX) {
208                 index = ((data & mask) != 0);
209         }
210 }
211
212 void MAIN::update_irq()
213 {
214         bool next = false;
215         
216         if(intfd && me) {
217                 intfd = false;
218                 inp = 0;
219                 next = true;
220         } else if(e1) {
221                 if(int0) {
222                         inp = 1;
223                         next = true;
224                 } else if(int1) {
225                         inp = 2;
226                         next = true;
227                 } else if(int2) {
228                         inp = 3;
229                         next = true;
230                 } else if(int3) {
231                         inp = 4;
232                         next = true;
233                 } else if(int4) {
234                         inp = 5;
235                         next = true;
236                 }
237         }
238         if(next) {
239                 emu->out_debug_log("MAIN IRQ=%d SRC=%d\n", next?1:0,inp);
240                 d_cpu->set_intr_line(true, true, 0);
241         }
242 }
243
244 void MAIN::update_bank()
245 {
246         SET_BANK(0x0000, 0xffff, wdmy, rdmy);
247         
248         if((ms & 3) == 0) {
249                 // SD0: INITIALIZE STATE
250                 SET_BANK(0x0000, 0x0fff, wdmy, ipl + 0x1000);
251                 SET_BANK(0x1000, 0x1fff, wdmy, ipl + 0x1000);
252                 SET_BANK(0x2000, 0x3fff, wdmy, basic + 0x2000);
253                 SET_BANK(0x4000, 0xbfff, ram + 0x4000, ram + 0x4000);   // note: check me1 and me2
254                 switch(ma & 0x0f) {
255                 case 0x00: SET_BANK(0xc000, 0xffff, ram + 0x0c000, ram + 0x0c000); break;
256                 case 0x01: SET_BANK(0xc000, 0xffff, ram + 0x00000, ram + 0x00000); break;
257                 case 0x0f: SET_BANK(0xf800, 0xffff, common, common); break;
258                 }
259         } else if((ms & 3) == 1) {
260                 // SD1: SYSTEM LOADING & CP/M
261                 SET_BANK(0x0000, 0xf7ff, ram, ram);
262                 SET_BANK(0xf800, 0xffff, common, common);
263         } else if((ms & 3) == 2) {
264                 // SD2: ROM based BASIC
265                 SET_BANK(0x0000, 0x1fff, wdmy, basic);
266                 switch(mo & 0x07) {
267                 case 0x00: SET_BANK(0x2000, 0x3fff, wdmy, basic + 0x2000); break;
268                 case 0x01: SET_BANK(0x2000, 0x3fff, wdmy, basic + 0x4000); break;
269                 case 0x02: SET_BANK(0x2000, 0x3fff, wdmy, basic + 0x6000); break;
270                 case 0x03: SET_BANK(0x2000, 0x3fff, wdmy, ext + 0x0000); break;
271                 case 0x04: SET_BANK(0x2000, 0x3fff, wdmy, ext + 0x2000); break;
272                 case 0x05: SET_BANK(0x2000, 0x3fff, wdmy, ext + 0x4000); break;
273                 case 0x06: SET_BANK(0x2000, 0x3fff, wdmy, ext + 0x6000); break;
274                 }
275                 SET_BANK(0x4000, 0xbfff, ram + 0x4000, ram + 0x4000);   // note: check me1 and me2
276                 switch(ma & 0x0f) {
277                 case 0x00: SET_BANK(0xc000, 0xffff, ram + 0x0c000, ram + 0x0c000); break;
278                 case 0x01: SET_BANK(0xc000, 0xffff, ram + 0x00000, ram + 0x00000); break;
279                 case 0x02: SET_BANK(0xc000, 0xffff, ram + 0x10000, ram + 0x10000); break;
280                 case 0x03: SET_BANK(0xc000, 0xffff, ram + 0x14000, ram + 0x14000); break;
281                 case 0x04: SET_BANK(0xc000, 0xffff, ram + 0x18000, ram + 0x18000); break;
282                 case 0x05: SET_BANK(0xc000, 0xffff, ram + 0x1c000, ram + 0x1c000); break;
283                 case 0x06: SET_BANK(0xc000, 0xffff, ram + 0x20000, ram + 0x20000); break;
284                 case 0x07: SET_BANK(0xc000, 0xffff, ram + 0x24000, ram + 0x24000); break;
285                 case 0x08: SET_BANK(0xc000, 0xffff, ram + 0x28000, ram + 0x28000); break;
286                 case 0x09: SET_BANK(0xc000, 0xffff, ram + 0x2c000, ram + 0x2c000); break;
287                 case 0x0a: SET_BANK(0xc000, 0xffff, ram + 0x30000, ram + 0x30000); break;
288                 case 0x0b: SET_BANK(0xc000, 0xffff, ram + 0x34000, ram + 0x34000); break;
289                 case 0x0c: SET_BANK(0xc000, 0xffff, ram + 0x38000, ram + 0x38000); break;
290                 case 0x0d: SET_BANK(0xc000, 0xffff, ram + 0x3c000, ram + 0x3c000); break;
291                 case 0x0f: SET_BANK(0xf800, 0xffff, common, common); break;
292                 }
293         } else {
294                 // SD3: RAM based BASIC
295                 SET_BANK(0x0000, 0x1fff, ram, ram);
296                 switch(mo & 0x07) {
297                 case 0x0: SET_BANK(0x2000, 0x3fff, ram + 0x2000, ram + 0x2000); break;
298                 case 0x1: SET_BANK(0x2000, 0x3fff, ram + 0xc000, ram + 0xc000); break;
299                 case 0x2: SET_BANK(0x2000, 0x3fff, ram + 0xe000, ram + 0xe000); break;
300                 case 0x3: SET_BANK(0x2000, 0x3fff, wdmy, ext + 0x0000); break;
301                 case 0x4: SET_BANK(0x2000, 0x3fff, wdmy, ext + 0x2000); break;
302                 case 0x5: SET_BANK(0x2000, 0x3fff, wdmy, ext + 0x4000); break;
303                 case 0x6: SET_BANK(0x2000, 0x3fff, wdmy, ext + 0x6000); break;
304                 }
305                 SET_BANK(0x4000, 0xbfff, ram + 0x4000, ram + 0x4000);   // note: check me1 and me2
306                 switch(ma & 0x0f) {
307                 case 0x00: SET_BANK(0xc000, 0xffff, ram + 0x10000, ram + 0x10000); break;
308                 case 0x01: SET_BANK(0xc000, 0xffff, ram + 0x14000, ram + 0x14000); break;
309                 case 0x02: SET_BANK(0xc000, 0xffff, ram + 0x18000, ram + 0x18000); break;
310                 case 0x03: SET_BANK(0xc000, 0xffff, ram + 0x1c000, ram + 0x1c000); break;
311                 case 0x04: SET_BANK(0xc000, 0xffff, ram + 0x20000, ram + 0x20000); break;
312                 case 0x05: SET_BANK(0xc000, 0xffff, ram + 0x24000, ram + 0x24000); break;
313                 case 0x06: SET_BANK(0xc000, 0xffff, ram + 0x28000, ram + 0x28000); break;
314                 case 0x07: SET_BANK(0xc000, 0xffff, ram + 0x2c000, ram + 0x2c000); break;
315                 case 0x08: SET_BANK(0xc000, 0xffff, ram + 0x30000, ram + 0x30000); break;
316                 case 0x09: SET_BANK(0xc000, 0xffff, ram + 0x34000, ram + 0x34000); break;
317                 case 0x0a: SET_BANK(0xc000, 0xffff, ram + 0x38000, ram + 0x38000); break;
318                 case 0x0b: SET_BANK(0xc000, 0xffff, ram + 0x3c000, ram + 0x3c000); break;
319                 case 0x0f: SET_BANK(0xf800, 0xffff, common, common); break;
320                 }
321         }
322 }
323