OSDN Git Service

[General] Merge Upstream 2018-12-27.
[csp-qt/common_source_project-fm7.git] / source / src / vm / pc6001 / memory.cpp
1 /** iP6: PC-6000/6600 series emualtor ************************/
2 /**                                                         **/
3 /**                         Refresh.c                       **/
4 /**                                                         **/
5 /** modified by Windy 2002-2004                             **/
6 /** by ISHIOKA Hiroshi 1998,1999                            **/
7 /** This code is based on fMSX written by Marat Fayzullin   **/
8 /** and Adaptions for any X-terminal by Arnold Metselaar    **/
9 /*************************************************************/
10
11 /*
12         NEC PC-6001 Emulator 'yaPC-6001'
13         NEC PC-6001mkII Emulator 'yaPC-6201'
14         NEC PC-6001mkIISR Emulator 'yaPC-6401'
15         NEC PC-6601 Emulator 'yaPC-6601'
16         NEC PC-6601SR Emulator 'yaPC-6801'
17
18         Author : tanam
19         Date   : 2013.07.15-
20
21         [ memory ]
22 */
23
24 #include "./memory.h"
25 #include "timer.h"
26
27 #define RAM             (MEMORY_BASE + RAM_BASE)
28 #define BASICROM        (MEMORY_BASE + BASICROM_BASE)
29 #define EXTROM          (MEMORY_BASE + EXTROM_BASE)
30 #define CGROM1          (MEMORY_BASE + CGROM1_BASE)
31 #define EmptyRAM        (MEMORY_BASE + EmptyRAM_BASE)
32 // PC-6001mkII, PC-6601
33 #define VOICEROM        (MEMORY_BASE + VOICEROM_BASE)
34 #define KANJIROM        (MEMORY_BASE + KANJIROM_BASE)
35 #define CGROM5          (MEMORY_BASE + CGROM5_BASE)
36 // PC-6001mkIISR, PC-6601SR
37 #define EXTRAM          (MEMORY_BASE + EXTRAM_BASE)
38 #define SYSTEMROM1      (MEMORY_BASE + SYSTEMROM1_BASE)
39 #define SYSTEMROM2      (MEMORY_BASE + SYSTEMROM2_BASE)
40 #define CGROM6          (MEMORY_BASE + CGROM6_BASE)
41
42 namespace PC6001 {
43
44 void MEMORY::initialize()
45 {
46         FILEIO* fio = new FILEIO();
47 #if defined(_PC6001)
48         if(fio->Fopen(create_local_path(_T("BASICROM.60")), FILEIO_READ_BINARY)) {
49                 fio->Fread(BASICROM, 0x4000, 1);
50                 fio->Fclose();
51         }
52         if(fio->Fopen(create_local_path(_T("CGROM60.60")), FILEIO_READ_BINARY)) {
53                 fio->Fread(CGROM1, 0x1000, 1);
54                 fio->Fclose();
55         }
56 #elif defined(_PC6001MK2)
57         if (fio->Fopen(create_local_path(_T("CGROM62.62")), FILEIO_READ_BINARY)) {
58                 fio->Fread(CGROM5, 0x2000, 1);
59                 fio->Fclose();
60         }
61         else if (fio->Fopen(create_local_path(_T("CGROM60m.62")), FILEIO_READ_BINARY)) {
62                 fio->Fread(CGROM5, 0x2000, 1);
63                 fio->Fclose();
64         }
65         if (fio->Fopen(create_local_path(_T("BASICROM.62")), FILEIO_READ_BINARY)) {
66                 fio->Fread(BASICROM, 0x8000, 1);
67                 fio->Fclose();
68         }
69         if (fio->Fopen(create_local_path(_T("CGROM60.62")), FILEIO_READ_BINARY)) {
70                 fio->Fread(CGROM1, 0x2000, 1);
71                 fio->Fclose();
72         }
73         if (fio->Fopen(create_local_path(_T("KANJIROM.62")), FILEIO_READ_BINARY)) {
74                 fio->Fread(KANJIROM, 0x8000, 1);
75                 fio->Fclose();
76         }
77         if (fio->Fopen(create_local_path(_T("VOICEROM.62")), FILEIO_READ_BINARY)) {
78                 fio->Fread(VOICEROM, 0x4000, 1);
79                 fio->Fclose();
80         }
81 #elif defined(_PC6601)
82         if (fio->Fopen(create_local_path(_T("CGROM66.66")), FILEIO_READ_BINARY)) {
83                 fio->Fread(CGROM5, 0x2000, 1);
84                 fio->Fclose();
85         }
86         if (fio->Fopen(create_local_path(_T("BASICROM.66")), FILEIO_READ_BINARY)) {
87                 fio->Fread(BASICROM, 0x8000, 1);
88                 fio->Fclose();
89         }
90         if (fio->Fopen(create_local_path(_T("CGROM60.66")), FILEIO_READ_BINARY)) {
91                 fio->Fread(CGROM1, 0x2000, 1);
92                 fio->Fclose();
93         }
94         if (fio->Fopen(create_local_path(_T("KANJIROM.66")), FILEIO_READ_BINARY)) {
95                 fio->Fread(KANJIROM, 0x8000, 1);
96                 fio->Fclose();
97         }
98         if (fio->Fopen(create_local_path(_T("VOICEROM.66")), FILEIO_READ_BINARY)) {
99                 fio->Fread(VOICEROM, 0x4000, 1);
100                 fio->Fclose();
101         }
102 #elif defined(_PC6601SR) || defined(_PC6001MK2SR)
103         if (fio->Fopen(create_local_path(_T("CGROM68.68")), FILEIO_READ_BINARY)) {
104                 fio->Fread(CGROM6, 0x4000, 1);
105                 fio->Fclose();
106         }
107         memcpy(CGROM1, CGROM6, 0x2400);
108         memcpy(CGROM5, CGROM6+0x2000, 0x2000);
109         if (fio->Fopen(create_local_path(_T("SYSTEMROM1.68")), FILEIO_READ_BINARY)) {
110                 fio->Fread(SYSTEMROM1, 0x10000, 1);
111                 fio->Fclose();
112         }
113         memcpy(BASICROM, SYSTEMROM1, 0x8000);
114         if (fio->Fopen(create_local_path(_T("SYSTEMROM2.68")), FILEIO_READ_BINARY)) {
115                 fio->Fread(SYSTEMROM2, 0x10000, 1);
116                 fio->Fclose();
117         }
118         memcpy(VOICEROM, SYSTEMROM2+0x4000, 0x4000);
119         memcpy(KANJIROM, SYSTEMROM2+0x8000, 0x8000);
120 #endif
121         delete fio;
122         
123 #ifndef _PC6001
124         int i;
125         // for mkII/66
126         int Pal11[ 4] = { 15, 8,10, 8 };
127         int Pal12[ 8] = { 10,11,12, 9,15,14,13, 1 };
128         int Pal13[ 8] = { 10,11,12, 9,15,14,13, 1 };
129         int Pal14[ 4] = {  8,10, 8,15 };
130         int Pal15[ 8] = {  8,9,11,14, 8,9,14,15 };
131         int Pal53[32] = {  0, 4, 1, 5, 2, 6, 3, 7, 8,12, 9,13,10,14,11,15,
132                 10,11,12, 9,15,14,13, 1,10,11,12, 9,15,14,13, 1 };
133         
134         for(i=0;i<32;i++) {
135                 BPal53[i]=Pal53[i];
136                 if (i>15) continue;
137                 BPal[i]=i;
138                 if (i>7) continue;
139                 BPal12[i]=Pal12[i];
140                 BPal13[i]=Pal13[i];
141                 BPal15[i]=Pal15[i];
142                 if (i>3) continue;
143                 BPal11[i]=Pal11[i];
144                 BPal14[i]=Pal14[i];
145         }
146         for (i=0;i<32;i++) BPal62[i] = BPal53[i];       // for RefreshScr62/63
147         for (i=0;i<16;i++) BPal61[i] = BPal[i];         // for RefreshScr61
148
149         // mk2\81` palette
150         palette_pc[ 0] = RGB_COLOR(0x14,0x14,0x14); // COL065                   = 141414                        ;mk2\81\93§\96¾(\8d\95)
151         palette_pc[ 1] = RGB_COLOR(0xFF,0xAC,0x00); // COL066                   = FFAC00                        ;mk2\81\9eò
152         palette_pc[ 2] = RGB_COLOR(0x00,0xFF,0xAC); // COL067                   = 00FFAC                        ;mk2\81\90Â\97Î
153         palette_pc[ 3] = RGB_COLOR(0xAC,0xFF,0x00); // COL068                   = ACFF00                        ;mk2\81\89©\97Î
154         palette_pc[ 4] = RGB_COLOR(0xAC,0x00,0xFF); // COL069                   = AC00FF                        ;mk2\81\90Â\8e\87
155         palette_pc[ 5] = RGB_COLOR(0xFF,0x00,0xAC); // COL070                   = FF00AC                        ;mk2\81\90Ô\8e\87
156         palette_pc[ 6] = RGB_COLOR(0x00,0xAC,0xFF); // COL071                   = 00ACFF                        ;mk2\81\8bó\90F
157         palette_pc[ 7] = RGB_COLOR(0xAC,0xAC,0xAC); // COL072                   = ACACAC                        ;mk2\81\8aD\90F
158         palette_pc[ 8] = RGB_COLOR(0x14,0x14,0x14); // COL073                   = 141414                        ;mk2\81\8d\95
159         palette_pc[ 9] = RGB_COLOR(0xFF,0x00,0x00); // COL074                   = FF0000                        ;mk2\81\90Ô
160         palette_pc[10] = RGB_COLOR(0x00,0xFF,0x00); // COL075                   = 00FF00                        ;mk2\81\97Î
161         palette_pc[11] = RGB_COLOR(0xFF,0xFF,0x00); // COL076                   = FFFF00                        ;mk2\81\89©
162         palette_pc[12] = RGB_COLOR(0x00,0x00,0xFF); // COL077                   = 0000FF                        ;mk2\81\90Â
163         palette_pc[13] = RGB_COLOR(0xFF,0x00,0xFF); // COL078                   = FF00FF                        ;mk2\81\83}\83[\83\93\83^
164         palette_pc[14] = RGB_COLOR(0x00,0xFF,0xFF); // COL079                   = 00FFFF                        ;mk2\81\83V\83A\83\93
165         palette_pc[15] = RGB_COLOR(0xFF,0xFF,0xFF); // COL080                   = FFFFFF                        ;mk2\81\94\92
166         
167         // register event
168 #endif
169         register_vline_event(this);
170 }
171
172 void MEMORY::reset()
173 {
174 #ifdef _PC6001
175         int J;
176         if (!inserted) {
177 ///             EXTROM1 = EXTROM2 = EmptyRAM;
178                 EXTROM1 = RAM + 0x4000;
179                 EXTROM2 = RAM + 0x6000;
180                 FILEIO* fio = new FILEIO();
181                 if (fio->Fopen(create_local_path(_T("EXTROM.60")), FILEIO_READ_BINARY)) {
182                         fio->Fread(EXTROM, 0x4000, 1);
183                         fio->Fclose();
184                         EXTROM1 = EXTROM;
185                         EXTROM2 = EXTROM + 0x2000;
186                         inserted = true;
187                 }
188                 delete fio;
189         }
190         memset(RAM ,0,0x10000);
191         memset(EmptyRAM, 0, 0x2000);
192         CGROM = CGROM1;
193         CGSW93 = 0;
194         VRAM = RAM;
195         for(J=0;J<4;J++) {RdMem[J]=BASICROM+0x2000*J;WrMem[J]=RAM+0x2000*J;};
196         RdMem[2] = EXTROM1; RdMem[3] = EXTROM2;
197         for(J=4;J<8;J++) {RdMem[J]=RAM+0x2000*J;WrMem[J]=RAM+0x2000*J;};
198         EnWrite[0]=0; EnWrite[1]=EnWrite[2]=EnWrite[3]=1;
199 #else
200         int I, J;
201         uint8_t *addr=RAM;
202         memset(RAM ,0,0x10000);
203         memset(EmptyRAM, 0, 0x2000);
204         for(I=0; I<256; I++ ){
205                 for( J=0; J<64; J++ ){
206                         *addr++ = 0x00;
207                         *addr++ = 0xff;
208                 }
209                 for( J=0; J<64; J++ ){
210                         *addr++ = 0xff;
211                         *addr++ = 0x00;
212                 }
213         }
214         if (!inserted) {
215                 EXTROM1 = EXTROM2 = EmptyRAM;
216         }
217 #if defined(_PC6001MK2) || defined(_PC6601)
218         static_cast<VM *>(vm)->sr_mode=0;
219         CGROM = CGROM1;
220         VRAM = RAM+0xE000;
221         for (I=0; I<0x200; I++ ) *(VRAM+I)=0xde;
222         for(J=0;J<4;J++) {RdMem[J]=BASICROM+0x2000*J;WrMem[J]=RAM+0x2000*J;};
223         for(J=4;J<8;J++) {RdMem[J]=RAM+0x2000*J;WrMem[J]=RAM+0x2000*J;};
224         EnWrite[0]=EnWrite[1]=0; EnWrite[2]=EnWrite[3]=1;
225 #elif defined(_PC6601SR) || defined(_PC6001MK2SR)
226         static_cast<VM *>(vm)->sr_mode=1;
227         bitmap=1;
228         cols=40;
229         rows=20;
230         lines=200;
231         memset(EXTRAM ,0,0x10000);
232         for (int i=0; i<16; i++) palet[i] = i;
233         port60[0]= 0xf8;                                        //I/O[60..67] READ  MEMORY MAPPING
234         for (I=1; I<15; I++) port60[I]=0;       //I/O[68-6f]  WRITE MEMORY MAPPING
235         portC1 = 0x00;                                          //I/O[C1]     CRT CONTROLLER MODE
236         portC8 = 0x00;                                          //I/O[C8]     CRT CONTROLLER TYPE
237         portCA = 0x00;                                          //I/O[CA]     X GEOMETORY low  HARDWARE SCROLL
238         portCB = 0x00;                                          //I/O[CB]     X GEOMETORY high HARDWARE SCROLL
239         portCC = 0x00;                                          //I/O[CC]     Y GEOMETORY      HARDWARE SCROLL
240         portCE = 0x00;                                          //I/O[CE]     LINE SETTING  BITMAP (low) */
241         portCF = 0x00;                                          //I/O[CF]     LINE SETTING  BITMAP (High) */
242         CGROM=CGROM6;
243         make_semigraph();
244         for(J=0;J<4;J++) {RdMem[J]=SYSTEMROM1+0x2000*J+0x8000;WrMem[J]=RAM+0x2000*J;};
245         RdMem[2] = EXTROM1; RdMem[3] = EXTROM2;
246         for(J=4;J<8;J++) {RdMem[J]=RAM+0x2000*J;WrMem[J]=RAM+0x2000*J;};
247         EnWrite[0]=EnWrite[1]=0; EnWrite[2]=EnWrite[3]=1;
248         VRAM=RAM;
249         TEXTVRAM=RAM;
250         SYSROM2=EmptyRAM;
251 #endif
252         portF0 = 0x11;
253         portF1 = 0xdd;
254         CRTMode1 = CRTMode2 = CRTMode3 = 0;
255         CSS3=CSS2=CSS1=0;
256         CurKANJIROM = KANJIROM;
257 #endif
258         CGSW93 = CRTKILL = 0;
259 }
260
261 void MEMORY::write_data8(uint32_t addr, uint32_t data)
262 {
263 #if defined(_PC6601SR) || defined(_PC6001MK2SR)
264         /* Graphics Vram Write (SR basic) */
265         if(static_cast<VM *>(vm)->sr_mode && chk_gvram(addr ,8)) 
266                 gvram_write(addr, data);
267         else
268 #endif
269         /* normal memory write */
270         if(EnWrite[addr >> 14]) 
271                 WrMem[addr >> 13][addr & 0x1FFF] = data;
272 }
273
274 uint32_t MEMORY::read_data8(uint32_t addr)
275 {
276 #if defined(_PC6601SR) || defined(_PC6001MK2SR)
277         /* Graphics Vram Read (SR basic) */
278         if(static_cast<VM *>(vm)->sr_mode && chk_gvram(addr, 0))
279                 return(gvram_read(addr));
280 #endif
281         return(RdMem[addr >> 13][addr & 0x1FFF]);
282 }
283
284 void MEMORY::write_data8w(uint32_t addr, uint32_t data, int *wait)
285 {
286 #ifdef _PC6001
287         *wait = addr < 0x8000 ? 1 : 0;
288 #else
289         bool is_rom;
290         uint32_t portF3 = d_timer->read_io8(0xf3);
291 #if defined(_PC6601SR) || defined(_PC6001MK2SR)
292         if (static_cast<VM *>(vm)->sr_mode) {
293                 is_rom = (port60[8 + (addr >> 13)] & 0xf0) > 0x20 ? true: false;
294         } else
295 #endif
296         {
297                 is_rom = EnWrite[addr >> 14] ? false : true;
298         }
299         *wait = is_rom && (portF3 & 0x40) || !is_rom && (portF3 & 0x20) ? 1 : 0;
300 #endif
301         write_data8(addr, data);
302 }
303
304 uint32_t MEMORY::read_data8w(uint32_t addr, int *wait)
305 {
306 #ifdef _PC6001
307         *wait = addr < 0x8000 ? 1 : 0;
308 #else
309         bool is_rom;
310         uint32_t portF3 = d_timer->read_io8(0xf3);
311 #if defined(_PC6601SR) || defined(_PC6001MK2SR)
312         if (static_cast<VM *>(vm)->sr_mode) {
313                 is_rom = (port60[addr >> 13] & 0xf0) > 0x20 ? true : false;
314         } else
315 #endif
316         {
317                 if (CGSW93 && 0x6000 <= addr && addr < 0x8000) {
318                         is_rom = true;
319                 } else if (addr < 0x4000) {
320                         is_rom = (portF0 & 0x0f) == 0x0d || (portF0 & 0x0f) == 0x0e ? false : true;
321                 } else if (addr < 0x8000) {
322                         is_rom = (portF0 & 0xf0) == 0xd0 || (portF0 & 0xf0) == 0xe0 ? false : true;
323                 } else if (addr < 0xc000) {
324                         is_rom = (portF1 & 0x0f) == 0x0d || (portF1 & 0x0f) == 0x0e ? false : true;
325                 } else {
326                         is_rom = (portF1 & 0xf0) == 0xd0 || (portF1 & 0xf0) == 0xe0 ? false : true;
327                 }
328         }
329         *wait = is_rom && (portF3 & 0x40) || !is_rom && (portF3 & 0x20) ? 1 : 0;
330 #endif
331         return read_data8(addr);
332 }
333
334 uint32_t MEMORY::fetch_op(uint32_t addr, int *wait)
335 {
336 #ifndef _PC6001
337         uint32_t portF3 = d_timer->read_io8(0xf3);
338         if ((portF3 & 0x80) == 0) {
339                 return read_data8w(addr, wait);
340         }
341 #endif
342         *wait = 1;
343         return read_data8(addr);
344 }
345
346 void MEMORY::write_io8(uint32_t addr, uint32_t data)
347 {
348         unsigned int VRAMHead[2][4] = {
349                 { 0xc000, 0xe000, 0x8000, 0xa000 },
350                 { 0x8000, 0xc000, 0x0000, 0x4000 }
351         };
352         uint16_t port=(addr & 0x00ff);
353         uint8_t Value=data;
354         switch(port)
355         {
356 #ifdef _PC6001
357         /// 64K RAM ///
358         case 0x00:
359                 if (Value & 1) {
360                         RdMem[0]=RAM;
361                         RdMem[1]=RAM+0x2000;
362                         EnWrite[0]=1;
363                 } else {
364                         RdMem[0]=BASICROM;
365                         RdMem[1]=BASICROM+0x2000;
366                         EnWrite[0]=0;
367                 }
368                 break;
369         /// CP/M ///
370         case 0xf0:
371                 if (Value ==0xdd) {
372                         RdMem[0]=RAM;
373                         RdMem[1]=RAM+0x2000;
374                         RdMem[2]=RAM+0x4000;
375                         RdMem[3]=RAM+0x6000;
376                         EnWrite[0]=EnWrite[1]=1;
377                 } else {
378                         RdMem[0]=BASICROM;
379                         RdMem[1]=BASICROM+0x2000;
380                         RdMem[2]=EXTROM1;
381                         RdMem[3]=EXTROM2;
382                         EnWrite[0]=EnWrite[1]=0;
383                 }
384                 break;
385 #else
386 #if defined(_PC6601SR) || defined(_PC6001MK2SR)
387         case 0x40:
388         case 0x41:
389         case 0x42:
390         case 0x43:
391                 int reg,val;
392                 reg= 15-(port-0x40);
393                 val= 15-Value;
394                 palet[ reg]= val;
395                 do_palet( reg,val);
396                 break;
397         case 0x60:
398         case 0x61:
399         case 0x62:
400         case 0x63:
401         case 0x64:
402         case 0x65:
403         case 0x66:
404         case 0x67:
405                 int start_adr;
406                 start_adr= Value & 0xe;
407                 port60[port-0x60]= Value;
408                 switch( Value & 0xf0) {
409                 case 0xf0: RdMem[(port& 0xf)]=SYSTEMROM1+(start_adr)*0x1000;break;
410                 case 0xe0: RdMem[(port& 0xf)]=SYSTEMROM2+(start_adr)*0x1000;break;
411                 case 0xd0: RdMem[(port& 0xf)]=    CGROM6+(start_adr)*0x1000;break;
412                 case 0xc0: RdMem[(port& 0xf)]=   EXTROM2; /*+(start_adr)*0x1000; */break;
413                 case 0xb0: RdMem[(port& 0xf)]=   EXTROM1; /*+(start_adr)*0x1000; */break;
414                 case 0x00: RdMem[(port& 0xf)]=       RAM+(start_adr)*0x1000;break;
415                 case 0x20: if (EXTRAM) RdMem[ port & 0xf]=  EXTRAM+((start_adr)*0x1000); break;
416                 }
417                 return;
418         case 0x68:
419         case 0x69:
420         case 0x6a:
421         case 0x6b:
422         case 0x6c:
423         case 0x6d:
424         case 0x6e:
425         case 0x6f:
426                 port60[port-0x60]= Value;
427                 if ((Value & 0xf0)==0x00) {
428                         WrMem[ (port& 0xf)-8]= RAM+((Value & 0xe)*0x1000);
429                         EnWrite[ ((port & 0xe)-8)/2 ]= 1;
430                 }
431                 if (EXTRAM) {
432                         if((Value & 0xf0)==0x20) {
433                                 WrMem[ (port& 0xf)-8]= EXTRAM+((Value & 0xe)*0x1000);
434                         }
435                 }
436                 break;
437 #endif
438         case 0xB0:
439                 if (static_cast<VM *>(vm)->sr_mode) {
440                         d_timer->set_portB0(Value);
441                 } else {
442                         VRAM=(RAM+VRAMHead[CRTMode1][(data&0x06)>>1]);
443                         if (CRTMode1 && Value == 6) d_timer->set_portB0(Value | 0x01); /// Colony Oddysey
444                         else d_timer->set_portB0(Value);
445                 }
446                 break;
447         case 0xC0: // CSS
448                 CSS3=(Value&0x04)<<2;CSS2=(Value&0x02)<<2;CSS1=(Value&0x01)<<2;
449                 break;
450         case 0xC1: // CRT controller mode
451                 CRTMode1=(Value&0x02) ? 0 : 1;
452                 CRTMode2=(Value&0x04) ? 0 : 1;
453                 CRTMode3=(Value&0x08) ? 0 : 1;
454 #if defined(_PC6601SR) || defined(_PC6001MK2SR)
455                 portC1 = Value;
456                 if (static_cast<VM *>(vm)->sr_mode)
457                         lines=(Value&0x01) ? 200 : 204;
458                 if (static_cast<VM *>(vm)->sr_mode)
459                         CGROM = CGROM6;    // N66SR BASIC use CGROM6
460                 else
461                         CGROM = ((CRTMode1 == 0) ? CGROM1 : CGROM5);
462                 if (static_cast<VM *>(vm)->sr_mode) {
463                         if (CRTMode1==1 && CRTMode2==0 && !bitmap) { /* width 80 */
464                                 cols=80;
465                         } else if(CRTMode1==0 && CRTMode2==0 && !bitmap) { /* Width 40  */
466                                 cols=40;
467                         }
468                 }
469 #else
470                 CGROM = ((CRTMode1 == 0) ? CGROM1 : CGROM5);
471 #endif
472                 break;
473         case 0xC2: // ROM swtich
474                 if (static_cast<VM *>(vm)->sr_mode) return;     /* sr_mode do nothing! */
475                 if ((Value&0x02)==0x00) CurKANJIROM=KANJIROM;
476                 else CurKANJIROM=KANJIROM+0x4000;
477                 if ((Value&0x01)==0x00) {
478 ///                     if(RdMem[0]!=BASICROM) RdMem[0]=VOICEROM;
479 ///                     if(RdMem[1]!=BASICROM+0x2000) RdMem[1]=VOICEROM+0x2000;
480 ///                     if(RdMem[0]!=BASICROM)        RdMem[0]=SYSTEMROM2;
481 ///                     if(RdMem[1]!=BASICROM+0x2000) RdMem[1]=SYSTEMROM2+0x2000;
482                         if(RdMem[2]!=BASICROM+0x4000) RdMem[2]=VOICEROM;
483                         if(RdMem[3]!=BASICROM+0x6000) RdMem[3]=VOICEROM+0x2000;
484                 }
485                 else {
486                         write_io8(0xF0,portF0);         
487                 };
488                 break;
489         case 0xC3: break; // C2H in/out switch
490 #if defined(_PC6601SR) || defined(_PC6001MK2SR)
491         case 0xC8:
492                 portC8  = Value;
493                 bitmap  = (Value & 8)? 0:1;
494                 rows    = (Value & 4)? 20:25;
495 ///             busreq  = (Value & 2)? 0:1;
496                 static_cast<VM *>(vm)->sr_mode = ((Value & 1)==1) ? 0 : 1;
497                 if (bitmap && static_cast<VM *>(vm)->sr_mode)
498                 {
499                         VRAM = (Value & 0x10) ? RAM+0x8000:RAM+0x0000;
500                 }
501                 if (static_cast<VM *>(vm)->sr_mode) {
502                         CGROM=CGROM6; 
503                         portF0=0x11;
504                 }
505                 break;  
506         case 0xC9:
507                 if (static_cast<VM *>(vm)->sr_mode && !bitmap ) 
508                 {               
509                         TEXTVRAM=RAM+(Value & 0xf)*0x1000;
510                 }
511                 break;  
512         case 0xCA: portCA=Value; break; // Graphics scroll X low
513         case 0xCB: portCB=Value; break;// Graphics scroll X high
514         case 0xCC: portCC=Value; break; // Graphics scroll Y
515         case 0xCE: portCE=Value; break; /* Graphics Y zahyou SR-BASIC add 2002/2 */
516         case 0xCF: portCF=0; break;
517 #endif
518         case 0xF0: // read block set 
519                 if (static_cast<VM *>(vm)->sr_mode) return;     /* sr_mode do nothing! */
520                 portF0 = Value;
521                 switch(data & 0x0f)
522                 {
523                 case 0x00: RdMem[0]=RdMem[1]=EmptyRAM; break;
524                 case 0x01: RdMem[0]=BASICROM;RdMem[1]=BASICROM+0x2000; break;
525                 case 0x02: RdMem[0]=CurKANJIROM;RdMem[1]=CurKANJIROM+0x2000; break;
526                 case 0x03: RdMem[0]=RdMem[1]=EXTROM2; break;
527                 case 0x04: RdMem[0]=RdMem[1]=EXTROM1; break;
528                 case 0x05: RdMem[0]=CurKANJIROM;RdMem[1]=BASICROM+0x2000; break;
529 #if defined(_PC6601SR) || defined(_PC6001MK2SR)
530                 case 0x06: RdMem[0]=BASICROM;RdMem[1]=(SYSROM2==EmptyRAM ? CurKANJIROM+0x2000 : SYSROM2); break;
531 #else
532                 case 0x06: RdMem[0]=BASICROM;RdMem[1]=CurKANJIROM+0x2000;break;
533 #endif
534                 case 0x07: RdMem[0]=EXTROM1;RdMem[1]=EXTROM2; break;
535                 case 0x08: RdMem[0]=EXTROM2;RdMem[1]=EXTROM1; break;
536                 case 0x09: RdMem[0]=EXTROM2;RdMem[1]=BASICROM+0x2000; break;
537                 case 0x0a: RdMem[0]=BASICROM;RdMem[1]=EXTROM2; break;
538                 case 0x0b: RdMem[0]=EXTROM1;RdMem[1]=CurKANJIROM+0x2000; break;
539                 case 0x0c: RdMem[0]=CurKANJIROM;RdMem[1]=EXTROM1; break;
540                 case 0x0d: RdMem[0]=RAM;RdMem[1]=RAM+0x2000; break;
541 #if defined(_PC6601SR) || defined(_PC6001MK2SR)
542                 case 0x0e: if (EXTRAM) {RdMem[0]=EXTRAM; RdMem[1]=EXTRAM+0x2000;break;}
543 #else
544                 case 0x0e: RdMem[0]=RdMem[1]=EmptyRAM; break;
545 #endif
546                 case 0x0f: RdMem[0]=RdMem[1]=EmptyRAM; break;
547                 };
548                 switch(data & 0xf0)
549                 {
550                 case 0x00: RdMem[2]=RdMem[3]=EmptyRAM; break;
551                 case 0x10: RdMem[2]=BASICROM+0x4000;RdMem[3]=BASICROM+0x6000; break;
552                 case 0x20: RdMem[2]=VOICEROM;RdMem[3]=VOICEROM+0x2000; break;
553                 case 0x30: RdMem[2]=RdMem[3]=EXTROM2; break;
554                 case 0x40: RdMem[2]=RdMem[3]=EXTROM1; break;
555                 case 0x50: RdMem[2]=VOICEROM;RdMem[3]=BASICROM+0x6000; break;
556                 case 0x60: RdMem[2]=BASICROM+0x4000;RdMem[3]=VOICEROM+0x2000; break;
557                 case 0x70: RdMem[2]=EXTROM1;RdMem[3]=EXTROM2; break;
558                 case 0x80: RdMem[2]=EXTROM2;RdMem[3]=EXTROM1; break;
559                 case 0x90: RdMem[2]=EXTROM2;RdMem[3]=BASICROM+0x6000; break;
560                 case 0xa0: RdMem[2]=BASICROM+0x4000;RdMem[3]=EXTROM2; break;
561                 case 0xb0: RdMem[2]=EXTROM1;RdMem[3]=VOICEROM+0x2000; break;
562                 case 0xc0: RdMem[2]=VOICEROM;RdMem[3]=EXTROM1; break;
563                 case 0xd0: RdMem[2]=RAM+0x4000;RdMem[3]=RAM+0x6000; break;
564 #if defined(_PC6601SR) || defined(_PC6001MK2SR)
565                 case 0xe0: if (EXTRAM) {RdMem[2]=EXTRAM+0x4000; RdMem[3]=EXTRAM+0x6000; break;}
566 #else
567                 case 0xe0: RdMem[2]=RdMem[3]=EmptyRAM; break;
568 #endif
569                 case 0xf0: RdMem[2]=RdMem[3]=EmptyRAM; break;
570                 };
571                 if (CGSW93)     RdMem[3] = CGROM;
572                 break;
573         case 0xF1: // read block set
574                 if (static_cast<VM *>(vm)->sr_mode) return;     /* sr_mode do nothing! */
575                 portF1 = Value;
576                 switch(data & 0x0f)
577                 {
578                 case 0x00: RdMem[4]=RdMem[5]=EmptyRAM; break;
579                 case 0x01: RdMem[4]=BASICROM;RdMem[5]=BASICROM+0x2000; break;
580                 case 0x02: RdMem[4]=CurKANJIROM;RdMem[5]=CurKANJIROM+0x2000; break;
581                 case 0x03: RdMem[4]=RdMem[5]=EXTROM2; break;
582                 case 0x04: RdMem[4]=RdMem[5]=EXTROM1; break;
583                 case 0x05: RdMem[4]=CurKANJIROM;RdMem[5]=BASICROM+0x2000; break;
584                 case 0x06: RdMem[4]=BASICROM;RdMem[5]=CurKANJIROM+0x2000; break;
585                 case 0x07: RdMem[4]=EXTROM1;RdMem[5]=EXTROM2; break;
586                 case 0x08: RdMem[4]=EXTROM2;RdMem[5]=EXTROM1; break;
587                 case 0x09: RdMem[4]=EXTROM2;RdMem[5]=BASICROM+0x2000; break;
588                 case 0x0a: RdMem[4]=BASICROM;RdMem[5]=EXTROM2; break;
589                 case 0x0b: RdMem[4]=EXTROM1;RdMem[5]=CurKANJIROM+0x2000; break;
590                 case 0x0c: RdMem[4]=CurKANJIROM;RdMem[5]=EXTROM1; break;
591                 case 0x0d: RdMem[4]=RAM+0x8000;RdMem[5]=RAM+0xa000; break;
592 #if defined(_PC6601SR) || defined(_PC6001MK2SR)
593                 case 0x0e: if (EXTRAM) {RdMem[4]=EXTRAM+0x8000; RdMem[5]=EXTRAM+0xa000; break;}
594 #else
595                 case 0x0e: RdMem[4]=RdMem[5]=EmptyRAM; break;
596 #endif
597                 case 0x0f: RdMem[4]=RdMem[5]=EmptyRAM; break;
598                 };
599                 switch(data & 0xf0)
600                 {
601                 case 0x00: RdMem[6]=RdMem[7]=EmptyRAM; break;
602                 case 0x10: RdMem[6]=BASICROM+0x4000;RdMem[7]=BASICROM+0x6000; break;
603                 case 0x20: RdMem[6]=CurKANJIROM;RdMem[7]=CurKANJIROM+0x2000; break;
604                 case 0x30: RdMem[6]=RdMem[7]=EXTROM2; break;
605                 case 0x40: RdMem[6]=RdMem[7]=EXTROM1; break;
606                 case 0x50: RdMem[6]=CurKANJIROM;RdMem[7]=BASICROM+0x6000; break;
607                 case 0x60: RdMem[6]=BASICROM+0x4000;RdMem[7]=CurKANJIROM+0x2000; break;
608                 case 0x70: RdMem[6]=EXTROM1;RdMem[7]=EXTROM2; break;
609                 case 0x80: RdMem[6]=EXTROM2;RdMem[7]=EXTROM1; break;
610                 case 0x90: RdMem[6]=EXTROM2;RdMem[7]=BASICROM+0x6000; break;
611                 case 0xa0: RdMem[6]=BASICROM+0x4000;RdMem[7]=EXTROM2; break;
612                 case 0xb0: RdMem[6]=EXTROM1;RdMem[7]=CurKANJIROM+0x2000; break;
613                 case 0xc0: RdMem[6]=CurKANJIROM;RdMem[7]=EXTROM1; break;
614                 case 0xd0: RdMem[6]=RAM+0xc000;RdMem[7]=RAM+0xe000; break;
615 #if defined(_PC6601SR) || defined(_PC6001MK2SR)
616                 case 0xe0: if (EXTRAM) {RdMem[6]=EXTRAM+0xc000;RdMem[7]=EXTRAM+0xe000; break;}
617 #else
618                 case 0xe0: RdMem[6]=RdMem[7]=EmptyRAM; break;
619 #endif
620                 case 0xf0: RdMem[6]=RdMem[7]=EmptyRAM; break;
621                 };
622                 break;
623         case 0xF2: // write ram block set
624                 if (static_cast<VM *>(vm)->sr_mode) return;     /* sr_mode do nothing! */
625                 if (data & 0x40) {EnWrite[3]=1;WrMem[6]=RAM+0xc000;WrMem[7]=RAM+0xe000;}
626                 else EnWrite[3]=0;
627                 if (data & 0x010) {EnWrite[2]=1;WrMem[4]=RAM+0x8000;WrMem[5]=RAM+0xa000;}
628                 else EnWrite[2]=0;
629                 if (data & 0x04) {EnWrite[1]=1;WrMem[2]=RAM+0x4000;WrMem[3]=RAM+0x6000;}
630                 else EnWrite[1]=0;
631                 if (data & 0x01) {EnWrite[0]=1;WrMem[0]=RAM;WrMem[1]=RAM+0x2000;}
632                 else EnWrite[0]=0;
633 #if defined(_PC6601SR) || defined(_PC6001MK2SR)
634                 if (EXTRAM) {
635                         if (Value&0x80) {EnWrite[3]=2;WrMem[6]=EXTRAM+0xc000;WrMem[7]=EXTRAM+0xe000;}
636                         if (Value&0x20) {EnWrite[2]=2;WrMem[4]=EXTRAM+0x8000;WrMem[5]=EXTRAM+0xa000;}
637                         if (Value&0x08) {EnWrite[1]=2;WrMem[2]=EXTRAM+0x4000;WrMem[3]=EXTRAM+0x6000;}
638                         if (Value&0x02) {EnWrite[0]=2;WrMem[0]=EXTRAM+0x0000;WrMem[1]=EXTRAM+0x2000;}
639                 }
640 #endif
641                 break;
642 #endif
643         }
644         return;
645 }
646
647 #ifndef _PC6001
648 uint32_t MEMORY::read_io8(uint32_t addr)
649 {
650         uint16_t port=(addr & 0x00ff);
651         uint8_t Value=0xff;
652
653         switch(port)
654         {
655 #if defined(_PC6601SR) || defined(_PC6001MK2SR)
656         case 0x60:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65:case 0x66:case 0x67:
657         case 0x68:case 0x69:case 0x6a:case 0x6b:case 0x6c:case 0x6d:case 0x6e:case 0x6f:
658                 Value=port60[ port-0x60 ];
659                 break;
660         case 0xC0: Value=0xff;break;
661         case 0xC2: Value=0xff;break;
662 #endif
663         case 0xF0: if (!static_cast<VM *>(vm)->sr_mode) Value=portF0;break;
664         case 0xF1: if (!static_cast<VM *>(vm)->sr_mode) Value=portF1;break;
665         }
666         return(Value);
667 }
668 #endif
669
670 void MEMORY::write_io8w(uint32_t addr, uint32_t data, int* wait)
671 {
672         *wait = (addr & 0xf0) == 0xa0 ? 1 : 0;
673         write_io8(addr, data);
674 }
675
676 uint32_t MEMORY::read_io8w(uint32_t addr, int* wait)
677 {
678         *wait = (addr & 0xf0) == 0xa0 ? 1 : 0;
679         return read_io8(addr);
680 }
681
682 #define EVENT_HBLANK    1
683
684 void MEMORY::event_vline(int v, int clock)
685 {
686 #if defined(_PC6601SR) || defined(_PC6001MK2SR)
687         if(static_cast<VM *>(vm)->sr_mode) {
688                 if(v == (CRTMode1 ? 200 : 192)) {
689                         d_timer->write_signal(SIG_TIMER_IRQ_VRTC, 1, 1);
690                 }
691                 if(!CRTKILL) {
692                         // SR\83\82\81[\83h\82ÌBUSRQ\82É\82Â\82¢\82Ä\82Í\81A\82¦\82Ñ\82·\97l\82Ì\8fî\95ñ\91Ò\82¿
693                 }
694         } else
695 #endif
696         {
697                 if (!CRTKILL) {
698 #ifdef _PC6001
699                         if (v < 192) {
700                                 d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
701                                 register_event_by_clock(this, EVENT_HBLANK, (uint64_t)((double)CPU_CLOCKS / FRAMES_PER_SEC / LINES_PER_FRAME * 296 / 455), false, NULL);
702                         }
703 #else
704                         if (v < (CRTMode1 ? 200 : 192)) {
705                                 d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
706                                 register_event_by_clock(this, EVENT_HBLANK, (uint64_t)((double)CPU_CLOCKS / FRAMES_PER_SEC / LINES_PER_FRAME * (CRTMode1 ? 368 : 304) / 456), false, NULL);
707                         }
708 #endif
709                 }
710         }
711 }
712
713 void MEMORY::event_callback(int event_id, int err)
714 {
715         if(event_id == EVENT_HBLANK) {
716                 d_cpu->write_signal(SIG_CPU_BUSREQ, 0, 0);
717         }
718 }
719
720 void MEMORY::write_signal(int id, uint32_t data, uint32_t mask)
721 {
722         if(id == SIG_MEMORY_PIO_PORT_C) {
723 #ifdef _PC6001
724                 if(data & 4) {
725                         CGSW93=0;RdMem[3]=EXTROM2;
726                 } else {
727                         CGSW93=1; RdMem[3]=CGROM1;
728                 }
729 #else
730                 if(data & 4) {
731                         CGSW93=0; if (!static_cast<VM *>(vm)->sr_mode) write_io8(0xf0, portF0);
732                 } else {
733                         CGSW93=1; RdMem[3]=CGROM;
734                 }
735 #endif
736                 CRTKILL = (data & 2) ? 0 : 1;
737                 if (CRTKILL) {
738                         d_cpu->write_signal(SIG_CPU_BUSREQ, 0, 0);
739                 }
740         }
741 }
742
743 void MEMORY::open_cart(const _TCHAR* file_path)
744 {
745         FILEIO* fio = new FILEIO();
746         if(fio->Fopen(file_path, FILEIO_READ_BINARY)) {
747                 fio->Fread(EXTROM, 0x4000, 1);
748                 fio->Fclose();
749                 EXTROM1 = EXTROM;
750                 EXTROM2 = EXTROM + 0x2000;
751                 EnWrite[1]=0;
752                 inserted = true;
753         } else {
754 ///             EXTROM1 = EXTROM2 = EmptyRAM;
755                 EXTROM1 = RAM + 0x4000;
756                 EXTROM2 = RAM + 0x6000;
757                 EnWrite[1]=1;
758                 inserted = false;
759         }
760         delete fio;
761 }
762
763 void MEMORY::close_cart()
764 {
765 ///     EXTROM1 = EXTROM2 = EmptyRAM;
766         EXTROM1 = RAM + 0x4000;
767         EXTROM2 = RAM + 0x6000;
768         EnWrite[1]=1;
769         inserted = false;
770 }
771
772 #define STATE_VERSION   1
773
774 bool MEMORY::process_state(FILEIO* state_fio, bool loading)
775 {
776         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
777                 return false;
778         }
779         if(!state_fio->StateCheckInt32(this_device_id)) {
780                 return false;
781         }
782         state_fio->StateArray(RAM, RAM_SIZE, 1);
783         if(loading) {
784                 CGROM = MEMORY_BASE + state_fio->FgetInt32_LE();
785                 EXTROM1 = MEMORY_BASE + state_fio->FgetInt32_LE();
786                 EXTROM2 = MEMORY_BASE + state_fio->FgetInt32_LE();
787                 for(int i = 0; i < 8; i++) {
788                         RdMem[i] = MEMORY_BASE + state_fio->FgetInt32_LE();
789                         WrMem[i] = MEMORY_BASE + state_fio->FgetInt32_LE();
790                 }
791                 VRAM = MEMORY_BASE + state_fio->FgetInt32_LE();
792         } else {
793                 state_fio->FputInt32_LE((int)(CGROM - MEMORY_BASE));
794                 state_fio->FputInt32_LE((int)(EXTROM1 - MEMORY_BASE));
795                 state_fio->FputInt32_LE((int)(EXTROM2 - MEMORY_BASE));
796                 for(int i = 0; i < 8; i++) {
797                         state_fio->FputInt32_LE((int)(RdMem[i] - MEMORY_BASE));
798                         state_fio->FputInt32_LE((int)(WrMem[i] - MEMORY_BASE));
799                 }
800                 state_fio->FputInt32_LE((int)(VRAM - MEMORY_BASE));
801         }
802         state_fio->StateArray(EnWrite, sizeof(EnWrite), 1);
803         state_fio->StateValue(CGSW93);
804         state_fio->StateValue(inserted);
805 #ifndef _PC6001
806         state_fio->StateValue(CRTKILL);
807         if(loading) {
808                 CurKANJIROM = MEMORY_BASE + state_fio->FgetInt32_LE();
809         } else {
810                 state_fio->FputInt32_LE((int)(CurKANJIROM - MEMORY_BASE));
811         }
812         state_fio->StateValue(CRTMode1);
813         state_fio->StateValue(CRTMode2);
814         state_fio->StateValue(CRTMode3);
815         state_fio->StateValue(CSS1);
816         state_fio->StateValue(CSS2);
817         state_fio->StateValue(CSS3);
818         state_fio->StateValue(portF0);
819         state_fio->StateValue(portF1);
820 #if defined(_PC6601SR) || defined(_PC6001MK2SR)
821         state_fio->StateValue(bitmap);
822         state_fio->StateValue(cols);
823         state_fio->StateValue(rows);
824         state_fio->StateValue(lines);
825         if(loading) {
826                 TEXTVRAM = MEMORY_BASE + state_fio->FgetInt32_LE();
827                 SYSROM2 = MEMORY_BASE + state_fio->FgetInt32_LE();
828         } else {
829                 state_fio->FputInt32_LE((int)(TEXTVRAM - MEMORY_BASE));
830                 state_fio->FputInt32_LE((int)(SYSROM2 - MEMORY_BASE));
831         }
832         state_fio->StateArray(EXTRAM, EXTRAM_SIZE, 1);
833         state_fio->StateArray(port60, sizeof(port60), 1);
834         state_fio->StateValue(portC1);
835         state_fio->StateValue(portC8);
836         state_fio->StateValue(portCA);
837         state_fio->StateValue(portCB);
838         state_fio->StateValue(portCC);
839         state_fio->StateValue(portCE);
840         state_fio->StateValue(portCF);
841         state_fio->StateArray(palet, sizeof(palet), 1);
842 #endif
843 #endif
844         return true;
845 }
846
847 }