2 IBM Japan Ltd PC/JX Emulator 'eJX'
4 Author : Takeda.Toshiya
12 #include "../memory.h"
14 void DISPLAY::initialize()
17 for(int i = 0; i < 16; i++) {
18 int val = (i & 8) ? 127 : 0;
19 palette_pc[i] = RGB_COLOR((i & 4) ? 255 : val, (i & 2) ? 255 : val, (i & 1) ? 255 : val);
21 palette_pc[8] = RGB_COLOR(127, 127, 127);
28 register_frame_event(this);
33 memset(vgarray, 0, sizeof(vgarray));
34 memset(palette, 0, sizeof(palette));
37 memset(bankreg, 0, sizeof(bankreg));
39 d_mem->set_memory_r(0x80000, 0xb7fff, kanji);
42 d_mem->set_memory_rw(0xb8000, 0xbbfff, vram);
43 d_mem->set_memory_rw(0xbc000, 0xbffff, vram);
48 void DISPLAY::write_io8(uint32_t addr, uint32_t data)
53 if(bankreg_num == 7 && (bankreg[7] & 0x80) != (data & 0x80)) {
59 } else if(bankreg_num == 10 && (bankreg[10] & 0x80) != (data & 0x80)) {
62 d_mem->set_memory_rw(0xa0000, 0xaffff, extvram);
65 d_mem->set_memory_r(0xa0000, 0xaffff, kanji + 0x20000);
66 d_mem->unset_memory_w(0xa0000, 0xaffff);
69 bankreg[bankreg_num] = data;
75 if(vgarray_num == -1) {
76 vgarray_num = data & 0x1f;
79 if(vgarray_num < 0x10) {
80 vgarray[vgarray_num] = data;
82 palette[vgarray_num & 0x0f] = data & 0x0f;
91 if((page & 0xb8) != (data & 0xb8)) {
92 int page1 = data >> 3;
93 int page2 = (data & 0x80) ? (page1 + 1) : page1;
94 d_mem->set_memory_rw(0xb8000, 0xbbfff, vram + 0x4000 * (page1 & 7));
95 d_mem->set_memory_rw(0xbc000, 0xbffff, vram + 0x4000 * (page2 & 7));
102 uint32_t DISPLAY::read_io8(uint32_t addr)
108 vgarray_num = -1; // okay ???
118 void DISPLAY::write_signal(int id, uint32_t data, uint32_t mask)
120 if(id == SIG_DISPLAY_ENABLE) {
126 } else if(id == SIG_DISPLAY_VBLANK) {
135 void DISPLAY::event_frame()
137 cblink = (cblink + 1) & 0x1f;
140 void DISPLAY::draw_screen()
142 int mode1 = vgarray[0];
143 int mode2 = vgarray[3];
144 int screen_width, screen_height, window_height_aspect, width;
146 memset(screen, 0, sizeof(screen));
148 // change screen size
149 if((hires_mode & 3) == 1) {
150 screen_width = width = 640;
152 window_height_aspect = 480;
154 screen_width = width = 720;
156 window_height_aspect = 540;
158 // if(!(prev_width == screen_width && prev_height == screen_height)) {
159 emu->set_vm_screen_size(screen_width, screen_height, screen_width, screen_height, screen_width, window_height_aspect);
160 // prev_width = screen_width;
161 // prev_height = screen_height;
163 // we need to wait until screen manager updates buffer size
168 if((hires_mode & 3) == 1) {
169 switch(mode1 & 0x1a) {
172 width = 320; // 40column
177 if((mode1 & 4) && (mode2 & 8)) {
178 draw_graph_640x200_2col();
179 } else if((page & 0xc0) == 0xc0) {
180 draw_graph_640x200_4col();
182 draw_graph_320x200_4col();
188 draw_graph_320x200_16col();
191 draw_graph_160x200_16col();
197 switch(hires_mode & 3) {
200 width = 360; // 40column
205 draw_graph_720x512_2col();
208 // draw_graph_360x512_4col();
210 draw_graph_720x512_2col();
215 // copy to real screen
216 if((hires_mode & 3) == 1) {
217 for(int y = 0; y < 200; y++) {
218 scrntype_t* dest0 = emu->get_screen_buffer(y * 2 + 0);
219 scrntype_t* dest1 = emu->get_screen_buffer(y * 2 + 1);
220 uint8_t *src = screen[y];
223 for(int x = 0; x < 640; x++) {
224 dest0[x] = palette_pc[src[x]];
226 } else if(width == 320) {
227 for(int x = 0, x2 = 0; x < 320; x++, x2 += 2) {
228 dest0[x2] = dest0[x2 + 1] = palette_pc[src[x]];
230 } else if(width == 160) {
231 for(int x = 0, x4 = 0; x < 160; x++, x4 += 4) {
232 dest0[x4] = dest0[x4 + 1] = dest0[x4 + 2] = dest0[x4 + 3] = palette_pc[src[x]];
235 if(!config.scan_line) {
236 my_memcpy(dest1, dest0, 640 * sizeof(scrntype_t));
238 memset(dest1, 0, 640 * sizeof(scrntype_t));
241 emu->screen_skip_line(true);
243 for(int y = 0; y < 512; y++) {
244 scrntype_t* dest = emu->get_screen_buffer(y);
245 uint8_t *src = screen[y];
248 for(int x = 0; x < 720; x++) {
249 dest[x] = palette_pc[src[x]];
251 } else if(width == 360) {
252 for(int x = 0, x2 = 0; x < 360; x++, x2 += 2) {
253 dest[x2] = dest[x2 + 1] = palette_pc[src[x]];
257 emu->screen_skip_line(false);
261 void DISPLAY::draw_alpha()
263 int src = ((regs[12] << 8) | regs[13]) * 2;
264 int cursor = ((regs[8] & 0xc0) == 0xc0) ? -1 : ((regs[14] << 8) | regs[15]) * 2;
265 int hz_disp = regs[1];
266 int vt_disp = regs[6] & 0x7f;
267 int ch_height = (regs[9] & 0x1f) + 1;
268 int ymax = (ch_height < 16) ? 8 : 16;
269 int shift = (ch_height < 16) ? 0 : 1;
270 int bp = regs[10] & 0x60;
272 uint8_t *vram_ptr = vram + (page & 7) * 0x4000;
273 uint8_t pal_mask = vgarray[1] & 0x0f;
277 for(int y = 0; y < vt_disp; y++) {
278 int ytop = y * ch_height;
280 for(int x = 0; x < hz_disp; x++) {
281 bool draw_cursor = ((src & 0x3fff) == (cursor & 0x3fff));
282 int code = vram_ptr[(src++) & 0x3fff];
283 int attr = vram_ptr[(src++) & 0x3fff];
284 if(x >= 90) { // 720dot / 8dot
287 int fore_color = palette[(attr ) & pal_mask];
288 int back_color = palette[(attr >> 4) & pal_mask];
289 if((hires_mode & 3) != 1) {
291 fore_color = (attr & 4) ? 0 : 7;
292 back_color = (attr & 4) ? 7 : 0;
293 attr = ((attr & 1) ? 0x80 : 0) | ((attr & 2) ? 8 : 0) | 7;
308 lo = vram_ptr[src & 0x3fff];
313 code = (hi << 8) | lo;
324 pattern = &font[code * 8];
326 pattern = &kanji[code * 32];
329 for(int l = 0; l < ch_height; l++) {
330 if(ytop + l >= 512) {
333 uint8_t pat = (l < ymax) ? pattern[(l << shift) | lr] : 0;
334 uint8_t *dest = &screen[ytop + l][x * 8];
336 dest[0] = (pat & 0x80) ? fore_color : back_color;
337 dest[1] = (pat & 0x40) ? fore_color : back_color;
338 dest[2] = (pat & 0x20) ? fore_color : back_color;
339 dest[3] = (pat & 0x10) ? fore_color : back_color;
340 dest[4] = (pat & 0x08) ? fore_color : back_color;
341 dest[5] = (pat & 0x04) ? fore_color : back_color;
342 dest[6] = (pat & 0x02) ? fore_color : back_color;
343 dest[7] = (pat & 0x01) ? fore_color : back_color;
348 int s = regs[10] & 0x1f;
349 int e = regs[11] & 0x1f;
350 if(bp == 0 || (bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
351 for(int l = s; l <= e && l < ch_height; l++) {
353 memset(&screen[ytop + l][x * 8], 7, 8);
362 void DISPLAY::draw_graph_160x200_16col()
364 int src = (regs[12] << 8) | regs[13];
366 uint8_t mask = vgarray[1] & 0x0f;
368 for(int l = 0; l < 2; l++) {
369 uint8_t *vram_ptr = vram + (page & 7) * 0x4000 + l * 0x2000;
372 for(int y = 0; y < 200; y += 2) {
373 uint8_t *dest = screen[y + l];
375 for(int x = 0; x < 160; x += 2) {
376 uint8_t pat = vram_ptr[(src2++) & 0x1fff];
378 dest[x ] = palette[(pat >> 4) & mask];
379 dest[x + 1] = palette[(pat ) & mask];
385 void DISPLAY::draw_graph_320x200_4col()
387 int src = (regs[12] << 8) | regs[13];
389 uint8_t mask = vgarray[1] & 3;
391 for(int l = 0; l < 2; l++) {
392 uint8_t *vram_ptr = vram + (page & 7) * 0x4000 + l * 0x2000;
395 for(int y = 0; y < 200; y += 2) {
396 uint8_t *dest = screen[y + l];
398 for(int x = 0; x < 320; x += 4) {
399 uint8_t pat = vram_ptr[(src2++) & 0x1fff];
401 dest[x ] = palette[(pat >> 6) & mask];
402 dest[x + 1] = palette[(pat >> 4) & mask];
403 dest[x + 2] = palette[(pat >> 2) & mask];
404 dest[x + 3] = palette[(pat ) & mask];
410 void DISPLAY::draw_graph_320x200_16col()
412 int src = (regs[12] << 8) | regs[13];
414 uint8_t mask = vgarray[1] & 0x0f;
416 for(int l = 0; l < 4; l++) {
417 uint8_t *vram_ptr = vram + ((page >> 1) & 3) * 0x8000 + l * 0x2000;
420 for(int y = 0; y < 200; y += 4) {
421 uint8_t *dest = screen[y + l];
423 for(int x = 0; x < 320; x += 2) {
424 uint8_t pat = vram_ptr[(src2++) & 0x1fff];
426 dest[x ] = palette[(pat >> 4) & mask];
427 dest[x + 1] = palette[(pat ) & mask];
433 void DISPLAY::draw_graph_640x200_2col()
435 int src = (regs[12] << 8) | regs[13];
437 uint8_t mask = vgarray[1] & 1;
439 for(int l = 0; l < 2; l++) {
440 uint8_t *vram_ptr = vram + (page & 7) * 0x4000 + l * 0x2000;
443 for(int y = 0; y < 200; y += 2) {
444 uint8_t *dest = screen[y + l];
446 for(int x = 0; x < 640; x += 8) {
447 uint8_t pat = vram_ptr[(src2++) & 0x1fff];
449 dest[x ] = palette[(pat >> 7) & mask];
450 dest[x + 1] = palette[(pat >> 6) & mask];
451 dest[x + 2] = palette[(pat >> 5) & mask];
452 dest[x + 3] = palette[(pat >> 4) & mask];
453 dest[x + 4] = palette[(pat >> 3) & mask];
454 dest[x + 5] = palette[(pat >> 2) & mask];
455 dest[x + 6] = palette[(pat >> 1) & mask];
456 dest[x + 7] = palette[(pat ) & mask];
462 void DISPLAY::draw_graph_640x200_4col()
464 int src = (regs[12] << 8) | regs[13];
466 uint8_t mask = vgarray[1] & 3;
468 for(int l = 0; l < 4; l++) {
469 uint8_t *vram_ptr = vram + ((page >> 1) & 3) * 0x8000 + l * 0x2000;
472 for(int y = 0; y < 200; y += 4) {
473 uint8_t *dest = screen[y + l];
475 for(int x = 0; x < 640; x += 8) {
476 uint8_t pat0 = vram_ptr[(src2++) & 0x1fff];
477 uint8_t pat1 = vram_ptr[(src2++) & 0x1fff];
479 dest[x ] = palette[(((pat0 >> 7) & 1) | ((pat1 >> 6) & 2)) & mask];
480 dest[x + 1] = palette[(((pat0 >> 6) & 1) | ((pat1 >> 5) & 2)) & mask];
481 dest[x + 2] = palette[(((pat0 >> 5) & 1) | ((pat1 >> 4) & 2)) & mask];
482 dest[x + 3] = palette[(((pat0 >> 4) & 1) | ((pat1 >> 3) & 2)) & mask];
483 dest[x + 4] = palette[(((pat0 >> 3) & 1) | ((pat1 >> 2) & 2)) & mask];
484 dest[x + 5] = palette[(((pat0 >> 2) & 1) | ((pat1 >> 1) & 2)) & mask];
485 dest[x + 6] = palette[(((pat0 >> 1) & 1) | ((pat1 ) & 2)) & mask];
486 dest[x + 7] = palette[(((pat0 >> 0) & 1) | ((pat1 << 1) & 2)) & mask];
492 void DISPLAY::draw_graph_720x512_2col()
494 static const uint8_t palette2[2] = {0, 7};
496 int src = (regs[12] << 8) | regs[13];
498 uint8_t mask = 1;//vgarray[1] & 1;
500 for(int l = 0; l < 2; l++) {
501 uint8_t *vram_ptr = extvram + l * 0x8000;
504 for(int y = 0; y < 512; y += 2) {
505 uint8_t *dest = screen[y + l];
507 for(int x = 0; x < 720; x += 8) {
508 uint8_t pat = vram_ptr[(src2++) & 0x7fff];
510 dest[x ] = palette2[(pat >> 7) & mask];
511 dest[x + 1] = palette2[(pat >> 6) & mask];
512 dest[x + 2] = palette2[(pat >> 5) & mask];
513 dest[x + 3] = palette2[(pat >> 4) & mask];
514 dest[x + 4] = palette2[(pat >> 3) & mask];
515 dest[x + 5] = palette2[(pat >> 2) & mask];
516 dest[x + 6] = palette2[(pat >> 1) & mask];
517 dest[x + 7] = palette2[(pat ) & mask];
523 void DISPLAY::draw_graph_360x512_4col()
528 #define STATE_VERSION 1
530 bool DISPLAY::process_state(FILEIO* state_fio, bool loading)
532 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
535 if(!state_fio->StateCheckInt32(this_device_id)) {
538 state_fio->StateBuffer(vram, sizeof(vram), 1);
539 state_fio->StateBuffer(extvram, sizeof(extvram), 1);
540 state_fio->StateBuffer(vgarray, sizeof(vgarray), 1);
541 state_fio->StateBuffer(palette, sizeof(palette), 1);
542 state_fio->StateInt32(vgarray_num);
543 state_fio->StateBuffer(bankreg, sizeof(bankreg), 1);
544 state_fio->StateInt32(bankreg_num);
545 state_fio->StateUint8(hires_mode);
546 state_fio->StateUint8(page);
547 state_fio->StateUint8(status);
548 state_fio->StateInt32(cblink);
552 bool DISPLAY::process_state(FILEIO* state_fio, bool loading)
554 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
557 if(!state_fio->StateCheckInt32(this_device_id)) {
560 state_fio->StateBuffer(vram, sizeof(vram), 1);
561 state_fio->StateBuffer(extvram, sizeof(extvram), 1);
562 state_fio->StateBuffer(vgarray, sizeof(vgarray), 1);
563 state_fio->StateBuffer(palette, sizeof(palette), 1);
564 state_fio->StateInt32(vgarray_num);
565 state_fio->StateBuffer(bankreg, sizeof(bankreg), 1);
566 state_fio->StateInt32(bankreg_num);
567 state_fio->StateUint8(hires_mode);
568 state_fio->StateUint8(page);
569 state_fio->StateUint8(status);
570 state_fio->StateInt32(cblink);