OSDN Git Service

[VM][I286] Save cpustate without StateBuffer().
[csp-qt/common_source_project-fm7.git] / source / src / vm / jr100 / memory.cpp
1 /*
2         National JR-100 Emulator 'eJR-100'
3
4         Author : Takeda.Toshiya
5         Date   : 2015.08.27-
6
7         [ memory bus ]
8 */
9
10 #include "memory.h"
11 #include "../sy6522.h"
12
13 #define SET_BANK(s, e, w, r) { \
14         int sb = (s) >> 13, eb = (e) >> 13; \
15         for(int i = sb; i <= eb; i++) { \
16                 if((w) == wdmy) { \
17                         wbank[i] = wdmy; \
18                 } else { \
19                         wbank[i] = (w) + 0x2000 * (i - sb); \
20                 } \
21                 if((r) == rdmy) { \
22                         rbank[i] = rdmy; \
23                 } else { \
24                         rbank[i] = (r) + 0x2000 * (i - sb); \
25                 } \
26         } \
27 }
28
29 void JR100_MEMORY::initialize()
30 {
31         // initialize memory
32         memset(ram, 0, sizeof(ram));
33         memset(vram, 0, sizeof(vram));
34         memset(rom, 0xff, sizeof(rom));
35         memset(rdmy, 0xff, sizeof(rdmy));
36         
37         // load rom images
38         FILEIO* fio = new FILEIO();
39         if(fio->Fopen(create_local_path(_T("BASIC.ROM")), FILEIO_READ_BINARY)) {
40                 fio->Fread(rom, sizeof(rom), 1);
41                 fio->Fclose();
42         } else if(fio->Fopen(create_local_path(_T("JR100.ROM")), FILEIO_READ_BINARY)) {
43                 fio->Fread(rom, sizeof(rom), 1);
44                 fio->Fclose();
45         }
46         delete fio;
47         
48         SET_BANK(0x0000, 0x7fff, ram,  ram );
49         SET_BANK(0x8000, 0xdfff, wdmy, rdmy);
50         SET_BANK(0xe000, 0xffff, wdmy, rom );
51         
52         // initialize inputs
53         key_stat = emu->get_key_buffer();
54         joy_stat = emu->get_joy_buffer();
55         
56         // initialize display
57         palette_pc[0] = RGB_COLOR(0, 0, 0);
58         palette_pc[1] = RGB_COLOR(255, 255, 255);
59         
60         key_column = 0;
61         cmode = false;
62         
63         // register event
64         register_frame_event(this);
65 }
66
67 void JR100_MEMORY::write_data8(uint32_t addr, uint32_t data)
68 {
69         if((addr & 0xf000) == 0xc000) {
70                 switch(addr & 0xfc00) {
71                 case 0xc000:
72                         vram[addr & 0x3ff] = data;
73                         break;
74                 case 0xc800:
75                         d_via->write_io8(addr, data);
76                         break;
77                 }
78                 return;
79         }
80         wbank[(addr >> 13) & 7][addr & 0x1fff] = data;
81 }
82
83 uint32_t JR100_MEMORY::read_data8(uint32_t addr)
84 {
85         if((addr & 0xf000) == 0xc000) {
86                 switch(addr & 0xfc00) {
87                 case 0xc000:
88                         return vram[addr & 0x3ff];
89                 case 0xc800:
90                         return d_via->read_io8(addr);
91                 case 0xcc00:
92                         if((addr & 0xffff) == 0xcc02) {
93                                 return ((joy_stat[0] & 0x08) >> 3) |    // bit0: right
94                                        ((joy_stat[0] & 0x04) >> 1) |    // bit1: left
95                                        ((joy_stat[0] & 0x01) << 2) |    // bit2: up
96                                        ((joy_stat[0] & 0x02) << 2) |    // bit3: down
97                                        ((joy_stat[0] & 0x10)     ) |    // bit4: switch
98                                        ((joy_stat[0] & 0x20) >> 1);
99                         }
100                         break;
101                 }
102                 return 0xff;
103         }
104         return rbank[(addr >> 13) & 7][addr & 0x1fff];
105 }
106
107 void JR100_MEMORY::write_signal(int id, uint32_t data, uint32_t mask)
108 {
109         if(id == SIG_MEMORY_VIA_PORT_A) {
110                 key_column = data & 0x0f;
111                 event_frame();
112         } else if(id == SIG_MEMORY_VIA_PORT_B) {
113                 cmode = ((data & 0x20) != 0);
114         }
115 }
116
117 static const int key_table[9][5] = {
118         {0x11, 0x10, 0x5a, 0x58, 0x43}, //      CTRL    SHIFT   Z       X       C
119         {0x41, 0x53, 0x44, 0x46, 0x47}, //      A       S       D       F       G
120         {0x51, 0x57, 0x45, 0x52, 0x54}, //      Q       W       E       R       T
121         {0x31, 0x32, 0x33, 0x34, 0x35}, //      1       2       3       4       5
122         {0x36, 0x37, 0x38, 0x39, 0x30}, //      6       7       8       9       0
123         {0x59, 0x55, 0x49, 0x4F, 0x50}, //      Y       U       I       O       P
124         {0x48, 0x4a, 0x4b, 0x4c, 0xbb}, //      H       J       K       L       ;
125         {0x56, 0x42, 0x4e, 0x4d, 0xbc}, //      V       B       N       M       ,
126         {0xbe, 0x20, 0xba, 0x0d, 0xbd}, //      .       SPACE   :       RET     -
127 };
128
129 void JR100_MEMORY::event_frame()
130 {
131         uint32_t data = 0;
132         if(key_column < 9) {
133                 if(key_stat[key_table[key_column][0]]) data |= 0x01;
134                 if(key_stat[key_table[key_column][1]]) data |= 0x02;
135                 if(key_stat[key_table[key_column][2]]) data |= 0x04;
136                 if(key_stat[key_table[key_column][3]]) data |= 0x08;
137                 if(key_stat[key_table[key_column][4]]) data |= 0x10;
138         }
139         d_via->write_signal(SIG_SY6522_PORT_B, ~data, 0x1f);
140 }
141
142 void JR100_MEMORY::draw_screen()
143 {
144         int src = 0x100;
145         for(int y = 0, yy = 0; y < 24; y++, yy += 8) {
146                 for(int x = 0, xx = 0; x < 32; x++, xx += 8) {
147                         int code = (vram[src  ] & 0x7f) << 3;
148                         bool attr = ((vram[src++] & 0x80) != 0);
149                         
150                         for(int l = 0; l < 8; l++) {
151                                 scrntype_t* dest = emu->get_screen_buffer(yy + l) + xx;
152                                 uint8_t pat = (cmode && attr) ? vram[(code + l) & 0x3ff] : attr ? ~rom[code + l] : rom[code + l];
153                                 dest[0] = palette_pc[(pat >> 7) & 1];
154                                 dest[1] = palette_pc[(pat >> 6) & 1];
155                                 dest[2] = palette_pc[(pat >> 5) & 1];
156                                 dest[3] = palette_pc[(pat >> 4) & 1];
157                                 dest[4] = palette_pc[(pat >> 3) & 1];
158                                 dest[5] = palette_pc[(pat >> 2) & 1];
159                                 dest[6] = palette_pc[(pat >> 1) & 1];
160                                 dest[7] = palette_pc[(pat     ) & 1];
161                         }
162                 }
163         }
164 //      emu->screen_skip_line(false);
165 }
166
167 #define STATE_VERSION   1
168
169 bool JR100_MEMORY::process_state(FILEIO* state_fio, bool loading)
170 {
171         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
172                 return false;
173         }
174         if(!state_fio->StateCheckInt32(this_device_id)) {
175                 return false;
176         }
177         state_fio->StateBuffer(ram, sizeof(ram), 1);
178         state_fio->StateBuffer(vram, sizeof(vram), 1);
179         state_fio->StateInt32(key_column);
180         state_fio->StateBool(cmode);
181         return true;
182 }