trunk/src/emu/video/mc6845.c
| r17794 | r17795 | |
| 22 | 22 | |
| 23 | 23 | **********************************************************************/ |
| 24 | 24 | |
| 25 | /* |
| 26 | |
| 27 | TODO: |
| 28 | |
| 29 | - mos8563 |
| 30 | |
| 31 | - horizontal scroll |
| 32 | - vertical scroll |
| 33 | - pixel double width |
| 34 | - bitmap modes |
| 35 | - display enable begin/end |
| 36 | |
| 37 | */ |
| 38 | |
| 25 | 39 | #include "emu.h" |
| 26 | 40 | #include "mc6845.h" |
| 27 | 41 | #include "machine/devhelpr.h" |
| r17794 | r17795 | |
| 369 | 383 | case 0x15: m_attribute_addr = ((data & 0xff) << 0) | (m_attribute_addr & 0xff00); break; |
| 370 | 384 | case 0x16: m_horiz_char = data & 0xff; break; |
| 371 | 385 | case 0x17: m_vert_char_disp = data & 0x1f; break; |
| 372 | | case 0x18: m_vert_scroll = data & 0x1f; break; |
| 373 | | case 0x19: m_horiz_scroll = data & 0x1f; break; |
| 386 | case 0x18: m_vert_scroll = data & 0xff; break; |
| 387 | case 0x19: m_horiz_scroll = data & 0xff; break; |
| 374 | 388 | case 0x1a: m_color = data & 0xff; break; |
| 375 | 389 | case 0x1b: m_row_addr_incr = data & 0xff; break; |
| 376 | 390 | case 0x1c: m_char_base_addr = data & 0xf0; break; |
| r17794 | r17795 | |
| 856 | 870 | } |
| 857 | 871 | |
| 858 | 872 | |
| 873 | UINT8 mc6845_device::draw_scanline(int y, bitmap_rgb32 &bitmap, const rectangle &cliprect, void *param) |
| 874 | { |
| 875 | /* compute the current raster line */ |
| 876 | UINT8 ra = y % (m_max_ras_addr + 1); |
| 877 | |
| 878 | /* check if the cursor is visible and is on this scanline */ |
| 879 | int cursor_visible = m_cursor_state && |
| 880 | (ra >= (m_cursor_start_ras & 0x1f)) && |
| 881 | (ra <= m_cursor_end_ras) && |
| 882 | (m_cursor_addr >= m_current_disp_addr) && |
| 883 | (m_cursor_addr < (m_current_disp_addr + m_horiz_disp)); |
| 884 | |
| 885 | /* compute the cursor X position, or -1 if not visible */ |
| 886 | INT8 cursor_x = cursor_visible ? (m_cursor_addr - m_current_disp_addr) : -1; |
| 887 | |
| 888 | /* call the external system to draw it */ |
| 889 | if (MODE_ROW_COLUMN_ADDRESSING) |
| 890 | { |
| 891 | UINT8 cc = 0; |
| 892 | UINT8 cr = y / (m_max_ras_addr + 1); |
| 893 | UINT16 ma = (cr << 8) | cc; |
| 894 | |
| 895 | m_update_row(this, bitmap, cliprect, ma, ra, y, m_horiz_disp, cursor_x, param); |
| 896 | } |
| 897 | else |
| 898 | { |
| 899 | m_update_row(this, bitmap, cliprect, m_current_disp_addr, ra, y, m_horiz_disp, cursor_x, param); |
| 900 | } |
| 901 | |
| 902 | /* update MA if the last raster address */ |
| 903 | if (ra == m_max_ras_addr) |
| 904 | m_current_disp_addr = (m_current_disp_addr + m_horiz_disp) & 0x3fff; |
| 905 | |
| 906 | return ra; |
| 907 | } |
| 908 | |
| 909 | |
| 859 | 910 | UINT32 mc6845_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) |
| 860 | 911 | { |
| 861 | 912 | assert(bitmap.valid()); |
| r17794 | r17795 | |
| 881 | 932 | /* for each row in the visible region */ |
| 882 | 933 | for (y = cliprect.min_y; y <= cliprect.max_y; y++) |
| 883 | 934 | { |
| 884 | | /* compute the current raster line */ |
| 885 | | UINT8 ra = y % (m_max_ras_addr + 1); |
| 886 | | |
| 887 | | /* check if the cursor is visible and is on this scanline */ |
| 888 | | int cursor_visible = m_cursor_state && |
| 889 | | (ra >= (m_cursor_start_ras & 0x1f)) && |
| 890 | | (ra <= m_cursor_end_ras) && |
| 891 | | (m_cursor_addr >= m_current_disp_addr) && |
| 892 | | (m_cursor_addr < (m_current_disp_addr + m_horiz_disp)); |
| 893 | | |
| 894 | | /* compute the cursor X position, or -1 if not visible */ |
| 895 | | INT8 cursor_x = cursor_visible ? (m_cursor_addr - m_current_disp_addr) : -1; |
| 896 | | |
| 897 | | /* call the external system to draw it */ |
| 898 | | if (MODE_ROW_COLUMN_ADDRESSING) |
| 899 | | { |
| 900 | | UINT8 cc = 0; |
| 901 | | UINT8 cr = y / (m_max_ras_addr + 1); |
| 902 | | UINT16 ma = (cr << 8) | cc; |
| 903 | | |
| 904 | | m_update_row(this, bitmap, cliprect, ma, ra, y, m_horiz_disp, cursor_x, param); |
| 905 | | } |
| 906 | | else |
| 907 | | { |
| 908 | | m_update_row(this, bitmap, cliprect, m_current_disp_addr, ra, y, m_horiz_disp, cursor_x, param); |
| 909 | | } |
| 910 | | |
| 911 | | /* update MA if the last raster address */ |
| 912 | | if (ra == m_max_ras_addr) |
| 913 | | m_current_disp_addr = (m_current_disp_addr + m_horiz_disp) & 0x3fff; |
| 935 | this->draw_scanline(y, bitmap, cliprect, param); |
| 914 | 936 | } |
| 915 | 937 | |
| 916 | 938 | /* call the tear down function if any */ |
| r17794 | r17795 | |
| 1171 | 1193 | |
| 1172 | 1194 | m_update_row = vdc_update_row; |
| 1173 | 1195 | |
| 1196 | m_char_blink_state = false; |
| 1197 | m_char_blink_count = 0; |
| 1198 | m_attribute_addr = 0; |
| 1199 | m_horiz_char = 0; |
| 1200 | m_vert_char_disp = 0; |
| 1201 | m_vert_scroll = 0; |
| 1202 | m_horiz_scroll = 0; |
| 1203 | m_color = 0; |
| 1204 | m_row_addr_incr = 0; |
| 1205 | m_char_base_addr = 0; |
| 1206 | m_underline_ras = 0; |
| 1207 | m_word_count = 0; |
| 1208 | m_data = 0; |
| 1209 | m_block_addr = 0; |
| 1210 | m_de_begin = 0; |
| 1211 | m_dram_refresh = 0; |
| 1212 | m_sync_polarity = 0; |
| 1213 | |
| 1174 | 1214 | save_item(NAME(m_char_buffer)); |
| 1175 | 1215 | save_item(NAME(m_attr_buffer)); |
| 1176 | 1216 | save_item(NAME(m_attribute_addr)); |
| r17794 | r17795 | |
| 1187 | 1227 | save_item(NAME(m_block_addr)); |
| 1188 | 1228 | save_item(NAME(m_de_begin)); |
| 1189 | 1229 | save_item(NAME(m_dram_refresh)); |
| 1230 | save_item(NAME(m_sync_polarity)); |
| 1190 | 1231 | } |
| 1191 | 1232 | |
| 1192 | 1233 | |
| 1193 | 1234 | void mos8568_device::device_start() |
| 1194 | 1235 | { |
| 1195 | 1236 | mos8563_device::device_start(); |
| 1196 | | |
| 1197 | | save_item(NAME(m_sync_polarity)); |
| 1198 | 1237 | } |
| 1199 | 1238 | |
| 1200 | 1239 | |
| r17794 | r17795 | |
| 1362 | 1401 | }; |
| 1363 | 1402 | |
| 1364 | 1403 | |
| 1404 | void mos8563_device::update_cursor_state() |
| 1405 | { |
| 1406 | mc6845_device::update_cursor_state(); |
| 1407 | |
| 1408 | /* save and increment character blink counter */ |
| 1409 | UINT8 last_char_blink_count = m_char_blink_count; |
| 1410 | m_char_blink_count++; |
| 1411 | |
| 1412 | /* switch on character blinking mode */ |
| 1413 | if (VSS_CBRATE) |
| 1414 | { |
| 1415 | if ((last_char_blink_count & 0x20) != (m_char_blink_count & 0x20)) |
| 1416 | m_char_blink_state = !m_char_blink_state; |
| 1417 | } |
| 1418 | else |
| 1419 | { |
| 1420 | if ((last_char_blink_count & 0x10) != (m_char_blink_count & 0x10)) |
| 1421 | m_char_blink_state = !m_char_blink_state; |
| 1422 | } |
| 1423 | } |
| 1424 | |
| 1425 | |
| 1426 | UINT8 mos8563_device::draw_scanline(int y, bitmap_rgb32 &bitmap, const rectangle &cliprect, void *param) |
| 1427 | { |
| 1428 | UINT8 ra = mc6845_device::draw_scanline(y, bitmap, cliprect, param); |
| 1429 | |
| 1430 | if (ra == m_max_ras_addr) |
| 1431 | m_current_disp_addr = (m_current_disp_addr + m_row_addr_incr) & 0x3fff; |
| 1432 | |
| 1433 | return ra; |
| 1434 | } |
| 1435 | |
| 1436 | |
| 1365 | 1437 | void mos8563_device::update_row(bitmap_rgb32 &bitmap, const rectangle &cliprect, UINT16 ma, UINT8 ra, UINT16 y, UINT8 x_count, INT8 cursor_x, void *param) |
| 1366 | 1438 | { |
| 1367 | 1439 | for (int column = 0; column < x_count; column++) |
| r17794 | r17795 | |
| 1372 | 1444 | } |
| 1373 | 1445 | else |
| 1374 | 1446 | { |
| 1375 | | UINT8 code = read_videoram(ma + column); |
| 1447 | UINT16 code = read_videoram(ma + column); |
| 1376 | 1448 | |
| 1377 | | offs_t attr_addr = m_attribute_addr + column; |
| 1449 | offs_t attr_addr = m_attribute_addr + (ma - m_disp_start_addr) + column; |
| 1378 | 1450 | UINT8 attr = 0; |
| 1379 | 1451 | |
| 1380 | 1452 | UINT8 cth = (m_horiz_char >> 4) + 1; |
| r17794 | r17795 | |
| 1397 | 1469 | |
| 1398 | 1470 | offs_t font_addr; |
| 1399 | 1471 | |
| 1472 | code |= ATTR_ALTERNATE_CHARSET << 8; |
| 1473 | |
| 1400 | 1474 | if (m_max_ras_addr < 16) |
| 1401 | | font_addr = ((m_char_base_addr >> 5) << 13) | (ATTR_ALTERNATE_CHARSET << 12) | (code << 4) | ra; |
| 1475 | font_addr = ((m_char_base_addr >> 5) << 13) | (code << 4) | ra; |
| 1402 | 1476 | else |
| 1403 | | font_addr = ((m_char_base_addr >> 5) << 13) | (ATTR_ALTERNATE_CHARSET << 13) | (code << 5) | ra; |
| 1477 | font_addr = ((m_char_base_addr >> 5) << 13) | (code << 5) | ra; |
| 1404 | 1478 | |
| 1405 | 1479 | UINT8 data = read_videoram(font_addr); |
| 1406 | 1480 | |
| 1407 | 1481 | if (column == cursor_x) data = 0xff; |
| 1408 | 1482 | if (ra >= cdv) data = 0; |
| 1409 | 1483 | if (ATTR_UNDERLINE && (ra == m_underline_ras)) data = 0xff; |
| 1484 | if (ATTR_BLINK && !m_char_blink_state) data = 0; |
| 1410 | 1485 | |
| 1411 | 1486 | if (ATTR_REVERSE) |
| 1412 | 1487 | { |
| r17794 | r17795 | |
| 1414 | 1489 | bg = fg; |
| 1415 | 1490 | fg = temp; |
| 1416 | 1491 | } |
| 1417 | | // TODO ATTR_BLINK |
| 1418 | 1492 | |
| 1419 | | for (int bit = 0; bit < MIN(cdh, 8); bit++) |
| 1493 | for (int bit = 0; bit < cdh; bit++) |
| 1420 | 1494 | { |
| 1421 | 1495 | int x = (column * cth) + bit; |
| 1422 | 1496 | |
| 1423 | | bitmap.pix32(y, x) = MOS8563_PALETTE[BIT(data, 7) ? fg : bg]; |
| 1424 | | data <<= 1; |
| 1497 | bitmap.pix32(y, x) = MOS8563_PALETTE[(BIT(data, 7) ^ VSS_RVS) ? fg : bg]; |
| 1498 | |
| 1499 | if ((bit < 8) || !HSS_SEMI) data <<= 1; |
| 1425 | 1500 | } |
| 1426 | 1501 | } |
| 1427 | 1502 | } |