OSDN Git Service

[General] Convert sourcecode's CRLF format: DOS(WINDOWS) to Unix, to apply patches...
[csp-qt/common_source_project-fm7.git] / source / src / vm / phc20 / memory.cpp
1 /*
2         SANYO PHC-20 Emulator 'ePHC-20'
3
4         Author : Takeda.Toshiya
5         Date   : 2010.09.03-
6
7         [ memory ]
8 */
9
10 #include "memory.h"
11 #include "../datarec.h"
12 #include "../../fileio.h"
13
14 static const uint8 key_map[9][8] = {
15         {0x31, 0x57, 0x53, 0x58, 0x00, 0x28, 0xba, 0xbd},       //      1       W       S       X               DOWN    :       -
16         {0x1b, 0x51, 0x41, 0x5a, 0x00, 0x0d, 0xbb, 0xbf},       //      ESC???  Q       A       Z               RET     ;       /
17         {0x33, 0x52, 0x46, 0x56, 0x00, 0x27, 0xdb, 0x00},       //      3       R       F       V               RIGHT   [       
18         {0x32, 0x45, 0x44, 0x43, 0x00, 0x26, 0xdd, 0x20},       //      2       E       D       C               UP      ]       SPACE
19         {0x35, 0x59, 0x48, 0x4e, 0x00, 0x30, 0x50, 0x00},       //      5       Y       H       N               0       P       
20         {0x34, 0x54, 0x47, 0x42, 0x00, 0x25, 0xc0, 0x00},       //      4       T       G       B               LEFT    @       
21         {0x36, 0x55, 0x4a, 0x4d, 0x00, 0x39, 0x4f, 0x00},       //      6       U       J       M               9       O       
22         {0x37, 0x49, 0x4b, 0xbc, 0x00, 0x38, 0x4c, 0xbe},       //      7       I       K       ,               8       L       .
23         {0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},       //      ???             SHIFT                                   
24 };
25
26 #define SET_BANK(s, e, w, r) { \
27         int sb = (s) >> 10, eb = (e) >> 10; \
28         for(int i = sb; i <= eb; i++) { \
29                 if((w) == wdmy) { \
30                         wbank[i] = wdmy; \
31                 } else { \
32                         wbank[i] = (w) + 0x400 * (i - sb); \
33                 } \
34                 if((r) == rdmy) { \
35                         rbank[i] = rdmy; \
36                 } else { \
37                         rbank[i] = (r) + 0x400 * (i - sb); \
38                 } \
39         } \
40 }
41
42 void MEMORY::initialize()
43 {
44         memset(rom, 0xff, sizeof(rom));
45         memset(rdmy, 0xff, sizeof(rdmy));
46         
47         // load rom image
48         FILEIO* fio = new FILEIO();
49         if(fio->Fopen(emu->bios_path(_T("BASIC.ROM")), FILEIO_READ_BINARY)) {
50                 fio->Fread(rom, sizeof(rom), 1);
51                 fio->Fclose();
52         }
53         delete fio;
54         
55         // set memory map
56         SET_BANK(0x0000, 0x1fff, wdmy, rom );
57         SET_BANK(0x2000, 0x2fff, ram,  ram );
58         SET_BANK(0x3000, 0x3fff, wdmy, rdmy);
59         SET_BANK(0x4000, 0x43ff, vram, vram);
60         SET_BANK(0x4400, 0xffff, wdmy, rdmy);
61         
62         key_stat = emu->key_buffer();
63         
64         // register event to update the key status
65         register_frame_event(this);
66 }
67
68 void MEMORY::reset()
69 {
70         memset(ram, 0, sizeof(ram));
71         memset(vram, 0, sizeof(vram));
72         
73         memset(status, 0, sizeof(status));
74         sysport = 0;
75 }
76
77 void MEMORY::write_data8(uint32 addr, uint32 data)
78 {
79         addr &= 0xffff;
80         if((0x3000 <= addr && addr < 0x4000) || 0x4400 <= addr) {
81                 // memory mapped i/o
82                 switch(addr) {
83                 case 0x6000:
84                         if(data == 0xf9) {
85                                 // datarec out h
86                                 d_drec->write_signal(SIG_DATAREC_OUT, 1, 1);
87                         } else if(data == 0x0a) {
88                                 // datarec out l
89                                 d_drec->write_signal(SIG_DATAREC_OUT, 0, 1);
90                         } else {
91                                 // unknown ???
92 #ifdef _IO_DEBUG_LOG
93                                 emu->out_debug_log("%6x\tWM8\t%4x,%2x\n", get_cpu_pc(0), addr, data);
94 #endif
95                         }
96                         break;
97                 default:
98 #ifdef _IO_DEBUG_LOG
99                         emu->out_debug_log("%6x\tWM8\t%4x,%2x\n", get_cpu_pc(0), addr, data);
100 #endif
101                         break;
102                 }
103                 return;
104         }
105         wbank[addr >> 10][addr & 0x3ff] = data;
106 }
107
108 uint32 MEMORY::read_data8(uint32 addr)
109 {
110         addr &= 0xffff;
111         if((0x3000 <= addr && addr < 0x4000) || 0x4400 <= addr) {
112                 // memory mapped i/o
113                 switch(addr) {
114                 case 0x3800:
115                 case 0x3801:
116                 case 0x3802:
117                 case 0x3803:
118                 case 0x3804:
119                 case 0x3805:
120                 case 0x3806:
121                 case 0x3807:
122                 case 0x3808:
123                         // note: bit0 of 3808h ... break cload ???
124                         return ~status[addr & 0x0f];
125                 case 0x6000:
126                         // bit0: datarec in
127                         // bit1: vsync or hsync ???
128                         return sysport;
129                 }
130 #ifdef _IO_DEBUG_LOG
131                 emu->out_debug_log("%6x\tRM8\t%4x\n", get_cpu_pc(0), addr);
132 #endif
133                 return 0xff;
134         }
135         return rbank[addr >> 10][addr & 0x3ff];
136 }
137
138 void MEMORY::event_frame()
139 {
140         memset(status, 0, sizeof(status));
141         
142         for(int i = 0; i < 9; i++) {
143                 uint8 val = 0;
144                 for(int j = 0; j < 8; j++) {
145                         val |= key_stat[key_map[i][j]] ? (1 << j) : 0;
146                 }
147                 status[i] = val;
148         }
149 }
150
151 void MEMORY::write_signal(int id, uint32 data, uint32 mask)
152 {
153         if(data & mask) {
154                 sysport |= mask;
155         } else {
156                 sysport &= ~mask;
157         }
158 }
159
160 #define STATE_VERSION   1
161
162 void MEMORY::save_state(FILEIO* state_fio)
163 {
164         state_fio->FputUint32(STATE_VERSION);
165         state_fio->FputInt32(this_device_id);
166         
167         state_fio->Fwrite(ram, sizeof(ram), 1);
168         state_fio->Fwrite(vram, sizeof(vram), 1);
169         state_fio->Fwrite(status, sizeof(status), 1);
170         state_fio->FputUint8(sysport);
171 }
172
173 bool MEMORY::load_state(FILEIO* state_fio)
174 {
175         if(state_fio->FgetUint32() != STATE_VERSION) {
176                 return false;
177         }
178         if(state_fio->FgetInt32() != this_device_id) {
179                 return false;
180         }
181         state_fio->Fread(ram, sizeof(ram), 1);
182         state_fio->Fread(vram, sizeof(vram), 1);
183         state_fio->Fread(status, sizeof(status), 1);
184         sysport = state_fio->FgetUint8();
185         return true;
186 }
187