2 Nintendo Family BASIC Emulator 'eFamilyBASIC'
\r
5 Author : Takeda.Toshiya
\r
12 #include "../datarec.h"
\r
13 #include "../../fileio.h"
\r
15 #define EVENT_DMA_DONE 0
\r
17 void MEMORY::initialize()
\r
19 memset(ram, 0, sizeof(ram));
\r
21 key_stat = emu->key_buffer();
\r
22 joy_stat = emu->joy_buffer();
\r
25 register_vline_event(this);
\r
28 void MEMORY::load_rom_image(_TCHAR *file_name)
\r
30 FILEIO* fio = new FILEIO();
\r
31 bool file_open = false;
\r
33 if(fio->Fopen(emu->bios_path(file_name), FILEIO_READ_BINARY)) {
\r
35 // create save file name
\r
36 _TCHAR tmp_file_name[_MAX_PATH];
\r
37 _tcscpy(tmp_file_name, file_name);
\r
38 _TCHAR *dot = _tcsstr(tmp_file_name, _T("."));
\r
39 if(dot != NULL) dot[0] = _T('\0');
\r
40 _stprintf(save_file_name, _T("%s.SAV"), tmp_file_name);
\r
42 // for compatibility
\r
43 if(fio->Fopen(emu->bios_path(_T("BASIC.NES")), FILEIO_READ_BINARY)) {
\r
46 _tcscpy(save_file_name, _T("BACKUP.BIN"));
\r
50 fio->Fread(header, sizeof(header), 1);
\r
51 // read program rom (max 32kb)
\r
52 fio->Fread(rom, 0x4000, 1);
\r
53 memcpy(rom + 0x4000, rom, 0x4000);
\r
54 fio->Fread(rom + 0x4000, 0x4000, 1);
\r
57 memset(header, 0, sizeof(header));
\r
58 memset(rom, 0xff, sizeof(rom));
\r
60 if(fio->Fopen(emu->bios_path(save_file_name), FILEIO_READ_BINARY)) {
\r
61 fio->Fread(save_ram, sizeof(save_ram), 1);
\r
64 memset(save_ram, 0, sizeof(save_ram));
\r
68 save_ram_crc32 = getcrc32(save_ram, sizeof(save_ram));
\r
71 void MEMORY::save_backup()
\r
73 if(save_ram_crc32 != getcrc32(save_ram, sizeof(save_ram))) {
\r
74 FILEIO* fio = new FILEIO();
\r
75 if(fio->Fopen(emu->bios_path(save_file_name), FILEIO_WRITE_BINARY)) {
\r
76 fio->Fwrite(save_ram, sizeof(save_ram), 1);
\r
83 void MEMORY::release()
\r
88 void MEMORY::reset()
\r
91 frame_irq_enabled = 0xff;
\r
94 pad1_bits = pad2_bits = 0xff;
\r
100 void MEMORY::write_data8(uint32 addr, uint32 data)
\r
104 if(addr < 0x2000) {
\r
105 ram[addr & 0x7ff] = data;
\r
106 } else if(addr < 0x4000) {
\r
107 d_ppu->write_data8(addr, data);
\r
108 } else if(addr == 0x4014) {
\r
110 d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
\r
111 register_event_by_clock(this, EVENT_DMA_DONE, 514, false, NULL);
\r
113 dma_addr = data << 8;
\r
114 for(int i = 0; i < 256; i++) {
\r
115 spr_ram[i] = read_data8(dma_addr | i);
\r
117 } else if(addr == 0x4016) {
\r
120 } else if(pad_strobe) {
\r
121 pad_strobe = false;
\r
124 if(joy_stat[0] & 0x10) pad1_bits |= 0x01; // A
\r
125 if(joy_stat[0] & 0x20) pad1_bits |= 0x02; // B
\r
126 if(joy_stat[0] & 0x40) pad1_bits |= 0x04; // SEL
\r
127 if(joy_stat[0] & 0x80) pad1_bits |= 0x08; // START
\r
128 if(joy_stat[0] & 0x01) pad1_bits |= 0x10; // UP
\r
129 if(joy_stat[0] & 0x02) pad1_bits |= 0x20; // DOWN
\r
130 if(joy_stat[0] & 0x04) pad1_bits |= 0x40; // LEFT
\r
131 if(joy_stat[0] & 0x08) pad1_bits |= 0x80; // RIGHT
\r
134 if(joy_stat[1] & 0x10) pad2_bits |= 0x01; // A
\r
135 if(joy_stat[1] & 0x20) pad2_bits |= 0x02; // B
\r
136 if(joy_stat[1] & 0x01) pad2_bits |= 0x10; // UP
\r
137 if(joy_stat[1] & 0x02) pad2_bits |= 0x20; // DOWN
\r
138 if(joy_stat[1] & 0x04) pad2_bits |= 0x40; // LEFT
\r
139 if(joy_stat[1] & 0x08) pad2_bits |= 0x80; // RIGHT
\r
142 if((data & 0x07) == 0x04) {
\r
143 if(++kb_scan > 9) {
\r
147 } else if((data & 0x07) == 0x05) {
\r
150 } else if((data & 0x07) == 0x06) {
\r
154 d_drec->write_signal(SIG_DATAREC_OUT, data, 2);
\r
155 } else if(addr < 0x4018) {
\r
156 if(addr == 0x4017) {
\r
157 frame_irq_enabled = data;
\r
159 d_apu->write_data8(addr, data);
\r
160 } else if(addr < 0x6000) {
\r
161 // mapper independent
\r
162 } else if(addr < 0x8000) {
\r
163 save_ram[addr & 0x1fff] = data;
\r
165 // mapper independent
\r
169 uint32 MEMORY::read_data8(uint32 addr)
\r
173 if(addr < 0x2000) {
\r
174 return ram[addr & 0x7ff];
\r
175 } else if(addr < 0x4000) {
\r
176 return d_ppu->read_data8(addr);
\r
177 } else if(addr == 0x4014) {
\r
178 return dma_addr >> 8;
\r
179 } else if(addr < 0x4016) {
\r
180 uint32 val = d_apu->read_data8(addr);
\r
181 if(addr == 0x4015 && !(frame_irq_enabled & 0xc0)) {
\r
185 } else if(addr == 0x4016) {
\r
187 uint32 val = pad1_bits & 1;
\r
190 val |= d_drec->read_signal(0) ? 2 : 0;
\r
192 val |= key_stat[0x7b] ? 4 : 0; // F12
\r
194 } else if(addr == 0x4017) {
\r
196 uint32 val = 0xfe | (pad2_bits & 1);
\r
202 if(key_stat[0x77]) val &= ~0x02; // F8
\r
203 if(key_stat[0x0d]) val &= ~0x04; // RETURN
\r
204 if(key_stat[0xdb]) val &= ~0x08; // [
\r
205 if(key_stat[0xdd]) val &= ~0x10; // ]
\r
208 if(key_stat[0x76]) val &= ~0x02; // F7
\r
209 if(key_stat[0xc0]) val &= ~0x04; // @
\r
210 if(key_stat[0xba]) val &= ~0x08; // :
\r
211 if(key_stat[0xbb]) val &= ~0x10; // ;
\r
214 if(key_stat[0x75]) val &= ~0x02; // F6
\r
215 if(key_stat[0x4f]) val &= ~0x04; // O
\r
216 if(key_stat[0x4c]) val &= ~0x08; // L
\r
217 if(key_stat[0x4b]) val &= ~0x10; // K
\r
220 if(key_stat[0x74]) val &= ~0x02; // F5
\r
221 if(key_stat[0x49]) val &= ~0x04; // I
\r
222 if(key_stat[0x55]) val &= ~0x08; // U
\r
223 if(key_stat[0x4a]) val &= ~0x10; // J
\r
226 if(key_stat[0x73]) val &= ~0x02; // F4
\r
227 if(key_stat[0x59]) val &= ~0x04; // Y
\r
228 if(key_stat[0x47]) val &= ~0x08; // G
\r
229 if(key_stat[0x48]) val &= ~0x10; // H
\r
232 if(key_stat[0x72]) val &= ~0x02; // F3
\r
233 if(key_stat[0x54]) val &= ~0x04; // T
\r
234 if(key_stat[0x52]) val &= ~0x08; // R
\r
235 if(key_stat[0x44]) val &= ~0x10; // D
\r
238 if(key_stat[0x71]) val &= ~0x02; // F2
\r
239 if(key_stat[0x57]) val &= ~0x04; // W
\r
240 if(key_stat[0x53]) val &= ~0x08; // S
\r
241 if(key_stat[0x41]) val &= ~0x10; // A
\r
244 if(key_stat[0x70]) val &= ~0x02; // F1
\r
245 if(key_stat[0x1b]) val &= ~0x04; // ESC
\r
246 if(key_stat[0x51]) val &= ~0x08; // Q
\r
247 if(key_stat[0x11]) val &= ~0x10; // CTRL
\r
250 if(key_stat[0x24]) val &= ~0x02; // CLS
\r
251 if(key_stat[0x26]) val &= ~0x04; // UP
\r
252 if(key_stat[0x27]) val &= ~0x08; // RIGHT
\r
253 if(key_stat[0x25]) val &= ~0x10; // LEFT
\r
259 if(key_stat[0x15]) val &= ~0x02; // KANA
\r
260 // if(key_stat[0x10]) val &= ~0x04; // RSHIFT
\r
261 if(key_stat[0xdc]) val &= ~0x08; // '\\'
\r
262 if(key_stat[0x23]) val &= ~0x10; // STOP
\r
265 if(key_stat[0xe2]) val &= ~0x02; // _
\r
266 if(key_stat[0xbf]) val &= ~0x04; // /
\r
267 if(key_stat[0xbd]) val &= ~0x08; // -
\r
268 if(key_stat[0xde]) val &= ~0x10; // ^
\r
271 if(key_stat[0xbe]) val &= ~0x02; // .
\r
272 if(key_stat[0xbc]) val &= ~0x04; // ,
\r
273 if(key_stat[0x50]) val &= ~0x08; // P
\r
274 if(key_stat[0x30]) val &= ~0x10; // 0
\r
277 if(key_stat[0x4d]) val &= ~0x02; // M
\r
278 if(key_stat[0x4e]) val &= ~0x04; // N
\r
279 if(key_stat[0x39]) val &= ~0x08; // 9
\r
280 if(key_stat[0x38]) val &= ~0x10; // 8
\r
283 if(key_stat[0x42]) val &= ~0x02; // B
\r
284 if(key_stat[0x56]) val &= ~0x04; // V
\r
285 if(key_stat[0x37]) val &= ~0x08; // 7
\r
286 if(key_stat[0x36]) val &= ~0x10; // 6
\r
289 if(key_stat[0x46]) val &= ~0x02; // F
\r
290 if(key_stat[0x43]) val &= ~0x04; // C
\r
291 if(key_stat[0x35]) val &= ~0x08; // 5
\r
292 if(key_stat[0x34]) val &= ~0x10; // 4
\r
295 if(key_stat[0x58]) val &= ~0x02; // X
\r
296 if(key_stat[0x5a]) val &= ~0x04; // Z
\r
297 if(key_stat[0x45]) val &= ~0x08; // E
\r
298 if(key_stat[0x33]) val &= ~0x10; // 3
\r
301 if(key_stat[0x10]) val &= ~0x02; // LSHIFT
\r
302 if(key_stat[0x12]) val &= ~0x04; // GRAPH
\r
303 if(key_stat[0x31]) val &= ~0x08; // 1
\r
304 if(key_stat[0x32]) val &= ~0x10; // 2
\r
307 if(key_stat[0x28]) val &= ~0x02; // DOWN
\r
308 if(key_stat[0x20]) val &= ~0x04; // SPACE
\r
309 if(key_stat[0x2e]) val &= ~0x08; // DEL
\r
310 if(key_stat[0x2d]) val &= ~0x10; // INS
\r
315 } else if(addr < 0x6000) {
\r
316 // mapper independent
\r
318 } else if(addr < 0x8000) {
\r
319 return save_ram[addr & 0x1fff];
\r
321 return rom[addr & 0x7fff];
\r
325 void MEMORY::event_vline(int v, int clock)
\r
328 if(v == 240 && !(frame_irq_enabled & 0xc0)) {
\r
330 d_cpu->write_signal(SIG_CPU_IRQ, 1, 1);
\r
334 void MEMORY::event_callback(int event_id, int err)
\r
337 d_cpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
\r