OSDN Git Service

b2f197ace8830418e38a34fa9cd65065950632ae
[csp-qt/common_source_project-fm7.git] / source / src / vm / pc8201 / memory.cpp
1 /*
2         NEC PC-8201 Emulator 'ePC-8201'
3
4         Author : Takeda.Toshiya
5         Date   : 2009.03.31-
6
7         [ memory ]
8 */
9
10 #include "memory.h"
11 #include "cmt.h"
12 #include "../datarec.h"
13 #include "../upd1990a.h"
14
15 #define SET_BANK(s, e, w, r) { \
16         int sb = (s) >> 12, eb = (e) >> 12; \
17         for(int i = sb; i <= eb; i++) { \
18                 if((w) == wdmy) { \
19                         wbank[i] = wdmy; \
20                 } else { \
21                         wbank[i] = (w) + 0x1000 * (i - sb); \
22                 } \
23                 if((r) == rdmy) { \
24                         rbank[i] = rdmy; \
25                 } else { \
26                         rbank[i] = (r) + 0x1000 * (i - sb); \
27                 } \
28         } \
29 }
30
31 void PC8201_MEMORY::initialize()
32 {
33         // init memory
34         memset(ram, 0, sizeof(ram));
35         memset(ipl, 0xff, sizeof(ipl));
36         memset(ext, 0xff, sizeof(ext));
37         memset(rdmy, 0xff, sizeof(rdmy));
38         
39         // load rom / ram images
40         FILEIO* fio = new FILEIO();
41         if(fio->Fopen(create_local_path(_T("IPL.ROM")), FILEIO_READ_BINARY)) {
42                 fio->Fread(ipl, sizeof(ipl), 1);
43                 fio->Fclose();
44         }
45         if(fio->Fopen(create_local_path(_T("EXT.ROM")), FILEIO_READ_BINARY)) {
46                 fio->Fread(ext, sizeof(ext), 1);
47                 fio->Fclose();
48         }
49         if(fio->Fopen(create_local_path(_T("RAM.BIN")), FILEIO_READ_BINARY)) {
50                 fio->Fread(ram, sizeof(ram), 1);
51                 fio->Fclose();
52         }
53         delete fio;
54 }
55
56 void PC8201_MEMORY::release()
57 {
58         // save ram image
59         FILEIO* fio = new FILEIO();
60         if(fio->Fopen(create_local_path(_T("RAM.BIN")), FILEIO_WRITE_BINARY)) {
61                 fio->Fwrite(ram, sizeof(ram), 1);
62                 fio->Fclose();
63         }
64         delete fio;
65 }
66
67 void PC8201_MEMORY::reset()
68 {
69         sio = bank = 0;
70         update_bank();
71 }
72
73 void PC8201_MEMORY::write_data8(uint32_t addr, uint32_t data)
74 {
75         addr &= 0xffff;
76         wbank[addr >> 12][addr & 0xfff] = data;
77 }
78
79 uint32_t PC8201_MEMORY::read_data8(uint32_t addr)
80 {
81         addr &= 0xffff;
82         return rbank[addr >> 12][addr & 0xfff];
83 }
84
85 void PC8201_MEMORY::write_io8(uint32_t addr, uint32_t data)
86 {
87         switch(addr & 0xf0) {
88         case 0x90:
89                 // system control
90                 if((sio & 8) != (data & 8)) {
91                         d_cmt->write_signal(SIG_CMT_REMOTE, data, 8);
92                         d_drec->write_signal(SIG_DATAREC_REMOTE, data, 8);
93                 }
94                 if((sio & 0x10) != (data & 0x10)) {
95                         d_rtc->write_signal(SIG_UPD1990A_STB, data, 0x10);
96                 }
97                 sio = data;
98                 break;
99         case 0xa0:
100                 // bank control
101                 bank = data;
102                 update_bank();
103                 break;
104         }
105 }
106
107 uint32_t PC8201_MEMORY::read_io8(uint32_t addr)
108 {
109         // $A0: bank status
110         return (sio & 0xc0) | (bank & 0xf);
111 }
112
113 void PC8201_MEMORY::update_bank()
114 {
115         switch(bank & 3) {
116         case 0:
117                 SET_BANK(0x0000, 0x7fff, wdmy, ipl);
118                 break;
119         case 1:
120                 SET_BANK(0x0000, 0x7fff, wdmy, ext);
121                 break;
122         case 2:
123                 SET_BANK(0x0000, 0x7fff, ram + 0x08000, ram + 0x08000);
124                 break;
125         case 3:
126                 SET_BANK(0x0000, 0x7fff, ram + 0x10000, ram + 0x10000);
127                 break;
128         }
129         switch((bank >> 2) & 3) {
130         case 0:
131                 SET_BANK(0x8000, 0xffff, ram + 0x00000, ram + 0x00000);
132                 break;
133         case 1:
134                 SET_BANK(0x8000, 0xffff, wdmy, rdmy);
135                 break;
136         case 2:
137                 SET_BANK(0x8000, 0xffff, ram + 0x08000, ram + 0x08000);
138                 break;
139         case 3:
140                 SET_BANK(0x8000, 0xffff, ram + 0x10000, ram + 0x10000);
141                 break;
142         }
143 }
144
145 #define STATE_VERSION   1
146
147 bool PC8201_MEMORY::process_state(FILEIO* state_fio, bool loading)
148 {
149         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
150                 return false;
151         }
152         if(!state_fio->StateCheckInt32(this_device_id)) {
153                 return false;
154         }
155         state_fio->StateBuffer(ram, sizeof(ram), 1);
156         state_fio->StateUint8(sio);
157         state_fio->StateUint8(bank);
158         
159         // post process
160         if(loading) {
161                 update_bank();
162         }
163         return true;
164 }