OSDN Git Service

[VM][STATE] Use namespace {VMNAME} to separate per VMs.
[csp-qt/common_source_project-fm7.git] / source / src / vm / pasopia / memory.cpp
1 /*
2         TOSHIBA PASOPIA Emulator 'EmuPIA'
3
4         Author : Takeda.Toshiya
5         Date   : 2006.12.28 -
6
7         [ memory ]
8 */
9
10 #include "./memory.h"
11 #include "../i8255.h"
12
13 namespace PASOPIA {
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 MEMORY::initialize()
32 {
33         // load ipl
34         memset(rdmy, 0xff, sizeof(rdmy));
35         load_ipl();
36         
37         // init memory map
38         SET_BANK(0x0000, 0x7fff, ram + 0x0000, rom + 0x0000);
39         SET_BANK(0x8000, 0xffff, ram + 0x8000, ram + 0x8000);
40         vram_ptr = 0;
41         vram_data = mem_map = 0;
42 }
43
44 void MEMORY::load_ipl()
45 {
46         // load ipl
47         memset(rom, 0xff, sizeof(rom));
48         
49         const _TCHAR *file_path = NULL;
50         FILEIO* fio = new FILEIO();
51         
52         switch(config.boot_mode) {
53         case MODE_TBASIC_V1_0:
54                 file_path = create_local_path(_T("TBASIC10.ROM"));
55                 break;
56         case MODE_TBASIC_V1_1:
57                 file_path = create_local_path(_T("TBASIC11.ROM"));
58                 break;
59         case MODE_OABASIC:
60         case MODE_OABASIC_NO_DISK:
61                 file_path = create_local_path(_T("OABASIC.ROM"));
62                 break;
63         case MODE_MINI_PASCAL:
64                 file_path = create_local_path(_T("PASCAL.ROM"));
65                 break;
66         }
67         if(file_path != NULL && fio->Fopen(file_path, FILEIO_READ_BINARY)) {
68                 fio->Fread(rom, sizeof(rom), 1);
69                 fio->Fclose();
70         } else {
71                 // old bios file name
72                 if(fio->Fopen(create_local_path(_T("TBASIC.ROM")), FILEIO_READ_BINARY)) {
73                         fio->Fread(rom, sizeof(rom), 1);
74                         fio->Fclose();
75                 }
76         }
77         delete fio;
78         
79 }
80
81 void MEMORY::reset()
82 {
83         memset(vram, 0, sizeof(vram));
84 }
85
86 void MEMORY::write_data8(uint32_t addr, uint32_t data)
87 {
88         addr &= 0xffff;
89         wbank[addr >> 12][addr & 0xfff] = data;
90 }
91
92 uint32_t MEMORY::read_data8(uint32_t addr)
93 {
94         addr &= 0xffff;
95         return rbank[addr >> 12][addr & 0xfff];
96 }
97
98 void MEMORY::write_io8(uint32_t addr, uint32_t data)
99 {
100         mem_map = data;
101         
102         if(mem_map & 4) {
103                 vm->reset();
104         }
105         if(mem_map & 2) {
106                 SET_BANK(0x0000, 0x7fff, ram, ram);
107         } else {
108                 SET_BANK(0x0000, 0x7fff, ram, rom);
109         }
110         // to 8255-2 port-c, bit2
111         d_pio2->write_signal(SIG_I8255_PORT_C, (mem_map & 2) ? 4 : 0, 4);
112 }
113
114 void MEMORY::write_signal(int id, uint32_t data, uint32_t mask)
115 {
116         // vram control
117         if(id == SIG_MEMORY_I8255_0_A) {
118                 // bit6 of high byte: 0=write, 1=read
119                 vram_ptr = (vram_ptr & 0xff00) | (data & 0xff);
120                 if(!(vram_ptr & 0x4000)) {
121                         vram[vram_ptr & 0x3fff] = vram_data;
122                         attr[vram_ptr & 0x3fff] = (vram_ptr & 0x8000) ? 1 : 0;
123                 }
124                 // to 8255-0 port-c
125                 d_pio0->write_signal(SIG_I8255_PORT_C, vram[vram_ptr & 0x3fff], 0xff);
126                 // to 8255-1 port-b, bit7
127                 d_pio1->write_signal(SIG_I8255_PORT_B, attr[vram_ptr & 0x3fff] ? 0x80 : 0, 0x80);
128         } else if(id == SIG_MEMORY_I8255_0_B) {
129                 vram_data = data & 0xff;
130         } else if(id == SIG_MEMORY_I8255_1_C) {
131                 // bit6 of high byte: 0=write, 1=read
132                 vram_ptr = (vram_ptr & 0x00ff) | ((data & 0xff) << 8);
133                 if(!(vram_ptr & 0x4000)) {
134                         vram[vram_ptr & 0x3fff] = vram_data;
135                         attr[vram_ptr & 0x3fff] = (vram_ptr & 0x8000) ? 1 : 0;
136                 }
137                 // to 8255-0 port-c
138                 d_pio0->write_signal(SIG_I8255_PORT_C, vram[vram_ptr & 0x3fff], 0xff);
139                 // to 8255-1 port-b, bit7
140                 d_pio1->write_signal(SIG_I8255_PORT_B, attr[vram_ptr & 0x3fff] ? 0x80 : 0, 0x80);
141         }
142 }
143
144 #define STATE_VERSION   1
145
146 bool MEMORY::process_state(FILEIO* state_fio, bool loading)
147 {
148         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
149                 return false;
150         }
151         if(!state_fio->StateCheckInt32(this_device_id)) {
152                 return false;
153         }
154         state_fio->StateBuffer(ram, sizeof(ram), 1);
155         state_fio->StateBuffer(vram, sizeof(vram), 1);
156         state_fio->StateBuffer(attr, sizeof(attr), 1);
157         state_fio->StateUint16(vram_ptr);
158         state_fio->StateUint8(vram_data);
159         state_fio->StateUint8(mem_map);
160         
161         // post process
162         if(loading) {
163                 if(mem_map & 2) {
164                         SET_BANK(0x0000, 0x7fff, ram, ram);
165                 } else {
166                         SET_BANK(0x0000, 0x7fff, ram, rom);
167                 }
168         }
169         return true;
170 }
171
172 }