OSDN Git Service

[VM][PCENGINE][X1] Enable to build.
[csp-qt/common_source_project-fm7.git] / source / src / vm / x1 / memory.cpp
1 /*
2         SHARP X1 Emulator 'eX1'
3         SHARP X1twin Emulator 'eX1twin'
4         SHARP X1turbo Emulator 'eX1turbo'
5         SHARP X1turboZ Emulator 'eX1turboZ'
6
7         Author : Takeda.Toshiya
8         Date   : 2009.03.14-
9
10         [ memory ]
11 */
12
13 #include "memory.h"
14 #ifdef _X1TURBO_FEATURE
15 #include "../i8255.h"
16 #else
17 #include "../z80.h"
18 #endif
19
20 #define SET_BANK(s, e, w, r) { \
21         int sb = (s) >> 12, eb = (e) >> 12; \
22         for(int i = sb; i <= eb; i++) { \
23                 wbank[i] = (w) + 0x1000 * (i - sb); \
24                 rbank[i] = (r) + 0x1000 * (i - sb); \
25         } \
26 }
27
28 void MEMORY::initialize()
29 {
30         // init memory
31         memset(rom, 0xff, sizeof(rom));
32         memset(ram, 0, sizeof(ram));
33         
34         // load ipl
35         FILEIO* fio = new FILEIO();
36         if(fio->Fopen(create_local_path(IPL_ROM_FILE_NAME), FILEIO_READ_BINARY)) {
37                 // xmillenium rom
38                 fio->Fread(rom, IPL_ROM_FILE_SIZE, 1);
39                 fio->Fclose();
40         } else if(fio->Fopen(create_local_path(_T("IPL.ROM")), FILEIO_READ_BINARY)) {
41                 fio->Fread(rom, IPL_ROM_FILE_SIZE, 1);
42                 fio->Fclose();
43         }
44         delete fio;
45 #ifndef _X1TURBO_FEATURE
46         for(int ofs = 0x1000; ofs < 0x8000; ofs += 0x1000) {
47                 memcpy(rom + ofs, rom, 0x1000);
48         }
49 #endif
50 }
51
52 void MEMORY::reset()
53 {
54         SET_BANK(0x0000, 0x7fff, ram, rom);
55         SET_BANK(0x8000, 0xffff, ram + 0x8000, ram + 0x8000);
56         romsel = 1;
57 #ifdef _X1TURBO_FEATURE
58         bank = 0x10;
59         d_pio->write_signal(SIG_I8255_PORT_B, 0x00, 0x10);
60 #else
61         m1_cycle = 1;
62 #endif
63 }
64
65 void MEMORY::write_data8(uint32_t addr, uint32_t data)
66 {
67         addr &= 0xffff;
68         wbank[addr >> 12][addr & 0xfff] = data;
69 }
70
71 uint32_t MEMORY::read_data8(uint32_t addr)
72 {
73         addr &= 0xffff;
74         return rbank[addr >> 12][addr & 0xfff];
75 }
76
77 #ifndef _X1TURBO_FEATURE
78 uint32_t MEMORY::fetch_op(uint32_t addr, int *wait)
79 {
80         *wait = m1_cycle;
81         return read_data8(addr);
82 }
83 #endif
84
85 void MEMORY::write_io8(uint32_t addr, uint32_t data)
86 {
87         bool update_map_required = false;
88         
89         switch(addr & 0xff00) {
90 #ifdef _X1TURBO_FEATURE
91         case 0xb00:
92                 if((bank & 0x1f) != (data & 0x1f)) {
93                         update_map_required = true;
94                 }
95                 bank = data;
96                 break;
97 #endif
98         case 0x1d00:
99                 if(!romsel) {
100                         romsel = 1;
101                         update_map_required = true;
102 #ifdef _X1TURBO_FEATURE
103                         d_pio->write_signal(SIG_I8255_PORT_B, 0x00, 0x10);
104 #else
105                         m1_cycle = 1;
106 #endif
107                 }
108                 break;
109         case 0x1e00:
110                 if(romsel) {
111                         romsel = 0;
112                         update_map_required = true;
113 #ifdef _X1TURBO_FEATURE
114                         d_pio->write_signal(SIG_I8255_PORT_B, 0x10, 0x10);
115 #else
116                         m1_cycle = 0;
117 #endif
118                 }
119                 break;
120         }
121         if(update_map_required) {
122                 update_map();
123         }
124 }
125
126 uint32_t MEMORY::read_io8(uint32_t addr)
127 {
128         switch(addr & 0xff00) {
129         case 0x1e00: // thanks Mr.Sato
130                 if(romsel) {
131                         romsel = 0;
132 #ifdef _X1TURBO_FEATURE
133                         d_pio->write_signal(SIG_I8255_PORT_B, 0x10, 0x10);
134 #else
135                         m1_cycle = 0;
136 #endif
137                         update_map();
138                 }
139                 break;
140 #ifdef _X1TURBO_FEATURE
141         case 0xb00:
142                 return bank;
143 #endif
144         }
145         return 0xff;
146 }
147
148 void MEMORY::update_map()
149 {
150 #ifdef _X1TURBO_FEATURE
151         if(!(bank & 0x10)) {
152                 uint8_t *ptr = extram + 0x8000 * (bank & 0x0f);
153                 SET_BANK(0x0000, 0x7fff, ptr, ptr);
154         } else
155 #endif
156         if(romsel) {
157                 SET_BANK(0x0000, 0x7fff, ram, rom);
158         } else {
159                 SET_BANK(0x0000, 0x7fff, ram, ram);
160         }
161 }
162
163 #define STATE_VERSION   1
164
165 bool MEMORY::process_state(FILEIO* state_fio, bool loading)
166 {
167         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
168                 return false;
169         }
170         if(!state_fio->StateCheckInt32(this_device_id)) {
171                 return false;
172         }
173         state_fio->StateBuffer(ram, sizeof(ram), 1);
174         state_fio->StateUint8(romsel);
175 #ifdef _X1TURBO_FEATURE
176         state_fio->StateBuffer(extram, sizeof(extram), 1);
177         state_fio->StateUint8(bank);
178 #else
179         state_fio->StateInt32(m1_cycle);
180 #endif
181         
182         // post process
183         if(loading) {
184                 update_map();
185         }
186         return true;
187 }
188