OSDN Git Service

312dc75449c573e77e18712b4d54f45074bfce8d
[csp-qt/common_source_project-fm7.git] / source / src / vm / pasopia7 / memory.cpp
1 /*
2         TOSHIBA PASOPIA 7 Emulator 'EmuPIA7'
3
4         Author : Takeda.Toshiya
5         Date   : 2006.09.20 -
6
7         [ memory ]
8 */
9
10 #include "./memory.h"
11 #include "iobus.h"
12 #include "../i8255.h"
13
14 #define SET_BANK(s, e, w, r) { \
15         int sb = (s) >> 12, eb = (e) >> 12; \
16         for(int i = sb; i <= eb; i++) { \
17                 if((w) == wdmy) { \
18                         wbank[i] = wdmy; \
19                 } else { \
20                         wbank[i] = (w) + 0x1000 * (i - sb); \
21                 } \
22                 if((r) == rdmy) { \
23                         rbank[i] = rdmy; \
24                 } else { \
25                         rbank[i] = (r) + 0x1000 * (i - sb); \
26                 } \
27         } \
28 }
29
30 void PASOPIA7_MEMORY::initialize()
31 {
32         memset(bios, 0xff, sizeof(bios));
33         memset(basic, 0xff, sizeof(basic));
34         memset(rdmy, 0xff, sizeof(rdmy));
35         
36         // load rom images
37         FILEIO* fio = new FILEIO();
38         if(fio->Fopen(create_local_path(_T("BIOS.ROM")), FILEIO_READ_BINARY)) {
39                 fio->Fread(bios, sizeof(bios), 1);
40                 fio->Fclose();
41         }
42         if(fio->Fopen(create_local_path(_T("BASIC.ROM")), FILEIO_READ_BINARY)) {
43                 fio->Fread(basic, sizeof(basic), 1);
44                 fio->Fclose();
45         }
46         delete fio;
47         
48         mem_map = 0xff;
49         update_memory_map();
50         
51         plane = 0;
52         vram_sel = pal_sel = attr_wrap = false;
53 }
54
55 void PASOPIA7_MEMORY::reset()
56 {
57         memset(vram, 0, sizeof(vram));
58 }
59
60 void PASOPIA7_MEMORY::write_data8(uint32_t addr, uint32_t data)
61 {
62         addr &= 0xffff;
63         if(vram_sel && (addr & 0xc000) == 0x8000) {
64                 if(pal_sel && !(plane & 0x70)) {
65                         pal[addr & 0x0f] = data & 0x0f;
66                         return;
67                 }
68                 uint32_t laddr = addr & 0x3fff;
69                 if(plane & 0x10) {
70                         vram[0x0000 | laddr] = (plane & 0x1) ? data : 0xff;
71                 }
72                 if(plane & 0x20) {
73                         vram[0x4000 | laddr] = (plane & 0x2) ? data : 0xff;
74                 }
75                 if(plane & 0x40) {
76                         vram[0x8000 | laddr] = (plane & 0x4) ? data : 0xff;
77                         attr_latch = attr_wrap ? attr_latch : attr_data;
78                         vram[0xc000 | laddr] = attr_latch;
79                         // 8255-0, Port B
80                         d_pio0->write_signal(SIG_I8255_PORT_B, (attr_latch << 4) | (attr_latch & 7), 0x87);
81                 }
82                 return;
83         }
84         wbank[addr >> 12][addr & 0xfff] = data;
85 }
86
87 uint32_t PASOPIA7_MEMORY::read_data8(uint32_t addr)
88 {
89         addr &= 0xffff;
90         if(vram_sel && (addr & 0xc000) == 0x8000) {
91                 if(pal_sel && !(plane & 0x70)) {
92                         return pal[addr & 0x0f];
93                 }
94                 uint32_t laddr = addr & 0x3fff, val = 0xff;
95                 if((plane & 0x11) == 0x11) {
96                         val &= vram[0x0000 | laddr];
97                 }
98                 if((plane & 0x22) == 0x22) {
99                         val &= vram[0x4000 | laddr];
100                 }
101                 if((plane & 0x44) == 0x44) {
102                         attr_latch = vram[0xc000 | laddr];
103                         val &= vram[0x8000 | laddr];
104                         // 8255-0, Port B
105                         d_pio0->write_signal(SIG_I8255_PORT_B, (attr_latch << 4) | (attr_latch & 7), 0x87);
106                 }
107                 return val;
108         }
109         return rbank[addr >> 12][addr & 0xfff];
110 }
111
112 void PASOPIA7_MEMORY::write_io8(uint32_t addr, uint32_t data)
113 {
114         if(mem_map != (data & 7)) {
115                 mem_map = data & 7;
116                 update_memory_map();
117         }
118         vram_sel = ((data & 4) != 0);
119         
120         // I/O memory access
121         d_iobus->write_signal(SIG_IOBUS_MIO, data, 8);
122         
123         // 8255-2, Port C
124         d_pio2->write_signal(SIG_I8255_PORT_C, data, 3);
125 }
126
127 void PASOPIA7_MEMORY::write_signal(int id, uint32_t data, uint32_t mask)
128 {
129         if(id == SIG_MEMORY_I8255_1_A) {
130                 plane = data;
131         } else if(id == SIG_MEMORY_I8255_1_B) {
132                 attr_data = data & 0x0f;
133         } else if(id == SIG_MEMORY_I8255_1_C) {
134                 attr_wrap = ((data & 0x10) != 0);
135                 pal_sel = ((data & 0x0c) != 0);
136         }
137 }
138
139 void PASOPIA7_MEMORY::update_memory_map()
140 {
141         if(mem_map == 0xff) {
142                 SET_BANK(0x0000, 0x3fff, wdmy, bios);
143                 SET_BANK(0x4000, 0x7fff, wdmy, bios);
144                 SET_BANK(0x8000, 0xbfff, wdmy, bios);
145                 SET_BANK(0xc000, 0xffff, wdmy, bios);
146         } else {
147                 if(mem_map & 2) {
148                         SET_BANK(0x0000, 0x3fff, ram + 0x0000, ram + 0x0000);
149                 } else {
150                         SET_BANK(0x0000, 0x3fff, ram + 0x0000, basic + 0x0000);
151                 }
152                 if(mem_map & 1) {
153                         SET_BANK(0x4000, 0x7fff, ram + 0x4000, bios + 0x0000);
154                 } else if(mem_map & 2) {
155                         SET_BANK(0x4000, 0x7fff, ram + 0x4000, ram + 0x4000);
156                 } else {
157                         SET_BANK(0x4000, 0x7fff, ram + 0x4000, basic + 0x4000);
158                 }
159                 if(mem_map & 4) {
160                         SET_BANK(0x8000, 0xbfff, wdmy, rdmy);
161                 } else {
162                         SET_BANK(0x8000, 0xbfff, ram + 0x8000, ram + 0x8000);
163                 }
164                 SET_BANK(0xc000, 0xffff, ram + 0xc000, ram + 0xc000);
165         }
166 }
167
168 #define STATE_VERSION   1
169
170 bool PASOPIA7_MEMORY::process_state(FILEIO* state_fio, bool loading)
171 {
172         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
173                 return false;
174         }
175         if(!state_fio->StateCheckInt32(this_device_id)) {
176                 return false;
177         }
178         state_fio->StateBuffer(ram, sizeof(ram), 1);
179         state_fio->StateBuffer(vram, sizeof(vram), 1);
180         state_fio->StateBuffer(pal, sizeof(pal), 1);
181         state_fio->StateUint8(mem_map);
182         state_fio->StateUint8(plane);
183         state_fio->StateUint8(attr_data);
184         state_fio->StateUint8(attr_latch);
185         state_fio->StateBool(vram_sel);
186         state_fio->StateBool(pal_sel);
187         state_fio->StateBool(attr_wrap);
188         
189         // post process
190         if(loading) {
191                 update_memory_map();
192         }
193         return true;
194 }