diff options
Diffstat (limited to 'src/emu/video/crtc_ega.h')
-rw-r--r-- | src/emu/video/crtc_ega.h | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/src/emu/video/crtc_ega.h b/src/emu/video/crtc_ega.h new file mode 100644 index 00000000000..d211a63b888 --- /dev/null +++ b/src/emu/video/crtc_ega.h @@ -0,0 +1,223 @@ +/********************************************************************** + + IBM EGA CRT Controller emulation + +**********************************************************************/ + +#ifndef __CRTC_EGA__ +#define __CRTC_EGA__ + +#include "emu.h" + +#define CRTC_EGA_INTERFACE(name) \ + const crtc_ega_interface (name) = + +#define MCFG_CRTC_EGA_ADD(_tag, _clock, _intrf) \ + MCFG_DEVICE_ADD(_tag, CRTC_EGA, _clock) \ + MCFG_DEVICE_CONFIG(_intrf) + +#define MCFG_CRTC_EGA_SET_SCREEN MCFG_VIDEO_SET_SCREEN + + +class crtc_ega_device; + +/* callback definitions */ +typedef void * (*crtc_ega_begin_update_func)(crtc_ega_device *device, bitmap_ind16 &bitmap, const rectangle &cliprect); +#define CRTC_EGA_BEGIN_UPDATE(name) void *name(crtc_ega_device *device, bitmap_ind16 &bitmap, const rectangle &cliprect) + +typedef void (*crtc_ega_update_row_func)(crtc_ega_device *device, bitmap_ind16 &bitmap, + const rectangle &cliprect, UINT16 ma, UINT8 ra, + UINT16 y, UINT8 x_count, INT8 cursor_x, void *param); +#define CRTC_EGA_UPDATE_ROW(name) void name(crtc_ega_device *device, bitmap_ind16 &bitmap, \ + const rectangle &cliprect, UINT16 ma, UINT8 ra, \ + UINT16 y, UINT8 x_count, INT8 cursor_x, void *param) + +typedef void (*crtc_ega_end_update_func)(crtc_ega_device *device, bitmap_ind16 &bitmap, const rectangle &cliprect, void *param); +#define CRTC_EGA_END_UPDATE(name) void name(crtc_ega_device *device, bitmap_ind16 &bitmap, const rectangle &cliprect, void *param) + + +/* interface */ +struct crtc_ega_interface +{ + int m_hpixels_per_column; /* number of pixels per video memory address */ + + /* if specified, this gets called before any pixel update, + optionally return a pointer that will be passed to the + update and tear down callbacks */ + crtc_ega_begin_update_func m_begin_update; + + /* this gets called for every row, the driver must output + x_count * hpixels_per_column pixels. + cursor_x indicates the character position where the cursor is, or -1 + if there is no cursor on this row */ + crtc_ega_update_row_func m_update_row; + + /* if specified, this gets called after all row updating is complete */ + crtc_ega_end_update_func m_end_update; + + /* if specified, this gets called for every change of the disply enable signal */ + devcb_write_line m_out_de_func; + + /* if specified, this gets called for every change of the HSYNC signal */ + devcb_write_line m_out_hsync_func; + + /* if specified, this gets called for every change of the VSYNC signal */ + devcb_write_line m_out_vsync_func; + + devcb_write_line m_out_vblank_func; +}; + + +class crtc_ega_device : public device_t, + public device_video_interface, + public crtc_ega_interface +{ +public: + crtc_ega_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + /* select one of the registers for reading or writing */ + DECLARE_WRITE8_MEMBER( address_w ); + + /* read from the currently selected register */ + DECLARE_READ8_MEMBER( register_r ); + + /* write to the currently selected register */ + DECLARE_WRITE8_MEMBER( register_w ); + + /* return the current value on the MA0-MA15 pins */ + UINT16 get_ma(); + + /* return the current value on the RA0-RA4 pins */ + UINT8 get_ra(); + + /* simulates the LO->HI clocking of the light pen pin */ + void assert_light_pen_input(); + + /* set the clock of the chip */ + void set_clock(int clock); + + /* set number of pixels per video memory address */ + void set_hpixels_per_column(int hpixels_per_column); + + /* updates the screen -- this will call begin_update(), */ + /* followed by update_row() reapeatedly and after all row */ + /* updating is complete, end_update() */ + UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + +protected: + // device-level overrides + virtual void device_config_complete(); + virtual void device_start(); + virtual void device_reset(); + virtual void device_post_load(); + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); + +private: + devcb_resolved_write_line m_res_out_de_func; + devcb_resolved_write_line m_res_out_cur_func; + devcb_resolved_write_line m_res_out_hsync_func; + devcb_resolved_write_line m_res_out_vsync_func; + devcb_resolved_write_line m_res_out_vblank_func; + + /* ega/vga register file */ + UINT8 m_horiz_char_total; /* 0x00 */ + UINT8 m_horiz_disp; /* 0x01 */ + UINT8 m_horiz_blank_start; /* 0x02 */ + UINT8 m_horiz_blank_end; /* 0x03/0x05 */ + UINT8 m_ena_vert_access; /* 0x03 */ + UINT8 m_de_skew; /* 0x03 */ + UINT8 m_horiz_retr_start; /* 0x04 */ + UINT8 m_horiz_retr_end; /* 0x05 */ + UINT8 m_horiz_retr_skew; /* 0x05 */ + UINT16 m_vert_total; /* 0x06/0x07 */ + UINT8 m_preset_row_scan; /* 0x08 */ + UINT8 m_byte_panning; /* 0x08 */ + UINT8 m_max_ras_addr; /* 0x09 */ + UINT8 m_scan_doubling; /* 0x09 */ + UINT8 m_cursor_start_ras; /* 0x0a */ + UINT8 m_cursor_disable; /* 0x0a */ + UINT8 m_cursor_end_ras; /* 0x0b */ + UINT8 m_cursor_skew; /* 0x0b */ + UINT16 m_disp_start_addr; /* 0x0c/0x0d */ + UINT16 m_cursor_addr; /* 0x0e/0x0f */ + UINT16 m_light_pen_addr; /* 0x10/0x11 */ + UINT16 m_vert_retr_start; /* 0x10/0x07 */ + UINT8 m_vert_retr_end; /* 0x11 */ + UINT8 m_protect; /* 0x11 */ + UINT8 m_bandwidth; /* 0x11 */ + UINT16 m_vert_disp_end; /* 0x12/0x07 */ + UINT8 m_offset; /* 0x13 */ + UINT8 m_underline_loc; /* 0x14 */ + UINT16 m_vert_blank_start; /* 0x15/0x07/0x09 */ + UINT8 m_vert_blank_end; /* 0x16 */ + UINT8 m_mode_control; /* 0x17 */ + UINT16 m_line_compare; /* 0x18/0x07/0x09 */ + + /* other internal state */ + UINT8 m_register_address_latch; + bool m_cursor_state; /* 0 = off, 1 = on */ + UINT8 m_cursor_blink_count; + + /* output signals */ + int m_cur; + int m_hsync; + int m_vsync; + int m_vblank; + int m_de; + + /* internal counters */ + UINT8 m_character_counter; + UINT8 m_hsync_width_counter; + UINT16 m_line_counter; + UINT8 m_raster_counter; + UINT8 m_vsync_width_counter; + bool m_line_enable_ff; /* Internal flip flop which is set when the line_counter is reset and reset when vert_disp is reached */ + UINT8 m_vsync_ff; + UINT8 m_adjust_active; + UINT16 m_line_address; + INT16 m_cursor_x; + + /* timers */ + static const device_timer_id TIMER_LINE = 0; + static const device_timer_id TIMER_DE_OFF = 1; + static const device_timer_id TIMER_CUR_ON = 2; + static const device_timer_id TIMER_CUR_OFF = 3; + static const device_timer_id TIMER_HSYNC_ON = 4; + static const device_timer_id TIMER_HSYNC_OFF = 5; + static const device_timer_id TIMER_LIGHT_PEN_LATCH = 6; + + emu_timer *m_line_timer; + emu_timer *m_de_off_timer; + emu_timer *m_cur_on_timer; + emu_timer *m_cur_off_timer; + emu_timer *m_hsync_on_timer; + emu_timer *m_hsync_off_timer; + emu_timer *m_light_pen_latch_timer; + + /* computed values - do NOT state save these! */ + UINT16 m_horiz_pix_total; + UINT16 m_vert_pix_total; + UINT16 m_max_visible_x; + UINT16 m_max_visible_y; + UINT16 m_hsync_on_pos; + UINT16 m_hsync_off_pos; + UINT16 m_vsync_on_pos; + UINT16 m_vsync_off_pos; + UINT16 m_current_disp_addr; /* the display address currently drawn */ + UINT8 m_light_pen_latched; + bool m_has_valid_parameters; + + void recompute_parameters(bool postload); + void update_counters(); + void set_de(int state); + void set_hsync(int state); + void set_vsync(int state); + void set_vblank(int state); + void set_cur(int state); + void handle_line_timer(); + void update_cursor_state(); +}; + +extern const device_type CRTC_EGA; + +#endif |