summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--scripts/src/machine.lua12
-rw-r--r--scripts/target/mame/arcade.lua1
-rw-r--r--scripts/target/mame/mess.lua1
-rw-r--r--src/devices/machine/am2847.cpp169
-rw-r--r--src/devices/machine/am2847.h134
-rw-r--r--src/emu/drivers/xtal.h1
-rw-r--r--src/mame/drivers/hazeltin.cpp256
-rw-r--r--src/mame/drivers/ie15.cpp5
8 files changed, 561 insertions, 18 deletions
diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua
index f1cecc70ec8..028a8aba135 100644
--- a/scripts/src/machine.lua
+++ b/scripts/src/machine.lua
@@ -453,6 +453,18 @@ end
---------------------------------------------------
--
+--@src/devices/machine/am2847.h,MACHINES["AM2847"] = true
+---------------------------------------------------
+
+if (MACHINES["AM2847"]~=null) then
+ files {
+ MAME_DIR .. "src/devices/machine/am2847.cpp",
+ MAME_DIR .. "src/devices/machine/am2847.h",
+ }
+end
+
+---------------------------------------------------
+--
--@src/devices/machine/am53cf96.h,MACHINES["AM53CF96"] = true
---------------------------------------------------
diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua
index 0116a073a0e..55f33df751f 100644
--- a/scripts/target/mame/arcade.lua
+++ b/scripts/target/mame/arcade.lua
@@ -368,6 +368,7 @@ MACHINES["ADC083X"] = true
MACHINES["ADC1038"] = true
MACHINES["ADC1213X"] = true
MACHINES["AICARTC"] = true
+--MACHINES["AM2847"] = true
MACHINES["AM53CF96"] = true
MACHINES["AM9517A"] = true
MACHINES["AMIGAFDC"] = true
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua
index 4bfdc58da40..2685bfaec98 100644
--- a/scripts/target/mame/mess.lua
+++ b/scripts/target/mame/mess.lua
@@ -374,6 +374,7 @@ MACHINES["ADC083X"] = true
MACHINES["ADC1038"] = true
MACHINES["ADC1213X"] = true
MACHINES["AICARTC"] = true
+MACHINES["AM2847"] = true
MACHINES["AM53CF96"] = true
MACHINES["AM9517A"] = true
MACHINES["AMIGAFDC"] = true
diff --git a/src/devices/machine/am2847.cpp b/src/devices/machine/am2847.cpp
new file mode 100644
index 00000000000..ef8954c859e
--- /dev/null
+++ b/src/devices/machine/am2847.cpp
@@ -0,0 +1,169 @@
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz
+/**********************************************************************
+
+ AMD Am2847/Am2896 Quad 80/96-Bit Static Shift Registers
+
+**********************************************************************/
+
+#include "am2847.h"
+
+const device_type AM2847 = &device_creator<am2847_device>;
+const device_type AM2849 = &device_creator<am2849_device>;
+const device_type TMS3409 = &device_creator<tms3409_device>;
+
+am2847_base_device::am2847_base_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, size_t size)
+ : device_t(mconfig, type, name, tag, owner, clock, shortname, __FILE__)
+ , m_in(0)
+ , m_out(0)
+ , m_rc(0)
+ , m_cp(0)
+ , m_buffer_size(size)
+{
+}
+
+am2847_device::am2847_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : am2847_base_device(mconfig, AM2847, "AMD Am2847 80-bit Static Shift Register", tag, owner, clock, "am2847", 5)
+{
+}
+
+am2849_device::am2849_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : am2847_base_device(mconfig, AM2849, "AMD Am2849 96-bit Static Shift Register", tag, owner, clock, "am2847", 6)
+{
+}
+
+tms3409_device::tms3409_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : am2847_base_device(mconfig, TMS3409, "TI TMS3409 80-bit Static Shift Register", tag, owner, clock, "am2847", 5)
+{
+}
+
+void am2847_base_device::device_start()
+{
+ for (int bit = 0; bit < 4; bit++)
+ {
+ m_shifters[bit].alloc(m_buffer_size);
+ }
+
+ init();
+
+ save_item(NAME(m_in));
+ save_item(NAME(m_out));
+}
+
+void am2847_base_device::device_reset()
+{
+ init();
+}
+
+void am2847_base_device::init()
+{
+ m_in = 0;
+ m_out = 0;
+}
+
+WRITE_LINE_MEMBER( am2847_base_device::in_a_w )
+{
+ m_in &= ~0x01;
+ m_in |= state;
+}
+
+WRITE_LINE_MEMBER( am2847_base_device::in_b_w )
+{
+ m_in &= ~0x02;
+ m_in |= state << 1;
+}
+
+WRITE_LINE_MEMBER( am2847_base_device::in_c_w )
+{
+ m_in &= ~0x04;
+ m_in |= state << 2;
+}
+
+WRITE_LINE_MEMBER( am2847_base_device::in_d_w )
+{
+ m_in &= ~0x08;
+ m_in |= state << 3;
+}
+
+void am2847_base_device::in_w(uint8_t data)
+{
+ m_in = data & 0x0f;
+}
+
+WRITE_LINE_MEMBER( am2847_base_device::rc_a_w )
+{
+ m_rc &= ~0x01;
+ m_rc |= state;
+}
+
+WRITE_LINE_MEMBER( am2847_base_device::rc_b_w )
+{
+ m_rc &= ~0x02;
+ m_rc |= state << 1;
+}
+
+WRITE_LINE_MEMBER( am2847_base_device::rc_c_w )
+{
+ m_rc &= ~0x04;
+ m_rc |= state << 2;
+}
+
+WRITE_LINE_MEMBER( am2847_base_device::rc_d_w )
+{
+ m_rc &= ~0x08;
+ m_rc |= state << 3;
+}
+
+void am2847_base_device::rc_w(uint8_t data)
+{
+ m_rc = data & 0x0f;
+}
+
+WRITE_LINE_MEMBER( am2847_base_device::cp_w )
+{
+ if (m_cp != state && state != 0)
+ {
+ shift();
+ }
+ m_cp = state;
+}
+
+void am2847_base_device::shift()
+{
+ for (int bit = 0; bit < 4; bit++)
+ {
+ m_out &= ~(1 << bit);
+ m_out |= m_shifters[bit].shift(BIT(m_rc, bit) != 0, BIT(m_in, bit)) << bit;
+ }
+}
+
+void am2847_base_device::shifter::alloc(size_t size)
+{
+ m_buffer_size = size;
+ m_buffer = std::make_unique<uint16_t[]>(m_buffer_size);
+ init();
+}
+
+void am2847_base_device::shifter::init()
+{
+ memset(&m_buffer[0], 0, m_buffer_size * 2);
+}
+
+int am2847_base_device::shifter::shift(bool recycle, int in)
+{
+ int out = m_buffer[m_buffer_size-1] & 1;
+ for (int word = m_buffer_size - 1; word >= 1; word--)
+ {
+ m_buffer[word] >>= 1;
+ m_buffer[word] |= (m_buffer[word - 1] & 1) << 15;
+ }
+
+ m_buffer[0] >>= 1;
+
+ if (recycle)
+ m_buffer[0] |= out << 15;
+ else
+ m_buffer[0] |= (in & 1) << 15;
+
+ return out;
+}
diff --git a/src/devices/machine/am2847.h b/src/devices/machine/am2847.h
new file mode 100644
index 00000000000..a019a733537
--- /dev/null
+++ b/src/devices/machine/am2847.h
@@ -0,0 +1,134 @@
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz
+/**********************************************************************
+
+ AMD Am2847/Am2896 Quad 80/96-Bit Static Shift Registers
+
+ Pin-compatible with:
+ * 2532B
+ * TMS3120
+ * TMS3409
+ * MK1007
+ * 3347
+
+***********************************************************************
+
+ Connection Diagram:
+ ___ ___
+ OUT A 1 |* u | 16 Vss
+ RC A 2 | | 15 IN D
+ IN A 3 | | 14 RC D
+ OUT B 4 | | 13 OUT D
+ RC B 5 | | 12 Vgg
+ IN B 6 | | 11 CP
+ OUT C 7 | | 10 IN C
+ Vdd 8 |_______| 9 RC C
+
+ Logic Symbol:
+
+ 2 5 9 14
+ | | | |
+ _____|______|______|______|_____
+ | RC A RC B RC C RC D |
+ 3 ---| IN A OUT A |--- 1
+ 6 ---| IN A OUT B |--- 4
+ 10 ---| IN A OUT C |--- 7
+ 15 ---| IN A OUT D |--- 13
+ 11 ---| CP |
+ |________________________________|
+
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef AM2847_H
+#define AM2847_H
+
+#include "emu.h"
+
+#define MCFG_AM2847_ADD(_tag) \
+ MCFG_DEVICE_ADD(_tag, AM2847, 0)
+
+#define MCFG_AM2849_ADD(_tag) \
+ MCFG_DEVICE_ADD(_tag, AM2849, 0)
+
+#define MCFG_TMS3409_ADD(_tag) \
+ MCFG_DEVICE_ADD(_tag, TMS3409, 0)
+
+class am2847_base_device : public device_t
+{
+public:
+ am2847_base_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, size_t size);
+
+ DECLARE_WRITE_LINE_MEMBER( in_a_w );
+ DECLARE_WRITE_LINE_MEMBER( in_b_w );
+ DECLARE_WRITE_LINE_MEMBER( in_c_w );
+ DECLARE_WRITE_LINE_MEMBER( in_d_w );
+ void in_w(uint8_t data); // Or if you prefer...
+
+ DECLARE_WRITE_LINE_MEMBER( rc_a_w );
+ DECLARE_WRITE_LINE_MEMBER( rc_b_w );
+ DECLARE_WRITE_LINE_MEMBER( rc_c_w );
+ DECLARE_WRITE_LINE_MEMBER( rc_d_w );
+ void rc_w(uint8_t data); // Or if you prefer...
+
+ DECLARE_WRITE_LINE_MEMBER( cp_w );
+
+ uint8_t out_r() const { return m_out; }
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ void init();
+ void shift();
+
+ class shifter
+ {
+ public:
+ shifter() : m_buffer_size(0) { }
+ void alloc(size_t size);
+ void init();
+ int shift(bool recycle, int in);
+ protected:
+ std::unique_ptr<uint16_t[]> m_buffer;
+ size_t m_buffer_size;
+ };
+
+ shifter m_shifters[4];
+ uint8_t m_in;
+ uint8_t m_out;
+ uint8_t m_rc;
+ int m_cp;
+
+ const size_t m_buffer_size;
+};
+
+class am2847_device : public am2847_base_device
+{
+public:
+ // construction/destruction
+ am2847_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+};
+
+class am2849_device : public am2847_base_device
+{
+public:
+ // construction/destruction
+ am2849_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+};
+
+class tms3409_device : public am2847_base_device
+{
+public:
+ // construction/destruction
+ tms3409_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+};
+
+// device type definition
+extern const device_type AM2847;
+extern const device_type AM2849;
+extern const device_type TMS3409;
+
+#endif // AM2847_H \ No newline at end of file
diff --git a/src/emu/drivers/xtal.h b/src/emu/drivers/xtal.h
index b868219e45d..a4f00cd82f4 100644
--- a/src/emu/drivers/xtal.h
+++ b/src/emu/drivers/xtal.h
@@ -199,6 +199,7 @@ enum
XTAL_32_22MHz = 32220000, /* Typically used on 90's Data East PCBs (close to 9x NTSC subcarrier which is 32.215905Mhz*/
XTAL_32_5304MHz = 32530400, /* Seta 2 */
XTAL_33MHz = 33000000, /* Sega Model 3 video board */
+ XTAL_33_264MHz = 33264000, /* Hazeltine 1500 terminal */
XTAL_33_333MHz = 33333000, /* Sega Model 3 CPU board, Vegas */
XTAL_33_833MHz = 33833000,
XTAL_33_8688MHz = 33868800, /* Usually used to drive 90's Yamaha OPL/FM chips with /2 divider */
diff --git a/src/mame/drivers/hazeltin.cpp b/src/mame/drivers/hazeltin.cpp
index 3af908590af..e1282c84773 100644
--- a/src/mame/drivers/hazeltin.cpp
+++ b/src/mame/drivers/hazeltin.cpp
@@ -20,23 +20,49 @@ References:
#include "machine/ay31015.h"
#include "machine/kb3600.h"
#include "machine/com8116.h"
-#include "machine/keyboard.h"
+#include "machine/am2847.h"
-#define KEYBOARD_TAG "keyboard"
#define CPU_TAG "maincpu"
#define UART_TAG "uart"
#define BAUDGEN_TAG "baudgen"
#define KBDC_TAG "ay53600"
-#define BAUDPORT_TAG "BAUD"
-#define MISCPORT_TAG "MISC"
-#define MISCKEYS_TAG "MISC_KEYS"
+#define CHARRAM_TAG "chrram"
+#define CHARROM_TAG "chargen"
+#define BAUDPORT_TAG "baud"
+#define MISCPORT_TAG "misc"
+#define MISCKEYS_TAG "misc_keys"
+#define SCREEN_TAG "screen"
+#define TMS3409A_TAG "u67"
+#define TMS3409B_TAG "u57"
+
+// Number of cycles to burn when fetching the next row of characters into the line buffer:
+// CPU clock is 18MHz / 9
+// Dot clock is 33.264MHz / 2
+// 9 dots per character
+// 80 visible characters per line
+// Total duration of fetch: 1440 33.264MHz clock cycles
+//
+// 2*9*80 1 1440 * XTAL_2MHz
+// -------------- divided by --------- = ---------------- = 86.5 main CPU cycles per line fetch
+// XTAL_33_264MHz XTAL_2MHz XTAL_33_264MHz
+#define LINE_FETCH_CYCLES (87)
#define SR2_FULL_DUPLEX (0x01)
#define SR2_UPPER_ONLY (0x08)
#define SR3_PB_RESET (0x04)
-#define KBD_STATUS_KBDR (0x01)
+#define KBD_STATUS_KBDR (0x01)
+#define KBD_STATUS_TV_INT (0x40)
+#define KBD_STATUS_TV_UB (0x80)
+
+#define SCREEN_HTOTAL (9*100)
+#define SCREEN_HDISP (9*80)
+#define SCREEN_HSTART (9*5)
+
+#define SCREEN_VTOTAL (28*11)
+#define SCREEN_VDISP (24*11)
+#define SCREEN_VSTART (0)
class hazl1500_state : public driver_device
{
@@ -49,11 +75,25 @@ public:
, m_baud_dips(*this, BAUDPORT_TAG)
, m_misc_dips(*this, MISCPORT_TAG)
, m_kbd_misc_keys(*this, MISCKEYS_TAG)
+ , m_char_ram(*this, CHARRAM_TAG)
+ , m_char_rom(*this, CHARROM_TAG)
+ , m_line_buffer_lsb(*this, TMS3409A_TAG)
+ , m_line_buffer_msb(*this, TMS3409B_TAG)
+ , m_screen(*this, SCREEN_TAG)
+ , m_hblank_timer(nullptr)
+ , m_scanline_timer(nullptr)
, m_status_reg_3(0)
, m_kbd_status_latch(0)
+ , m_refresh_address(0)
+ , m_vpos(0)
+ , m_hblank(false)
+ , m_vblank(false)
{
}
+ //m_maincpu->adjust_icount(-14);
+
+ virtual void machine_start() override;
virtual void machine_reset() override;
uint32_t screen_update_hazl1500(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
@@ -64,13 +104,27 @@ public:
DECLARE_READ8_MEMBER(status_reg_2_r);
DECLARE_WRITE8_MEMBER(status_reg_3_w);
+ DECLARE_READ8_MEMBER(uart_r);
+ DECLARE_WRITE8_MEMBER(uart_w);
+
DECLARE_READ8_MEMBER(kbd_status_latch_r);
DECLARE_READ8_MEMBER(kbd_encoder_r);
DECLARE_READ_LINE_MEMBER(ay3600_shift_r);
DECLARE_READ_LINE_MEMBER(ay3600_control_r);
DECLARE_WRITE_LINE_MEMBER(ay3600_data_ready_w);
+ DECLARE_WRITE8_MEMBER(refresh_address_w);
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+
+ static const device_timer_id TIMER_HBLANK = 0;
+ static const device_timer_id TIMER_SCANLINE = 1;
+
private:
+ void check_tv_interrupt();
+ void update_tv_unblank();
+ void scanline_tick();
+ void draw_scanline(uint32_t *pix);
+
required_device<cpu_device> m_maincpu;
required_device<ay31015_device> m_uart;
required_device<ay3600_device> m_kbdc;
@@ -78,16 +132,60 @@ private:
required_ioport m_misc_dips;
required_ioport m_kbd_misc_keys;
+ required_shared_ptr<uint8_t> m_char_ram;
+ required_region_ptr<uint8_t> m_char_rom;
+ required_device<tms3409_device> m_line_buffer_lsb;
+ required_device<tms3409_device> m_line_buffer_msb;
+ required_device<screen_device> m_screen;
+
+ std::unique_ptr<uint32_t[]> m_screen_pixbuf;
+
+ emu_timer *m_hblank_timer;
+ emu_timer *m_scanline_timer;
+
uint8_t m_status_reg_3;
uint8_t m_kbd_status_latch;
+
+ uint8_t m_refresh_address;
+ uint16_t m_vpos;
+ bool m_hblank;
+ bool m_vblank;
};
+void hazl1500_state::machine_start()
+{
+ m_hblank_timer = timer_alloc(TIMER_HBLANK);
+ m_hblank_timer->adjust(attotime::never);
+
+ m_scanline_timer = timer_alloc(TIMER_SCANLINE);
+ m_scanline_timer->adjust(attotime::never);
+
+ m_screen_pixbuf = std::make_unique<uint32_t[]>(SCREEN_HTOTAL * SCREEN_VTOTAL);
+
+ save_item(NAME(m_status_reg_3));
+ save_item(NAME(m_kbd_status_latch));
+ save_item(NAME(m_refresh_address));
+ save_item(NAME(m_vpos));
+ save_item(NAME(m_hblank));
+ save_item(NAME(m_vblank));
+}
+
void hazl1500_state::machine_reset()
{
m_status_reg_3 = 0;
m_kbd_status_latch = 0;
+
+ m_refresh_address = 0;
+ m_vpos = m_screen->vpos();
+ m_vblank = (m_vpos >= SCREEN_VDISP);
+ if (!m_vblank)
+ m_kbd_status_latch |= KBD_STATUS_TV_UB;
+ m_hblank = true;
+ m_hblank_timer->adjust(m_screen->time_until_pos(m_vpos, SCREEN_HSTART));
+ m_scanline_timer->adjust(m_screen->time_until_pos(m_vpos + 1, 0));
}
+
WRITE_LINE_MEMBER( hazl1500_state::com5016_fr_w )
{
m_uart->rx_process();
@@ -96,6 +194,7 @@ WRITE_LINE_MEMBER( hazl1500_state::com5016_fr_w )
uint32_t hazl1500_state::screen_update_hazl1500(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
+ memcpy(&bitmap.pix32(0), &m_screen_pixbuf[0], sizeof(uint32_t) * SCREEN_HTOTAL * SCREEN_VTOTAL);
return 0;
}
@@ -122,6 +221,16 @@ WRITE8_MEMBER( hazl1500_state::status_reg_3_w )
m_status_reg_3 = data;
}
+READ8_MEMBER( hazl1500_state::uart_r )
+{
+ return m_uart->get_received_data();
+}
+
+WRITE8_MEMBER( hazl1500_state::uart_w )
+{
+ m_uart->set_transmit_data(data);
+}
+
READ8_MEMBER( hazl1500_state::kbd_status_latch_r )
{
return m_kbd_status_latch;
@@ -161,18 +270,131 @@ WRITE_LINE_MEMBER(hazl1500_state::ay3600_data_ready_w)
m_kbd_status_latch &= ~KBD_STATUS_KBDR;
}
+void hazl1500_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ switch(id)
+ {
+ case TIMER_HBLANK:
+ if (m_hblank)
+ {
+ m_hblank_timer->adjust(m_screen->time_until_pos(m_vpos, SCREEN_HSTART + SCREEN_HDISP));
+ }
+ else
+ {
+ m_hblank_timer->adjust(m_screen->time_until_pos((m_vpos + 1) % SCREEN_VTOTAL, SCREEN_HSTART));
+ }
+ m_hblank ^= 1;
+ break;
+
+ case TIMER_SCANLINE:
+ {
+ scanline_tick();
+ break;
+ }
+ }
+}
+
+WRITE8_MEMBER(hazl1500_state::refresh_address_w)
+{
+ m_refresh_address = data;
+}
+
+void hazl1500_state::check_tv_interrupt()
+{
+ uint8_t char_row = m_vpos % 11;
+ bool bit_match = char_row == 2 || char_row == 3;
+ bool no_vblank = !m_vblank;
+ bool tv_interrupt = bit_match && no_vblank;
+
+ m_kbd_status_latch &= ~KBD_STATUS_TV_INT;
+ m_kbd_status_latch |= tv_interrupt ? KBD_STATUS_TV_INT : 0;
+
+ m_maincpu->set_input_line(INPUT_LINE_IRQ0, tv_interrupt ? ASSERT_LINE : CLEAR_LINE);
+}
+
+void hazl1500_state::update_tv_unblank()
+{
+ if (!m_vblank)
+ {
+ m_kbd_status_latch |= KBD_STATUS_TV_UB;
+ }
+ else
+ {
+ m_kbd_status_latch &= ~KBD_STATUS_TV_UB;
+ }
+}
+
+void hazl1500_state::scanline_tick()
+{
+ uint16_t old_vpos = m_vpos;
+ m_vpos = (m_vpos + 1) % SCREEN_VTOTAL;
+ m_vblank = (m_vpos >= SCREEN_VDISP);
+
+ check_tv_interrupt();
+ update_tv_unblank();
+
+ draw_scanline(&m_screen_pixbuf[old_vpos * SCREEN_HTOTAL + SCREEN_HSTART]);
+
+ m_scanline_timer->adjust(m_screen->time_until_pos((m_vpos + 1) % SCREEN_VTOTAL, 0));
+}
+
+void hazl1500_state::draw_scanline(uint32_t *pix)
+{
+ static const uint32_t palette[4] = { 0xff000000, 0xff006000, 0xff000000, 0xff00c000 };
+
+ uint16_t ram_offset = m_refresh_address << 4;
+ uint8_t char_row = m_vpos % 11;
+ uint8_t recycle = (char_row != 10 ? 0xff : 0x00);
+ m_line_buffer_lsb->rc_w(recycle & 0xf);
+ m_line_buffer_msb->rc_w(recycle >> 4);
+
+ if (recycle == 0)
+ m_maincpu->adjust_icount(-LINE_FETCH_CYCLES);
+
+ for (uint16_t x = 0; x < 80; x++)
+ {
+ uint8_t in = 0;
+ if (!m_vblank)
+ in = m_char_ram[ram_offset + x];
+
+ m_line_buffer_lsb->in_w(in & 0xf);
+ m_line_buffer_lsb->cp_w(1);
+ m_line_buffer_lsb->cp_w(0);
+
+ m_line_buffer_msb->in_w(in >> 4);
+ m_line_buffer_msb->cp_w(1);
+ m_line_buffer_msb->cp_w(0);
+
+ const uint8_t chr = (m_line_buffer_msb->out_r() << 4) | m_line_buffer_lsb->out_r();
+ const uint16_t chr_addr = (chr & 0x7f) << 4;
+ const uint8_t gfx = m_char_rom[chr_addr | char_row];
+ const uint8_t bright = (chr & 0x80) >> 6;
+
+ *pix++ = palette[0];
+ *pix++ = palette[BIT(gfx, 6) | bright];
+ *pix++ = palette[BIT(gfx, 5) | bright];
+ *pix++ = palette[BIT(gfx, 4) | bright];
+ *pix++ = palette[BIT(gfx, 3) | bright];
+ *pix++ = palette[BIT(gfx, 2) | bright];
+ *pix++ = palette[BIT(gfx, 1) | bright];
+ *pix++ = palette[BIT(gfx, 0) | bright];
+ *pix++ = palette[0];
+ }
+}
+
static ADDRESS_MAP_START(hazl1500_mem, AS_PROGRAM, 8, hazl1500_state)
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x0000, 0x07ff) AM_ROM
- AM_RANGE(0x3000, 0x377f) AM_RAM AM_SHARE("char_ram")
+ AM_RANGE(0x3000, 0x377f) AM_RAM AM_SHARE(CHARRAM_TAG)
AM_RANGE(0x3780, 0x37ff) AM_RAM
ADDRESS_MAP_END
static ADDRESS_MAP_START(hazl1500_io, AS_IO, 8, hazl1500_state)
ADDRESS_MAP_GLOBAL_MASK(0xff)
AM_RANGE(0x7f, 0x7f) AM_READWRITE(status_reg_2_r, status_reg_3_w)
+ AM_RANGE(0xbf, 0xbf) AM_READWRITE(uart_r, uart_w)
AM_RANGE(0xdf, 0xdf) AM_READ(kbd_encoder_r)
- AM_RANGE(0xef, 0xef) AM_READ(system_test_r)
+ AM_RANGE(0xef, 0xef) AM_READWRITE(system_test_r, refresh_address_w)
AM_RANGE(0xf7, 0xf7) AM_READ(kbd_status_latch_r)
ADDRESS_MAP_END
@@ -376,16 +598,17 @@ GFXDECODE_END
static MACHINE_CONFIG_START( hazl1500, hazl1500_state )
/* basic machine hardware */
- MCFG_CPU_ADD("maincpu",I8080, XTAL_1MHz) //unknown clock
+ MCFG_CPU_ADD(CPU_TAG, I8080, XTAL_18MHz/9) // 18MHz crystal on schematics, using an i8224 clock gen/driver IC
MCFG_CPU_PROGRAM_MAP(hazl1500_mem)
MCFG_CPU_IO_MAP(hazl1500_io)
+ MCFG_QUANTUM_PERFECT_CPU(CPU_TAG)
/* video hardware */
- MCFG_SCREEN_ADD("screen", RASTER)
- MCFG_SCREEN_REFRESH_RATE(60)
- MCFG_SCREEN_SIZE(640, 384)
- MCFG_SCREEN_VISIBLE_AREA(0, 640-1, 0, 384-1)
+ MCFG_SCREEN_ADD_MONOCHROME(SCREEN_TAG, RASTER, rgb_t::green())
MCFG_SCREEN_UPDATE_DRIVER(hazl1500_state, screen_update_hazl1500)
+ MCFG_SCREEN_RAW_PARAMS(XTAL_33_264MHz/2,
+ SCREEN_HTOTAL, SCREEN_HSTART, SCREEN_HSTART + SCREEN_HDISP,
+ SCREEN_VTOTAL, SCREEN_VSTART, SCREEN_VSTART + SCREEN_VDISP);
MCFG_PALETTE_ADD_MONOCHROME("palette")
MCFG_GFXDECODE_ADD("gfxdecode", "palette", hazl1500)
@@ -395,6 +618,9 @@ static MACHINE_CONFIG_START( hazl1500, hazl1500_state )
MCFG_DEVICE_ADD(UART_TAG, AY51013, 0)
+ MCFG_TMS3409_ADD(TMS3409A_TAG)
+ MCFG_TMS3409_ADD(TMS3409B_TAG)
+
/* keyboard controller */
MCFG_DEVICE_ADD(KBDC_TAG, AY3600, 0)
MCFG_AY3600_MATRIX_X0(IOPORT("X0"))
@@ -413,10 +639,10 @@ MACHINE_CONFIG_END
ROM_START( hazl1500 )
- ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF )
+ ROM_REGION( 0x10000, CPU_TAG, ROMREGION_ERASEFF )
ROM_LOAD( "h15s-00I-10-3.bin", 0x0000, 0x0800, CRC(a2015f72) SHA1(357cde517c3dcf693de580881add058c7b26dfaa))
- ROM_REGION( 0x800, "chargen", ROMREGION_ERASEFF )
+ ROM_REGION( 0x800, CHARROM_TAG, ROMREGION_ERASEFF )
ROM_LOAD( "u83_chr.bin", 0x0000, 0x0800, CRC(e0c6b734) SHA1(7c42947235c66c41059fd4384e09f4f3a17c9857))
ROM_END
diff --git a/src/mame/drivers/ie15.cpp b/src/mame/drivers/ie15.cpp
index fdef494af27..c9c0710bb51 100644
--- a/src/mame/drivers/ie15.cpp
+++ b/src/mame/drivers/ie15.cpp
@@ -106,7 +106,7 @@ public:
private:
TIMER_CALLBACK_MEMBER(ie15_beepoff);
void update_leds();
- uint32_t draw_scanline(uint32_t *p, uint16_t offset, uint8_t scanline);
+ void draw_scanline(uint32_t *p, uint16_t offset, uint8_t scanline);
std::unique_ptr<uint32_t[]> m_tmpbmp;
emu_timer *m_hblank_timer;
@@ -526,7 +526,7 @@ void ie15_state::video_start()
XXX 'dotted look' is caused by strobe at 2x pixel clock -- use HLSL for this.
*/
-uint32_t ie15_state::draw_scanline(uint32_t *p, uint16_t offset, uint8_t scanline)
+void ie15_state::draw_scanline(uint32_t *p, uint16_t offset, uint8_t scanline)
{
static const uint32_t palette[2] = { 0xff000000, 0xff00c000 };
@@ -571,7 +571,6 @@ uint32_t ie15_state::draw_scanline(uint32_t *p, uint16_t offset, uint8_t scanlin
*p++ = palette[0];
}
}
- return 0;
}
void ie15_state::update_leds()