trunk/src/mess/video/vtvideo.c
| r28711 | r28712 | |
| 47 | 47 | vt100_video_device::vt100_video_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) |
| 48 | 48 | : device_t(mconfig, type, name, tag, owner, clock, shortname, source), |
| 49 | 49 | device_video_interface(mconfig, *this), |
| 50 | m_read_ram(*this), |
| 51 | m_write_clear_video_interrupt(*this), |
| 50 | 52 | m_palette(*this, "palette") |
| 51 | 53 | { |
| 52 | 54 | } |
| r28711 | r28712 | |
| 55 | 57 | vt100_video_device::vt100_video_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 56 | 58 | : device_t(mconfig, VT100_VIDEO, "VT100 Video", tag, owner, clock, "vt100_video", __FILE__), |
| 57 | 59 | device_video_interface(mconfig, *this), |
| 60 | m_read_ram(*this), |
| 61 | m_write_clear_video_interrupt(*this), |
| 58 | 62 | m_palette(*this, "palette") |
| 59 | 63 | { |
| 60 | 64 | } |
| r28711 | r28712 | |
| 82 | 86 | // or initialize to defaults if none provided |
| 83 | 87 | else |
| 84 | 88 | { |
| 85 | | memset(&m_in_ram_cb, 0, sizeof(m_in_ram_cb)); |
| 86 | | memset(&m_clear_video_cb, 0, sizeof(m_clear_video_cb)); |
| 87 | 89 | m_char_rom_tag = ""; |
| 88 | 90 | } |
| 89 | 91 | } |
| r28711 | r28712 | |
| 95 | 97 | void vt100_video_device::device_start() |
| 96 | 98 | { |
| 97 | 99 | /* resolve callbacks */ |
| 98 | | m_in_ram_func.resolve(m_in_ram_cb, *this); |
| 99 | | m_clear_video_interrupt.resolve(m_clear_video_cb, *this); |
| 100 | m_read_ram.resolve_safe(0); |
| 101 | m_write_clear_video_interrupt.resolve_safe(); |
| 100 | 102 | |
| 101 | 103 | m_gfx = machine().root_device().memregion(m_char_rom_tag)->base(); |
| 102 | 104 | assert(m_gfx != NULL); |
| r28711 | r28712 | |
| 264 | 266 | break; |
| 265 | 267 | case 0x09: |
| 266 | 268 | // clear vertical frequency interrupt; |
| 267 | | m_clear_video_interrupt(0, 0); |
| 269 | m_write_clear_video_interrupt(0); |
| 268 | 270 | |
| 269 | 271 | break; |
| 270 | 272 | case 0x0a: |
| r28711 | r28712 | |
| 438 | 440 | UINT8 display_type = 3; // binary 11 |
| 439 | 441 | UINT16 temp = 0; |
| 440 | 442 | |
| 441 | | if (m_in_ram_func(0) != 0x7f) |
| 443 | if (m_read_ram(0) != 0x7f) |
| 442 | 444 | return; |
| 443 | 445 | |
| 444 | 446 | while (line < (m_height + m_skip_lines)) |
| 445 | 447 | { |
| 446 | | code = m_in_ram_func(addr + xpos); |
| 448 | code = m_read_ram(addr + xpos); |
| 447 | 449 | if (code == 0x7f) |
| 448 | 450 | { |
| 449 | 451 | // end of line, fill empty till end of line |
| r28711 | r28712 | |
| 455 | 457 | } |
| 456 | 458 | } |
| 457 | 459 | // move to new data |
| 458 | | temp = m_in_ram_func(addr + xpos + 1) * 256 + m_in_ram_func(addr + xpos + 2); |
| 460 | temp = m_read_ram(addr + xpos + 1) * 256 + m_read_ram(addr + xpos + 2); |
| 459 | 461 | addr = (temp) & 0x1fff; |
| 460 | 462 | // if A12 is 1 then it is 0x2000 block, if 0 then 0x4000 (AVO) |
| 461 | 463 | if (addr & 0x1000) addr &= 0xfff; else addr |= 0x2000; |
| r28711 | r28712 | |
| 708 | 710 | |
| 709 | 711 | while (line < (m_height + m_skip_lines)) |
| 710 | 712 | { |
| 711 | | code = m_in_ram_func(addr + xpos); |
| 713 | code = m_read_ram(addr + xpos); |
| 712 | 714 | |
| 713 | 715 | if ( code == 0x00 ) // TODO: investigate side effect on regular zero character! |
| 714 | 716 | display_type |= 0x80; // DEFAULT: filler chars (till end of line) and empty lines (00) will be blanked |
| r28711 | r28712 | |
| 732 | 734 | attr_addr = 0x1000 | ( (addr + xpos + 1) & 0x0fff ); |
| 733 | 735 | |
| 734 | 736 | // MOVE TO NEW DATA |
| 735 | | temp = m_in_ram_func(addr + xpos + 2) * 256 + m_in_ram_func(addr + xpos + 1); |
| 737 | temp = m_read_ram(addr + xpos + 2) * 256 + m_read_ram(addr + xpos + 1); |
| 736 | 738 | addr = (temp) & 0x0fff; |
| 737 | 739 | |
| 738 | | temp = m_in_ram_func(attr_addr); |
| 740 | temp = m_read_ram(attr_addr); |
| 739 | 741 | scroll_region = (temp) & 1; |
| 740 | 742 | display_type = (temp >> 1) & 3; |
| 741 | 743 | |
| r28711 | r28712 | |
| 752 | 754 | if (line >= m_skip_lines) |
| 753 | 755 | { |
| 754 | 756 | attr_addr = 0x1000 | ( (addr + xpos) & 0x0fff ); |
| 755 | | temp = m_in_ram_func(attr_addr); // get character attribute |
| 757 | temp = m_read_ram(attr_addr); // get character attribute |
| 756 | 758 | |
| 757 | 759 | // CONFIRMED: Reverse active on 1. No attributes = 0x0E |
| 758 | 760 | // 1 = display char. in REVERSE (encoded as 8) |
trunk/src/mess/video/vtvideo.h
| r28711 | r28712 | |
| 15 | 15 | |
| 16 | 16 | #include "emu.h" |
| 17 | 17 | |
| 18 | #define MCFG_VT_VIDEO_RAM_CALLBACK(_read) \ |
| 19 | devcb = &vt100_video_device::set_ram_rd_callback(*device, DEVCB2_##_read); |
| 20 | |
| 21 | #define MCFG_VT_VIDEO_CLEAR_VIDEO_INTERRUPT_CALLBACK(_write) \ |
| 22 | devcb = &vt100_video_device::set_clear_video_irq_wr_callback(*device, DEVCB2_##_write); |
| 23 | |
| 18 | 24 | struct vt_video_interface |
| 19 | 25 | { |
| 20 | 26 | const char *m_char_rom_tag; /* character rom region */ |
| 21 | | |
| 22 | | /* this gets called for every memory read */ |
| 23 | | devcb_read8 m_in_ram_cb; |
| 24 | | devcb_write8 m_clear_video_cb; |
| 25 | 27 | }; |
| 26 | 28 | |
| 27 | 29 | |
| r28711 | r28712 | |
| 34 | 36 | vt100_video_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 35 | 37 | ~vt100_video_device() {} |
| 36 | 38 | |
| 39 | template<class _Object> static devcb2_base &set_ram_rd_callback(device_t &device, _Object object) { return downcast<vt100_video_device &>(device).m_read_ram.set_callback(object); } |
| 40 | template<class _Object> static devcb2_base &set_clear_video_irq_wr_callback(device_t &device, _Object object) { return downcast<vt100_video_device &>(device).m_write_clear_video_interrupt.set_callback(object); } |
| 41 | |
| 37 | 42 | DECLARE_READ8_MEMBER(lba7_r); |
| 38 | 43 | DECLARE_WRITE8_MEMBER(dc012_w); |
| 39 | 44 | DECLARE_WRITE8_MEMBER(dc011_w); |
| r28711 | r28712 | |
| 52 | 57 | virtual void display_char(bitmap_ind16 &bitmap, UINT8 code, int x, int y, UINT8 scroll_region, UINT8 display_type); |
| 53 | 58 | TIMER_CALLBACK_MEMBER(lba7_change); |
| 54 | 59 | |
| 55 | | devcb_resolved_read8 m_in_ram_func; |
| 56 | | devcb_resolved_write8 m_clear_video_interrupt; |
| 60 | devcb2_read8 m_read_ram; |
| 61 | devcb2_write8 m_write_clear_video_interrupt; |
| 57 | 62 | |
| 58 | 63 | UINT8 *m_gfx; /* content of char rom */ |
| 59 | 64 | |
trunk/src/mess/drivers/rainbow.c
| r28711 | r28712 | |
| 221 | 221 | } |
| 222 | 222 | |
| 223 | 223 | DECLARE_READ8_MEMBER(read_video_ram_r); |
| 224 | | DECLARE_WRITE8_MEMBER(clear_video_interrupt); |
| 224 | DECLARE_WRITE_LINE_MEMBER(clear_video_interrupt); |
| 225 | 225 | |
| 226 | 226 | DECLARE_READ8_MEMBER(diagnostic_r); |
| 227 | 227 | DECLARE_WRITE8_MEMBER(diagnostic_w); |
| r28711 | r28712 | |
| 1010 | 1010 | raise_8088_irq(IRQ_8088_VBL); |
| 1011 | 1011 | } |
| 1012 | 1012 | |
| 1013 | | WRITE8_MEMBER( rainbow_state::clear_video_interrupt ) |
| 1013 | WRITE_LINE_MEMBER( rainbow_state::clear_video_interrupt ) |
| 1014 | 1014 | { |
| 1015 | 1015 | lower_8088_irq(IRQ_8088_VBL); |
| 1016 | 1016 | } |
| r28711 | r28712 | |
| 1146 | 1146 | static const vt_video_interface video_interface = |
| 1147 | 1147 | { |
| 1148 | 1148 | "chargen", |
| 1149 | | DEVCB_DRIVER_MEMBER(rainbow_state, read_video_ram_r), |
| 1150 | | DEVCB_DRIVER_MEMBER(rainbow_state, clear_video_interrupt) |
| 1151 | 1149 | }; |
| 1152 | 1150 | |
| 1153 | 1151 | /* F4 Character Displayer */ |
| r28711 | r28712 | |
| 1214 | 1212 | MCFG_GFXDECODE_ADD("gfxdecode", "vt100_video:palette", rainbow) |
| 1215 | 1213 | |
| 1216 | 1214 | MCFG_RAINBOW_VIDEO_ADD("vt100_video", "screen", video_interface) |
| 1215 | MCFG_VT_VIDEO_RAM_CALLBACK(READ8(rainbow_state, read_video_ram_r)) |
| 1216 | MCFG_VT_VIDEO_CLEAR_VIDEO_INTERRUPT_CALLBACK(WRITELINE(rainbow_state, clear_video_interrupt)) |
| 1217 | 1217 | |
| 1218 | 1218 | MCFG_FD1793_ADD("wd1793", rainbow_wd17xx_interface ) |
| 1219 | 1219 | MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(floppy_intf) |
trunk/src/mess/drivers/vt100.c
| r28711 | r28712 | |
| 54 | 54 | DECLARE_WRITE8_MEMBER(vt100_baud_rate_w); |
| 55 | 55 | DECLARE_WRITE8_MEMBER(vt100_nvr_latch_w); |
| 56 | 56 | DECLARE_READ8_MEMBER(vt100_read_video_ram_r); |
| 57 | | DECLARE_WRITE8_MEMBER(vt100_clear_video_interrupt); |
| 57 | DECLARE_WRITE_LINE_MEMBER(vt100_clear_video_interrupt); |
| 58 | 58 | required_shared_ptr<UINT8> m_p_ram; |
| 59 | 59 | bool m_keyboard_int; |
| 60 | 60 | bool m_receiver_int; |
| r28711 | r28712 | |
| 369 | 369 | return m_p_ram[offset]; |
| 370 | 370 | } |
| 371 | 371 | |
| 372 | | WRITE8_MEMBER( vt100_state::vt100_clear_video_interrupt ) |
| 372 | WRITE_LINE_MEMBER( vt100_state::vt100_clear_video_interrupt ) |
| 373 | 373 | { |
| 374 | 374 | m_vertical_int = 0; |
| 375 | 375 | } |
| r28711 | r28712 | |
| 377 | 377 | static const vt_video_interface vt100_video_interface = |
| 378 | 378 | { |
| 379 | 379 | "chargen", |
| 380 | | DEVCB_DRIVER_MEMBER(vt100_state, vt100_read_video_ram_r), |
| 381 | | DEVCB_DRIVER_MEMBER(vt100_state, vt100_clear_video_interrupt) |
| 382 | 380 | }; |
| 383 | 381 | |
| 384 | 382 | INTERRUPT_GEN_MEMBER(vt100_state::vt100_vertical_interrupt) |
| r28711 | r28712 | |
| 428 | 426 | MCFG_DEFAULT_LAYOUT( layout_vt100 ) |
| 429 | 427 | |
| 430 | 428 | MCFG_VT100_VIDEO_ADD("vt100_video", "screen", vt100_video_interface) |
| 429 | MCFG_VT_VIDEO_RAM_CALLBACK(READ8(vt100_state, vt100_read_video_ram_r)) |
| 430 | MCFG_VT_VIDEO_CLEAR_VIDEO_INTERRUPT_CALLBACK(WRITELINE(vt100_state, vt100_clear_video_interrupt)) |
| 431 | 431 | |
| 432 | 432 | MCFG_DEVICE_ADD("i8251", I8251, 0) |
| 433 | 433 | MCFG_I8251_TXD_HANDLER(DEVWRITELINE(RS232_TAG, rs232_port_device, write_txd)) |