/*************************************************************************** dai.c Functions to emulate the video hardware of DAI. Krzysztof Strzecha All video modes are emulated but not fully tested yet. SCREEN_UPDATE_IND16 function needs strong cleanup and optimalisation. ***************************************************************************/ #include "emu.h" #include "includes/dai.h" #define DEBUG_DAI_VIDEO 0 #define LOG_DAI_VIDEO_LINE(_mode, _unit, _resolution, _repeat, _scan) do { if (DEBUG_DAI_VIDEO) logerror ("Mode: %02x, Unit: %02x, Resolution: %02x, Repeat: %d, Current line: %d\n", _mode, _unit, _resolution, _repeat, _scan); } while (0) const unsigned char dai_palette[16*3] = { 0x00, 0x00, 0x00, /* 0 Black */ 0x00, 0x00, 0x8b, /* 1 Dark Blue */ 0xb1, 0x00, 0x95, /* 2 Purple Red */ 0xff, 0x00, 0x00, /* 3 Red */ 0x75, 0x2e, 0x50, /* 4 Purple Brown */ 0x00, 0xb2, 0x38, /* 5 Emerald Green */ 0x98, 0x62, 0x00, /* 6 Kakhi Brown */ 0xae, 0x7a, 0x00, /* 7 Mustard Brown */ 0x89, 0x89, 0x89, /* 8 Grey */ 0xa1, 0x6f, 0xff, /* 9 Middle Blue */ 0xff, 0xa5, 0x00, /* 10 Orange */ 0xff, 0x99, 0xff, /* 11 Pink */ 0x9e, 0xf4, 0xff, /* 12 Light Blue */ 0xb3, 0xff, 0xbb, /* 13 Light Green */ 0xff, 0xff, 0x28, /* 14 Light Yellow */ 0xff, 0xff, 0xff, /* 15 White */ }; PALETTE_INIT( dai ) { int i; for ( i = 0; i < sizeof(dai_palette) / 3; i++ ) { palette_set_color_rgb(machine, i, dai_palette[i * 3], dai_palette[i * 3 + 1], dai_palette[i * 3 + 2]); } } VIDEO_START( dai ) { } SCREEN_UPDATE_IND16( dai ) { dai_state *state = screen.machine().driver_data(); address_space *space = screen.machine().device("maincpu")->memory().space(AS_PROGRAM); int i, j, k, l; UINT8* char_rom = state->memregion("gfx1")->base(); UINT16 dai_video_memory_start = 0xbfff; UINT16 dai_scan_lines = 604; /* scan lines of PAL tv */ UINT16 current_scan_line = 0; UINT16 current_video_memory_address = dai_video_memory_start; UINT8 mode; /* mode byte of line bits 0-3 - line repeat count bits 4-5 - resolution control bits 6-7 - display mode control */ UINT8 colour; /* colour byte of line bits 0-3 - one of 16 colours bits 4-5 - colour register for update bit 6 - if unset force 'unit colour mode' bit 7 - enable coulor change if unset bits 0-5 are ignored */ UINT8 line_repeat_count; /* number of horizontalraster scans for which same data will be displayed 0000 - 2 lines each additional repeat adds 2 scans */ UINT8 horizontal_resolution; /* number of blobs per line 00 - 88 (low resolution graphics) 01 - 176 (medium resolution graphics) 10 - 352 (high resolution graphics) 11 - 528 (text with 66 chars per line) */ UINT8 display_mode; /* determine how data will be used to generate the picture 00 - four colour graphics 01 - four colour characters 10 - sixteen colour graphics 11 - sixteen colour characters */ UINT8 unit_mode; UINT8 current_data_1, current_data_2; UINT8 current_colour; while (current_scan_line < dai_scan_lines) { mode = space->read_byte(current_video_memory_address--); colour = space->read_byte(current_video_memory_address--); line_repeat_count = mode & 0x0f; horizontal_resolution = (mode & 0x30) >> 4; display_mode = (mode & 0xc0) >> 6; unit_mode = (colour & 0x40) >> 6; if (colour & 0x80) state->m_4_colours_palette[(colour & 0x30) >> 4] = colour & 0x0f; switch (display_mode) { case 0x00: /* 4 colour grahics modes */ switch (horizontal_resolution) { case 0x00: /* 88 pixels */ switch (unit_mode) { case 0: current_data_1 = space->read_byte(current_video_memory_address--); current_data_2 = space->read_byte(current_video_memory_address--); for (i=0; i<11; i++) { for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = state->m_4_colours_palette[(((current_data_1>>(7-k)) & 0x01)<<1) | ((current_data_2>>(7-k)) & 0x01)]; for (l=0; l<12; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*12+l) = current_colour; } } } current_video_memory_address-=2; break; case 1: for (i=0; i<11; i++) { current_data_1 = space->read_byte(current_video_memory_address--); current_data_2 = space->read_byte(current_video_memory_address--); for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = state->m_4_colours_palette[(((current_data_1>>(7-k)) & 0x01)<<1) | ((current_data_2>>(7-k)) & 0x01)]; for (l=0; l<12; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*12+l) = current_colour; } } } break; } break; case 0x01: /* 176 pixels */ switch (unit_mode) { case 0: current_data_1 = space->read_byte(current_video_memory_address--); current_data_2 = space->read_byte(current_video_memory_address--); for (i=0; i<22; i++) { for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = state->m_4_colours_palette[(((current_data_1>>(7-k)) & 0x01)<<1) | ((current_data_2>>(7-k)) & 0x01)]; for (l=0; l<6; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*6+l) = current_colour; } } } current_video_memory_address-=2; break; case 1: for (i=0; i<22; i++) { current_data_1 = space->read_byte(current_video_memory_address--); current_data_2 = space->read_byte(current_video_memory_address--); for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = state->m_4_colours_palette[(((current_data_1>>(7-k)) & 0x01)<<1) | ((current_data_2>>(7-k)) & 0x01)]; for (l=0; l<6; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*6+l) = current_colour; } } } break; } break; case 0x02: /* 352 pixels */ switch (unit_mode) { case 0: current_data_1 = space->read_byte(current_video_memory_address--); current_data_2 = space->read_byte(current_video_memory_address--); for (i=0; i<44; i++) { for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = state->m_4_colours_palette[(((current_data_1>>(7-k)) & 0x01)<<1) | ((current_data_2>>(7-k)) & 0x01)]; for (l=0; l<3; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*3+l) = current_colour; } } } break; case 1: for (i=0; i<44; i++) { current_data_1 = space->read_byte(current_video_memory_address--); current_data_2 = space->read_byte(current_video_memory_address--); for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = state->m_4_colours_palette[(((current_data_1>>(7-k)) & 0x01)<<1) | ((current_data_2>>(7-k)) & 0x01)]; for (l=0; l<3; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*3+l) = current_colour; } } } break; } break; case 0x03: /* 528 pixels */ switch (unit_mode) { case 0: current_data_1 = space->read_byte(current_video_memory_address--); current_data_2 = space->read_byte(current_video_memory_address--); for (i=0; i<66; i++) { for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = state->m_4_colours_palette[(((current_data_1>>(7-k)) & 0x01)<<1) | ((current_data_2>>(7-k)) & 0x01)]; for (l=0; l<2; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*2+l) = current_colour; } } } break; case 1: for (i=0; i<66; i++) { current_data_1 = space->read_byte(current_video_memory_address--); current_data_2 = space->read_byte(current_video_memory_address--); for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = state->m_4_colours_palette[(((current_data_1>>(7-k)) & 0x01)<<1) | ((current_data_2>>(7-k)) & 0x01)]; for (l=0; l<2; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*2+l) = current_colour; } } } break; } break; } break; case 0x01: /* 4 colour characters */ switch (horizontal_resolution) { case 0x00: /* 11 chars */ switch (unit_mode) { case 0: current_data_1 = space->read_byte(current_video_memory_address); current_data_2 = space->read_byte(current_video_memory_address-1); current_video_memory_address-=2; for (i=0; i<11; i++) { for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = state->m_4_colours_palette[(((current_data_2 >> k)&0x01)<<1) | ((char_rom[current_data_1*16+j]>>k) & 0x01)]; for (l=0; l<12; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*12+l) = current_colour; } } } current_video_memory_address-=2; break; case 1: for (i=0; i<11; i++) { current_data_1 = space->read_byte(current_video_memory_address); current_data_2 = space->read_byte(current_video_memory_address-1); current_video_memory_address-=2; for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = state->m_4_colours_palette[(((current_data_2 >> k)&0x01)<<1) | ((char_rom[current_data_1*16+j]>>k) & 0x01)]; for (l=0; l<12; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*12+l) = current_colour; } } } current_video_memory_address-=2; break; } break; case 0x01: /* 22 chars */ switch (unit_mode) { case 0: current_data_1 = space->read_byte(current_video_memory_address); current_data_2 = space->read_byte(current_video_memory_address-1); current_video_memory_address-=2; for (i=0; i<22; i++) { for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = state->m_4_colours_palette[(((current_data_2 >> k)&0x01)<<1) | ((char_rom[current_data_1*16+j]>>k) & 0x01)]; for (l=0; l<6; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*6+l) = current_colour; } } } current_video_memory_address-=2; break; case 1: for (i=0; i<22; i++) { current_data_1 = space->read_byte(current_video_memory_address); current_data_2 = space->read_byte(current_video_memory_address-1); current_video_memory_address-=2; for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = state->m_4_colours_palette[(((current_data_2 >> k)&0x01)<<1) | ((char_rom[current_data_1*16+j]>>k) & 0x01)]; for (l=0; l<6; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*6+l) = current_colour; } } } current_video_memory_address-=2; break; } break; case 0x02: /* 44 chars */ switch (unit_mode) { case 0: current_data_1 = space->read_byte(current_video_memory_address); current_data_2 = space->read_byte(current_video_memory_address-1); current_video_memory_address-=2; for (i=0; i<44; i++) { for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = state->m_4_colours_palette[(((current_data_2 >> k)&0x01)<<1) | ((char_rom[current_data_1*16+j]>>k) & 0x01)]; for (l=0; l<3; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*3+l) = current_colour; } } } break; case 1: for (i=0; i<44; i++) { current_data_1 = space->read_byte(current_video_memory_address); current_data_2 = space->read_byte(current_video_memory_address-1); current_video_memory_address-=2; for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = state->m_4_colours_palette[(((current_data_2 >> k)&0x01)<<1) | ((char_rom[current_data_1*16+j]>>k) & 0x01)]; for (l=0; l<3; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*3+l) = current_colour; } } } break; } break; case 0x03: /* 66 chars */ switch (unit_mode) { case 0: current_data_1 = space->read_byte(current_video_memory_address); current_data_2 = space->read_byte(current_video_memory_address-1); current_video_memory_address-=2; for (i=0; i<66; i++) { for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = state->m_4_colours_palette[(((current_data_2 >> k)&0x01)<<1) | ((char_rom[current_data_1*16+j]>>k) & 0x01)]; for (l=0; l<2; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*2+l) = current_colour; } } } break; case 1: for (i=0; i<66; i++) { current_data_1 = space->read_byte(current_video_memory_address); current_data_2 = space->read_byte(current_video_memory_address-1); current_video_memory_address-=2; for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = state->m_4_colours_palette[(((current_data_2 >> k)&0x01)<<1) | ((char_rom[current_data_1*16+j]>>k) & 0x01)]; for (l=0; l<2; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*2+l) = current_colour; } } } break; } break; } break; case 0x02: /* 16 colour graphics */ switch (horizontal_resolution) { case 0x00: /* 88 pixels */ switch (unit_mode) { case 0: current_data_1 = space->read_byte(current_video_memory_address--); current_data_2 = space->read_byte(current_video_memory_address--); for (i=0; i<11; i++) { for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = ((current_data_1>>(7-k)) & 0x01) ? (current_data_2>>4)&0x0f : current_data_2&0x0f; for (l=0; l<12; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*12+l) = current_colour; } } } current_video_memory_address-=2; break; case 1: for (i=0; i<11; i++) { current_data_1 = space->read_byte(current_video_memory_address--); current_data_2 = space->read_byte(current_video_memory_address--); for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = ((current_data_1>>(7-k)) & 0x01) ? (current_data_2>>4)&0x0f : current_data_2&0x0f; for (l=0; l<12; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*12+l) = current_colour; } } } break; } break; case 0x01: /* 176 pixels */ switch (unit_mode) { case 0: current_data_1 = space->read_byte(current_video_memory_address--); current_data_2 = space->read_byte(current_video_memory_address--); for (i=0; i<22; i++) { for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = ((current_data_1>>(7-k)) & 0x01) ? (current_data_2>>4)&0x0f : current_data_2&0x0f; for (l=0; l<6; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*6+l) = current_colour; } } } current_video_memory_address-=2; break; case 1: for (i=0; i<22; i++) { current_data_1 = space->read_byte(current_video_memory_address--); current_data_2 = space->read_byte(current_video_memory_address--); for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = ((current_data_1>>(7-k)) & 0x01) ? (current_data_2>>4)&0x0f : current_data_2&0x0f; for (l=0; l<6; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*6+l) = current_colour; } } } break; } break; case 0x02: /* 352 pixels */ switch (unit_mode) { case 0: current_data_1 = space->read_byte(current_video_memory_address--); current_data_2 = space->read_byte(current_video_memory_address--); for (i=0; i<44; i++) { for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = ((current_data_1>>(7-k)) & 0x01) ? (current_data_2>>4)&0x0f : current_data_2&0x0f; for (l=0; l<3; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*3+l) = current_colour; } } } break; case 1: for (i=0; i<44; i++) { current_data_1 = space->read_byte(current_video_memory_address--); current_data_2 = space->read_byte(current_video_memory_address--); for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = ((current_data_1>>(7-k)) & 0x01) ? (current_data_2>>4)&0x0f : current_data_2&0x0f; for (l=0; l<3; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*3+l) = current_colour; } } } break; } break; case 0x03: /* 528 pixels */ switch (unit_mode) { case 0: current_data_1 = space->read_byte(current_video_memory_address--); current_data_2 = space->read_byte(current_video_memory_address--); for (i=0; i<66; i++) { for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = ((current_data_1>>(7-k)) & 0x01) ? (current_data_2>>4)&0x0f : current_data_2&0x0f; for (l=0; l<2; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*2+l) = current_colour; } } } break; case 1: for (i=0; i<66; i++) { current_data_1 = space->read_byte(current_video_memory_address--); current_data_2 = space->read_byte(current_video_memory_address--); for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = ((current_data_1>>(7-k)) & 0x01) ? (current_data_2>>4)&0x0f : current_data_2&0x0f; for (l=0; l<2; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*2+l) = current_colour; } } } break; } break; } break; case 0x03: /* 16 colour characters */ switch (horizontal_resolution) { case 0x00: /* 11 chars */ switch (unit_mode) { case 0: current_data_1 = space->read_byte(current_video_memory_address--); current_data_2 = space->read_byte(current_video_memory_address--); for (i=0; i<11; i++) { for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = ((char_rom[current_data_1*16+j]>>k) & 0x01) ? (current_data_2>>4)&0x0f : current_data_2&0x0f; for (l=0; l<12; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*12+l) = current_colour; } } } current_video_memory_address-=2; break; case 1: for (i=0; i<11; i++) { current_data_1 = space->read_byte(current_video_memory_address--); current_data_2 = space->read_byte(current_video_memory_address--); for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = ((char_rom[current_data_1*16+j]>>k) & 0x01) ? (current_data_2>>4)&0x0f : current_data_2&0x0f; for (l=0; l<12; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*12+l) = current_colour; } } } current_video_memory_address-=2; break; } break; case 0x01: /* 22 chars */ switch (unit_mode) { case 0: current_data_1 = space->read_byte(current_video_memory_address--); current_data_2 = space->read_byte(current_video_memory_address--); for (i=0; i<22; i++) { for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = ((char_rom[current_data_1*16+j]>>k) & 0x01) ? (current_data_2>>4)&0x0f : current_data_2&0x0f; for (l=0; l<6; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*6+l) = current_colour; } } } current_video_memory_address-=2; break; case 1: for (i=0; i<22; i++) { current_data_1 = space->read_byte(current_video_memory_address--); current_data_2 = space->read_byte(current_video_memory_address--); for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = ((char_rom[current_data_1*16+j]>>k) & 0x01) ? (current_data_2>>4)&0x0f : current_data_2&0x0f; for (l=0; l<6; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*6+l) = current_colour; } } } current_video_memory_address-=2; break; } break; case 0x02: /* 44 chars */ switch (unit_mode) { case 0: current_data_1 = space->read_byte(current_video_memory_address--); current_data_2 = space->read_byte(current_video_memory_address--); for (i=0; i<44; i++) { for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = ((char_rom[current_data_1*16+j]>>k) & 0x01) ? (current_data_2>>4)&0x0f : current_data_2&0x0f; for (l=0; l<3; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*3+l) = current_colour; } } } break; case 1: for (i=0; i<44; i++) { current_data_1 = space->read_byte(current_video_memory_address--); current_data_2 = space->read_byte(current_video_memory_address--); for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = ((char_rom[current_data_1*16+j]>>k) & 0x01) ? (current_data_2>>4)&0x0f : current_data_2&0x0f; for (l=0; l<3; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*3+l) = current_colour; } } } break; } break; case 0x03: /* 66 chars */ switch (unit_mode) { case 0: current_data_1 = space->read_byte(current_video_memory_address--); current_data_2 = space->read_byte(current_video_memory_address--); for (i=0; i<66; i++) { for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = ((char_rom[current_data_1*16+j]>>k) & 0x01) ? (current_data_2>>4)&0x0f : current_data_2&0x0f; for (l=0; l<2; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*2+l) = current_colour; } } } break; case 1: for (i=0; i<66; i++) { current_data_1 = space->read_byte(current_video_memory_address--); current_data_2 = space->read_byte(current_video_memory_address--); for (j=0; j<=line_repeat_count; j++) { for (k=0; k<8; k++) { current_colour = ((char_rom[current_data_1*16+j]>>k) & 0x01) ? (current_data_2>>4)&0x0f : current_data_2&0x0f; for (l=0; l<2; l++) bitmap.pix16(current_scan_line/2 + j, (i*8+k)*2+l) = current_colour; } } } break; } break; } break; } current_scan_line += line_repeat_count*2+2; LOG_DAI_VIDEO_LINE(display_mode, unit_mode, horizontal_resolution, line_repeat_count, current_scan_line); } return 0; }