2 IBM Japan Ltd PC/JX Emulator 'eJX'
\r
4 Author : Takeda.Toshiya
\r
11 #include "display.h"
\r
12 #include "../memory.h"
\r
14 void DISPLAY::initialize()
\r
17 // create pc palette
\r
18 for(int i = 0; i < 16; i++) {
\r
19 int val = (i & 8) ? 127 : 0;
\r
20 palette_pc[i] = RGB_COLOR((i & 4) ? 255 : val, (i & 2) ? 255 : val, (i & 1) ? 255 : val);
\r
22 palette_pc[8] = RGB_COLOR(127, 127, 127);
\r
29 register_frame_event(this);
\r
32 void DISPLAY::reset()
\r
34 memset(vgarray, 0, sizeof(vgarray));
\r
35 memset(palette, 0, sizeof(palette));
\r
38 memset(bankreg, 0, sizeof(bankreg));
\r
40 d_mem->set_memory_r(0x80000, 0xb7fff, kanji);
\r
43 d_mem->set_memory_rw(0xb8000, 0xbbfff, vram);
\r
44 d_mem->set_memory_rw(0xbc000, 0xbffff, vram);
\r
50 void DISPLAY::write_io8(uint32 addr, uint32 data)
\r
55 if(bankreg_num == 7 && (bankreg[7] & 0x80) != (data & 0x80)) {
\r
61 } else if(bankreg_num == 10 && (bankreg[10] & 0x80) != (data & 0x80)) {
\r
64 d_mem->set_memory_rw(0xa0000, 0xaffff, extvram);
\r
67 d_mem->set_memory_r(0xa0000, 0xaffff, kanji + 0x20000);
\r
68 d_mem->unset_memory_w(0xa0000, 0xaffff);
\r
71 bankreg[bankreg_num] = data;
\r
77 if(vgarray_num == -1) {
\r
78 vgarray_num = data & 0x1f;
\r
81 if(vgarray_num < 0x10) {
\r
82 vgarray[vgarray_num] = data;
\r
84 palette[vgarray_num & 0x0f] = data & 0x0f;
\r
93 if((page & 0xb8) != (data & 0xb8)) {
\r
94 int page1 = data >> 3;
\r
95 int page2 = (data & 0x80) ? (page1 + 1) : page1;
\r
96 d_mem->set_memory_rw(0xb8000, 0xbbfff, vram + 0x4000 * (page1 & 7));
\r
97 d_mem->set_memory_rw(0xbc000, 0xbffff, vram + 0x4000 * (page2 & 7));
\r
104 uint32 DISPLAY::read_io8(uint32 addr)
\r
108 return 0x69;//0x7f;
\r
110 vgarray_num = -1; // okay ???
\r
120 void DISPLAY::write_signal(int id, uint32 data, uint32 mask)
\r
122 if(id == SIG_DISPLAY_ENABLE) {
\r
128 } else if(id == SIG_DISPLAY_VBLANK) {
\r
137 void DISPLAY::event_frame()
\r
139 cblink = (cblink + 1) & 0x1f;
\r
142 void DISPLAY::draw_screen()
\r
144 int mode1 = vgarray[0];
\r
145 int mode2 = vgarray[3];
\r
146 int screen_width, screen_height, width;
\r
148 memset(screen, 0, sizeof(screen));
\r
150 // change screen size
\r
151 if((hires_mode & 3) == 1) {
\r
152 screen_width = width = 640;
\r
153 screen_height = 400;
\r
155 screen_width = width = 720;
\r
156 screen_height = 512;
\r
158 if(!(prev_width == screen_width && prev_height == screen_height)) {
\r
159 emu->change_screen_size(screen_width, screen_height, -1, -1, screen_width, screen_height);
\r
160 prev_width = screen_width;
\r
161 prev_height = screen_height;
\r
163 // we need to wait until screen manager updates buffer size
\r
168 if((hires_mode & 3) == 1) {
\r
169 switch(mode1 & 0x1a) {
\r
172 width = 320; // 40column
\r
177 if((mode1 & 4) && (mode2 & 8)) {
\r
178 draw_graph_640x200_2col();
\r
179 } else if((page & 0xc0) == 0xc0) {
\r
180 draw_graph_640x200_4col();
\r
182 draw_graph_320x200_4col();
\r
188 draw_graph_320x200_16col();
\r
191 draw_graph_160x200_16col();
\r
197 switch(hires_mode & 3) {
\r
200 width = 360; // 40column
\r
205 draw_graph_720x512_2col();
\r
208 // draw_graph_360x512_4col();
\r
210 draw_graph_720x512_2col();
\r
215 // copy to real screen
\r
216 if((hires_mode & 3) == 1) {
\r
217 for(int y = 0; y < 200; y++) {
\r
218 scrntype* dest0 = emu->screen_buffer(y * 2 + 0);
\r
219 scrntype* dest1 = emu->screen_buffer(y * 2 + 1);
\r
220 uint8 *src = screen[y];
\r
223 for(int x = 0; x < 640; x++) {
\r
224 dest0[x] = palette_pc[src[x]];
\r
226 } else if(width == 320) {
\r
227 for(int x = 0, x2 = 0; x < 320; x++, x2 += 2) {
\r
228 dest0[x2] = dest0[x2 + 1] = palette_pc[src[x]];
\r
230 } else if(width == 160) {
\r
231 for(int x = 0, x4 = 0; x < 160; x++, x4 += 4) {
\r
232 dest0[x4] = dest0[x4 + 1] = dest0[x4 + 2] = dest0[x4 + 3] = palette_pc[src[x]];
\r
235 if(!config.scan_line) {
\r
236 memcpy(dest1, dest0, 640 * sizeof(scrntype));
\r
238 memset(dest1, 0, 640 * sizeof(scrntype));
\r
241 emu->screen_skip_line = true;
\r
243 for(int y = 0; y < 512; y++) {
\r
244 scrntype* dest = emu->screen_buffer(y);
\r
245 uint8 *src = screen[y];
\r
248 for(int x = 0; x < 720; x++) {
\r
249 dest[x] = palette_pc[src[x]];
\r
251 } else if(width == 360) {
\r
252 for(int x = 0, x2 = 0; x < 360; x++, x2 += 2) {
\r
253 dest[x2] = dest[x2 + 1] = palette_pc[src[x]];
\r
257 emu->screen_skip_line = false;
\r
261 void DISPLAY::draw_alpha()
\r
263 int src = ((regs[12] << 8) | regs[13]) * 2;
\r
264 int cursor = ((regs[8] & 0xc0) == 0xc0) ? -1 : ((regs[14] << 8) | regs[15]) * 2;
\r
265 int hz_disp = regs[1];
\r
266 int vt_disp = regs[6] & 0x7f;
\r
267 int ch_height = (regs[9] & 0x1f) + 1;
\r
268 int ymax = (ch_height < 16) ? 8 : 16;
\r
269 int shift = (ch_height < 16) ? 0 : 1;
\r
270 int bp = regs[10] & 0x60;
\r
272 uint8 *vram_ptr = vram + (page & 7) * 0x4000;
\r
273 uint8 pal_mask = vgarray[1] & 0x0f;
\r
277 for(int y = 0; y < vt_disp; y++) {
\r
278 int ytop = y * ch_height;
\r
280 for(int x = 0; x < hz_disp; x++) {
\r
281 bool draw_cursor = ((src & 0x3fff) == (cursor & 0x3fff));
\r
282 int code = vram_ptr[(src++) & 0x3fff];
\r
283 int attr = vram_ptr[(src++) & 0x3fff];
\r
284 if(x >= 90) { // 720dot / 8dot
\r
287 int fore_color = palette[(attr ) & pal_mask];
\r
288 int back_color = palette[(attr >> 4) & pal_mask];
\r
289 if((hires_mode & 3) != 1) {
\r
291 fore_color = (attr & 4) ? 0 : 7;
\r
292 back_color = (attr & 4) ? 7 : 0;
\r
293 attr = ((attr & 1) ? 0x80 : 0) | ((attr & 2) ? 8 : 0) | 7;
\r
295 int lr = 0, hi, lo;
\r
308 lo = vram_ptr[src & 0x3fff];
\r
312 // shift-jis -> addr
\r
313 code = (hi << 8) | lo;
\r
314 if(code < 0x9900) {
\r
323 if(ch_height < 16) {
\r
324 pattern = &font[code * 8];
\r
326 pattern = &kanji[code * 32];
\r
329 for(int l = 0; l < ch_height; l++) {
\r
330 if(ytop + l >= 512) {
\r
333 uint8 pat = (l < ymax) ? pattern[(l << shift) | lr] : 0;
\r
334 uint8 *dest = &screen[ytop + l][x * 8];
\r
336 dest[0] = (pat & 0x80) ? fore_color : back_color;
\r
337 dest[1] = (pat & 0x40) ? fore_color : back_color;
\r
338 dest[2] = (pat & 0x20) ? fore_color : back_color;
\r
339 dest[3] = (pat & 0x10) ? fore_color : back_color;
\r
340 dest[4] = (pat & 0x08) ? fore_color : back_color;
\r
341 dest[5] = (pat & 0x04) ? fore_color : back_color;
\r
342 dest[6] = (pat & 0x02) ? fore_color : back_color;
\r
343 dest[7] = (pat & 0x01) ? fore_color : back_color;
\r
348 int s = regs[10] & 0x1f;
\r
349 int e = regs[11] & 0x1f;
\r
350 if(bp == 0 || (bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
\r
351 for(int l = s; l <= e && l < ch_height; l++) {
\r
352 if(ytop + l < 512) {
\r
353 memset(&screen[ytop + l][x * 8], 7, 8);
\r
362 void DISPLAY::draw_graph_160x200_16col()
\r
364 int src = (regs[12] << 8) | regs[13];
\r
366 uint8 mask = vgarray[1] & 0x0f;
\r
368 for(int l = 0; l < 2; l++) {
\r
369 uint8 *vram_ptr = vram + (page & 7) * 0x4000 + l * 0x2000;
\r
372 for(int y = 0; y < 200; y += 2) {
\r
373 uint8 *dest = screen[y + l];
\r
375 for(int x = 0; x < 160; x += 2) {
\r
376 uint8 pat = vram_ptr[(src2++) & 0x1fff];
\r
378 dest[x ] = palette[(pat >> 4) & mask];
\r
379 dest[x + 1] = palette[(pat ) & mask];
\r
385 void DISPLAY::draw_graph_320x200_4col()
\r
387 int src = (regs[12] << 8) | regs[13];
\r
389 uint8 mask = vgarray[1] & 3;
\r
391 for(int l = 0; l < 2; l++) {
\r
392 uint8 *vram_ptr = vram + (page & 7) * 0x4000 + l * 0x2000;
\r
395 for(int y = 0; y < 200; y += 2) {
\r
396 uint8 *dest = screen[y + l];
\r
398 for(int x = 0; x < 320; x += 4) {
\r
399 uint8 pat = vram_ptr[(src2++) & 0x1fff];
\r
401 dest[x ] = palette[(pat >> 6) & mask];
\r
402 dest[x + 1] = palette[(pat >> 4) & mask];
\r
403 dest[x + 2] = palette[(pat >> 2) & mask];
\r
404 dest[x + 3] = palette[(pat ) & mask];
\r
410 void DISPLAY::draw_graph_320x200_16col()
\r
412 int src = (regs[12] << 8) | regs[13];
\r
414 uint8 mask = vgarray[1] & 0x0f;
\r
416 for(int l = 0; l < 4; l++) {
\r
417 uint8 *vram_ptr = vram + ((page >> 1) & 3) * 0x8000 + l * 0x2000;
\r
420 for(int y = 0; y < 200; y += 4) {
\r
421 uint8 *dest = screen[y + l];
\r
423 for(int x = 0; x < 320; x += 2) {
\r
424 uint8 pat = vram_ptr[(src2++) & 0x1fff];
\r
426 dest[x ] = palette[(pat >> 4) & mask];
\r
427 dest[x + 1] = palette[(pat ) & mask];
\r
433 void DISPLAY::draw_graph_640x200_2col()
\r
435 int src = (regs[12] << 8) | regs[13];
\r
437 uint8 mask = vgarray[1] & 1;
\r
439 for(int l = 0; l < 2; l++) {
\r
440 uint8 *vram_ptr = vram + (page & 7) * 0x4000 + l * 0x2000;
\r
443 for(int y = 0; y < 200; y += 2) {
\r
444 uint8 *dest = screen[y + l];
\r
446 for(int x = 0; x < 640; x += 8) {
\r
447 uint8 pat = vram_ptr[(src2++) & 0x1fff];
\r
449 dest[x ] = palette[(pat >> 7) & mask];
\r
450 dest[x + 1] = palette[(pat >> 6) & mask];
\r
451 dest[x + 2] = palette[(pat >> 5) & mask];
\r
452 dest[x + 3] = palette[(pat >> 4) & mask];
\r
453 dest[x + 4] = palette[(pat >> 3) & mask];
\r
454 dest[x + 5] = palette[(pat >> 2) & mask];
\r
455 dest[x + 6] = palette[(pat >> 1) & mask];
\r
456 dest[x + 7] = palette[(pat ) & mask];
\r
462 void DISPLAY::draw_graph_640x200_4col()
\r
464 int src = (regs[12] << 8) | regs[13];
\r
466 uint8 mask = vgarray[1] & 3;
\r
468 for(int l = 0; l < 4; l++) {
\r
469 uint8 *vram_ptr = vram + ((page >> 1) & 3) * 0x8000 + l * 0x2000;
\r
472 for(int y = 0; y < 200; y += 4) {
\r
473 uint8 *dest = screen[y + l];
\r
475 for(int x = 0; x < 640; x += 8) {
\r
476 uint8 pat0 = vram_ptr[(src2++) & 0x1fff];
\r
477 uint8 pat1 = vram_ptr[(src2++) & 0x1fff];
\r
479 dest[x ] = palette[(((pat0 >> 7) & 1) | ((pat1 >> 6) & 2)) & mask];
\r
480 dest[x + 1] = palette[(((pat0 >> 6) & 1) | ((pat1 >> 5) & 2)) & mask];
\r
481 dest[x + 2] = palette[(((pat0 >> 5) & 1) | ((pat1 >> 4) & 2)) & mask];
\r
482 dest[x + 3] = palette[(((pat0 >> 4) & 1) | ((pat1 >> 3) & 2)) & mask];
\r
483 dest[x + 4] = palette[(((pat0 >> 3) & 1) | ((pat1 >> 2) & 2)) & mask];
\r
484 dest[x + 5] = palette[(((pat0 >> 2) & 1) | ((pat1 >> 1) & 2)) & mask];
\r
485 dest[x + 6] = palette[(((pat0 >> 1) & 1) | ((pat1 ) & 2)) & mask];
\r
486 dest[x + 7] = palette[(((pat0 >> 0) & 1) | ((pat1 << 1) & 2)) & mask];
\r
492 void DISPLAY::draw_graph_720x512_2col()
\r
494 static const uint8 palette2[2] = {0, 7};
\r
496 int src = (regs[12] << 8) | regs[13];
\r
498 uint8 mask = 1;//vgarray[1] & 1;
\r
500 for(int l = 0; l < 2; l++) {
\r
501 uint8 *vram_ptr = extvram + l * 0x8000;
\r
504 for(int y = 0; y < 512; y += 2) {
\r
505 uint8 *dest = screen[y + l];
\r
507 for(int x = 0; x < 720; x += 8) {
\r
508 uint8 pat = vram_ptr[(src2++) & 0x7fff];
\r
510 dest[x ] = palette2[(pat >> 7) & mask];
\r
511 dest[x + 1] = palette2[(pat >> 6) & mask];
\r
512 dest[x + 2] = palette2[(pat >> 5) & mask];
\r
513 dest[x + 3] = palette2[(pat >> 4) & mask];
\r
514 dest[x + 4] = palette2[(pat >> 3) & mask];
\r
515 dest[x + 5] = palette2[(pat >> 2) & mask];
\r
516 dest[x + 6] = palette2[(pat >> 1) & mask];
\r
517 dest[x + 7] = palette2[(pat ) & mask];
\r
523 void DISPLAY::draw_graph_360x512_4col()
\r