OSDN Git Service

c54379e77999526af4aeb85541fd36a249f9c8ad
[csp-qt/common_source_project-fm7.git] / source / src / vm / tk80bs / display.cpp
1 /*
2         NEC TK-80BS (COMPO BS/80) Emulator 'eTK-80BS'
3         NEC TK-80 Emulator 'eTK-80'
4         NEC TK-85 Emulator 'eTK-85'
5
6         Author : Takeda.Toshiya
7         Date   : 2008.08.26 -
8
9         [ display ]
10 */
11
12 #include "display.h"
13
14 static const int led_pattern[LED_SIZE_Y][LED_SIZE_X] = {
15 #if defined(_TK80BS) || defined(_TK80)
16         {9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9},
17         {9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9},
18         {9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9},
19         {9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9},
20         {9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9},
21         {9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9},
22         {9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9},
23         {9,9,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,2,0,0,0,0,9,9},
24         {9,9,0,0,0,0,6,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,2,2,0,0,0,0,9,9},
25         {9,9,0,0,0,0,6,6,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,2,2,2,0,0,0,0,9,9},
26         {9,9,0,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,9,9},
27         {9,9,0,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,9,9},
28         {9,9,0,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,9,9},
29         {9,9,0,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,9,9},
30         {9,9,0,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,9,9},
31         {9,9,0,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,9,9},
32         {9,9,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,9,9},
33         {9,9,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,9,9},
34         {9,9,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,9,9},
35         {9,9,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,9,9},
36         {9,9,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,9,9},
37         {9,9,0,0,0,0,6,0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,0,2,0,0,0,0,0,0,9,9},
38         {9,9,0,0,0,0,0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0,0,9,9},
39         {9,9,0,0,0,0,5,0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,0,3,0,0,0,0,0,0,9,9},
40         {9,9,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,0,0,0,0,0,9,9},
41         {9,9,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,0,0,0,0,0,9,9},
42         {9,9,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,0,0,0,0,0,9,9},
43         {9,9,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,0,0,0,0,0,9,9},
44         {9,9,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,0,0,0,0,0,9,9},
45         {9,9,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,0,0,0,0,0,0,9,9},
46         {9,9,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,0,0,0,0,0,0,9,9},
47         {9,9,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,0,0,0,0,0,0,9,9},
48         {9,9,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,0,0,0,0,0,0,9,9},
49         {9,9,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,0,0,0,0,0,0,9,9},
50         {9,9,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,0,0,0,0,0,0,9,9},
51         {9,9,0,0,5,5,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,3,3,3,0,8,8,8,0,0,9,9},
52         {9,9,0,0,5,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,3,3,0,8,8,8,0,0,9,9},
53         {9,9,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,3,0,8,8,8,0,0,9,9},
54         {9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9},
55         {9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9},
56         {9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9},
57         {9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9},
58         {9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9},
59         {9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9},
60         {9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9},
61         {9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9},
62 #else
63         {9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9},
64         {9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9},
65         {9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9},
66         {9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9},
67         {9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9},
68         {9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9},
69         {9,9,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,2,0,0,0,9,9},
70         {9,9,0,0,0,0,6,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,2,2,0,0,0,9,9},
71         {9,9,0,0,0,0,6,6,0,1,1,1,1,1,1,1,1,1,1,1,0,2,2,2,0,0,0,9,9},
72         {9,9,0,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,9,9},
73         {9,9,0,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,9,9},
74         {9,9,0,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,9,9},
75         {9,9,0,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,9,9},
76         {9,9,0,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,9,9},
77         {9,9,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,9,9},
78         {9,9,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,9,9},
79         {9,9,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,9,9},
80         {9,9,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,9,9},
81         {9,9,0,0,0,0,6,0,7,7,7,7,7,7,7,7,7,7,7,7,0,2,0,0,0,0,0,9,9},
82         {9,9,0,0,0,0,0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0,9,9},
83         {9,9,0,0,0,0,5,0,7,7,7,7,7,7,7,7,7,7,7,7,0,3,0,0,0,0,0,9,9},
84         {9,9,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,0,0,0,0,9,9},
85         {9,9,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,0,0,0,0,9,9},
86         {9,9,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,0,0,0,0,9,9},
87         {9,9,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,0,0,0,0,9,9},
88         {9,9,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,0,0,0,0,0,9,9},
89         {9,9,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,0,0,0,0,0,9,9},
90         {9,9,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,0,0,0,0,0,9,9},
91         {9,9,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,0,0,0,0,0,9,9},
92         {9,9,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,0,0,0,0,0,9,9},
93         {9,9,0,0,5,5,0,4,4,4,4,4,4,4,4,4,4,4,0,3,3,3,0,8,8,8,0,9,9},
94         {9,9,0,0,5,0,4,4,4,4,4,4,4,4,4,4,4,4,4,0,3,3,0,8,8,8,0,9,9},
95         {9,9,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,3,0,8,8,8,0,9,9},
96         {9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9},
97         {9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9},
98         {9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9},
99         {9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9},
100         {9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9},
101         {9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9},
102 #endif
103 };
104
105 void DISPLAY::initialize()
106 {
107 #if defined(_TK80BS)
108         // load rom image
109         FILEIO* fio = new FILEIO();
110         if(fio->Fopen(create_local_path(_T("FONT.ROM")), FILEIO_READ_BINARY)) {
111                 fio->Fread(font, sizeof(font), 1);
112                 fio->Fclose();
113         }
114         delete fio;
115         
116         mode = 2;
117 #endif
118         dma = true;
119 }
120
121 void DISPLAY::write_signal(int id, uint32_t data, uint32_t mask)
122 {
123 #if defined(_TK80BS)
124         if(id == SIG_DISPLAY_MODE) {
125                 // 8255 PC on TK-80BS
126                 mode = data & mask;
127         } else
128 #endif
129         if(id == SIG_DISPLAY_DMA) {
130                 // 8255 PC on TK-80
131                 dma = ((data & mask) != 0);
132         }
133 }
134
135 void DISPLAY::draw_screen()
136 {
137 #if defined(_TK80BS)
138         // draw screen
139         scrntype_t color_w = (mode & 2) ? RGB_COLOR(255, 255, 255) : RGB_COLOR(0, 0, 1);
140         scrntype_t color_b = (mode & 2) ? RGB_COLOR(0, 0, 1) : RGB_COLOR(255, 255, 255);
141         scrntype_t screen[36][256] = {0};
142         int code_ofs = (mode & 1) << 8;
143         int ptr = 0;
144
145         for(int y = 0; y < 128; y += 8) {
146                 for(int x = 0; x < 256; x += 8) {
147                         int code = vram[ptr++];
148                         if(code != 0x20) {
149                                 static_cast<VM *>(vm)->draw_ranges = 9;
150                         }
151                         code |= code_ofs;
152                         uint8_t* font_base = &font[code << 3];
153                         
154                         for(int l = 0; l < 8; l++) {
155                                 uint8_t pat = font_base[l];
156                                 scrntype_t* dest = &screen[l][x];
157                                 
158                                 dest[0] = (pat & 0x80) ? color_w : color_b;
159                                 dest[1] = (pat & 0x40) ? color_w : color_b;
160                                 dest[2] = (pat & 0x20) ? color_w : color_b;
161                                 dest[3] = (pat & 0x10) ? color_w : color_b;
162                                 dest[4] = (pat & 0x08) ? color_w : color_b;
163                                 dest[5] = (pat & 0x04) ? color_w : color_b;
164                                 dest[6] = (pat & 0x02) ? color_w : color_b;
165                                 dest[7] = (pat & 0x01) ? color_w : color_b;
166                         }
167                 }
168                 for(int l = 0; l < 8; l++) {
169                         scrntype_t* dest0 = emu->get_screen_buffer(vm_ranges[8].y + (y + l) * 2 + 0) + vm_ranges[8].x;
170                         scrntype_t* dest1 = emu->get_screen_buffer(vm_ranges[8].y + (y + l) * 2 + 1) + vm_ranges[8].x;
171                         scrntype_t* src = screen[l];
172                         for(int x = 0, xx = 0; x < 256; x++, xx += 2) {
173                                 dest0[xx] = dest0[xx + 1] = src[x];
174                         }
175                         memcpy(dest1, dest0, 256 * 2 * sizeof(scrntype_t));
176                 }
177         }
178 #endif
179         
180         // draw 7-seg LEDs
181         scrntype_t col[10];
182         scrntype_t color_on  = RGB_COLOR(255, 8, 72);
183 #if defined(_TK80BS) || defined(_TK80)
184         scrntype_t color_off = RGB_COLOR(56, 0, 0);
185         col[0] = RGB_COLOR(38, 8, 0);
186 #else
187         scrntype_t color_off = RGB_COLOR(111, 33, 33);
188         col[0] = RGB_COLOR(96, 53, 53);
189 #endif
190         col[9] = color_off;
191         
192         for(int i = 0; i < 8; i++) {
193                 uint8_t pat = dma ? led[i] : 0;
194                 col[1] = pat & 0x01 ? color_on : color_off;
195                 col[2] = pat & 0x02 ? color_on : color_off;
196                 col[3] = pat & 0x04 ? color_on : color_off;
197                 col[4] = pat & 0x08 ? color_on : color_off;
198                 col[5] = pat & 0x10 ? color_on : color_off;
199                 col[6] = pat & 0x20 ? color_on : color_off;
200                 col[7] = pat & 0x40 ? color_on : color_off;
201                 col[8] = pat & 0x80 ? color_on : color_off;
202                 for(int y = 0; y < LED_SIZE_Y; y++) {
203                         scrntype_t* dest = emu->get_screen_buffer(vm_ranges[i].y + y) + vm_ranges[i].x;
204                         for(int x = 0; x < LED_SIZE_X; x++) {
205                                 dest[x] = col[led_pattern[y][x]];
206                         }
207                 }
208         }
209 }
210
211 #define STATE_VERSION   1
212
213 #include "../../statesub.h"
214
215 void DISPLAY::decl_state()
216 {
217         enter_decl_state(STATE_VERSION);
218
219 #if defined(_TK80BS)
220         DECL_STATE_ENTRY_INT32(mode);
221 #endif
222         DECL_STATE_ENTRY_BOOL(dma);
223         
224         leave_decl_state();
225 }
226
227 void DISPLAY::save_state(FILEIO* state_fio)
228 {
229         if(state_entry != NULL) {
230                 state_entry->save_state(state_fio);
231         }
232 //      state_fio->FputUint32(STATE_VERSION);
233 //      state_fio->FputInt32(this_device_id);
234 //      
235 //#if defined(_TK80BS)
236 //      state_fio->FputInt32(mode);
237 //#endif
238 //      state_fio->FputBool(dma);
239 }
240
241 bool DISPLAY::load_state(FILEIO* state_fio)
242 {
243         bool mb = false;
244         if(state_entry != NULL) {
245                 mb = state_entry->load_state(state_fio);
246         }
247         if(!mb) {
248                 return false;
249         }
250 //      if(state_fio->FgetUint32() != STATE_VERSION) {
251 //              return false;
252 //      }
253 //      if(state_fio->FgetInt32() != this_device_id) {
254 //              return false;
255 //      }
256 //#if defined(_TK80BS)
257 //      mode = state_fio->FgetInt32();
258 //#endif
259 //      dma = state_fio->FgetBool();
260         return true;
261 }
262
263 bool DISPLAY::process_state(FILEIO* state_fio, bool loading)
264 {
265         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
266                 return false;
267         }
268         if(!state_fio->StateCheckInt32(this_device_id)) {
269                 return false;
270         }
271 #if defined(_TK80BS)
272         state_fio->StateInt32(mode);
273 #endif
274         state_fio->StateBool(dma);
275         return true;
276 }