OSDN Git Service

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