trunk/src/emu/video/crtc_ega.c
| r29504 | r29505 | |
| 16 | 16 | const device_type CRTC_EGA = &device_creator<crtc_ega_device>; |
| 17 | 17 | |
| 18 | 18 | |
| 19 | | void crtc_ega_device::device_config_complete() |
| 20 | | { |
| 21 | | const crtc_ega_interface *intf = reinterpret_cast<const crtc_ega_interface *>(static_config()); |
| 22 | | |
| 23 | | if ( intf != NULL ) |
| 24 | | { |
| 25 | | *static_cast<crtc_ega_interface *>(this) = *intf; |
| 26 | | } |
| 27 | | else |
| 28 | | { |
| 29 | | m_hpixels_per_column = 0; |
| 30 | | m_begin_update = NULL; |
| 31 | | m_update_row = NULL; |
| 32 | | m_end_update = NULL; |
| 33 | | memset(&m_out_de_func, 0, sizeof(m_out_de_func)); |
| 34 | | memset(&m_out_hsync_func, 0, sizeof(m_out_hsync_func)); |
| 35 | | memset(&m_out_vsync_func, 0, sizeof(m_out_vsync_func)); |
| 36 | | memset(&m_out_vblank_func, 0, sizeof(m_out_vblank_func)); |
| 37 | | } |
| 38 | | } |
| 39 | | |
| 40 | | |
| 41 | 19 | crtc_ega_device::crtc_ega_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 42 | 20 | : device_t(mconfig, CRTC_EGA, "crtc_EGA", tag, owner, clock, "crtc_ega", __FILE__), |
| 43 | | device_video_interface(mconfig, *this, false) |
| 21 | device_video_interface(mconfig, *this, false), |
| 22 | m_res_out_de_cb(*this), |
| 23 | m_res_out_hsync_cb(*this), |
| 24 | m_res_out_vsync_cb(*this), |
| 25 | m_res_out_vblank_cb(*this), |
| 26 | m_hpixels_per_column(0) |
| 44 | 27 | { |
| 45 | 28 | } |
| 46 | 29 | |
| r29504 | r29505 | |
| 239 | 222 | |
| 240 | 223 | void crtc_ega_device::set_de(int state) |
| 241 | 224 | { |
| 242 | | if ( m_de != state ) |
| 225 | if (m_de != state) |
| 243 | 226 | { |
| 244 | 227 | m_de = state; |
| 245 | 228 | |
| 246 | | if ( !m_res_out_de_func.isnull() ) |
| 247 | | m_res_out_de_func( m_de ); |
| 229 | if (!m_res_out_de_cb.isnull()) |
| 230 | m_res_out_de_cb(m_de); |
| 248 | 231 | } |
| 249 | 232 | } |
| 250 | 233 | |
| 251 | 234 | |
| 252 | 235 | void crtc_ega_device::set_hsync(int state) |
| 253 | 236 | { |
| 254 | | if ( m_hsync != state ) |
| 237 | if (m_hsync != state) |
| 255 | 238 | { |
| 256 | 239 | m_hsync = state; |
| 257 | 240 | |
| 258 | | if ( !m_res_out_hsync_func.isnull() ) |
| 259 | | m_res_out_hsync_func( m_hsync ); |
| 241 | if (!m_res_out_hsync_cb.isnull()) |
| 242 | m_res_out_hsync_cb(m_hsync); |
| 260 | 243 | } |
| 261 | 244 | } |
| 262 | 245 | |
| 263 | 246 | |
| 264 | 247 | void crtc_ega_device::set_vsync(int state) |
| 265 | 248 | { |
| 266 | | if ( m_vsync != state ) |
| 249 | if (m_vsync != state) |
| 267 | 250 | { |
| 268 | 251 | m_vsync = state; |
| 269 | 252 | |
| 270 | | if ( !m_res_out_vsync_func.isnull() ) |
| 271 | | m_res_out_vsync_func( m_vsync ); |
| 253 | if (!m_res_out_vsync_cb.isnull()) |
| 254 | m_res_out_vsync_cb(m_vsync); |
| 272 | 255 | } |
| 273 | 256 | } |
| 274 | 257 | |
| 275 | 258 | |
| 276 | 259 | void crtc_ega_device::set_vblank(int state) |
| 277 | 260 | { |
| 278 | | if ( m_vblank != state ) |
| 261 | if (m_vblank != state) |
| 279 | 262 | { |
| 280 | 263 | m_vblank = state; |
| 281 | 264 | |
| 282 | | if ( !m_res_out_vblank_func.isnull() ) |
| 283 | | m_res_out_vblank_func( m_vblank ); |
| 265 | if (!m_res_out_vblank_cb.isnull()) |
| 266 | m_res_out_vblank_cb(m_vblank); |
| 284 | 267 | } |
| 285 | 268 | } |
| 286 | 269 | |
| 287 | 270 | |
| 288 | 271 | void crtc_ega_device::set_cur(int state) |
| 289 | 272 | { |
| 290 | | if ( m_cur != state ) |
| 273 | if (m_cur != state) |
| 291 | 274 | { |
| 292 | 275 | m_cur = state; |
| 293 | 276 | |
| 294 | | // if ( !m_res_out_cur_func.isnull() ) |
| 295 | | // m_res_out_cur_func( m_cur ); |
| 277 | // if (!m_res_out_cur_cb.isnull()) |
| 278 | // m_res_out_cur_cb(m_cur); |
| 296 | 279 | } |
| 297 | 280 | } |
| 298 | 281 | |
| r29504 | r29505 | |
| 538 | 521 | { |
| 539 | 522 | UINT16 y; |
| 540 | 523 | |
| 541 | | void *param = NULL; |
| 524 | assert(!m_row_update_cb.isnull() != NULL); |
| 542 | 525 | |
| 543 | | assert(m_update_row != NULL); |
| 544 | | |
| 545 | 526 | /* call the set up function if any */ |
| 546 | | if (m_begin_update != NULL) |
| 547 | | param = m_begin_update(this, bitmap, cliprect); |
| 527 | if (!m_begin_update_cb.isnull()) |
| 528 | m_begin_update_cb(bitmap, cliprect); |
| 548 | 529 | |
| 549 | 530 | if (cliprect.min_y == 0) |
| 550 | 531 | { |
| r29504 | r29505 | |
| 569 | 550 | INT8 cursor_x = cursor_visible ? (m_cursor_addr - m_current_disp_addr) : -1; |
| 570 | 551 | |
| 571 | 552 | /* call the external system to draw it */ |
| 572 | | m_update_row(this, bitmap, cliprect, m_current_disp_addr, ra, y, m_horiz_disp + 1, cursor_x, param); |
| 553 | m_row_update_cb(bitmap, cliprect, m_current_disp_addr, ra, y, m_horiz_disp + 1, cursor_x); |
| 573 | 554 | |
| 574 | 555 | /* update MA if the last raster address */ |
| 575 | 556 | if (ra == m_max_ras_addr) |
| r29504 | r29505 | |
| 577 | 558 | } |
| 578 | 559 | |
| 579 | 560 | /* call the tear down function if any */ |
| 580 | | if (m_end_update != NULL) |
| 581 | | m_end_update(this, bitmap, cliprect, param); |
| 561 | if (!m_end_update_cb.isnull()) |
| 562 | m_end_update_cb(bitmap, cliprect); |
| 582 | 563 | } |
| 583 | 564 | else |
| 584 | 565 | logerror("Invalid crtc_ega screen parameters - display disabled!!!\n"); |
| r29504 | r29505 | |
| 595 | 576 | assert(m_hpixels_per_column > 0); |
| 596 | 577 | |
| 597 | 578 | /* resolve callbacks */ |
| 598 | | m_res_out_de_func.resolve(m_out_de_func, *this); |
| 599 | | m_res_out_hsync_func.resolve(m_out_hsync_func, *this); |
| 600 | | m_res_out_vsync_func.resolve(m_out_vsync_func, *this); |
| 601 | | m_res_out_vblank_func.resolve(m_out_vblank_func, *this); |
| 579 | m_res_out_de_cb.resolve(); |
| 580 | m_res_out_hsync_cb.resolve(); |
| 581 | m_res_out_vsync_cb.resolve(); |
| 582 | m_res_out_vblank_cb.resolve(); |
| 602 | 583 | |
| 584 | /* bind delegates */ |
| 585 | m_begin_update_cb.bind_relative_to(*owner()); |
| 586 | m_row_update_cb.bind_relative_to(*owner()); |
| 587 | m_end_update_cb.bind_relative_to(*owner()); |
| 588 | |
| 603 | 589 | /* create the timers */ |
| 604 | 590 | m_line_timer = timer_alloc(TIMER_LINE); |
| 605 | 591 | m_de_off_timer = timer_alloc(TIMER_DE_OFF); |
| r29504 | r29505 | |
| 699 | 685 | void crtc_ega_device::device_reset() |
| 700 | 686 | { |
| 701 | 687 | /* internal registers other than status remain unchanged, all outputs go low */ |
| 702 | | if ( !m_res_out_de_func.isnull() ) |
| 703 | | m_res_out_de_func( FALSE ); |
| 688 | if (!m_res_out_de_cb.isnull()) |
| 689 | m_res_out_de_cb(false); |
| 704 | 690 | |
| 705 | | if ( !m_res_out_hsync_func.isnull() ) |
| 706 | | m_res_out_hsync_func( FALSE ); |
| 691 | if (!m_res_out_hsync_cb.isnull()) |
| 692 | m_res_out_hsync_cb(false); |
| 707 | 693 | |
| 708 | | if ( !m_res_out_vsync_func.isnull() ) |
| 709 | | m_res_out_vsync_func( FALSE ); |
| 694 | if (!m_res_out_vsync_cb.isnull()) |
| 695 | m_res_out_vsync_cb(false); |
| 710 | 696 | |
| 711 | | if ( !m_res_out_vblank_func.isnull() ) |
| 712 | | m_res_out_vblank_func( FALSE ); |
| 697 | if (!m_res_out_vblank_cb.isnull()) |
| 698 | m_res_out_vblank_cb(false); |
| 713 | 699 | |
| 714 | | if ( ! m_line_timer->enabled( ) ) |
| 700 | if (!m_line_timer->enabled()) |
| 715 | 701 | { |
| 716 | 702 | m_line_timer->adjust( attotime::from_ticks( m_horiz_char_total + 2, m_clock ) ); |
| 717 | 703 | } |
trunk/src/emu/video/crtc_ega.h
| r29504 | r29505 | |
| 9 | 9 | |
| 10 | 10 | #include "emu.h" |
| 11 | 11 | |
| 12 | | #define CRTC_EGA_INTERFACE(name) \ |
| 13 | | const crtc_ega_interface (name) = |
| 12 | /* callback definitions */ |
| 13 | typedef device_delegate<void (bitmap_ind16 &bitmap, const rectangle &cliprect)> crtc_ega_begin_update_delegate; |
| 14 | 14 | |
| 15 | | #define MCFG_CRTC_EGA_ADD(_tag, _clock, _intrf) \ |
| 16 | | MCFG_DEVICE_ADD(_tag, CRTC_EGA, _clock) \ |
| 17 | | MCFG_DEVICE_CONFIG(_intrf) |
| 15 | typedef device_delegate<void (bitmap_ind16 &bitmap, const rectangle &cliprect, UINT16 ma, UINT8 ra, |
| 16 | UINT16 y, UINT8 x_count, INT8 cursor_x)> crtc_ega_row_update_delegate; |
| 18 | 17 | |
| 19 | | #define MCFG_CRTC_EGA_SET_SCREEN MCFG_VIDEO_SET_SCREEN |
| 18 | typedef device_delegate<void (bitmap_ind16 &bitmap, const rectangle &cliprect)> crtc_ega_end_update_delegate; |
| 20 | 19 | |
| 21 | 20 | |
| 22 | | class crtc_ega_device; |
| 21 | #define CRTC_EGA_BEGIN_UPDATE(_name) void _name(bitmap_ind16 &bitmap, const rectangle &cliprect) |
| 22 | #define CRTC_EGA_ROW_UPDATE(_name) void _name(bitmap_ind16 &bitmap, \ |
| 23 | const rectangle &cliprect, UINT16 ma, UINT8 ra, \ |
| 24 | UINT16 y, UINT8 x_count, INT8 cursor_x) |
| 25 | #define CRTC_EGA_END_UPDATE(_name) void _name(bitmap_ind16 &bitmap, const rectangle &cliprect) |
| 23 | 26 | |
| 24 | | /* callback definitions */ |
| 25 | | typedef void * (*crtc_ega_begin_update_func)(crtc_ega_device *device, bitmap_ind16 &bitmap, const rectangle &cliprect); |
| 26 | | #define CRTC_EGA_BEGIN_UPDATE(name) void *name(crtc_ega_device *device, bitmap_ind16 &bitmap, const rectangle &cliprect) |
| 27 | 27 | |
| 28 | | typedef void (*crtc_ega_update_row_func)(crtc_ega_device *device, bitmap_ind16 &bitmap, |
| 29 | | const rectangle &cliprect, UINT16 ma, UINT8 ra, |
| 30 | | UINT16 y, UINT8 x_count, INT8 cursor_x, void *param); |
| 31 | | #define CRTC_EGA_UPDATE_ROW(name) void name(crtc_ega_device *device, bitmap_ind16 &bitmap, \ |
| 32 | | const rectangle &cliprect, UINT16 ma, UINT8 ra, \ |
| 33 | | UINT16 y, UINT8 x_count, INT8 cursor_x, void *param) |
| 34 | 28 | |
| 35 | | typedef void (*crtc_ega_end_update_func)(crtc_ega_device *device, bitmap_ind16 &bitmap, const rectangle &cliprect, void *param); |
| 36 | | #define CRTC_EGA_END_UPDATE(name) void name(crtc_ega_device *device, bitmap_ind16 &bitmap, const rectangle &cliprect, void *param) |
| 29 | #define MCFG_CRTC_EGA_SET_SCREEN MCFG_VIDEO_SET_SCREEN |
| 37 | 30 | |
| 31 | #define MCFG_CRTC_EGA_BEGIN_UPDATE_CB(_class, _method) \ |
| 32 | crtc_ega_device::set_begin_update_callback(*device, crtc_ega_begin_update_delegate(&_class::_method, #_class "::" #_method, downcast<_class *>(owner))); |
| 38 | 33 | |
| 39 | | /* interface */ |
| 40 | | struct crtc_ega_interface |
| 41 | | { |
| 42 | | int m_hpixels_per_column; /* number of pixels per video memory address */ |
| 34 | #define MCFG_CRTC_EGA_ROW_UPDATE_CB(_class, _method) \ |
| 35 | crtc_ega_device::set_row_update_callback(*device, crtc_ega_row_update_delegate(&_class::_method, #_class "::" #_method, downcast<_class *>(owner))); |
| 43 | 36 | |
| 44 | | /* if specified, this gets called before any pixel update, |
| 45 | | optionally return a pointer that will be passed to the |
| 46 | | update and tear down callbacks */ |
| 47 | | crtc_ega_begin_update_func m_begin_update; |
| 37 | #define MCFG_CRTC_EGA_END_UPDATE_CB(_class, _method) \ |
| 38 | crtc_ega_device::set_end_update_callback(*device, crtc_ega_end_update_delegate(&_class::_method, #_class "::" #_method, downcast<_class *>(owner))); |
| 48 | 39 | |
| 49 | | /* this gets called for every row, the driver must output |
| 50 | | x_count * hpixels_per_column pixels. |
| 51 | | cursor_x indicates the character position where the cursor is, or -1 |
| 52 | | if there is no cursor on this row */ |
| 53 | | crtc_ega_update_row_func m_update_row; |
| 40 | #define MCFG_CRTC_EGA_HPIXELS_PER_COLUMN(_pix) \ |
| 41 | crtc_ega_device::set_hpixels_per_column(*device, _pix); |
| 54 | 42 | |
| 55 | | /* if specified, this gets called after all row updating is complete */ |
| 56 | | crtc_ega_end_update_func m_end_update; |
| 43 | #define MCFG_CRTC_EGA_RES_OUT_DE_CB(_devcb) \ |
| 44 | devcb = &crtc_ega_device::set_res_out_de_callback(*device, DEVCB2_##_devcb); |
| 57 | 45 | |
| 58 | | /* if specified, this gets called for every change of the disply enable signal */ |
| 59 | | devcb_write_line m_out_de_func; |
| 46 | #define MCFG_CRTC_EGA_RES_OUT_HSYNC_CB(_devcb) \ |
| 47 | devcb = &crtc_ega_device::set_res_out_hsync_callback(*device, DEVCB2_##_devcb); |
| 60 | 48 | |
| 61 | | /* if specified, this gets called for every change of the HSYNC signal */ |
| 62 | | devcb_write_line m_out_hsync_func; |
| 49 | #define MCFG_CRTC_EGA_RES_OUT_VSYNC_CB(_devcb) \ |
| 50 | devcb = &crtc_ega_device::set_res_out_vsync_callback(*device, DEVCB2_##_devcb); |
| 63 | 51 | |
| 64 | | /* if specified, this gets called for every change of the VSYNC signal */ |
| 65 | | devcb_write_line m_out_vsync_func; |
| 52 | #define MCFG_CRTC_EGA_RES_OUT_VBLANK_CB(_devcb) \ |
| 53 | devcb = &crtc_ega_device::set_res_out_vblank_callback(*device, DEVCB2_##_devcb); |
| 66 | 54 | |
| 67 | | devcb_write_line m_out_vblank_func; |
| 68 | | }; |
| 69 | 55 | |
| 70 | | |
| 71 | 56 | class crtc_ega_device : public device_t, |
| 72 | | public device_video_interface, |
| 73 | | public crtc_ega_interface |
| 57 | public device_video_interface |
| 74 | 58 | { |
| 75 | 59 | public: |
| 76 | 60 | crtc_ega_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 77 | 61 | |
| 62 | template<class _Object> static devcb2_base &set_res_out_de_callback(device_t &device, _Object object) |
| 63 | { return downcast<crtc_ega_device &>(device).m_res_out_de_cb.set_callback(object); } |
| 64 | template<class _Object> static devcb2_base &set_res_out_hsync_callback(device_t &device, _Object object) |
| 65 | { return downcast<crtc_ega_device &>(device).m_res_out_hsync_cb.set_callback(object); } |
| 66 | template<class _Object> static devcb2_base &set_res_out_vsync_callback(device_t &device, _Object object) |
| 67 | { return downcast<crtc_ega_device &>(device).m_res_out_vsync_cb.set_callback(object); } |
| 68 | template<class _Object> static devcb2_base &set_res_out_vblank_callback(device_t &device, _Object object) |
| 69 | { return downcast<crtc_ega_device &>(device).m_res_out_vblank_cb.set_callback(object); } |
| 70 | |
| 71 | static void set_begin_update_callback(device_t &device, crtc_ega_begin_update_delegate callback) { downcast<crtc_ega_device &>(device).m_begin_update_cb = callback; } |
| 72 | static void set_row_update_callback(device_t &device, crtc_ega_row_update_delegate callback) { downcast<crtc_ega_device &>(device).m_row_update_cb = callback; } |
| 73 | static void set_end_update_callback(device_t &device, crtc_ega_end_update_delegate callback) { downcast<crtc_ega_device &>(device).m_end_update_cb = callback; } |
| 74 | static void set_hpixels_per_column(device_t &device, int hpixels_per_column) { downcast<crtc_ega_device &>(device).m_hpixels_per_column = hpixels_per_column; } |
| 75 | |
| 78 | 76 | /* select one of the registers for reading or writing */ |
| 79 | 77 | DECLARE_WRITE8_MEMBER( address_w ); |
| 80 | 78 | |
| r29504 | r29505 | |
| 106 | 104 | |
| 107 | 105 | protected: |
| 108 | 106 | // device-level overrides |
| 109 | | virtual void device_config_complete(); |
| 110 | 107 | virtual void device_start(); |
| 111 | 108 | virtual void device_reset(); |
| 112 | 109 | virtual void device_post_load(); |
| 113 | 110 | virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); |
| 114 | 111 | |
| 115 | 112 | private: |
| 116 | | devcb_resolved_write_line m_res_out_de_func; |
| 117 | | devcb_resolved_write_line m_res_out_cur_func; |
| 118 | | devcb_resolved_write_line m_res_out_hsync_func; |
| 119 | | devcb_resolved_write_line m_res_out_vsync_func; |
| 120 | | devcb_resolved_write_line m_res_out_vblank_func; |
| 113 | devcb2_write_line m_res_out_de_cb; |
| 114 | devcb2_write_line m_res_out_hsync_cb; |
| 115 | devcb2_write_line m_res_out_vsync_cb; |
| 116 | devcb2_write_line m_res_out_vblank_cb; |
| 121 | 117 | |
| 118 | /* if specified, this gets called before any pixel update, |
| 119 | optionally return a pointer that will be passed to the |
| 120 | update and tear down callbacks */ |
| 121 | crtc_ega_begin_update_delegate m_begin_update_cb; |
| 122 | |
| 123 | /* this gets called for every row, the driver must output |
| 124 | x_count * hpixels_per_column pixels. |
| 125 | cursor_x indicates the character position where the cursor is, or -1 |
| 126 | if there is no cursor on this row */ |
| 127 | crtc_ega_row_update_delegate m_row_update_cb; |
| 128 | |
| 129 | /* if specified, this gets called after all row updating is complete */ |
| 130 | crtc_ega_end_update_delegate m_end_update_cb; |
| 131 | |
| 122 | 132 | /* ega/vga register file */ |
| 123 | 133 | UINT8 m_horiz_char_total; /* 0x00 */ |
| 124 | 134 | UINT8 m_horiz_disp; /* 0x01 */ |
| r29504 | r29505 | |
| 157 | 167 | UINT8 m_register_address_latch; |
| 158 | 168 | bool m_cursor_state; /* 0 = off, 1 = on */ |
| 159 | 169 | UINT8 m_cursor_blink_count; |
| 170 | int m_hpixels_per_column; /* number of pixels per video memory address */ |
| 160 | 171 | |
| 161 | 172 | /* output signals */ |
| 162 | 173 | int m_cur; |
trunk/src/emu/bus/isa/ega.c
| r29504 | r29505 | |
| 449 | 449 | #define EGA_SCREEN_NAME "ega_screen" |
| 450 | 450 | #define EGA_CRTC_NAME "crtc_ega_ega" |
| 451 | 451 | |
| 452 | |
| 453 | #define EGA_MODE_GRAPHICS 1 |
| 454 | #define EGA_MODE_TEXT 2 |
| 455 | |
| 456 | |
| 452 | 457 | /* |
| 453 | 458 | Prototypes |
| 454 | 459 | */ |
| 455 | | static CRTC_EGA_UPDATE_ROW( ega_update_row ); |
| 456 | 460 | |
| 457 | | static CRTC_EGA_INTERFACE( crtc_ega_ega_intf ) |
| 458 | | { |
| 459 | | 8, /* numbers of pixels per video memory address */ |
| 460 | | NULL, /* begin_update */ |
| 461 | | ega_update_row, /* update_row */ |
| 462 | | NULL, /* end_update */ |
| 463 | | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, isa8_ega_device, de_changed), /* on_de_chaged */ |
| 464 | | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, isa8_ega_device, hsync_changed), /* on_hsync_changed */ |
| 465 | | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, isa8_ega_device, vsync_changed), /* on vsync_changed */ |
| 466 | | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, isa8_ega_device, vblank_changed) /* on_vblank_changed */ |
| 467 | | }; |
| 468 | | |
| 469 | | |
| 470 | 461 | MACHINE_CONFIG_FRAGMENT( pcvideo_ega ) |
| 471 | 462 | MCFG_SCREEN_ADD(EGA_SCREEN_NAME, RASTER) |
| 472 | 463 | MCFG_SCREEN_RAW_PARAMS(16257000,912,0,640,262,0,200) |
| r29504 | r29505 | |
| 474 | 465 | MCFG_SCREEN_PALETTE("palette") |
| 475 | 466 | |
| 476 | 467 | MCFG_PALETTE_ADD( "palette", 64 ) |
| 477 | | MCFG_CRTC_EGA_ADD(EGA_CRTC_NAME, 16257000/8, crtc_ega_ega_intf) |
| 468 | |
| 469 | MCFG_DEVICE_ADD(EGA_CRTC_NAME, CRTC_EGA, 16257000/8) |
| 478 | 470 | MCFG_CRTC_EGA_SET_SCREEN(EGA_SCREEN_NAME) |
| 471 | MCFG_CRTC_EGA_HPIXELS_PER_COLUMN(8) |
| 472 | MCFG_CRTC_EGA_ROW_UPDATE_CB(isa8_ega_device, ega_update_row) |
| 473 | MCFG_CRTC_EGA_RES_OUT_DE_CB(WRITELINE(isa8_ega_device, de_changed)) |
| 474 | MCFG_CRTC_EGA_RES_OUT_HSYNC_CB(WRITELINE(isa8_ega_device, hsync_changed)) |
| 475 | MCFG_CRTC_EGA_RES_OUT_VSYNC_CB(WRITELINE(isa8_ega_device, vsync_changed)) |
| 476 | MCFG_CRTC_EGA_RES_OUT_VBLANK_CB(WRITELINE(isa8_ega_device, vblank_changed)) |
| 479 | 477 | MACHINE_CONFIG_END |
| 480 | 478 | |
| 481 | 479 | ROM_START( ega ) |
| r29504 | r29505 | |
| 664 | 662 | |
| 665 | 663 | install_banks(); |
| 666 | 664 | |
| 667 | | m_update_row = NULL; |
| 668 | 665 | m_misc_output = 0; |
| 669 | 666 | m_attribute.index_write = 1; |
| 670 | 667 | |
| r29504 | r29505 | |
| 686 | 683 | m_attribute.data[14] = 0x3E; |
| 687 | 684 | m_attribute.data[15] = 0x3F; |
| 688 | 685 | |
| 686 | m_video_mode = 0; |
| 689 | 687 | } |
| 690 | 688 | |
| 691 | 689 | void isa8_ega_device::install_banks() |
| r29504 | r29505 | |
| 746 | 744 | } |
| 747 | 745 | } |
| 748 | 746 | |
| 749 | | static CRTC_EGA_UPDATE_ROW( ega_update_row ) |
| 747 | CRTC_EGA_ROW_UPDATE( isa8_ega_device::ega_update_row ) |
| 750 | 748 | { |
| 751 | | isa8_ega_device *ega = dynamic_cast<isa8_ega_device*>(device->owner()); |
| 752 | | if ( ega->m_update_row ) |
| 753 | | { |
| 754 | | ega->m_update_row( device, bitmap, cliprect, ma, ra, y, x_count, cursor_x, param ); |
| 755 | | } |
| 749 | if (m_video_mode == EGA_MODE_GRAPHICS) |
| 750 | pc_ega_graphics(bitmap, cliprect, ma, ra, y, x_count, cursor_x); |
| 751 | else if (m_video_mode == EGA_MODE_TEXT) |
| 752 | pc_ega_text(bitmap, cliprect, ma, ra, y, x_count, cursor_x); |
| 756 | 753 | } |
| 757 | 754 | |
| 758 | 755 | |
| r29504 | r29505 | |
| 784 | 781 | } |
| 785 | 782 | |
| 786 | 783 | |
| 787 | | static CRTC_EGA_UPDATE_ROW( pc_ega_graphics ) |
| 784 | CRTC_EGA_ROW_UPDATE( isa8_ega_device::pc_ega_graphics ) |
| 788 | 785 | { |
| 789 | | isa8_ega_device *ega = dynamic_cast<isa8_ega_device*>(device->owner()); |
| 790 | 786 | UINT16 *p = &bitmap.pix16(y); |
| 791 | 787 | |
| 792 | 788 | // logerror( "pc_ega_graphics: y = %d, x_count = %d, ma = %d, ra = %d\n", y, x_count, ma, ra ); |
| 793 | 789 | |
| 794 | | if ( ega->m_graphics_controller.data[5] & 0x10 ) |
| 790 | if ( m_graphics_controller.data[5] & 0x10 ) |
| 795 | 791 | { |
| 796 | 792 | // Odd/Even mode (CGA compatible) |
| 797 | 793 | |
| 798 | 794 | for ( int i = 0; i < x_count; i++ ) |
| 799 | 795 | { |
| 800 | 796 | UINT16 offset = ( ( ma + i ) & 0x1fff ) | ( ( y & 1 ) << 12 ); |
| 801 | | UINT8 data = ega->m_plane[0][offset]; |
| 797 | UINT8 data = m_plane[0][offset]; |
| 802 | 798 | |
| 803 | | *p = ega->m_attribute.data[ ( data >> 6 ) ]; p++; |
| 804 | | *p = ega->m_attribute.data[ ( data >> 4 ) & 0x03 ]; p++; |
| 805 | | *p = ega->m_attribute.data[ ( data >> 2 ) & 0x03 ]; p++; |
| 806 | | *p = ega->m_attribute.data[ data & 0x03 ]; p++; |
| 799 | *p = m_attribute.data[ ( data >> 6 ) ]; p++; |
| 800 | *p = m_attribute.data[ ( data >> 4 ) & 0x03 ]; p++; |
| 801 | *p = m_attribute.data[ ( data >> 2 ) & 0x03 ]; p++; |
| 802 | *p = m_attribute.data[ data & 0x03 ]; p++; |
| 807 | 803 | |
| 808 | | data = ega->m_plane[1][offset]; |
| 804 | data = m_plane[1][offset]; |
| 809 | 805 | |
| 810 | | *p = ega->m_attribute.data[ ( data >> 6 ) ]; p++; |
| 811 | | *p = ega->m_attribute.data[ ( data >> 4 ) & 0x03 ]; p++; |
| 812 | | *p = ega->m_attribute.data[ ( data >> 2 ) & 0x03 ]; p++; |
| 813 | | *p = ega->m_attribute.data[ data & 0x03 ]; p++; |
| 806 | *p = m_attribute.data[ ( data >> 6 ) ]; p++; |
| 807 | *p = m_attribute.data[ ( data >> 4 ) & 0x03 ]; p++; |
| 808 | *p = m_attribute.data[ ( data >> 2 ) & 0x03 ]; p++; |
| 809 | *p = m_attribute.data[ data & 0x03 ]; p++; |
| 814 | 810 | } |
| 815 | 811 | } |
| 816 | 812 | else |
| 817 | 813 | { |
| 818 | 814 | // EGA mode |
| 819 | 815 | |
| 820 | | UINT8 mask = ega->m_attribute.data[0x12] & 0x0f; |
| 816 | UINT8 mask = m_attribute.data[0x12] & 0x0f; |
| 821 | 817 | |
| 822 | 818 | for ( int i = 0; i < x_count; i++ ) |
| 823 | 819 | { |
| 824 | 820 | UINT16 offset = ma + i; |
| 825 | | UINT16 data0 = ega->m_plane[0][offset]; |
| 826 | | UINT16 data1 = ega->m_plane[1][offset] << 1; |
| 827 | | UINT16 data2 = ega->m_plane[2][offset] << 2; |
| 828 | | UINT16 data3 = ega->m_plane[3][offset] << 3; |
| 821 | UINT16 data0 = m_plane[0][offset]; |
| 822 | UINT16 data1 = m_plane[1][offset] << 1; |
| 823 | UINT16 data2 = m_plane[2][offset] << 2; |
| 824 | UINT16 data3 = m_plane[3][offset] << 3; |
| 829 | 825 | |
| 830 | 826 | for ( int j = 7; j >= 0; j-- ) |
| 831 | 827 | { |
| r29504 | r29505 | |
| 833 | 829 | |
| 834 | 830 | col &= mask; |
| 835 | 831 | |
| 836 | | p[j] = ega->m_attribute.data[col]; |
| 832 | p[j] = m_attribute.data[col]; |
| 837 | 833 | |
| 838 | 834 | data0 >>= 1; |
| 839 | 835 | data1 >>= 1; |
| r29504 | r29505 | |
| 846 | 842 | } |
| 847 | 843 | |
| 848 | 844 | |
| 849 | | static CRTC_EGA_UPDATE_ROW( pc_ega_text ) |
| 845 | CRTC_EGA_ROW_UPDATE( isa8_ega_device::pc_ega_text ) |
| 850 | 846 | { |
| 851 | | isa8_ega_device *ega = dynamic_cast<isa8_ega_device*>(device->owner()); |
| 852 | 847 | UINT16 *p = &bitmap.pix16(y); |
| 853 | 848 | int i; |
| 854 | 849 | |
| r29504 | r29505 | |
| 857 | 852 | for ( i = 0; i < x_count; i++ ) |
| 858 | 853 | { |
| 859 | 854 | UINT16 offset = ma + i; |
| 860 | | UINT8 chr = ega->m_plane[0][ offset ]; |
| 861 | | UINT8 attr = ega->m_plane[1][ offset ]; |
| 855 | UINT8 chr = m_plane[0][ offset ]; |
| 856 | UINT8 attr = m_plane[1][ offset ]; |
| 862 | 857 | UINT8 data = 0; |
| 863 | | UINT16 fg = ega->m_attribute.data[ attr & 0x07 ]; |
| 864 | | UINT16 bg = ega->m_attribute.data[ ( attr >> 4 ) & 0x07 ]; |
| 858 | UINT16 fg = m_attribute.data[ attr & 0x07 ]; |
| 859 | UINT16 bg = m_attribute.data[ ( attr >> 4 ) & 0x07 ]; |
| 865 | 860 | |
| 866 | 861 | /* If character set A and B are equal attribute bit 3 is used as intensity */ |
| 867 | | if ( ega->m_charA == ega->m_charB ) |
| 862 | if ( m_charA == m_charB ) |
| 868 | 863 | { |
| 869 | 864 | /* intensity selector */ |
| 870 | | data = ega->m_charB[ chr * 32 + ra ]; |
| 865 | data = m_charB[ chr * 32 + ra ]; |
| 871 | 866 | fg += ( attr & 0x08 ) ? 0x38 : 0x00; |
| 872 | 867 | } |
| 873 | 868 | else |
| 874 | 869 | { |
| 875 | 870 | /* character set selector */ |
| 876 | | data = ( attr & 0x08 ) ? ega->m_charA[ chr * 32 + ra ] : ega->m_charB[ chr * 32 + ra ]; |
| 871 | data = ( attr & 0x08 ) ? m_charA[ chr * 32 + ra ] : m_charB[ chr * 32 + ra ]; |
| 877 | 872 | } |
| 878 | 873 | |
| 879 | 874 | if ( i == cursor_x ) |
| 880 | 875 | { |
| 881 | | if ( ega->m_frame_cnt & 0x08 ) |
| 876 | if ( m_frame_cnt & 0x08 ) |
| 882 | 877 | { |
| 883 | 878 | data = 0xFF; |
| 884 | 879 | } |
| r29504 | r29505 | |
| 886 | 881 | else |
| 887 | 882 | { |
| 888 | 883 | /* Check for blinking */ |
| 889 | | if ( ( ega->m_attribute.data[0x10] & 0x08 ) && ( attr & 0x80 ) && ( ega->m_frame_cnt & 0x10 ) ) |
| 884 | if ( ( m_attribute.data[0x10] & 0x08 ) && ( attr & 0x80 ) && ( m_frame_cnt & 0x10 ) ) |
| 890 | 885 | { |
| 891 | 886 | data = 0x00; |
| 892 | 887 | } |
| r29504 | r29505 | |
| 908 | 903 | { |
| 909 | 904 | int clock, pixels; |
| 910 | 905 | |
| 911 | | m_update_row = NULL; |
| 906 | m_video_mode = 0; |
| 912 | 907 | |
| 913 | 908 | /* Check for graphics mode */ |
| 914 | 909 | if ( ( m_attribute.data[0x10] & 0x01 ) && |
| r29504 | r29505 | |
| 920 | 915 | logerror("change_mode(): Switch to graphics mode\n"); |
| 921 | 916 | } |
| 922 | 917 | |
| 923 | | m_update_row = pc_ega_graphics; |
| 918 | m_video_mode = EGA_MODE_GRAPHICS; |
| 924 | 919 | } |
| 925 | 920 | |
| 926 | 921 | /* Check for text mode */ |
| r29504 | r29505 | |
| 933 | 928 | logerror("chnage_mode(): Switching to text mode\n"); |
| 934 | 929 | } |
| 935 | 930 | |
| 936 | | m_update_row = pc_ega_text; |
| 931 | m_video_mode = EGA_MODE_TEXT; |
| 937 | 932 | |
| 938 | 933 | /* Set character maps */ |
| 939 | 934 | if ( m_sequencer.data[0x04] & 0x02 ) |
| r29504 | r29505 | |
| 959 | 954 | m_crtc_ega->set_clock( clock / pixels ); |
| 960 | 955 | m_crtc_ega->set_hpixels_per_column( pixels ); |
| 961 | 956 | |
| 962 | | if ( ! m_update_row ) |
| 963 | | logerror("unknown video mode\n"); |
| 957 | if (!m_video_mode) |
| 958 | logerror("unknown video mode\n"); |
| 964 | 959 | } |
| 965 | 960 | |
| 966 | 961 | |