hp48: Removed first_screen and eliminated redundant function-name prefixes now that MAME is C++, nw

This commit is contained in:
mooglyguy 2018-03-10 05:46:58 +01:00
parent 796bb71902
commit b688161290
3 changed files with 304 additions and 320 deletions

View File

@ -1262,10 +1262,10 @@ MACHINE_CONFIG_START(hp48_state::hp48_common)
/* cpu */
MCFG_CPU_ADD ( "maincpu", SATURN, 3937007 ) /* almost 4 MHz */
MCFG_CPU_PROGRAM_MAP ( hp48)
MCFG_SATURN_CONFIG( WRITE32(hp48_state, hp48_reg_out), READ32(hp48_state, hp48_reg_in),
WRITELINE(hp48_state, hp48_mem_reset), WRITE32(hp48_state, hp48_mem_config),
WRITE32(hp48_state, hp48_mem_unconfig), READ32(hp48_state, hp48_mem_id),
WRITE32(hp48_state, hp48_mem_crc), WRITELINE(hp48_state, hp48_rsi) )
MCFG_SATURN_CONFIG( WRITE32(hp48_state, reg_out), READ32(hp48_state, reg_in),
WRITELINE(hp48_state, mem_reset), WRITE32(hp48_state, mem_config),
WRITE32(hp48_state, mem_unconfig), READ32(hp48_state, mem_id),
WRITE32(hp48_state, mem_crc), WRITELINE(hp48_state, rsi) )
/* memory */
MCFG_NVRAM_ADD_0FILL("nvram")

View File

@ -13,6 +13,7 @@
#pragma once
#include "sound/dac.h"
#include "screen.h"
/* model */
typedef enum {
@ -50,10 +51,72 @@ class hp48_state : public driver_device
{
public:
hp48_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_dac(*this, "dac"),
m_palette(*this, "palette") { }
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_dac(*this, "dac")
, m_palette(*this, "palette")
, m_screen(*this, "screen") {}
virtual void machine_reset() override;
void base_machine_start(hp48_models model);
DECLARE_DRIVER_INIT(hp48);
DECLARE_PALETTE_INIT(hp48);
DECLARE_MACHINE_START(hp49g);
DECLARE_MACHINE_START(hp48gx);
DECLARE_MACHINE_START(hp48g);
DECLARE_MACHINE_START(hp48gp);
DECLARE_MACHINE_START(hp48sx);
DECLARE_MACHINE_START(hp48s);
uint32_t screen_update_hp48(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
DECLARE_WRITE8_MEMBER(io_w);
DECLARE_READ8_MEMBER(io_r);
DECLARE_READ8_MEMBER(bank_r);
DECLARE_WRITE8_MEMBER(hp49_bank_w);
TIMER_CALLBACK_MEMBER(rs232_byte_recv_cb);
TIMER_CALLBACK_MEMBER(rs232_byte_sent_cb);
TIMER_CALLBACK_MEMBER(kbd_cb);
TIMER_CALLBACK_MEMBER(timer1_cb);
TIMER_CALLBACK_MEMBER(timer2_cb);
void update_annunciators();
void apply_modules();
void pulse_irq(int irq_line);
void rs232_start_recv_byte(uint8_t data);
void rs232_send_byte();
int get_in();
void update_kdn();
void reset_modules();
void decode_nibble(uint8_t* dst, uint8_t* src, int size);
void encode_nibble(uint8_t* dst, uint8_t* src, int size);
/* memory controller */
DECLARE_WRITE_LINE_MEMBER(mem_reset);
DECLARE_WRITE32_MEMBER(mem_config);
DECLARE_WRITE32_MEMBER(mem_unconfig);
DECLARE_READ32_MEMBER(mem_id);
/* CRC computation */
DECLARE_WRITE32_MEMBER(mem_crc);
/* IN/OUT registers */
DECLARE_READ32_MEMBER(reg_in);
DECLARE_WRITE32_MEMBER(reg_out);
/* keyboard interrupt system */
DECLARE_WRITE_LINE_MEMBER(rsi);
void hp48_common(machine_config &config);
void hp48s(machine_config &config);
void hp48gp(machine_config &config);
void hp48sx(machine_config &config);
void hp48g(machine_config &config);
void hp48gx(machine_config &config);
void hp49g(machine_config &config);
void hp48(address_map &map);
required_device<cpu_device> m_maincpu;
required_device<dac_bit_interface> m_dac;
required_device<palette_device> m_palette;
required_device<screen_device> m_screen;
uint8_t *m_videoram;
uint8_t m_io[64];
@ -87,64 +150,6 @@ public:
emu_timer *m_1st_timer;
emu_timer *m_2nd_timer;
emu_timer *m_kbd_timer;
DECLARE_DRIVER_INIT(hp48);
virtual void machine_reset() override;
DECLARE_PALETTE_INIT(hp48);
DECLARE_MACHINE_START(hp49g);
DECLARE_MACHINE_START(hp48gx);
DECLARE_MACHINE_START(hp48g);
DECLARE_MACHINE_START(hp48gp);
DECLARE_MACHINE_START(hp48sx);
DECLARE_MACHINE_START(hp48s);
uint32_t screen_update_hp48(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void hp48_machine_start(hp48_models model);
DECLARE_WRITE8_MEMBER(hp48_io_w);
DECLARE_READ8_MEMBER(hp48_io_r);
DECLARE_READ8_MEMBER(hp48_bank_r);
DECLARE_WRITE8_MEMBER(hp49_bank_w);
TIMER_CALLBACK_MEMBER(hp48_rs232_byte_recv_cb);
TIMER_CALLBACK_MEMBER(hp48_rs232_byte_sent_cb);
TIMER_CALLBACK_MEMBER(hp48_kbd_cb);
TIMER_CALLBACK_MEMBER(hp48_timer1_cb);
TIMER_CALLBACK_MEMBER(hp48_timer2_cb);
void hp48_update_annunciators();
void hp48_apply_modules();
required_device<cpu_device> m_maincpu;
required_device<dac_bit_interface> m_dac;
required_device<palette_device> m_palette;
void hp48_pulse_irq( int irq_line);
void hp48_rs232_start_recv_byte( uint8_t data );
void hp48_rs232_send_byte( );
int hp48_get_in( );
void hp48_update_kdn( );
void hp48_reset_modules( );
void hp48_decode_nibble( uint8_t* dst, uint8_t* src, int size );
void hp48_encode_nibble( uint8_t* dst, uint8_t* src, int size );
/* memory controller */
DECLARE_WRITE_LINE_MEMBER( hp48_mem_reset );
DECLARE_WRITE32_MEMBER( hp48_mem_config );
DECLARE_WRITE32_MEMBER( hp48_mem_unconfig );
DECLARE_READ32_MEMBER( hp48_mem_id );
/* CRC computation */
DECLARE_WRITE32_MEMBER( hp48_mem_crc );
/* IN/OUT registers */
DECLARE_READ32_MEMBER( hp48_reg_in );
DECLARE_WRITE32_MEMBER( hp48_reg_out );
/* keyboard interrupt system */
DECLARE_WRITE_LINE_MEMBER( hp48_rsi );
void hp48_common(machine_config &config);
void hp48s(machine_config &config);
void hp48gp(machine_config &config);
void hp48sx(machine_config &config);
void hp48g(machine_config &config);
void hp48gx(machine_config &config);
void hp49g(machine_config &config);
void hp48(address_map &map);
};
@ -218,8 +223,8 @@ protected:
// device-level overrides
virtual void device_start() override;
private:
void hp48_fill_port();
void hp48_unfill_port();
void fill_port();
void unfill_port();
int m_port; /* port index: 0 or 1 (for port 1 and 2) */
int m_module; /* memory module where the port is visible */

View File

@ -66,7 +66,7 @@ static const uint8_t hp48_module_addr_id[6] = { 0x19, 0xf4, 0xf6, 0xf8, 0xf2, 0x
FUNCTIONS
***************************************************************************/
void hp48_state::hp48_pulse_irq( int irq_line)
void hp48_state::pulse_irq(int irq_line)
{
m_maincpu->set_input_line(irq_line, ASSERT_LINE);
m_maincpu->set_input_line(irq_line, CLEAR_LINE);
@ -78,10 +78,9 @@ void hp48_state::hp48_pulse_irq( int irq_line)
#define RS232_DELAY attotime::from_usec(300)
/* end of receive event */
TIMER_CALLBACK_MEMBER(hp48_state::hp48_rs232_byte_recv_cb)
TIMER_CALLBACK_MEMBER(hp48_state::rs232_byte_recv_cb)
{
LOG_SERIAL(( "%f hp48_rs232_byte_recv_cb: end of receive, data=%02x\n",
machine().time().as_double(), param ));
LOG_SERIAL(("%f hp48_state::rs232_byte_recv_cb: end of receive, data=%02x\n", machine().time().as_double(), param));
m_io[0x14] = param & 0xf; /* receive zone */
m_io[0x15] = param >> 4;
@ -91,44 +90,42 @@ TIMER_CALLBACK_MEMBER(hp48_state::hp48_rs232_byte_recv_cb)
/* interrupt */
if (m_io[0x10] & 2)
{
hp48_pulse_irq( SATURN_IRQ_LINE );
pulse_irq(SATURN_IRQ_LINE);
}
}
/* outside world initiates a receive event */
void hp48_state::hp48_rs232_start_recv_byte( uint8_t data )
void hp48_state::rs232_start_recv_byte(uint8_t data)
{
LOG_SERIAL(( "%f hp48_rs232_start_recv_byte: start receiving, data=%02x\n",
machine().time().as_double(), data ));
LOG_SERIAL(("%f hp48_state::rs232_start_recv_byte: start receiving, data=%02x\n", machine().time().as_double(), data));
m_io[0x11] |= 2; /* set byte receiving */
/* interrupt */
if (m_io[0x10] & 1)
{
hp48_pulse_irq( SATURN_IRQ_LINE );
pulse_irq(SATURN_IRQ_LINE);
}
/* schedule end of reception */
machine().scheduler().timer_set( RS232_DELAY, timer_expired_delegate(FUNC(hp48_state::hp48_rs232_byte_recv_cb),this), data);
machine().scheduler().timer_set(RS232_DELAY, timer_expired_delegate(FUNC(hp48_state::rs232_byte_recv_cb),this), data);
}
/* end of send event */
TIMER_CALLBACK_MEMBER(hp48_state::hp48_rs232_byte_sent_cb)
TIMER_CALLBACK_MEMBER(hp48_state::rs232_byte_sent_cb)
{
//device_image_interface *xmodem = dynamic_cast<device_image_interface *>(machine().device("rs232_x"));
//device_image_interface *kermit = dynamic_cast<device_image_interface *>(machine().device("rs232_k"));
LOG_SERIAL(( "%f hp48_rs232_byte_sent_cb: end of send, data=%02x\n",
machine().time().as_double(), param ));
LOG_SERIAL(("%f hp48_state::rs232_byte_sent_cb: end of send, data=%02x\n", machine().time().as_double(), param));
m_io[0x12] &= ~3; /* clear byte sending and buffer full */
/* interrupt */
if (m_io[0x10] & 4)
{
hp48_pulse_irq( SATURN_IRQ_LINE );
pulse_irq(SATURN_IRQ_LINE);
}
/* protocol action */
@ -137,18 +134,17 @@ TIMER_CALLBACK_MEMBER(hp48_state::hp48_rs232_byte_sent_cb)
}
/* CPU initiates a send event */
void hp48_state::hp48_rs232_send_byte( )
void hp48_state::rs232_send_byte()
{
uint8_t data = HP48_IO_8(0x16); /* byte to send */
LOG_SERIAL(( "%s %f hp48_rs232_send_byte: start sending, data=%02x\n",
machine().describe_context(), machine().time().as_double(), data ));
LOG_SERIAL(("%s %f hp48_state::rs232_send_byte: start sending, data=%02x\n", machine().describe_context(), machine().time().as_double(), data));
/* set byte sending and send buffer full */
m_io[0x12] |= 3;
/* schedule transmission */
machine().scheduler().timer_set( RS232_DELAY, timer_expired_delegate(FUNC(hp48_state::hp48_rs232_byte_sent_cb),this), data);
machine().scheduler().timer_set(RS232_DELAY, timer_expired_delegate(FUNC(hp48_state::rs232_byte_sent_cb),this), data);
}
@ -158,10 +154,9 @@ void hp48_state::hp48_rs232_send_byte( )
/* CPU sets OUT register (keyboard + beeper) */
WRITE32_MEMBER( hp48_state::hp48_reg_out )
WRITE32_MEMBER( hp48_state::reg_out )
{
LOG(( "%s %f hp48_reg_out: %03x\n",
machine().describe_context(), machine().time().as_double(), data ));
LOG(("%s %f hp48_state::reg_out: %03x\n", machine().describe_context(), machine().time().as_double(), data));
/* bits 0-8: keyboard lines */
m_out = data & 0x1ff;
@ -172,20 +167,20 @@ WRITE32_MEMBER( hp48_state::hp48_reg_out )
m_dac->write(BIT(data, 11));
}
int hp48_state::hp48_get_in( )
int hp48_state::get_in()
{
int in = 0;
/* regular keys */
if ( (m_out >> 0) & 1 ) in |= ioport( "LINE0" )->read();
if ( (m_out >> 1) & 1 ) in |= ioport( "LINE1" )->read();
if ( (m_out >> 2) & 1 ) in |= ioport( "LINE2" )->read();
if ( (m_out >> 3) & 1 ) in |= ioport( "LINE3" )->read();
if ( (m_out >> 4) & 1 ) in |= ioport( "LINE4" )->read();
if ( (m_out >> 5) & 1 ) in |= ioport( "LINE5" )->read();
if ( (m_out >> 6) & 1 ) in |= ioport( "LINE6" )->read();
if ( (m_out >> 7) & 1 ) in |= ioport( "LINE7" )->read();
if ( (m_out >> 8) & 1 ) in |= ioport( "LINE8" )->read();
if (BIT(m_out, 0)) in |= ioport("LINE0")->read();
if (BIT(m_out, 1)) in |= ioport("LINE1")->read();
if (BIT(m_out, 2)) in |= ioport("LINE2")->read();
if (BIT(m_out, 3)) in |= ioport("LINE3")->read();
if (BIT(m_out, 4)) in |= ioport("LINE4")->read();
if (BIT(m_out, 5)) in |= ioport("LINE5")->read();
if (BIT(m_out, 6)) in |= ioport("LINE6")->read();
if (BIT(m_out, 7)) in |= ioport("LINE7")->read();
if (BIT(m_out, 8)) in |= ioport("LINE8")->read();
/* on key */
in |= ioport("ON")->read();
@ -194,64 +189,60 @@ int hp48_state::hp48_get_in( )
}
/* CPU reads IN register (keyboard) */
READ32_MEMBER( hp48_state::hp48_reg_in )
READ32_MEMBER( hp48_state::reg_in )
{
int in = hp48_get_in();
LOG(( "%s %f hp48_reg_in: %04x\n",
machine().describe_context(), machine().time().as_double(), in ));
int in = get_in();
LOG(("%s %f hp48_state::reg_in: %04x\n", machine().describe_context(), machine().time().as_double(), in));
return in;
}
/* key detect */
void hp48_state::hp48_update_kdn( )
void hp48_state::update_kdn()
{
int in = hp48_get_in();
int in = get_in();
/* interrupt on raising edge */
if (in && !m_kdn)
{
LOG(( "%f hp48_update_kdn: interrupt\n", machine().time().as_double() ));
m_io[0x19] |= 8; /* service request */
hp48_pulse_irq( SATURN_WAKEUP_LINE );
hp48_pulse_irq( SATURN_IRQ_LINE );
LOG(("%f hp48_state::update_kdn: interrupt\n", machine().time().as_double()));
m_io[0x19] |= 8; // service request
pulse_irq(SATURN_WAKEUP_LINE);
pulse_irq(SATURN_IRQ_LINE);
}
m_kdn = (in != 0);
}
/* periodic keyboard polling, generates an interrupt */
TIMER_CALLBACK_MEMBER(hp48_state::hp48_kbd_cb)
TIMER_CALLBACK_MEMBER(hp48_state::kbd_cb)
{
/* NMI for ON key */
if (ioport( "ON" )->read())
{
LOG(( "%f hp48_kbd_cb: keyboard interrupt, on key\n",
machine().time().as_double() ));
m_io[0x19] |= 8; /* set service request */
hp48_pulse_irq( SATURN_WAKEUP_LINE );
hp48_pulse_irq( SATURN_NMI_LINE );
LOG(("%f hp48_state::kbd_cb: keyboard interrupt, on key\n", machine().time().as_double()));
m_io[0x19] |= 8; // set service request
pulse_irq(SATURN_WAKEUP_LINE);
pulse_irq(SATURN_NMI_LINE);
return;
}
/* regular keys */
hp48_update_kdn();
update_kdn();
}
/* RSI opcode */
WRITE_LINE_MEMBER( hp48_state::hp48_rsi )
WRITE_LINE_MEMBER( hp48_state::rsi )
{
LOG(( "%s %f hp48_rsi\n", machine().describe_context(), machine().time().as_double() ));
LOG(("%s %f hp48_state::rsi\n", machine().describe_context(), machine().time().as_double()));
/* enables interrupts on key repeat
(normally, there is only one interrupt, when the key is pressed)
*/
// enables interrupts on key repeat (normally, there is only one interrupt, when the key is pressed)
m_kdn = 0;
}
/* ------------- annonciators ------------ */
void hp48_state::hp48_update_annunciators()
void hp48_state::update_annunciators()
{
/* bit 0: left shift
bit 1: right shift
@ -279,10 +270,9 @@ void hp48_state::hp48_update_annunciators()
- perform some action on read / write
*/
WRITE8_MEMBER(hp48_state::hp48_io_w)
WRITE8_MEMBER(hp48_state::io_w)
{
LOG(( "%s %f hp48_io_w: off=%02x data=%x\n",
machine().describe_context(), machine().time().as_double(), offset, data ));
LOG(("%s %f hp48_state::io_w: off=%02x data=%x\n", machine().describe_context(), machine().time().as_double(), offset, data));
switch (offset)
{
@ -296,7 +286,7 @@ WRITE8_MEMBER(hp48_state::hp48_io_w)
case 0x0b:
case 0x0c:
m_io[offset] = data;
hp48_update_annunciators();
update_annunciators();
break;
/* cntrl ROM */
@ -306,7 +296,7 @@ WRITE8_MEMBER(hp48_state::hp48_io_w)
m_io[offset] = data;
if (old_cntrl != (data & 8))
{
hp48_apply_modules();
apply_modules();
}
break;
}
@ -329,9 +319,8 @@ WRITE8_MEMBER(hp48_state::hp48_io_w)
/* bit 0: software interrupt */
if (data & 1)
{
LOG(( "%f hp48_io_w: software interrupt requested\n",
machine().time().as_double() ));
hp48_pulse_irq( SATURN_IRQ_LINE );
LOG(("%f hp48_state::io_w: software interrupt requested\n", machine().time().as_double()));
pulse_irq(SATURN_IRQ_LINE);
data &= ~1;
}
@ -358,7 +347,7 @@ WRITE8_MEMBER(hp48_state::hp48_io_w)
case 0x17:
/* second nibble of sent data */
m_io[offset] = data;
hp48_rs232_send_byte();
rs232_send_byte();
break;
/* XXX not implemented:
@ -393,7 +382,7 @@ WRITE8_MEMBER(hp48_state::hp48_io_w)
}
READ8_MEMBER(hp48_state::hp48_io_r)
READ8_MEMBER(hp48_state::io_r)
{
uint8_t data = 0;
@ -427,7 +416,7 @@ READ8_MEMBER(hp48_state::hp48_io_r)
case 0x29:
{
int last_line = HP48_IO_8(0x28) & 0x3f; /* last line of main bitmap before menu */
int cur_line = machine().first_screen()->vpos();
int cur_line = m_screen->vpos();
if (last_line <= 1) last_line = 0x3f;
data = (cur_line >= 0 && cur_line <= last_line) ? last_line - cur_line : 0;
if (offset == 0x29)
@ -498,15 +487,14 @@ READ8_MEMBER(hp48_state::hp48_io_r)
default: data = m_io[offset];
}
LOG(( "%s %f hp48_io_r: off=%02x data=%x\n",
machine().describe_context(), machine().time().as_double(), offset, data ));
LOG(("%s %f hp48_state::io_r: off=%02x data=%x\n", machine().describe_context(), machine().time().as_double(), offset, data));
return data;
}
/* ---------- bank switcher --------- */
READ8_MEMBER(hp48_state::hp48_bank_r)
READ8_MEMBER(hp48_state::bank_r)
{
/* HP48 GX
bit 0: ignored
@ -522,9 +510,9 @@ READ8_MEMBER(hp48_state::hp48_bank_r)
offset &= 0x7e;
if ( m_bank_switch != offset )
{
LOG(( "%s %f hp48_bank_r: off=%03x\n", machine().describe_context(), machine().time().as_double(), offset ));
LOG(( "%s %f hp48_state::bank_r: off=%03x\n", machine().describe_context(), machine().time().as_double(), offset ));
m_bank_switch = offset;
hp48_apply_modules();
apply_modules();
}
return 0;
}
@ -537,7 +525,7 @@ WRITE8_MEMBER(hp48_state::hp49_bank_w)
{
LOG(( "%05x %f hp49_bank_w: off=%03x\n", space.device().safe_pcbase(), machine().time().as_double(), offset ));
m_bank_switch = offset;
hp48_apply_modules();
apply_modules();
}
}
@ -545,7 +533,7 @@ WRITE8_MEMBER(hp48_state::hp49_bank_w)
/* ---------------- timers --------------- */
TIMER_CALLBACK_MEMBER(hp48_state::hp48_timer1_cb)
TIMER_CALLBACK_MEMBER(hp48_state::timer1_cb)
{
if (!(m_io[0x2f] & 1)) return; /* timer enable */
@ -557,7 +545,7 @@ TIMER_CALLBACK_MEMBER(hp48_state::hp48_timer1_cb)
LOG(("wake-up on timer1\n"));
m_io[0x2e] |= 8; /* set service request */
m_io[0x18] |= 4; /* set service request */
hp48_pulse_irq( SATURN_WAKEUP_LINE );
pulse_irq(SATURN_WAKEUP_LINE);
}
/* interrupt on carry */
if ((m_io[0x2e] & 2) && (m_timer1 == 0xf))
@ -565,11 +553,11 @@ TIMER_CALLBACK_MEMBER(hp48_state::hp48_timer1_cb)
LOG(("generate timer1 interrupt\n"));
m_io[0x2e] |= 8; /* set service request */
m_io[0x18] |= 4; /* set service request */
hp48_pulse_irq( SATURN_NMI_LINE );
pulse_irq(SATURN_NMI_LINE);
}
}
TIMER_CALLBACK_MEMBER(hp48_state::hp48_timer2_cb)
TIMER_CALLBACK_MEMBER(hp48_state::timer2_cb)
{
if (!(m_io[0x2f] & 1)) return; /* timer enable */
@ -581,7 +569,7 @@ TIMER_CALLBACK_MEMBER(hp48_state::hp48_timer2_cb)
LOG(("wake-up on timer2\n"));
m_io[0x2f] |= 8; /* set service request */
m_io[0x18] |= 4; /* set service request */
hp48_pulse_irq( SATURN_WAKEUP_LINE );
pulse_irq(SATURN_WAKEUP_LINE);
}
/* interrupt on carry */
if ((m_io[0x2f] & 2) && (m_timer2 == 0xffffffff))
@ -589,7 +577,7 @@ TIMER_CALLBACK_MEMBER(hp48_state::hp48_timer2_cb)
LOG(("generate timer2 interrupt\n"));
m_io[0x2f] |= 8; /* set service request */
m_io[0x18] |= 4; /* set service request */
hp48_pulse_irq( SATURN_NMI_LINE );
pulse_irq(SATURN_NMI_LINE);
}
}
@ -635,9 +623,8 @@ TIMER_CALLBACK_MEMBER(hp48_state::hp48_timer2_cb)
/* remap all modules according to hp48_modules */
void hp48_state::hp48_apply_modules()
void hp48_state::apply_modules()
{
int i;
int nce3_enable = 1;
address_space& space = m_maincpu->space(AS_PROGRAM);
@ -649,8 +636,8 @@ void hp48_state::hp48_apply_modules()
{
int bank_lo = (m_bank_switch >> 5) & 3;
int bank_hi = (m_bank_switch >> 1) & 15;
LOG(( "hp48_apply_modules: low ROM bank is %i\n", bank_lo ));
LOG(( "hp48_apply_modules: high ROM bank is %i\n", bank_hi ));
LOG(("hp48_state::apply_modules: low ROM bank is %i\n", bank_lo));
LOG(("hp48_state::apply_modules: high ROM bank is %i\n", bank_hi));
space.install_read_bank(0x00000, 0x3ffff, 0x80000, "bank5");
space.install_read_bank(0x40000, 0x7ffff, 0x80000, "bank6");
if (m_rom)
@ -665,7 +652,7 @@ void hp48_state::hp48_apply_modules()
if (m_port_size[1] > 0)
{
int off = (m_bank_switch << 16) % m_port_size[1];
LOG(( "hp48_apply_modules: port 2 offset is %i\n", off ));
LOG(("hp48_state::apply_modules: port 2 offset is %i\n", off));
m_modules[HP48_NCE3].data = m_port_data[1].get() + off;
}
@ -673,7 +660,7 @@ void hp48_state::hp48_apply_modules()
if (m_io[0x29] & 8)
{
/* A19 */
LOG(( "hp48_apply_modules: A19 enabled, NCE3 disabled\n" ));
LOG(("hp48_state::apply_modules: A19 enabled, NCE3 disabled\n"));
nce3_enable = 0;
space.install_read_bank(0, 0xfffff, "bank5");
}
@ -685,18 +672,22 @@ void hp48_state::hp48_apply_modules()
space.install_read_bank(0, 0x7ffff, 0x80000, "bank5");
}
if (m_rom)
{
membank("bank5")->set_base(m_rom);
}
}
else
{
space.install_read_bank(0, 0x7ffff, 0x80000, "bank5");
if (m_rom)
{
membank("bank5")->set_base(m_rom);
}
}
/* from lowest to highest priority */
for ( i = 4; i >= 0; i-- )
for (int i = 4; i >= 0; i--)
{
uint32_t select_mask = m_modules[i].mask;
uint32_t nselect_mask = ~select_mask & 0xfffff;
@ -708,27 +699,31 @@ void hp48_state::hp48_apply_modules()
sprintf(bank,"bank%d",i);
if (m_modules[i].state != HP48_MODULE_CONFIGURED) continue;
if ((i == 4) && !nce3_enable) continue;
/* our code assumes that the 20-bit select_mask is all 1s followed by all 0s */
if (nselect_mask & (nselect_mask + 1))
{
logerror( "hp48_apply_modules: invalid mask %05x for module %s\n",
select_mask, hp48_module_names[i] );
logerror("hp48_apply_modules: invalid mask %05x for module %s\n", select_mask, hp48_module_names[i]);
continue;
}
if (m_modules[i].data)
{
space.install_read_bank(base, end, mirror, bank);
}
else
{
if (!m_modules[i].read.isnull())
{
space.install_read_handler(base, end, 0, mirror, 0, m_modules[i].read);
}
}
if (m_modules[i].isnop)
{
space.nop_write(base, end | mirror);
}
else
{
if (m_modules[i].data)
@ -738,12 +733,13 @@ void hp48_state::hp48_apply_modules()
else
{
if (!m_modules[i].write.isnull())
{
space.install_write_handler(base, end, 0, mirror, 0, m_modules[i].write);
}
}
}
LOG(( "hp48_apply_modules: module %s configured at %05x-%05x, mirror %05x\n",
hp48_module_names[i], base, end, mirror ));
LOG(("hp48_apply_modules: module %s configured at %05x-%05x, mirror %05x\n", hp48_module_names[i], base, end, mirror));
if (m_modules[i].data)
{
@ -759,14 +755,13 @@ void hp48_state::hp48_apply_modules()
/* reset the configuration */
void hp48_state::hp48_reset_modules( )
void hp48_state::reset_modules()
{
int i;
/* fixed size for HDW */
m_modules[HP48_HDW].state = HP48_MODULE_MASK_KNOWN;
m_modules[HP48_HDW].mask = 0xfffc0;
/* unconfigure NCE2, CE1, CE2, NCE3 */
for ( i = 1; i < 5; i++ )
for (int i = 1; i < 5; i++)
{
m_modules[i].state = HP48_MODULE_UNCONFIGURED;
}
@ -776,27 +771,25 @@ void hp48_state::hp48_reset_modules( )
m_modules[HP48_NCE1].base = 0;
m_modules[HP48_NCE1].mask = 0;
hp48_apply_modules();
apply_modules();
}
/* RESET opcode */
WRITE_LINE_MEMBER( hp48_state::hp48_mem_reset )
WRITE_LINE_MEMBER( hp48_state::mem_reset )
{
LOG(( "%s %f hp48_mem_reset\n", machine().describe_context(), machine().time().as_double() ));
hp48_reset_modules();
LOG(("%s %f hp48_state::mem_reset\n", machine().describe_context(), machine().time().as_double()));
reset_modules();
}
/* CONFIG opcode */
WRITE32_MEMBER( hp48_state::hp48_mem_config )
WRITE32_MEMBER( hp48_state::mem_config )
{
int i;
LOG(( "%s %f hp48_mem_config: %05x\n", machine().describe_context(), machine().time().as_double(), data ));
LOG(("%s %f hp48_state::mem_config: %05x\n", machine().describe_context(), machine().time().as_double(), data));
/* find the highest priority unconfigured module (except non-configurable NCE1)... */
for ( i = 0; i < 5; i++ )
for (int i = 0; i < 5; i++)
{
/* ... first call sets the address mask */
if (m_modules[i].state == HP48_MODULE_UNCONFIGURED)
@ -811,9 +804,8 @@ WRITE32_MEMBER( hp48_state::hp48_mem_config )
{
m_modules[i].base = data & m_modules[i].mask;
m_modules[i].state = HP48_MODULE_CONFIGURED;
LOG(( "hp48_mem_config: module %s configured base=%05x, mask=%05x\n",
hp48_module_names[i], m_modules[i].base, m_modules[i].mask ));
hp48_apply_modules();
LOG(("hp48_mem_config: module %s configured base=%05x, mask=%05x\n", hp48_module_names[i], m_modules[i].base, m_modules[i].mask));
apply_modules();
break;
}
}
@ -821,21 +813,19 @@ WRITE32_MEMBER( hp48_state::hp48_mem_config )
/* UNCFG opcode */
WRITE32_MEMBER( hp48_state::hp48_mem_unconfig )
WRITE32_MEMBER( hp48_state::mem_unconfig )
{
int i;
LOG(( "%s %f hp48_mem_unconfig: %05x\n", machine().describe_context(), machine().time().as_double(), data ));
LOG(("%s %f hp48_state::mem_unconfig: %05x\n", machine().describe_context(), machine().time().as_double(), data));
/* find the highest priority fully configured module at address v (except NCE1)... */
for ( i = 0; i < 5; i++ )
for (int i = 0; i < 5; i++)
{
/* ... and unconfigure it */
if ( m_modules[i].state == HP48_MODULE_CONFIGURED &&
(m_modules[i].base == (data & m_modules[i].mask)) )
if (m_modules[i].state == HP48_MODULE_CONFIGURED && (m_modules[i].base == (data & m_modules[i].mask)))
{
m_modules[i].state = i > 0 ? HP48_MODULE_UNCONFIGURED : HP48_MODULE_MASK_KNOWN;
LOG(("hp48_mem_unconfig: module %s\n", hp48_module_names[i]));
hp48_apply_modules();
apply_modules();
break;
}
}
@ -843,13 +833,12 @@ WRITE32_MEMBER( hp48_state::hp48_mem_unconfig )
/* C=ID opcode */
READ32_MEMBER( hp48_state::hp48_mem_id )
READ32_MEMBER( hp48_state::mem_id )
{
int i;
int data = 0; /* 0 = everything is configured */
/* find the highest priority unconfigured module (except NCE1)... */
for ( i = 0; i < 5; i++ )
for (int i = 0; i < 5; i++)
{
/* ... mask need to be configured */
if (m_modules[i].state == HP48_MODULE_UNCONFIGURED)
@ -866,8 +855,7 @@ READ32_MEMBER( hp48_state::hp48_mem_id )
}
}
LOG(( "%s %f hp48_mem_id = %02x\n",
machine().describe_context(), machine().time().as_double(), data ));
LOG(("%s %f mem_id = %02x\n", machine().describe_context(), machine().time().as_double(), data));
return data; /* everything is configured */
}
@ -877,7 +865,7 @@ READ32_MEMBER( hp48_state::hp48_mem_id )
/* --------- CRC ---------- */
/* each memory read by the CPU updates the internal CRC state */
WRITE32_MEMBER( hp48_state::hp48_mem_crc )
WRITE32_MEMBER( hp48_state::mem_crc )
{
/* no CRC for I/O RAM */
if (offset >= m_io_addr && offset < m_io_addr + 0x40) return;
@ -891,21 +879,19 @@ WRITE32_MEMBER( hp48_state::hp48_mem_crc )
/* decodes size bytes into 2*size nibbles (least significant first) */
void hp48_state::hp48_decode_nibble( uint8_t* dst, uint8_t* src, int size )
void hp48_state::decode_nibble(uint8_t* dst, uint8_t* src, int size)
{
int i;
for ( i=size-1; i >= 0; i-- )
for (int i = size - 1; i >= 0; i--)
{
dst[2 * i + 1] = src[i] >> 4;
dst[2 * i] = src[i] & 0xf;
}
}
/* inverse of hp48_decode_nibble */
void hp48_state::hp48_encode_nibble( uint8_t* dst, uint8_t* src, int size )
/* inverse of decode_nibble */
void hp48_state::encode_nibble(uint8_t* dst, uint8_t* src, int size)
{
int i;
for ( i=0; i < size; i++ )
for (int i = 0; i < size; i++)
{
dst[i] = (src[2 * i] & 0xf) | (src[2 * i + 1] << 4);
}
@ -917,25 +903,25 @@ void hp48_state::hp48_encode_nibble( uint8_t* dst, uint8_t* src, int size )
DEFINE_DEVICE_TYPE(HP48_PORT, hp48_port_image_device, "hp48_port_image", "HP48 memory card")
/* helper for load and create */
void hp48_port_image_device::hp48_fill_port()
void hp48_port_image_device::fill_port()
{
hp48_state *state = machine().driver_data<hp48_state>();
int size = state->m_port_size[m_port];
LOG(( "hp48_fill_port: %s module=%i size=%i rw=%i\n", tag(), m_module, size, state->m_port_write[m_port] ));
LOG(("hp48_port_image_device::fill_port: %s module=%i size=%i rw=%i\n", tag(), m_module, size, state->m_port_write[m_port]));
state->m_port_data[m_port] = make_unique_clear<uint8_t[]>(2 * size);
state->m_modules[m_module].off_mask = 2 * (( size > 128 * 1024 ) ? 128 * 1024 : size) - 1;
state->m_modules[m_module].read = read8_delegate();
state->m_modules[m_module].write = write8_delegate();
state->m_modules[m_module].isnop = state->m_port_write[m_port] ? 0 : 1;
state->m_modules[m_module].data = (void*)state->m_port_data[m_port].get();
state->hp48_apply_modules();
state->apply_modules();
}
/* helper for start and unload */
void hp48_port_image_device::hp48_unfill_port()
void hp48_port_image_device::unfill_port()
{
hp48_state *state = machine().driver_data<hp48_state>();
LOG(( "hp48_unfill_port\n" ));
LOG(("hp48_port_image_device::unfill_port\n"));
state->m_modules[m_module].off_mask = 0x00fff; /* 2 KB */
state->m_modules[m_module].read = read8_delegate();
state->m_modules[m_module].write = write8_delegate();
@ -961,9 +947,9 @@ image_init_result hp48_port_image_device::call_load()
state->m_port_size[m_port] = size;
state->m_port_write[m_port] = !is_readonly();
hp48_fill_port( );
fill_port();
fread(state->m_port_data[m_port].get(), state->m_port_size[m_port] );
state->hp48_decode_nibble( state->m_port_data[m_port].get(), state->m_port_data[m_port].get(), state->m_port_size[m_port] );
state->decode_nibble(state->m_port_data[m_port].get(), state->m_port_data[m_port].get(), state->m_port_size[m_port]);
return image_init_result::PASS;
}
@ -984,30 +970,29 @@ image_init_result hp48_port_image_device::call_create(int format_type, util::opt
state->m_port_size[m_port] = size;
state->m_port_write[m_port] = 1;
hp48_fill_port();
fill_port();
return image_init_result::PASS;
}
void hp48_port_image_device::call_unload()
{
hp48_state *state = machine().driver_data<hp48_state>();
LOG(( "hp48_port image unload: %s size=%i rw=%i\n",
tag(), state->m_port_size[m_port], state->m_port_write[m_port] ));
LOG(("hp48_port image unload: %s size=%i rw=%i\n", tag(), state->m_port_size[m_port], state->m_port_write[m_port]));
if (state->m_port_write[m_port])
{
state->hp48_encode_nibble( state->m_port_data[m_port].get(), state->m_port_data[m_port].get(), state->m_port_size[m_port] );
state->encode_nibble(state->m_port_data[m_port].get(), state->m_port_data[m_port].get(), state->m_port_size[m_port]);
fseek(0, SEEK_SET);
fwrite(state->m_port_data[m_port].get(), state->m_port_size[m_port]);
}
state->m_port_data[m_port] = nullptr;
hp48_unfill_port();
state->hp48_apply_modules();
unfill_port();
state->apply_modules();
}
void hp48_port_image_device::device_start()
{
LOG(("hp48_port_image start\n"));
hp48_unfill_port();
unfill_port();
}
hp48_port_image_device::hp48_port_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
@ -1041,34 +1026,31 @@ void hp48_state::machine_reset()
{
LOG(("hp48: machine reset called\n"));
m_bank_switch = 0;
hp48_reset_modules();
hp48_update_annunciators();
reset_modules();
update_annunciators();
}
void hp48_state::hp48_machine_start( hp48_models model )
void hp48_state::base_machine_start(hp48_models model)
{
uint8_t *ram;
int ram_size, rom_size, i;
LOG(( "hp48_machine_start: model %i\n", model ));
LOG(( "hp48_state::machine_start: model %i\n", model ));
m_model = model;
/* internal RAM */
ram_size =
uint32_t ram_size =
HP49_G_MODEL ? (512 * 1024) :
HP48_GX_MODEL ? (128 * 1024) : (32 * 1024);
ram = auto_alloc_array(machine(), uint8_t, 2 * ram_size);
uint8_t *ram = auto_alloc_array(machine(), uint8_t, 2 * ram_size);
machine().device<nvram_device>("nvram")->set_base(ram, 2 * ram_size);
/* ROM load */
rom_size =
uint32_t rom_size =
HP49_G_MODEL ? (2048 * 1024) :
HP48_S_SERIES ? (256 * 1024) : (512 * 1024);
m_rom = auto_alloc_array(machine(), uint8_t, 2 * rom_size);
hp48_decode_nibble( m_rom, memregion( "maincpu" )->base(), rom_size );
decode_nibble(m_rom, memregion("maincpu")->base(), rom_size);
/* init state */
memset(ram, 0, 2 * ram_size);
@ -1082,8 +1064,8 @@ void hp48_state::hp48_machine_start( hp48_models model )
/* I/O RAM */
m_modules[HP48_HDW].off_mask = 0x0003f; /* 32 B */
m_modules[HP48_HDW].read = read8_delegate(FUNC(hp48_state::hp48_io_r),this);
m_modules[HP48_HDW].write = write8_delegate(FUNC(hp48_state::hp48_io_w),this);
m_modules[HP48_HDW].read = read8_delegate(FUNC(hp48_state::io_r),this);
m_modules[HP48_HDW].write = write8_delegate(FUNC(hp48_state::io_w),this);
/* internal RAM */
if (HP49_G_MODEL)
@ -1105,19 +1087,19 @@ void hp48_state::hp48_machine_start( hp48_models model )
if (HP48_G_SERIES)
{
m_modules[HP48_CE1].off_mask = 0x00fff; /* 2 KB */
m_modules[HP48_CE1].read = read8_delegate(FUNC(hp48_state::hp48_bank_r),this);
m_modules[HP48_CE1].read = read8_delegate(FUNC(hp48_state::bank_r),this);
m_modules[HP48_CE1].write = HP49_G_MODEL ? write8_delegate(FUNC(hp48_state::hp49_bank_w),this) : write8_delegate();
}
/* timers */
m_1st_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(hp48_state::hp48_timer1_cb), this));
m_1st_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(hp48_state::timer1_cb), this));
m_1st_timer->adjust(attotime::from_hz(16), 0, attotime::from_hz(16));
m_2nd_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(hp48_state::hp48_timer2_cb), this));
m_2nd_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(hp48_state::timer2_cb), this));
m_2nd_timer->adjust(attotime::from_hz(8192), 0, attotime::from_hz(8192));
/* 1ms keyboard polling */
m_kbd_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(hp48_state::hp48_kbd_cb), this));
m_kbd_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(hp48_state::kbd_cb), this));
m_kbd_timer->adjust(attotime::from_msec(1), 0, attotime::from_msec(1));
/* save state */
@ -1128,47 +1110,44 @@ void hp48_state::hp48_machine_start( hp48_models model )
save_item(NAME(m_timer1) );
save_item(NAME(m_timer2) );
save_item(NAME(m_bank_switch) );
for ( i = 0; i < 6; i++ )
for (int i = 0; i < 6; i++)
{
save_item(m_modules[i].state, "globals/m_modules[i].state", i);
save_item(m_modules[i].base, "globals/m_modules[i].base", i);
save_item(m_modules[i].mask, "globals/m_modules[i].mask", i);
}
save_item(NAME(m_io) );
machine().save().register_postload( save_prepost_delegate(FUNC(hp48_state::hp48_update_annunciators), this ));
machine().save().register_postload( save_prepost_delegate(FUNC(hp48_state::hp48_apply_modules), this ));
machine().save().register_postload(save_prepost_delegate(FUNC(hp48_state::update_annunciators), this));
machine().save().register_postload(save_prepost_delegate(FUNC(hp48_state::apply_modules), this));
}
MACHINE_START_MEMBER(hp48_state,hp48s)
{
hp48_machine_start( HP48_S );
base_machine_start(HP48_S);
}
MACHINE_START_MEMBER(hp48_state,hp48sx)
{
hp48_machine_start( HP48_SX );
base_machine_start(HP48_SX);
}
MACHINE_START_MEMBER(hp48_state,hp48g)
{
hp48_machine_start( HP48_G );
base_machine_start(HP48_G);
}
MACHINE_START_MEMBER(hp48_state,hp48gx)
{
hp48_machine_start( HP48_GX );
base_machine_start(HP48_GX);
}
MACHINE_START_MEMBER(hp48_state,hp48gp)
{
hp48_machine_start( HP48_GP );
base_machine_start(HP48_GP);
}
MACHINE_START_MEMBER(hp48_state,hp49g)
{
hp48_machine_start( HP49_G );
base_machine_start(HP49_G);
}