diff --git a/src/emu/video/crt9021.h b/src/emu/video/crt9021.h index 7cf061c3ee4..c72c5d850e1 100644 --- a/src/emu/video/crt9021.h +++ b/src/emu/video/crt9021.h @@ -64,7 +64,8 @@ public: static void static_set_display_callback(device_t &device, crt9021_draw_character_delegate callback) { downcast(device).m_display_cb = callback; } - DECLARE_WRITE8_MEMBER( write ) { m_data = data; } + void write(UINT8 data) { m_data = data; } + DECLARE_WRITE8_MEMBER( write ) { write(data); } DECLARE_WRITE_LINE_MEMBER( ms0_w ) { m_ms0 = state; } DECLARE_WRITE_LINE_MEMBER( ms1_w ) { m_ms1 = state; } DECLARE_WRITE_LINE_MEMBER( revid_w ) { m_revid = state; } diff --git a/src/emu/video/crt9212.c b/src/emu/video/crt9212.c index 0deed6f55bf..e847c59d6f0 100644 --- a/src/emu/video/crt9212.c +++ b/src/emu/video/crt9212.c @@ -51,6 +51,10 @@ crt9212_t::crt9212_t(const machine_config &mconfig, const char *tag, device_t *o m_oe(0), m_rclk(0), m_wclk(0), + m_clrcnt_edge(false), + m_data_latch(0), + m_ren_int(0), + m_wen_int(0), m_buffer(0), m_rac(0), m_wac(0) @@ -79,6 +83,10 @@ void crt9212_t::device_start() save_item(NAME(m_oe)); save_item(NAME(m_rclk)); save_item(NAME(m_wclk)); + save_item(NAME(m_clrcnt_edge)); + save_item(NAME(m_data_latch)); + save_item(NAME(m_ren_int)); + save_item(NAME(m_wen_int)); save_item(NAME(m_ram[0])); save_item(NAME(m_ram[1])); save_item(NAME(m_buffer)); @@ -87,49 +95,68 @@ void crt9212_t::device_start() } +//------------------------------------------------- +// clrcnt_w - clear counter +//------------------------------------------------- + +WRITE_LINE_MEMBER( crt9212_t::clrcnt_w ) +{ + if (m_clrcnt && !state) + { + m_clrcnt_edge = true; + } + + m_clrcnt = state; +} + + //------------------------------------------------- // rclk_w - read clock //------------------------------------------------- WRITE_LINE_MEMBER( crt9212_t::rclk_w ) { - if (m_rclk && !state) + if (!m_rclk && state) { - if (!m_clrcnt) + if (m_clrcnt_edge) { + // reset read address counter + m_rac = 0; + + // reset read overflow + m_write_rof(0); + if (!m_tog) { - // switch buffer + // switch buffers m_buffer = !m_buffer; - // clear write address counter + // reset write address counter m_wac = 0; + + // reset write overflow m_write_wof(0); } - else - { - // clear read address counter - m_rac = 0; - m_write_rof(0); - } + + m_clrcnt_edge = false; } - else + + if (m_ren_int && (m_rac < CRT9212_RAM_SIZE)) { - if (m_ren && (m_rac < CRT9212_RAM_SIZE)) + // output data + m_write_dout(m_ram[m_rac][!m_buffer]); + + // increment read address counter + m_rac++; + + if (m_rac == CRT9212_RAM_SIZE - 1) { - // - m_write_dout(m_ram[m_rac][!m_buffer]); - - // increment read address counter - m_rac++; - - if (m_rac == CRT9212_RAM_SIZE) - { - // set read overflow - m_write_rof(1); - } + // set read overflow + m_write_rof(1); } } + + m_ren_int = m_ren; } m_rclk = state; @@ -144,20 +171,27 @@ WRITE_LINE_MEMBER( crt9212_t::wclk_w ) { if (!m_wclk && state) { - if (m_wen1 && m_wen2 && (m_wac < CRT9212_RAM_SIZE)) + if (m_wen_int && (m_wac < CRT9212_RAM_SIZE)) { - // - m_ram[m_rac][m_buffer] = m_data; + // input data + m_ram[m_rac][m_buffer] = m_data_latch; - // increment read address counter + // increment write address counter m_wac++; - if (m_wac == CRT9212_RAM_SIZE) + if (m_wac == CRT9212_RAM_SIZE - 1) { // set write overflow m_write_wof(1); } } + + if (m_wen1 && m_wen2) + { + m_data_latch = m_data; + } + + m_wen_int = m_wen1 && m_wen2; } m_wclk = state; diff --git a/src/emu/video/crt9212.h b/src/emu/video/crt9212.h index 56ef6032ae3..eb17158c4eb 100644 --- a/src/emu/video/crt9212.h +++ b/src/emu/video/crt9212.h @@ -47,6 +47,9 @@ const int CRT9212_RAM_SIZE = 135; // INTERFACE CONFIGURATION MACROS //************************************************************************** +#define MCFG_CRT9212_WEN2_VCC() \ + crt9212_t::static_set_wen2(*device, 1); + #define MCFG_CRT9212_DOUT_CALLBACK(_write) \ devcb = &crt9212_t::set_dout_wr_callback(*device, DEVCB2_##_write); @@ -70,12 +73,14 @@ public: // construction/destruction crt9212_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + static void static_set_wen2(device_t &device, int state) { downcast(device).m_wen2 = state; } + template static devcb2_base &set_dout_wr_callback(device_t &device, _Object object) { return downcast(device).m_write_dout.set_callback(object); } template static devcb2_base &set_rof_wr_callback(device_t &device, _Object object) { return downcast(device).m_write_rof.set_callback(object); } template static devcb2_base &set_wof_wr_callback(device_t &device, _Object object) { return downcast(device).m_write_wof.set_callback(object); } DECLARE_WRITE8_MEMBER( write ) { m_data = data; } - DECLARE_WRITE_LINE_MEMBER( clrcnt_w ) { m_clrcnt = state; } + DECLARE_WRITE_LINE_MEMBER( clrcnt_w ); DECLARE_WRITE_LINE_MEMBER( tog_w ) { m_tog = state; } DECLARE_WRITE_LINE_MEMBER( ren_w ) { m_ren = state; } DECLARE_WRITE_LINE_MEMBER( wen1_w ) { m_wen1 = state; } @@ -105,6 +110,10 @@ private: int m_wclk; // internal state + bool m_clrcnt_edge; + UINT8 m_data_latch; + int m_ren_int; + int m_wen_int; UINT8 m_ram[CRT9212_RAM_SIZE][2]; int m_buffer; int m_rac; diff --git a/src/mess/drivers/tandy2k.c b/src/mess/drivers/tandy2k.c index 91733954224..5921dbcf90e 100644 --- a/src/mess/drivers/tandy2k.c +++ b/src/mess/drivers/tandy2k.c @@ -12,9 +12,7 @@ TODO: - - CRT9007 - - CRT9212 Double Row Buffer - - CRT9021B Attribute Generator + - video - keyboard ROM - hires graphics board - floppy 720K DSQD @@ -26,14 +24,6 @@ */ #include "includes/tandy2k.h" -#include "bus/rs232/rs232.h" - -enum -{ - LPINEN = 0, - KBDINEN, - PORTINEN -}; // Read/Write Handlers @@ -44,9 +34,20 @@ void tandy2k_state::dma_request(int line, int state) void tandy2k_state::speaker_update() { int level = !(m_spkrdata & m_outspkr); + m_speaker->level_w(level); } +READ8_MEMBER( tandy2k_state::char_ram_r ) +{ + return m_char_ram[offset]; +} + +WRITE8_MEMBER( tandy2k_state::char_ram_w ) +{ + m_char_ram[offset] = data; +} + READ8_MEMBER( tandy2k_state::videoram_r ) { address_space &program = m_maincpu->space(AS_PROGRAM); @@ -80,7 +81,12 @@ READ8_MEMBER( tandy2k_state::enable_r ) */ - return 0x80; + UINT8 data = 0x80; + + data |= m_rs232->ri_r(); + data |= m_rs232->dcd_r() << 1; + + return data; } WRITE8_MEMBER( tandy2k_state::enable_w ) @@ -240,7 +246,7 @@ WRITE8_MEMBER( tandy2k_state::addr_ctrl_w ) m_vpac->set_character_width(clkcnt ? 8 : 10); m_vpac->set_unscaled_clock(vidcclk); - + m_vac->set_unscaled_clock(busdotclk); m_timer_vidldsh->adjust(attotime::from_hz(vidcclk), 0, attotime::from_hz(vidcclk)); @@ -261,7 +267,7 @@ static ADDRESS_MAP_START( tandy2k_mem, AS_PROGRAM, 16, tandy2k_state ) ADDRESS_MAP_UNMAP_HIGH // AM_RANGE(0x00000, 0xdffff) AM_RAM AM_RANGE(0xe0000, 0xf7fff) AM_RAM AM_SHARE("hires_ram") - AM_RANGE(0xf8000, 0xfbfff) AM_RAM AM_SHARE("char_ram") + AM_RANGE(0xf8000, 0xfbfff) AM_READWRITE8(char_ram_r, char_ram_w, 0x00ff) AM_RANGE(0xfc000, 0xfdfff) AM_MIRROR(0x2000) AM_ROM AM_REGION(I80186_TAG, 0) ADDRESS_MAP_END @@ -326,14 +332,38 @@ WRITE_LINE_MEMBER( tandy2k_state::vpac_wben_w ) m_drb1->wen1_w(state); } +WRITE_LINE_MEMBER( tandy2k_state::vpac_cblank_w ) +{ + m_cblank = state; +} + +WRITE_LINE_MEMBER( tandy2k_state::vpac_slg_w ) +{ + m_slg = state; + + m_vac->slg_w(state); +} + +WRITE_LINE_MEMBER( tandy2k_state::vpac_sld_w ) +{ + m_sld = state; + + m_vac->sld_w(state); +} + +WRITE8_MEMBER( tandy2k_state::vidla_w ) +{ + m_vidla = data; +} + WRITE8_MEMBER( tandy2k_state::drb_attr_w ) { /* bit description - 0 BLC -> DBLC - 1 BKC -> DBKC + 0 BLC -> DBLC (delayed 2 CCLKs) + 1 BKC -> DBKC (delayed 2 CCLKs) 2 CHABL 3 MS0 4 MS1 @@ -343,6 +373,8 @@ WRITE8_MEMBER( tandy2k_state::drb_attr_w ) */ + m_blc = BIT(data, 0); + m_bkc = BIT(data, 1); m_vac->chabl_w(BIT(data, 2)); m_vac->ms0_w(BIT(data, 3)); m_vac->ms1_w(BIT(data, 4)); @@ -372,6 +404,27 @@ TIMER_DEVICE_CALLBACK_MEMBER( tandy2k_state::vidldsh_tick ) m_vac->ld_sh_w(0); // 1 busdotclk later + m_vac->blc_w(BIT(m_dblc, 0)); + m_dblc >>= 1; + m_dblc |= m_blc << 2; + + m_vac->bkc_w(BIT(m_dbkc, 0)); + m_dbkc >>= 1; + m_dbkc |= m_bkc << 2; + + m_vac->retbl_w(BIT(m_dblank, 0)); + m_dblank >>= 1; + m_dblank |= m_cblank << 2; + + if (!m_slg) + { + m_cgra >>= 1; + m_cgra |= m_sld << 3; + } + + UINT8 vidd = m_char_ram[(m_vidla << 4) | m_cgra]; + m_vac->write(vidd); + m_drb0->rclk_w(1); m_drb0->wclk_w(1); m_drb1->rclk_w(1); @@ -610,6 +663,8 @@ void tandy2k_state::machine_start() program.install_ram(0x00000, ram_size - 1, ram); + m_char_ram.allocate(0x1000); + // register for state saving save_item(NAME(m_dma_mux)); save_item(NAME(m_kbdclk)); @@ -655,15 +710,17 @@ static MACHINE_CONFIG_START( tandy2k, tandy2k_state ) MCFG_CRT9007_CURS_CALLBACK(DEVWRITELINE(CRT9021B_TAG, crt9021_t, cursor_w)) MCFG_CRT9007_DRB_CALLBACK(WRITELINE(tandy2k_state, vpac_drb_w)) MCFG_CRT9007_WBEN_CALLBACK(WRITELINE(tandy2k_state, vpac_wben_w)) - MCFG_CRT9007_CBLANK_CALLBACK(DEVWRITELINE(CRT9021B_TAG, crt9021_t, retbl_w)) - MCFG_CRT9007_SLG_CALLBACK(DEVWRITELINE(CRT9021B_TAG, crt9021_t, slg_w)) - MCFG_CRT9007_SLD_CALLBACK(DEVWRITELINE(CRT9021B_TAG, crt9021_t, sld_w)) + MCFG_CRT9007_CBLANK_CALLBACK(WRITELINE(tandy2k_state, vpac_cblank_w)) + MCFG_CRT9007_SLG_CALLBACK(WRITELINE(tandy2k_state, vpac_slg_w)) + MCFG_CRT9007_SLD_CALLBACK(WRITELINE(tandy2k_state, vpac_sld_w)) MCFG_VIDEO_SET_SCREEN(SCREEN_TAG) MCFG_DEVICE_ADD(CRT9212_0_TAG, CRT9212, 0) - MCFG_CRT9212_DOUT_CALLBACK(DEVWRITE8(CRT9021B_TAG, crt9021_t, write)) + MCFG_CRT9212_WEN2_VCC() + MCFG_CRT9212_DOUT_CALLBACK(WRITE8(tandy2k_state, vidla_w)) MCFG_DEVICE_ADD(CRT9212_1_TAG, CRT9212, 0) + MCFG_CRT9212_WEN2_VCC() MCFG_CRT9212_DOUT_CALLBACK(WRITE8(tandy2k_state, drb_attr_w)) MCFG_DEVICE_ADD(CRT9021B_TAG, CRT9021, XTAL_16MHz*28/16) diff --git a/src/mess/includes/tandy2k.h b/src/mess/includes/tandy2k.h index 4e8c07b969f..1e36fa6dda9 100644 --- a/src/mess/includes/tandy2k.h +++ b/src/mess/includes/tandy2k.h @@ -3,12 +3,12 @@ #ifndef __TANDY2K__ #define __TANDY2K__ - #include "emu.h" +#include "bus/centronics/ctronics.h" +#include "bus/rs232/rs232.h" #include "cpu/i86/i186.h" #include "cpu/mcs48/mcs48.h" #include "imagedev/harddriv.h" -#include "bus/centronics/ctronics.h" #include "machine/i8255.h" #include "machine/i8251.h" #include "machine/pit8253.h" @@ -61,10 +61,39 @@ public: m_ram(*this, RAM_TAG), m_floppy0(*this, I8272A_TAG ":0:525qd"), m_floppy1(*this, I8272A_TAG ":1:525qd"), + m_rs232(*this, RS232_TAG), m_kb(*this, TANDY2K_KEYBOARD_TAG), m_hires_ram(*this, "hires_ram"), m_char_ram(*this, "char_ram"), - m_kbdclk(0) + m_dma_mux(0), + m_kbdclk(0), + m_kbddat(0), + m_kbdin(0), + m_extclk(0), + m_rxrdy(0), + m_txrdy(0), + m_pb_sel(0), + m_vram_base(0), + m_vidouts(0), + m_clkspd(0), + m_clkcnt(0), + m_blc(0), + m_bkc(0), + m_cblank(0), + m_dblc(0), + m_dbkc(0), + m_dblank(0), + m_slg(0), + m_sld(0), + m_cgra(0), + m_vidla(0), + m_outspkr(0), + m_spkrdata(0), + m_centronics_ack(0), + m_centronics_fault(0), + m_centronics_select(0), + m_centronics_perror(0), + m_centronics_busy(0) { } @@ -86,15 +115,18 @@ public: required_device m_ram; required_device m_floppy0; required_device m_floppy1; + required_device m_rs232; required_device m_kb; required_shared_ptr m_hires_ram; - required_shared_ptr m_char_ram; + optional_shared_ptr m_char_ram; virtual void machine_start(); void speaker_update(); void dma_request(int line, int state); + DECLARE_READ8_MEMBER( char_ram_r ); + DECLARE_WRITE8_MEMBER( char_ram_w ); DECLARE_READ8_MEMBER( videoram_r ); DECLARE_READ8_MEMBER( enable_r ); DECLARE_WRITE8_MEMBER( enable_w ); @@ -115,14 +147,30 @@ public: DECLARE_WRITE_LINE_MEMBER( vpac_vlt_w ); DECLARE_WRITE_LINE_MEMBER( vpac_drb_w ); DECLARE_WRITE_LINE_MEMBER( vpac_wben_w ); + DECLARE_WRITE_LINE_MEMBER( vpac_cblank_w ); + DECLARE_WRITE_LINE_MEMBER( vpac_slg_w ); + DECLARE_WRITE_LINE_MEMBER( vpac_sld_w ); + DECLARE_WRITE8_MEMBER( vidla_w ); DECLARE_WRITE8_MEMBER( drb_attr_w ); DECLARE_WRITE_LINE_MEMBER( kbdclk_w ); DECLARE_WRITE_LINE_MEMBER( kbddat_w ); DECLARE_READ8_MEMBER( irq_callback ); DECLARE_WRITE_LINE_MEMBER( fdc_drq ); + DECLARE_WRITE_LINE_MEMBER(write_centronics_ack); + DECLARE_WRITE_LINE_MEMBER(write_centronics_busy); + DECLARE_WRITE_LINE_MEMBER(write_centronics_perror); + DECLARE_WRITE_LINE_MEMBER(write_centronics_select); + DECLARE_WRITE_LINE_MEMBER(write_centronics_fault); CRT9021_DRAW_CHARACTER_MEMBER( vac_draw_character ); TIMER_DEVICE_CALLBACK_MEMBER( vidldsh_tick ); + enum + { + LPINEN = 0, + KBDINEN, + PORTINEN + }; + /* DMA state */ UINT8 m_dma_mux; @@ -144,6 +192,16 @@ public: int m_vidouts; int m_clkspd; int m_clkcnt; + int m_blc; + int m_bkc; + int m_cblank; + UINT8 m_dblc; + UINT8 m_dbkc; + UINT8 m_dblank; + int m_slg; + int m_sld; + UINT8 m_cgra; + UINT8 m_vidla; /* sound state */ int m_outspkr; @@ -154,12 +212,6 @@ public: int m_centronics_select; int m_centronics_perror; int m_centronics_busy; - - DECLARE_WRITE_LINE_MEMBER(write_centronics_ack); - DECLARE_WRITE_LINE_MEMBER(write_centronics_busy); - DECLARE_WRITE_LINE_MEMBER(write_centronics_perror); - DECLARE_WRITE_LINE_MEMBER(write_centronics_select); - DECLARE_WRITE_LINE_MEMBER(write_centronics_fault); }; #endif