mirror of
https://github.com/holub/mame
synced 2025-06-01 10:31:48 +03:00
[MESS] apple2: rewrote all 8-bit Apple II drivers with an aim towards modernity and improved runtime performance, improved correctness, and missing features. Fixes MT #5157, 5158, 5747, and 5748. [R. Belmont]
This commit is contained in:
parent
4235d4537a
commit
bc2193dab3
@ -241,9 +241,15 @@ void a2bus_device::set_nmi_line(int state, int slot)
|
||||
}
|
||||
}
|
||||
|
||||
void a2bus_device::set_inh_slotnum(int slot)
|
||||
void a2bus_device::set_maincpu_halt(int state)
|
||||
{
|
||||
m_out_inh_cb(slot);
|
||||
m_maincpu->set_input_line(INPUT_LINE_HALT, state);
|
||||
}
|
||||
|
||||
void a2bus_device::recalc_inh(int slot)
|
||||
{
|
||||
m_out_inh_cb(ASSERT_LINE);
|
||||
m_out_inh_cb(CLEAR_LINE);
|
||||
}
|
||||
|
||||
// interrupt request from a2bus card
|
||||
|
@ -15,7 +15,14 @@
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#define INH_SLOT_INVALID (255)
|
||||
// /INH special addresses
|
||||
#define INH_START_INVALID 0xffff;
|
||||
#define INH_END_INVALID 0x0000;
|
||||
|
||||
// /INH types
|
||||
#define INH_NONE 0x00
|
||||
#define INH_READ 0x01
|
||||
#define INH_WRITE 0x02
|
||||
|
||||
//**************************************************************************
|
||||
// INTERFACE CONFIGURATION MACROS
|
||||
@ -97,7 +104,8 @@ public:
|
||||
|
||||
void set_irq_line(int state, int slot);
|
||||
void set_nmi_line(int state, int slot);
|
||||
void set_inh_slotnum(int slot);
|
||||
void set_maincpu_halt(int state);
|
||||
void recalc_inh(int slot);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER( irq_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( nmi_w );
|
||||
@ -112,7 +120,7 @@ protected:
|
||||
|
||||
devcb_write_line m_out_irq_cb;
|
||||
devcb_write_line m_out_nmi_cb;
|
||||
devcb_write_line m_out_inh_cb;
|
||||
devcb_write8 m_out_inh_cb;
|
||||
|
||||
device_a2bus_card_interface *m_device_list[8];
|
||||
const char *m_cputag;
|
||||
@ -145,6 +153,9 @@ public:
|
||||
virtual bool take_c800() { return true; } // override and return false if your card doesn't take over the c800 space
|
||||
virtual UINT8 read_inh_rom(address_space &space, UINT16 offset) { return 0; }
|
||||
virtual void write_inh_rom(address_space &space, UINT16 offset, UINT8 data) { }
|
||||
virtual UINT16 inh_start() { return INH_START_INVALID; }
|
||||
virtual UINT16 inh_end() { return INH_END_INVALID; }
|
||||
virtual int inh_type() { return INH_NONE; }
|
||||
|
||||
device_a2bus_card_interface *next() const { return m_next; }
|
||||
|
||||
@ -157,8 +168,8 @@ public:
|
||||
void lower_slot_irq() { m_a2bus->set_irq_line(CLEAR_LINE, m_slot); }
|
||||
void raise_slot_nmi() { m_a2bus->set_nmi_line(ASSERT_LINE, m_slot); }
|
||||
void lower_slot_nmi() { m_a2bus->set_nmi_line(CLEAR_LINE, m_slot); }
|
||||
void raise_slot_inh() { m_a2bus->set_inh_slotnum(m_slot); }
|
||||
void lower_slot_inh() { m_a2bus->set_inh_slotnum(INH_SLOT_INVALID); }
|
||||
void recalc_slot_inh() { m_a2bus->recalc_inh(m_slot); }
|
||||
void set_maincpu_halt(int state) { m_a2bus->set_maincpu_halt(state); }
|
||||
|
||||
// inline configuration
|
||||
static void static_set_a2bus_tag(device_t &device, const char *tag, const char *slottag);
|
||||
|
@ -120,6 +120,7 @@ public:
|
||||
virtual void write_auxram(UINT16 offset, UINT8 data) { printf("a2eauxslot: unhandled auxram write %02x @ %04x\n", data, offset); }
|
||||
virtual void write_c07x(address_space &space, UINT8 offset, UINT8 data) {}
|
||||
virtual UINT8 *get_vram_ptr() = 0;
|
||||
virtual UINT8 *get_auxbank_ptr() = 0;
|
||||
virtual bool allow_dhr() { return true; }
|
||||
|
||||
device_a2eauxslot_card_interface *next() const { return m_next; }
|
||||
|
@ -66,3 +66,9 @@ UINT8 *a2eaux_ext80col_device::get_vram_ptr()
|
||||
{
|
||||
return &m_ram[0];
|
||||
}
|
||||
|
||||
UINT8 *a2eaux_ext80col_device::get_auxbank_ptr()
|
||||
{
|
||||
return &m_ram[0];
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@ protected:
|
||||
virtual UINT8 read_auxram(UINT16 offset);
|
||||
virtual void write_auxram(UINT16 offset, UINT8 data);
|
||||
virtual UINT8 *get_vram_ptr();
|
||||
virtual UINT8 *get_auxbank_ptr();
|
||||
virtual bool allow_dhr() { return true; }
|
||||
|
||||
private:
|
||||
|
@ -69,6 +69,11 @@ UINT8 *a2eaux_ramworks3_device::get_vram_ptr()
|
||||
return &m_ram[0];
|
||||
}
|
||||
|
||||
UINT8 *a2eaux_ramworks3_device::get_auxbank_ptr()
|
||||
{
|
||||
return &m_ram[m_bank];
|
||||
}
|
||||
|
||||
/*
|
||||
These cards are split into 64k logical banks.
|
||||
|
||||
|
@ -32,6 +32,7 @@ protected:
|
||||
virtual UINT8 read_auxram(UINT16 offset);
|
||||
virtual void write_auxram(UINT16 offset, UINT8 data);
|
||||
virtual UINT8 *get_vram_ptr();
|
||||
virtual UINT8 *get_auxbank_ptr();
|
||||
virtual bool allow_dhr() { return true; }
|
||||
virtual void write_c07x(address_space &space, UINT8 offset, UINT8 data);
|
||||
|
||||
|
@ -73,3 +73,9 @@ UINT8 *a2eaux_std80col_device::get_vram_ptr()
|
||||
{
|
||||
return &m_ram[0];
|
||||
}
|
||||
|
||||
UINT8 *a2eaux_std80col_device::get_auxbank_ptr()
|
||||
{
|
||||
return &m_ram[0];
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@ protected:
|
||||
virtual UINT8 read_auxram(UINT16 offset);
|
||||
virtual void write_auxram(UINT16 offset, UINT8 data);
|
||||
virtual UINT8 *get_vram_ptr();
|
||||
virtual UINT8 *get_auxbank_ptr();
|
||||
virtual bool allow_dhr() { return false; } // we don't allow DHR
|
||||
|
||||
private:
|
||||
|
@ -81,6 +81,7 @@ void a2bus_softcard_device::device_start()
|
||||
void a2bus_softcard_device::device_reset()
|
||||
{
|
||||
m_bEnabled = false;
|
||||
|
||||
m_6502space = NULL;
|
||||
m_FirstZ80Boot = true;
|
||||
m_z80->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
|
||||
@ -88,15 +89,13 @@ void a2bus_softcard_device::device_reset()
|
||||
|
||||
void a2bus_softcard_device::write_cnxx(address_space &space, UINT8 offset, UINT8 data)
|
||||
{
|
||||
apple2_state *state = machine().driver_data<apple2_state>();
|
||||
|
||||
if (!m_bEnabled)
|
||||
{
|
||||
// steal the 6502's address space
|
||||
m_6502space = &space;
|
||||
|
||||
m_z80->set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
|
||||
state->m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
|
||||
set_maincpu_halt(ASSERT_LINE);
|
||||
|
||||
if (m_FirstZ80Boot)
|
||||
{
|
||||
@ -109,7 +108,7 @@ void a2bus_softcard_device::write_cnxx(address_space &space, UINT8 offset, UINT8
|
||||
else
|
||||
{
|
||||
m_z80->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
|
||||
state->m_maincpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
|
||||
set_maincpu_halt(CLEAR_LINE);
|
||||
m_bEnabled = false;
|
||||
}
|
||||
}
|
||||
|
@ -74,10 +74,8 @@ void a2bus_swyft_device::device_reset()
|
||||
{
|
||||
m_rombank = 0;
|
||||
|
||||
// take over the machine
|
||||
apple2_state *state = machine().driver_data<apple2_state>();
|
||||
raise_slot_inh();
|
||||
state->m_maincpu->reset();
|
||||
m_inh_state = INH_READ; // read-enable the ROM
|
||||
recalc_slot_inh();
|
||||
}
|
||||
|
||||
UINT8 a2bus_swyft_device::read_c0nx(address_space &space, UINT8 offset)
|
||||
@ -86,17 +84,20 @@ UINT8 a2bus_swyft_device::read_c0nx(address_space &space, UINT8 offset)
|
||||
{
|
||||
case 0:
|
||||
m_rombank = 0;
|
||||
raise_slot_inh();
|
||||
m_inh_state = INH_READ;
|
||||
recalc_slot_inh();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
m_rombank = 0;
|
||||
lower_slot_inh();
|
||||
m_inh_state = INH_NONE;
|
||||
recalc_slot_inh();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
m_rombank = 0x1000;
|
||||
raise_slot_inh();
|
||||
m_inh_state = INH_READ;
|
||||
recalc_slot_inh();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -109,23 +110,28 @@ void a2bus_swyft_device::write_c0nx(address_space &space, UINT8 offset, UINT8 da
|
||||
{
|
||||
case 0:
|
||||
m_rombank = 0;
|
||||
raise_slot_inh();
|
||||
m_inh_state = INH_READ;
|
||||
recalc_slot_inh();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
m_rombank = 0;
|
||||
lower_slot_inh();
|
||||
m_inh_state = INH_NONE;
|
||||
recalc_slot_inh();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
m_rombank = 0x1000;
|
||||
raise_slot_inh();
|
||||
m_inh_state = INH_READ;
|
||||
recalc_slot_inh();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
UINT8 a2bus_swyft_device::read_inh_rom(address_space &space, UINT16 offset)
|
||||
{
|
||||
offset -= 0xd000;
|
||||
|
||||
if (offset < 0x1000) // banked area d000-dfff
|
||||
{
|
||||
return m_rom[offset + m_rombank];
|
||||
@ -135,3 +141,9 @@ UINT8 a2bus_swyft_device::read_inh_rom(address_space &space, UINT16 offset)
|
||||
return m_rom[offset - 0x1000 + 0x2000];
|
||||
}
|
||||
}
|
||||
|
||||
int a2bus_swyft_device::inh_type()
|
||||
{
|
||||
return m_inh_state;
|
||||
}
|
||||
|
||||
|
@ -34,10 +34,14 @@ protected:
|
||||
virtual UINT8 read_c0nx(address_space &space, UINT8 offset);
|
||||
virtual void write_c0nx(address_space &space, UINT8 offset, UINT8 data);
|
||||
virtual UINT8 read_inh_rom(address_space &space, UINT16 offset);
|
||||
virtual UINT16 inh_start() { return 0xd000; }
|
||||
virtual UINT16 inh_end() { return 0xffff; }
|
||||
virtual int inh_type();
|
||||
|
||||
private:
|
||||
UINT8 *m_rom;
|
||||
int m_rombank;
|
||||
int m_inh_state;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
|
191
src/emu/bus/a2bus/ramcard128k.c
Normal file
191
src/emu/bus/a2bus/ramcard128k.c
Normal file
@ -0,0 +1,191 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:R. Belmont
|
||||
/*********************************************************************
|
||||
|
||||
ramcard128k.c
|
||||
|
||||
Implemention of the Saturn Systems 128K extended language card
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#include "ramcard128k.h"
|
||||
|
||||
/***************************************************************************
|
||||
PARAMETERS
|
||||
***************************************************************************/
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
const device_type A2BUS_RAMCARD128K = &device_creator<a2bus_ssramcard_device>;
|
||||
|
||||
/***************************************************************************
|
||||
FUNCTION PROTOTYPES
|
||||
***************************************************************************/
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
a2bus_ssramcard_device::a2bus_ssramcard_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) :
|
||||
device_t(mconfig, type, name, tag, owner, clock, shortname, source),
|
||||
device_a2bus_card_interface(mconfig, *this)
|
||||
{
|
||||
}
|
||||
|
||||
a2bus_ssramcard_device::a2bus_ssramcard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
||||
device_t(mconfig, A2BUS_RAMCARD128K, "Saturn Systems 128K Extended Language Card", tag, owner, clock, "ssram128", __FILE__),
|
||||
device_a2bus_card_interface(mconfig, *this)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void a2bus_ssramcard_device::device_start()
|
||||
{
|
||||
// set_a2bus_device makes m_slot valid
|
||||
set_a2bus_device();
|
||||
|
||||
memset(m_ram, 0, 128*1024);
|
||||
|
||||
save_item(NAME(m_inh_state));
|
||||
save_item(NAME(m_ram));
|
||||
save_item(NAME(m_dxxx_bank));
|
||||
save_item(NAME(m_main_bank));
|
||||
save_item(NAME(m_last_offset));
|
||||
}
|
||||
|
||||
void a2bus_ssramcard_device::device_reset()
|
||||
{
|
||||
m_inh_state = INH_NONE;
|
||||
m_dxxx_bank = 0;
|
||||
m_main_bank = 0;
|
||||
m_last_offset = -1;
|
||||
}
|
||||
|
||||
void a2bus_ssramcard_device::do_io(int offset)
|
||||
{
|
||||
int old_inh_state = m_inh_state;
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0x1: case 0x3: case 0x9: case 0xb:
|
||||
if (offset != m_last_offset)
|
||||
{
|
||||
m_last_offset = offset;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
m_last_offset = offset;
|
||||
|
||||
if (offset & 4)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0x4: m_main_bank = 0x00000; break;
|
||||
case 0x5: m_main_bank = 0x04000; break;
|
||||
case 0x6: m_main_bank = 0x08000; break;
|
||||
case 0x7: m_main_bank = 0x0c000; break;
|
||||
case 0xc: m_main_bank = 0x10000; break;
|
||||
case 0xd: m_main_bank = 0x14000; break;
|
||||
case 0xe: m_main_bank = 0x18000; break;
|
||||
case 0xf: m_main_bank = 0x1c000; break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_inh_state = INH_NONE;
|
||||
m_dxxx_bank = 0;
|
||||
|
||||
if (offset & 0x1)
|
||||
{
|
||||
m_inh_state |= INH_WRITE;
|
||||
}
|
||||
|
||||
switch(offset & 0x03)
|
||||
{
|
||||
case 0x00:
|
||||
case 0x03:
|
||||
m_inh_state |= INH_READ;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(offset & 8))
|
||||
{
|
||||
m_dxxx_bank = 0x1000;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_inh_state != old_inh_state)
|
||||
{
|
||||
recalc_slot_inh();
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf("LC: (ofs %x) new state %c%c dxxx=%04x main=%05x\n",
|
||||
offset,
|
||||
(m_inh_state & INH_READ) ? 'R' : 'x',
|
||||
(m_inh_state & INH_WRITE) ? 'W' : 'x',
|
||||
m_dxxx_bank, m_main_bank);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
read_c0nx - called for reads from this card's c0nx space
|
||||
-------------------------------------------------*/
|
||||
|
||||
UINT8 a2bus_ssramcard_device::read_c0nx(address_space &space, UINT8 offset)
|
||||
{
|
||||
do_io(offset & 0xf);
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
write_c0nx - called for writes to this card's c0nx space
|
||||
-------------------------------------------------*/
|
||||
|
||||
void a2bus_ssramcard_device::write_c0nx(address_space &space, UINT8 offset, UINT8 data)
|
||||
{
|
||||
do_io(offset & 0xf);
|
||||
}
|
||||
|
||||
UINT8 a2bus_ssramcard_device::read_inh_rom(address_space &space, UINT16 offset)
|
||||
{
|
||||
assert(m_inh_state & INH_READ); // this should never happen
|
||||
|
||||
if (offset < 0xe000)
|
||||
{
|
||||
return m_ram[(offset & 0xfff) + m_dxxx_bank + m_main_bank];
|
||||
}
|
||||
|
||||
return m_ram[(offset & 0x1fff) + 0x2000 + m_main_bank];
|
||||
}
|
||||
|
||||
void a2bus_ssramcard_device::write_inh_rom(address_space &space, UINT16 offset, UINT8 data)
|
||||
{
|
||||
// are writes enabled?
|
||||
if (!(m_inh_state & INH_WRITE))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (offset < 0xe000)
|
||||
{
|
||||
m_ram[(offset & 0xfff) + m_dxxx_bank + m_main_bank] = data;
|
||||
return;
|
||||
}
|
||||
|
||||
m_ram[(offset & 0x1fff) + 0x2000 + m_main_bank] = data;
|
||||
}
|
||||
|
||||
int a2bus_ssramcard_device::inh_type()
|
||||
{
|
||||
return m_inh_state;
|
||||
}
|
||||
|
56
src/emu/bus/a2bus/ramcard128k.h
Normal file
56
src/emu/bus/a2bus/ramcard128k.h
Normal file
@ -0,0 +1,56 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:R. Belmont
|
||||
/*********************************************************************
|
||||
|
||||
ramcard128k.h
|
||||
|
||||
Implemention of the Saturn Systems 128K extended language card
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef __A2BUS_RAMCARD128K__
|
||||
#define __A2BUS_RAMCARD128K__
|
||||
|
||||
#include "emu.h"
|
||||
#include "a2bus.h"
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
class a2bus_ssramcard_device:
|
||||
public device_t,
|
||||
public device_a2bus_card_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
a2bus_ssramcard_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
|
||||
a2bus_ssramcard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
protected:
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
// overrides of standard a2bus slot functions
|
||||
virtual UINT8 read_c0nx(address_space &space, UINT8 offset);
|
||||
virtual void write_c0nx(address_space &space, UINT8 offset, UINT8 data);
|
||||
virtual UINT8 read_inh_rom(address_space &space, UINT16 offset);
|
||||
virtual void write_inh_rom(address_space &space, UINT16 offset, UINT8 data);
|
||||
virtual UINT16 inh_start() { return 0xd000; }
|
||||
virtual UINT16 inh_end() { return 0xffff; }
|
||||
virtual int inh_type();
|
||||
|
||||
private:
|
||||
void do_io(int offset);
|
||||
|
||||
int m_inh_state;
|
||||
int m_last_offset;
|
||||
int m_dxxx_bank;
|
||||
int m_main_bank;
|
||||
UINT8 m_ram[128*1024];
|
||||
};
|
||||
|
||||
// device type definition
|
||||
extern const device_type A2BUS_RAMCARD128K;
|
||||
|
||||
#endif /* __A2BUS_RAMCARD128K__ */
|
171
src/emu/bus/a2bus/ramcard16k.c
Normal file
171
src/emu/bus/a2bus/ramcard16k.c
Normal file
@ -0,0 +1,171 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:R. Belmont
|
||||
/*********************************************************************
|
||||
|
||||
ramcard16k.c
|
||||
|
||||
Implemention of the Apple II 16K RAM card (aka "language card")
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#include "ramcard16k.h"
|
||||
|
||||
/***************************************************************************
|
||||
PARAMETERS
|
||||
***************************************************************************/
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
const device_type A2BUS_RAMCARD16K = &device_creator<a2bus_ramcard_device>;
|
||||
|
||||
/***************************************************************************
|
||||
FUNCTION PROTOTYPES
|
||||
***************************************************************************/
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
a2bus_ramcard_device::a2bus_ramcard_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) :
|
||||
device_t(mconfig, type, name, tag, owner, clock, shortname, source),
|
||||
device_a2bus_card_interface(mconfig, *this)
|
||||
{
|
||||
}
|
||||
|
||||
a2bus_ramcard_device::a2bus_ramcard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
||||
device_t(mconfig, A2BUS_RAMCARD16K, "Apple II 16K Language Card", tag, owner, clock, "a2ram16k", __FILE__),
|
||||
device_a2bus_card_interface(mconfig, *this)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void a2bus_ramcard_device::device_start()
|
||||
{
|
||||
// set_a2bus_device makes m_slot valid
|
||||
set_a2bus_device();
|
||||
|
||||
memset(m_ram, 0, 16*1024);
|
||||
|
||||
save_item(NAME(m_inh_state));
|
||||
save_item(NAME(m_ram));
|
||||
save_item(NAME(m_dxxx_bank));
|
||||
save_item(NAME(m_last_offset));
|
||||
}
|
||||
|
||||
void a2bus_ramcard_device::device_reset()
|
||||
{
|
||||
m_inh_state = INH_NONE;
|
||||
m_dxxx_bank = 0;
|
||||
m_last_offset = -1;
|
||||
}
|
||||
|
||||
void a2bus_ramcard_device::do_io(int offset)
|
||||
{
|
||||
int old_inh_state = m_inh_state;
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0x1: case 0x3: case 0x9: case 0xb:
|
||||
if (offset != m_last_offset)
|
||||
{
|
||||
m_last_offset = offset;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
m_last_offset = offset;
|
||||
|
||||
m_inh_state = INH_NONE;
|
||||
m_dxxx_bank = 0;
|
||||
|
||||
if (offset & 0x1)
|
||||
{
|
||||
m_inh_state |= INH_WRITE;
|
||||
}
|
||||
|
||||
switch(offset & 0x03)
|
||||
{
|
||||
case 0x00:
|
||||
case 0x03:
|
||||
m_inh_state |= INH_READ;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(offset & 8))
|
||||
{
|
||||
m_dxxx_bank = 0x1000;
|
||||
}
|
||||
|
||||
if (m_inh_state != old_inh_state)
|
||||
{
|
||||
recalc_slot_inh();
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf("LC: new state %c%c dxxx=%04x\n",
|
||||
(m_inh_state & INH_READ) ? 'R' : 'x',
|
||||
(m_inh_state & INH_WRITE) ? 'W' : 'x',
|
||||
m_dxxx_bank);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
read_c0nx - called for reads from this card's c0nx space
|
||||
-------------------------------------------------*/
|
||||
|
||||
UINT8 a2bus_ramcard_device::read_c0nx(address_space &space, UINT8 offset)
|
||||
{
|
||||
do_io(offset & 0xf);
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
write_c0nx - called for writes to this card's c0nx space
|
||||
-------------------------------------------------*/
|
||||
|
||||
void a2bus_ramcard_device::write_c0nx(address_space &space, UINT8 offset, UINT8 data)
|
||||
{
|
||||
do_io(offset & 0xf);
|
||||
}
|
||||
|
||||
UINT8 a2bus_ramcard_device::read_inh_rom(address_space &space, UINT16 offset)
|
||||
{
|
||||
assert(m_inh_state & INH_READ); // this should never happen
|
||||
|
||||
if (offset < 0xe000)
|
||||
{
|
||||
return m_ram[(offset & 0xfff) + m_dxxx_bank];
|
||||
}
|
||||
|
||||
return m_ram[(offset & 0x1fff) + 0x2000];
|
||||
}
|
||||
|
||||
void a2bus_ramcard_device::write_inh_rom(address_space &space, UINT16 offset, UINT8 data)
|
||||
{
|
||||
// are writes enabled?
|
||||
if (!(m_inh_state & INH_WRITE))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (offset < 0xe000)
|
||||
{
|
||||
m_ram[(offset & 0xfff) + m_dxxx_bank] = data;
|
||||
return;
|
||||
}
|
||||
|
||||
m_ram[(offset & 0x1fff) + 0x2000] = data;
|
||||
}
|
||||
|
||||
int a2bus_ramcard_device::inh_type()
|
||||
{
|
||||
return m_inh_state;
|
||||
}
|
||||
|
55
src/emu/bus/a2bus/ramcard16k.h
Normal file
55
src/emu/bus/a2bus/ramcard16k.h
Normal file
@ -0,0 +1,55 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:R. Belmont
|
||||
/*********************************************************************
|
||||
|
||||
ramcard16k.h
|
||||
|
||||
Implemention of the Apple II 16K RAM card (aka "language card")
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef __A2BUS_RAMCARD16K__
|
||||
#define __A2BUS_RAMCARD16K__
|
||||
|
||||
#include "emu.h"
|
||||
#include "a2bus.h"
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
class a2bus_ramcard_device:
|
||||
public device_t,
|
||||
public device_a2bus_card_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
a2bus_ramcard_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
|
||||
a2bus_ramcard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
protected:
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
// overrides of standard a2bus slot functions
|
||||
virtual UINT8 read_c0nx(address_space &space, UINT8 offset);
|
||||
virtual void write_c0nx(address_space &space, UINT8 offset, UINT8 data);
|
||||
virtual UINT8 read_inh_rom(address_space &space, UINT16 offset);
|
||||
virtual void write_inh_rom(address_space &space, UINT16 offset, UINT8 data);
|
||||
virtual UINT16 inh_start() { return 0xd000; }
|
||||
virtual UINT16 inh_end() { return 0xffff; }
|
||||
virtual int inh_type();
|
||||
|
||||
private:
|
||||
void do_io(int offset);
|
||||
|
||||
int m_inh_state;
|
||||
int m_last_offset;
|
||||
int m_dxxx_bank;
|
||||
UINT8 m_ram[16*1024];
|
||||
};
|
||||
|
||||
// device type definition
|
||||
extern const device_type A2BUS_RAMCARD16K;
|
||||
|
||||
#endif /* __A2BUS_RAMCARD16K__ */
|
@ -913,6 +913,8 @@ BUSOBJS += $(BUSOBJ)/a2bus/timemasterho.o
|
||||
BUSOBJS += $(BUSOBJ)/a2bus/mouse.o
|
||||
BUSOBJS += $(BUSOBJ)/a2bus/corvfdc01.o
|
||||
BUSOBJS += $(BUSOBJ)/a2bus/corvfdc02.o
|
||||
BUSOBJS += $(BUSOBJ)/a2bus/ramcard16k.o
|
||||
BUSOBJS += $(BUSOBJ)/a2bus/ramcard128k.o
|
||||
endif
|
||||
|
||||
#-------------------------------------------------
|
||||
|
@ -147,10 +147,10 @@ void ay3600_device::device_timer(emu_timer &timer, device_timer_id id, int param
|
||||
|
||||
if (BIT(data, y))
|
||||
{
|
||||
ako = 1;
|
||||
|
||||
if (!(m_x_mask[x] & (1 << y)))
|
||||
{
|
||||
ako = 1;
|
||||
|
||||
m_x_mask[x] |= (1 << y);
|
||||
|
||||
if (m_b != b)
|
||||
@ -158,6 +158,12 @@ void ay3600_device::device_timer(emu_timer &timer, device_timer_id id, int param
|
||||
m_b = b;
|
||||
|
||||
m_write_data_ready(1);
|
||||
|
||||
if (ako != m_ako)
|
||||
{
|
||||
m_write_ako(ako);
|
||||
m_ako = ako;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
3558
src/mess/drivers/apple2e.c
Normal file
3558
src/mess/drivers/apple2e.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -143,7 +143,7 @@ PALETTE_INIT_MEMBER(apple2gs_state,apple2gs)
|
||||
{
|
||||
int i;
|
||||
|
||||
PALETTE_INIT_NAME(apple2)(palette);
|
||||
// PALETTE_INIT_NAME(apple2)(palette);
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
@ -271,7 +271,7 @@ WRITE_LINE_MEMBER(apple2gs_state::a2bus_nmi_w)
|
||||
|
||||
WRITE_LINE_MEMBER(apple2gs_state::a2bus_inh_w)
|
||||
{
|
||||
m_inh_slot = state;
|
||||
m_inh_slot = -1;
|
||||
apple2_update_memory();
|
||||
}
|
||||
|
||||
|
608
src/mess/drivers/tk2000.c
Normal file
608
src/mess/drivers/tk2000.c
Normal file
@ -0,0 +1,608 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:R. Belmont
|
||||
/***************************************************************************
|
||||
|
||||
tk2000.c - Microdigital TK2000
|
||||
|
||||
Driver by R. Belmont
|
||||
|
||||
This system is only vaguely Apple II compatible.
|
||||
The keyboard works entirely differently, which is a big deal.
|
||||
|
||||
$C05A - banks RAM from c100-ffff
|
||||
$C05B - banks ROM from c100-ffff
|
||||
|
||||
************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "machine/bankdev.h"
|
||||
#include "machine/ram.h"
|
||||
#include "sound/speaker.h"
|
||||
#include "imagedev/flopdrv.h"
|
||||
#include "imagedev/cassette.h"
|
||||
#include "formats/ap2_dsk.h"
|
||||
#include "cpu/m6502/m6502.h"
|
||||
#include "video/apple2.h"
|
||||
|
||||
#define A2_CPU_TAG "maincpu"
|
||||
#define A2_BUS_TAG "a2bus"
|
||||
#define A2_SPEAKER_TAG "speaker"
|
||||
#define A2_CASSETTE_TAG "tape"
|
||||
#define A2_UPPERBANK_TAG "inhbank"
|
||||
#define A2_VIDEO_TAG "a2video"
|
||||
|
||||
class tk2000_state : public driver_device
|
||||
{
|
||||
public:
|
||||
tk2000_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, A2_CPU_TAG),
|
||||
m_ram(*this, RAM_TAG),
|
||||
m_video(*this, A2_VIDEO_TAG),
|
||||
m_row0(*this, "ROW0"),
|
||||
m_row1(*this, "ROW1"),
|
||||
m_row2(*this, "ROW2"),
|
||||
m_row3(*this, "ROW3"),
|
||||
m_row4(*this, "ROW4"),
|
||||
m_row5(*this, "ROW5"),
|
||||
m_row6(*this, "ROW6"),
|
||||
m_row7(*this, "ROW7"),
|
||||
m_kbspecial(*this, "keyb_special"),
|
||||
m_sysconfig(*this, "a2_config"),
|
||||
m_speaker(*this, A2_SPEAKER_TAG),
|
||||
m_cassette(*this, A2_CASSETTE_TAG),
|
||||
m_upperbank(*this, A2_UPPERBANK_TAG)
|
||||
{ }
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<ram_device> m_ram;
|
||||
required_device<a2_video_device> m_video;
|
||||
required_ioport m_row0, m_row1, m_row2, m_row3, m_row4, m_row5, m_row6, m_row7;
|
||||
required_ioport m_kbspecial;
|
||||
required_ioport m_sysconfig;
|
||||
required_device<speaker_sound_device> m_speaker;
|
||||
required_device<cassette_image_device> m_cassette;
|
||||
required_device<address_map_bank_device> m_upperbank;
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(apple2_interrupt);
|
||||
|
||||
virtual void machine_start();
|
||||
virtual void machine_reset();
|
||||
|
||||
DECLARE_PALETTE_INIT(tk2000);
|
||||
UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
DECLARE_READ8_MEMBER(ram_r);
|
||||
DECLARE_WRITE8_MEMBER(ram_w);
|
||||
DECLARE_READ8_MEMBER(c000_r);
|
||||
DECLARE_WRITE8_MEMBER(c000_w);
|
||||
DECLARE_READ8_MEMBER(c080_r);
|
||||
DECLARE_WRITE8_MEMBER(c080_w);
|
||||
DECLARE_READ8_MEMBER(c100_r);
|
||||
DECLARE_WRITE8_MEMBER(c100_w);
|
||||
|
||||
private:
|
||||
int m_speaker_state;
|
||||
int m_cassette_state;
|
||||
|
||||
UINT8 m_strobe;
|
||||
|
||||
bool m_page2;
|
||||
|
||||
UINT8 *m_ram_ptr;
|
||||
int m_ram_size;
|
||||
|
||||
void do_io(address_space &space, int offset);
|
||||
UINT8 read_floatingbus();
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
START/RESET
|
||||
***************************************************************************/
|
||||
|
||||
void tk2000_state::machine_start()
|
||||
{
|
||||
m_ram_ptr = m_ram->pointer();
|
||||
m_ram_size = m_ram->size();
|
||||
m_speaker_state = 0;
|
||||
m_speaker->level_w(m_speaker_state);
|
||||
m_cassette_state = 0;
|
||||
m_cassette->output(-1.0f);
|
||||
m_upperbank->set_bank(0);
|
||||
|
||||
// setup save states
|
||||
save_item(NAME(m_speaker_state));
|
||||
save_item(NAME(m_cassette_state));
|
||||
save_item(NAME(m_strobe));
|
||||
save_item(NAME(m_page2));
|
||||
|
||||
// setup video pointers
|
||||
m_video->m_ram_ptr = m_ram_ptr;
|
||||
m_video->m_aux_ptr = m_ram_ptr;
|
||||
m_video->m_char_ptr = NULL;
|
||||
m_video->m_char_size = 0;
|
||||
}
|
||||
|
||||
void tk2000_state::machine_reset()
|
||||
{
|
||||
m_page2 = false;
|
||||
m_strobe = 0;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
VIDEO
|
||||
***************************************************************************/
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(tk2000_state::apple2_interrupt)
|
||||
{
|
||||
int scanline = param;
|
||||
|
||||
if((scanline % 8) == 0)
|
||||
machine().first_screen()->update_partial(machine().first_screen()->vpos());
|
||||
|
||||
// update the video system's shadow copy of the system config at the end of the frame
|
||||
if (scanline == 192)
|
||||
{
|
||||
m_video->m_sysconfig = m_sysconfig->read();
|
||||
}
|
||||
}
|
||||
|
||||
PALETTE_INIT_MEMBER(tk2000_state, tk2000)
|
||||
{
|
||||
m_video->palette_init_apple2(palette);
|
||||
}
|
||||
|
||||
UINT32 tk2000_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
m_video->hgr_update(screen, bitmap, cliprect, 0, 191);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
I/O
|
||||
***************************************************************************/
|
||||
// most softswitches don't care about read vs write, so handle them here
|
||||
void tk2000_state::do_io(address_space &space, int offset)
|
||||
{
|
||||
if(space.debugger_access())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0x20:
|
||||
m_cassette_state ^= 1;
|
||||
m_cassette->output(m_cassette_state ? 1.0f : -1.0f);
|
||||
break;
|
||||
|
||||
case 0x30:
|
||||
m_speaker_state ^= 1;
|
||||
m_speaker->level_w(m_speaker_state);
|
||||
break;
|
||||
|
||||
case 0x50: // monochrome
|
||||
break;
|
||||
|
||||
case 0x51: // color
|
||||
break;
|
||||
|
||||
case 0x54: // set page 1
|
||||
m_page2 = false;
|
||||
m_video->m_page2 = false;
|
||||
break;
|
||||
|
||||
case 0x55: // set page 2
|
||||
m_page2 = true;
|
||||
m_video->m_page2 = true;
|
||||
break;
|
||||
|
||||
case 0x5a: // ROM
|
||||
m_upperbank->set_bank(0);
|
||||
break;
|
||||
|
||||
case 0x5b: // RAM
|
||||
m_upperbank->set_bank(1);
|
||||
break;
|
||||
|
||||
case 0x5e:
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("do_io: unk access @ $C0%02X\n", offset & 0xff);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
READ8_MEMBER(tk2000_state::c000_r)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0x00:
|
||||
return 0;
|
||||
|
||||
case 0x10: // keyboard strobe
|
||||
return m_strobe;
|
||||
|
||||
case 0x60: // cassette in
|
||||
case 0x68:
|
||||
return m_cassette->input() > 0.0 ? 0x80 : 0;
|
||||
|
||||
default:
|
||||
do_io(space, offset);
|
||||
break;
|
||||
}
|
||||
|
||||
return read_floatingbus();
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(tk2000_state::c000_w)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0x00: // write row mask for keyboard scan
|
||||
switch (data)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case 0x01: m_strobe = m_row0->read(); break;
|
||||
case 0x02: m_strobe = m_row1->read(); break;
|
||||
case 0x04: m_strobe = m_row2->read(); break;
|
||||
case 0x08: m_strobe = m_row3->read(); break;
|
||||
case 0x10: m_strobe = m_row4->read(); break;
|
||||
case 0x20: m_strobe = m_row5->read(); break;
|
||||
case 0x40: m_strobe = m_row6->read(); break;
|
||||
case 0x80: m_strobe = m_row7->read(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x5f:
|
||||
m_strobe = m_kbspecial->read();
|
||||
break;
|
||||
|
||||
default:
|
||||
do_io(space, offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
READ8_MEMBER(tk2000_state::c080_r)
|
||||
{
|
||||
return read_floatingbus();
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(tk2000_state::c080_w)
|
||||
{
|
||||
}
|
||||
|
||||
READ8_MEMBER(tk2000_state::c100_r)
|
||||
{
|
||||
return m_ram_ptr[offset + 0xc100];
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(tk2000_state::c100_w)
|
||||
{
|
||||
m_ram_ptr[offset + 0xc100] = data;
|
||||
}
|
||||
|
||||
// floating bus code from old machine/apple2: needs to be reworked based on real beam position to enable e.g. Bob Bishop's screen splitter
|
||||
UINT8 tk2000_state::read_floatingbus()
|
||||
{
|
||||
enum
|
||||
{
|
||||
// scanner types
|
||||
kScannerNone = 0, kScannerApple2, kScannerApple2e,
|
||||
|
||||
// scanner constants
|
||||
kHBurstClock = 53, // clock when Color Burst starts
|
||||
kHBurstClocks = 4, // clocks per Color Burst duration
|
||||
kHClock0State = 0x18, // H[543210] = 011000
|
||||
kHClocks = 65, // clocks per horizontal scan (including HBL)
|
||||
kHPEClock = 40, // clock when HPE (horizontal preset enable) goes low
|
||||
kHPresetClock = 41, // clock when H state presets
|
||||
kHSyncClock = 49, // clock when HSync starts
|
||||
kHSyncClocks = 4, // clocks per HSync duration
|
||||
kNTSCScanLines = 262, // total scan lines including VBL (NTSC)
|
||||
kNTSCVSyncLine = 224, // line when VSync starts (NTSC)
|
||||
kPALScanLines = 312, // total scan lines including VBL (PAL)
|
||||
kPALVSyncLine = 264, // line when VSync starts (PAL)
|
||||
kVLine0State = 0x100, // V[543210CBA] = 100000000
|
||||
kVPresetLine = 256, // line when V state presets
|
||||
kVSyncLines = 4, // lines per VSync duration
|
||||
kClocksPerVSync = kHClocks * kNTSCScanLines // FIX: NTSC only?
|
||||
};
|
||||
|
||||
// vars
|
||||
//
|
||||
int i, Hires, Mixed, Page2, _80Store, ScanLines, /* VSyncLine, ScanCycles,*/
|
||||
h_clock, h_state, h_0, h_1, h_2, h_3, h_4, h_5,
|
||||
v_line, v_state, v_A, v_B, v_C, v_0, v_1, v_2, v_3, v_4, /* v_5, */
|
||||
_hires, addend0, addend1, addend2, sum, address;
|
||||
|
||||
// video scanner data
|
||||
//
|
||||
i = m_maincpu->total_cycles() % kClocksPerVSync; // cycles into this VSync
|
||||
|
||||
// machine state switches
|
||||
//
|
||||
Hires = 1; //m_video->m_hires ? 1 : 0;
|
||||
Mixed = 0; //m_video->m_mix ? 1 : 0;
|
||||
Page2 = m_page2 ? 1 : 0;
|
||||
_80Store = 0;
|
||||
|
||||
// calculate video parameters according to display standard
|
||||
//
|
||||
ScanLines = 1 ? kNTSCScanLines : kPALScanLines; // FIX: NTSC only?
|
||||
// VSyncLine = 1 ? kNTSCVSyncLine : kPALVSyncLine; // FIX: NTSC only?
|
||||
// ScanCycles = ScanLines * kHClocks;
|
||||
|
||||
// calculate horizontal scanning state
|
||||
//
|
||||
h_clock = (i + kHPEClock) % kHClocks; // which horizontal scanning clock
|
||||
h_state = kHClock0State + h_clock; // H state bits
|
||||
if (h_clock >= kHPresetClock) // check for horizontal preset
|
||||
{
|
||||
h_state -= 1; // correct for state preset (two 0 states)
|
||||
}
|
||||
h_0 = (h_state >> 0) & 1; // get horizontal state bits
|
||||
h_1 = (h_state >> 1) & 1;
|
||||
h_2 = (h_state >> 2) & 1;
|
||||
h_3 = (h_state >> 3) & 1;
|
||||
h_4 = (h_state >> 4) & 1;
|
||||
h_5 = (h_state >> 5) & 1;
|
||||
|
||||
// calculate vertical scanning state
|
||||
//
|
||||
v_line = i / kHClocks; // which vertical scanning line
|
||||
v_state = kVLine0State + v_line; // V state bits
|
||||
if ((v_line >= kVPresetLine)) // check for previous vertical state preset
|
||||
{
|
||||
v_state -= ScanLines; // compensate for preset
|
||||
}
|
||||
v_A = (v_state >> 0) & 1; // get vertical state bits
|
||||
v_B = (v_state >> 1) & 1;
|
||||
v_C = (v_state >> 2) & 1;
|
||||
v_0 = (v_state >> 3) & 1;
|
||||
v_1 = (v_state >> 4) & 1;
|
||||
v_2 = (v_state >> 5) & 1;
|
||||
v_3 = (v_state >> 6) & 1;
|
||||
v_4 = (v_state >> 7) & 1;
|
||||
//v_5 = (v_state >> 8) & 1;
|
||||
|
||||
// calculate scanning memory address
|
||||
//
|
||||
_hires = Hires;
|
||||
if (Hires && Mixed && (v_4 & v_2))
|
||||
{
|
||||
_hires = 0; // (address is in text memory)
|
||||
}
|
||||
|
||||
addend0 = 0x68; // 1 1 0 1
|
||||
addend1 = (h_5 << 5) | (h_4 << 4) | (h_3 << 3);
|
||||
addend2 = (v_4 << 6) | (v_3 << 5) | (v_4 << 4) | (v_3 << 3);
|
||||
sum = (addend0 + addend1 + addend2) & (0x0F << 3);
|
||||
|
||||
address = 0;
|
||||
address |= h_0 << 0; // a0
|
||||
address |= h_1 << 1; // a1
|
||||
address |= h_2 << 2; // a2
|
||||
address |= sum; // a3 - aa6
|
||||
address |= v_0 << 7; // a7
|
||||
address |= v_1 << 8; // a8
|
||||
address |= v_2 << 9; // a9
|
||||
address |= ((_hires) ? v_A : (1 ^ (Page2 & (1 ^ _80Store)))) << 10; // a10
|
||||
address |= ((_hires) ? v_B : (Page2 & (1 ^ _80Store))) << 11; // a11
|
||||
if (_hires) // hires?
|
||||
{
|
||||
// Y: insert hires only address bits
|
||||
//
|
||||
address |= v_C << 12; // a12
|
||||
address |= (1 ^ (Page2 & (1 ^ _80Store))) << 13; // a13
|
||||
address |= (Page2 & (1 ^ _80Store)) << 14; // a14
|
||||
}
|
||||
else
|
||||
{
|
||||
// N: text, so no higher address bits unless Apple ][, not Apple //e
|
||||
//
|
||||
if ((1) && // Apple ][? // FIX: check for Apple ][? (FB is most useful in old games)
|
||||
(kHPEClock <= h_clock) && // Y: HBL?
|
||||
(h_clock <= (kHClocks - 1)))
|
||||
{
|
||||
address |= 1 << 12; // Y: a12 (add $1000 to address!)
|
||||
}
|
||||
}
|
||||
|
||||
return m_ram_ptr[address % m_ram_size]; // FIX: this seems to work, but is it right!?
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
ADDRESS MAP
|
||||
***************************************************************************/
|
||||
|
||||
READ8_MEMBER(tk2000_state::ram_r)
|
||||
{
|
||||
if (offset < m_ram_size)
|
||||
{
|
||||
return m_ram_ptr[offset];
|
||||
}
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(tk2000_state::ram_w)
|
||||
{
|
||||
if (offset < m_ram_size)
|
||||
{
|
||||
m_ram_ptr[offset] = data;
|
||||
}
|
||||
}
|
||||
|
||||
static ADDRESS_MAP_START( apple2_map, AS_PROGRAM, 8, tk2000_state )
|
||||
AM_RANGE(0x0000, 0xbfff) AM_READWRITE(ram_r, ram_w)
|
||||
AM_RANGE(0xc000, 0xc07f) AM_READWRITE(c000_r, c000_w)
|
||||
AM_RANGE(0xc080, 0xc0ff) AM_READWRITE(c080_r, c080_w)
|
||||
AM_RANGE(0xc100, 0xffff) AM_DEVICE(A2_UPPERBANK_TAG, address_map_bank_device, amap8)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START( inhbank_map, AS_PROGRAM, 8, tk2000_state )
|
||||
AM_RANGE(0x0000, 0x3eff) AM_ROM AM_REGION("maincpu", 0x100)
|
||||
AM_RANGE(0x4000, 0x7eff) AM_READWRITE(c100_r, c100_w)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
/***************************************************************************
|
||||
INPUT PORTS
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
TK2000 matrix:
|
||||
|
||||
0 1 2 3 4 5 6 7
|
||||
0SHIF B V C X Z
|
||||
1 G F D S A
|
||||
2 SPC T R E W Q
|
||||
3 LFT 5 4 3 2 1
|
||||
4 RGT 6 7 8 9 0
|
||||
5 DWN Y U I O P
|
||||
6 UP H J K L :
|
||||
7 RTN N M , . ?
|
||||
|
||||
write row mask 1/2/4/8/10/20/40/80 to $C000
|
||||
read column at $C010
|
||||
|
||||
If $C05F is written, the Ctrl key is read in bit 0 of $C010 immediately afterwards.
|
||||
*/
|
||||
static INPUT_PORTS_START( tk2000 )
|
||||
PORT_START("ROW0")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_CHAR('b')
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_CHAR('v')
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CHAR('c')
|
||||
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CHAR('x')
|
||||
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_CHAR('z')
|
||||
|
||||
PORT_START("ROW1")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_CHAR('g')
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_CHAR('f')
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CHAR('d')
|
||||
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_CHAR('s')
|
||||
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_CHAR('a')
|
||||
|
||||
PORT_START("ROW2")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_CHAR('t')
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_CHAR('r')
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_CHAR('e')
|
||||
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_CHAR('w')
|
||||
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_CHAR('q')
|
||||
|
||||
PORT_START("ROW3")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(UTF8_LEFT) PORT_CODE(KEYCODE_LEFT)
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%')
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#')
|
||||
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('\"')
|
||||
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
|
||||
|
||||
PORT_START("ROW4")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(UTF8_RIGHT) PORT_CODE(KEYCODE_RIGHT)
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&')
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'')
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(')
|
||||
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')')
|
||||
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')')
|
||||
|
||||
PORT_START("ROW5")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(UTF8_DOWN) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(10)
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_CHAR('y')
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_CHAR('u')
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_CHAR('i')
|
||||
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_CHAR('o')
|
||||
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CHAR('p')
|
||||
|
||||
PORT_START("ROW6")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(UTF8_UP) PORT_CODE(KEYCODE_UP)
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_CHAR('h')
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_CHAR('j')
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_CHAR('k')
|
||||
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_CHAR('l')
|
||||
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':')
|
||||
|
||||
PORT_START("ROW7")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_CHAR('n')
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_CHAR('m')
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')
|
||||
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>')
|
||||
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?')
|
||||
|
||||
PORT_START("keyb_special")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Control") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_SHIFT_2)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
|
||||
PORT_START("a2_config")
|
||||
PORT_CONFNAME(0x03, 0x00, "Composite monitor type")
|
||||
PORT_CONFSETTING(0x00, "Color")
|
||||
PORT_CONFSETTING(0x01, "B&W")
|
||||
PORT_CONFSETTING(0x02, "Green")
|
||||
PORT_CONFSETTING(0x03, "Amber")
|
||||
INPUT_PORTS_END
|
||||
|
||||
static MACHINE_CONFIG_START( tk2000, tk2000_state )
|
||||
/* basic machine hardware */
|
||||
MCFG_CPU_ADD(A2_CPU_TAG, M6502, 1021800) /* close to actual CPU frequency of 1.020484 MHz */
|
||||
MCFG_CPU_PROGRAM_MAP(apple2_map)
|
||||
MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", tk2000_state, apple2_interrupt, "screen", 0, 1)
|
||||
MCFG_QUANTUM_TIME(attotime::from_hz(60))
|
||||
|
||||
MCFG_DEVICE_ADD(A2_VIDEO_TAG, APPLE2_VIDEO, XTAL_14_31818MHz)
|
||||
|
||||
MCFG_SCREEN_ADD("screen", RASTER)
|
||||
MCFG_SCREEN_REFRESH_RATE(60)
|
||||
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
|
||||
MCFG_SCREEN_SIZE(280*2, 262)
|
||||
MCFG_SCREEN_VISIBLE_AREA(0, (280*2)-1,0,192-1)
|
||||
MCFG_SCREEN_UPDATE_DRIVER(tk2000_state, screen_update)
|
||||
MCFG_SCREEN_PALETTE("palette")
|
||||
|
||||
MCFG_PALETTE_ADD("palette", 16)
|
||||
MCFG_PALETTE_INIT_OWNER(tk2000_state, tk2000)
|
||||
|
||||
/* sound hardware */
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
MCFG_SOUND_ADD(A2_SPEAKER_TAG, SPEAKER_SOUND, 0)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
|
||||
|
||||
/* /INH banking */
|
||||
MCFG_DEVICE_ADD(A2_UPPERBANK_TAG, ADDRESS_MAP_BANK, 0)
|
||||
MCFG_DEVICE_PROGRAM_MAP(inhbank_map)
|
||||
MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE)
|
||||
MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8)
|
||||
MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000)
|
||||
|
||||
MCFG_RAM_ADD(RAM_TAG)
|
||||
MCFG_RAM_DEFAULT_SIZE("64K")
|
||||
|
||||
MCFG_CASSETTE_ADD(A2_CASSETTE_TAG)
|
||||
MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Game driver(s)
|
||||
|
||||
***************************************************************************/
|
||||
ROM_START(tk2000)
|
||||
ROM_REGION(0x4000,"maincpu",0)
|
||||
ROM_LOAD( "tk2000.rom", 0x000000, 0x004000, CRC(dfdbacc3) SHA1(bb37844c31616046630868a4399ee3d55d6df277) )
|
||||
ROM_END
|
||||
|
||||
/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME */
|
||||
COMP( 1984, tk2000, 0, 0, tk2000, tk2000, driver_device, 0, "Microdigital", "TK2000", GAME_NOT_WORKING )
|
@ -928,6 +928,7 @@ static void apple2_mem_Cx00(running_machine &machine, offs_t begin, offs_t end,
|
||||
static void apple2_mem_C300(running_machine &machine, offs_t begin, offs_t end, apple2_meminfo *meminfo)
|
||||
{
|
||||
apple2_state *state = machine.driver_data<apple2_state>();
|
||||
|
||||
if (((state->m_flags & (VAR_INTCXROM|VAR_SLOTC3ROM)) != VAR_SLOTC3ROM) && !(state->m_flags_mask & VAR_SLOTC3ROM))
|
||||
{
|
||||
meminfo->read_mem = (begin & 0x0FFF) | (state->m_flags & VAR_ROMSWITCH ? 0x4000 : 0x0000) | APPLE2_MEM_ROM;
|
||||
@ -982,7 +983,7 @@ static void apple2_mem_D000(running_machine &machine, offs_t begin, offs_t end,
|
||||
{
|
||||
apple2_state *state = machine.driver_data<apple2_state>();
|
||||
|
||||
if (state->m_inh_slot == INH_SLOT_INVALID)
|
||||
if (state->m_inh_slot == -1)
|
||||
{
|
||||
if (state->m_flags & VAR_LCRAM)
|
||||
{
|
||||
@ -1028,7 +1029,7 @@ static void apple2_mem_E000(running_machine &machine, offs_t begin, offs_t end,
|
||||
{
|
||||
apple2_state *state = machine.driver_data<apple2_state>();
|
||||
|
||||
if (state->m_inh_slot == INH_SLOT_INVALID)
|
||||
if (state->m_inh_slot == -1)
|
||||
{
|
||||
if (state->m_flags & VAR_LCRAM)
|
||||
{
|
||||
@ -1921,12 +1922,10 @@ READ8_MEMBER ( apple2_state::apple2_c05x_r )
|
||||
if (offset == 0xa) // RAM
|
||||
{
|
||||
apple2_setvar(VAR_TK2000RAM, ~0);
|
||||
printf("TK2000: RAM (PC %x)\n", m_maincpu->pc());
|
||||
}
|
||||
else if (offset == 0xb) // ROM
|
||||
{
|
||||
apple2_setvar(0, ~VAR_TK2000RAM);
|
||||
printf("TK2000: ROM (PC %x)\n", m_maincpu->pc());
|
||||
}
|
||||
}
|
||||
|
||||
@ -2226,7 +2225,7 @@ const applefdc_interface apple2_fdc_interface =
|
||||
|
||||
void apple2_state::apple2_init_common()
|
||||
{
|
||||
m_inh_slot = INH_SLOT_INVALID;
|
||||
m_inh_slot = -1;
|
||||
m_flags = 0;
|
||||
m_fdc_diskreg = 0;
|
||||
|
||||
|
@ -993,8 +993,9 @@ $(MESSOBJ)/apollo.a: \
|
||||
|
||||
$(MESSOBJ)/apple.a: \
|
||||
$(MESS_DRIVERS)/apple1.o $(MESS_MACHINE)/apple1.o $(MESS_VIDEO)/apple1.o \
|
||||
$(MESS_DRIVERS)/apple2.o $(MESS_MACHINE)/apple2.o $(MESS_VIDEO)/apple2.o \
|
||||
$(MESS_DRIVERS)/apple2gs.o $(MESS_MACHINE)/apple2gs.o $(MESS_VIDEO)/apple2gs.o \
|
||||
$(MESS_DRIVERS)/apple2.o $(MESS_DRIVERS)/apple2e.o $(MESS_MACHINE)/apple2.o $(MESS_VIDEO)/apple2.o \
|
||||
$(MESS_DRIVERS)/tk2000.o \
|
||||
$(MESS_DRIVERS)/apple2gs.o $(MESS_MACHINE)/apple2gs.o $(MESS_VIDEO)/apple2gs.o \
|
||||
$(MESS_DRIVERS)/apple3.o $(MESS_MACHINE)/apple3.o $(MESS_VIDEO)/apple3.o \
|
||||
$(MESS_DRIVERS)/lisa.o $(MESS_MACHINE)/lisa.o \
|
||||
$(MESS_DRIVERS)/mac.o $(MESS_AUDIO)/mac.o $(MESS_MACHINE)/egret.o $(MESS_MACHINE)/mac.o $(MESS_MACHINE)/macadb.o $(MESS_MACHINE)/macrtc.o $(MESS_MACHINE)/mackbd.o $(MESS_MACHINE)/swim.o $(MESS_VIDEO)/mac.o \
|
||||
@ -2018,9 +2019,10 @@ $(MESS_DRIVERS)/mac.o: $(MESSSRC)/drivers/mac.c \
|
||||
$(MESS_MACHINE)/egret.o: $(MESSSRC)/machine/egret.c\
|
||||
$(MESSSRC)/machine/egret.h
|
||||
|
||||
$(MESS_DRIVERS)/apple2.o: $(MESSSRC)/includes/apple2.h
|
||||
$(MESS_DRIVERS)/apple2.o: $(MESSSRC)/video/apple2.h
|
||||
$(MESS_DRIVERS)/apple2e.o: $(MESSSRC)/video/apple2.h
|
||||
$(MESS_MACHINE)/apple2.o: $(MESSSRC)/includes/apple2.h
|
||||
$(MESS_VIDEO)/apple2.o: $(MESSSRC)/includes/apple2.h
|
||||
$(MESS_VIDEO)/apple2.o: $(MESSSRC)/includes/apple2.h $(MESSSRC)/video/apple2.h
|
||||
$(MESS_DRIVERS)/apple2gs.o: $(MESSSRC)/includes/apple2.h $(MESSSRC)/includes/apple2gs.h
|
||||
$(MESS_MACHINE)/apple2gs.o: $(MESSSRC)/includes/apple2.h $(MESSSRC)/includes/apple2gs.h
|
||||
$(MESS_VIDEO)/apple2gs.o: $(MESSSRC)/includes/apple2.h $(MESSSRC)/includes/apple2gs.h
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include "includes/apple2.h"
|
||||
#include "machine/ram.h"
|
||||
|
||||
#include "video/apple2.h"
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
@ -664,3 +666,803 @@ UINT32 apple2_state::screen_update_apple2(screen_device &screen, bitmap_ind16 &b
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
New implementation
|
||||
*/
|
||||
|
||||
const device_type APPLE2_VIDEO = &device_creator<a2_video_device>;
|
||||
|
||||
//-------------------------------------------------
|
||||
// a2_video_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
a2_video_device::a2_video_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, APPLE2_VIDEO, "Apple II video", tag, owner, clock, "a2video", __FILE__)
|
||||
{
|
||||
}
|
||||
|
||||
void a2_video_device::device_start()
|
||||
{
|
||||
static const UINT8 hires_artifact_color_table[] =
|
||||
{
|
||||
BLACK, PURPLE, GREEN, WHITE,
|
||||
BLACK, BLUE, ORANGE, WHITE
|
||||
};
|
||||
static const UINT8 dhires_artifact_color_table[] =
|
||||
{
|
||||
BLACK, DKGREEN, BROWN, GREEN,
|
||||
DKRED, DKGRAY, ORANGE, YELLOW,
|
||||
DKBLUE, BLUE, GRAY, AQUA,
|
||||
PURPLE, LTBLUE, PINK, WHITE
|
||||
};
|
||||
|
||||
// generate hi-res artifact data
|
||||
int i, j;
|
||||
UINT16 c;
|
||||
|
||||
/* 2^3 dependent pixels * 2 color sets * 2 offsets */
|
||||
m_hires_artifact_map = auto_alloc_array(machine(), UINT16, 8 * 2 * 2);
|
||||
|
||||
/* build hires artifact map */
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
if (i & 0x02)
|
||||
{
|
||||
if ((i & 0x05) != 0)
|
||||
c = 3;
|
||||
else
|
||||
c = j ? 2 : 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((i & 0x05) == 0x05)
|
||||
c = j ? 1 : 2;
|
||||
else
|
||||
c = 0;
|
||||
}
|
||||
m_hires_artifact_map[ 0 + j*8 + i] = hires_artifact_color_table[(c + 0) % 8];
|
||||
m_hires_artifact_map[16 + j*8 + i] = hires_artifact_color_table[(c + 4) % 8];
|
||||
}
|
||||
}
|
||||
|
||||
/* 2^4 dependent pixels */
|
||||
m_dhires_artifact_map = auto_alloc_array(machine(), UINT16, 16);
|
||||
|
||||
/* build double hires artifact map */
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
m_dhires_artifact_map[i] = dhires_artifact_color_table[i];
|
||||
}
|
||||
|
||||
save_item(NAME(m_page2));
|
||||
save_item(NAME(m_flash));
|
||||
save_item(NAME(m_mix));
|
||||
save_item(NAME(m_graphics));
|
||||
save_item(NAME(m_hires));
|
||||
save_item(NAME(m_dhires));
|
||||
save_item(NAME(m_80col));
|
||||
save_item(NAME(m_altcharset));
|
||||
}
|
||||
|
||||
void a2_video_device::device_reset()
|
||||
{
|
||||
m_page2 = false;
|
||||
m_graphics = false;
|
||||
m_hires = false;
|
||||
m_80col = false;
|
||||
m_altcharset = false;
|
||||
m_dhires = false;
|
||||
m_flash = false;
|
||||
m_sysconfig = 0;
|
||||
}
|
||||
|
||||
void a2_video_device::plot_text_character(bitmap_ind16 &bitmap, int xpos, int ypos, int xscale, UINT32 code,
|
||||
const UINT8 *textgfx_data, UINT32 textgfx_datalen, int fg, int bg)
|
||||
{
|
||||
int x, y, i;
|
||||
const UINT8 *chardata;
|
||||
UINT16 color;
|
||||
|
||||
if (!m_altcharset)
|
||||
{
|
||||
if ((code >= 0x40) && (code <= 0x7f))
|
||||
{
|
||||
code &= 0x3f;
|
||||
|
||||
if (m_flash)
|
||||
{
|
||||
i = fg;
|
||||
fg = bg;
|
||||
bg = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((code >= 0x60) && (code <= 0x7f))
|
||||
{
|
||||
code |= 0x80; // map to lowercase normal
|
||||
i = fg; // and flip the color
|
||||
fg = bg;
|
||||
bg = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* look up the character data */
|
||||
chardata = &textgfx_data[(code * 8)];
|
||||
|
||||
for (y = 0; y < 8; y++)
|
||||
{
|
||||
for (x = 0; x < 7; x++)
|
||||
{
|
||||
color = (chardata[y] & (1 << x)) ? bg : fg;
|
||||
|
||||
for (i = 0; i < xscale; i++)
|
||||
{
|
||||
bitmap.pix16(ypos + y, xpos + (x * xscale) + i) = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void a2_video_device::plot_text_character_orig(bitmap_ind16 &bitmap, int xpos, int ypos, int xscale, UINT32 code,
|
||||
const UINT8 *textgfx_data, UINT32 textgfx_datalen, int fg, int bg)
|
||||
{
|
||||
int x, y, i;
|
||||
const UINT8 *chardata;
|
||||
UINT16 color;
|
||||
|
||||
if ((code >= 0x40) && (code <= 0x7f))
|
||||
{
|
||||
if (m_flash)
|
||||
{
|
||||
i = fg;
|
||||
fg = bg;
|
||||
bg = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* look up the character data */
|
||||
chardata = &textgfx_data[(code * 8)];
|
||||
|
||||
for (y = 0; y < 8; y++)
|
||||
{
|
||||
for (x = 0; x < 7; x++)
|
||||
{
|
||||
color = (chardata[y] & (1 << (6-x))) ? fg : bg;
|
||||
|
||||
for (i = 0; i < xscale; i++)
|
||||
{
|
||||
bitmap.pix16(ypos + y, xpos + (x * xscale) + i) = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void a2_video_device::lores_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow)
|
||||
{
|
||||
int row, col, y, x;
|
||||
UINT8 code;
|
||||
UINT32 start_address = m_page2 ? 0x0800 : 0x0400;
|
||||
UINT32 address;
|
||||
int fg;
|
||||
|
||||
switch (m_sysconfig & 0x03)
|
||||
{
|
||||
case 0: fg = WHITE; break;
|
||||
case 1: fg = WHITE; break;
|
||||
case 2: fg = GREEN; break;
|
||||
case 3: fg = ORANGE; break;
|
||||
}
|
||||
|
||||
/* perform adjustments */
|
||||
beginrow = MAX(beginrow, cliprect.min_y - (cliprect.min_y % 8));
|
||||
endrow = MIN(endrow, cliprect.max_y - (cliprect.max_y % 8) + 7);
|
||||
|
||||
if (!(m_sysconfig & 0x03))
|
||||
{
|
||||
for (row = beginrow; row <= endrow; row += 8)
|
||||
{
|
||||
for (col = 0; col < 40; col++)
|
||||
{
|
||||
/* calculate adderss */
|
||||
address = start_address + ((((row/8) & 0x07) << 7) | (((row/8) & 0x18) * 5 + col));
|
||||
|
||||
/* perform the lookup */
|
||||
code = m_ram_ptr[address];
|
||||
|
||||
/* and now draw */
|
||||
for (y = 0; y < 4; y++)
|
||||
{
|
||||
for (x = 0; x < 14; x++)
|
||||
bitmap.pix16(row + y, col * 14 + x) = (code >> 0) & 0x0F;
|
||||
}
|
||||
for (y = 4; y < 8; y++)
|
||||
{
|
||||
for (x = 0; x < 14; x++)
|
||||
bitmap.pix16(row + y, col * 14 + x) = (code >> 4) & 0x0F;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (row = beginrow; row <= endrow; row += 8)
|
||||
{
|
||||
for (col = 0; col < 40; col++)
|
||||
{
|
||||
UINT8 bits;
|
||||
|
||||
/* calculate adderss */
|
||||
address = start_address + ((((row/8) & 0x07) << 7) | (((row/8) & 0x18) * 5 + col));
|
||||
|
||||
/* perform the lookup */
|
||||
code = m_ram_ptr[address];
|
||||
|
||||
bits = (code >> 0) & 0x0F;
|
||||
/* and now draw */
|
||||
for (y = 0; y < 4; y++)
|
||||
{
|
||||
for (x = 0; x < 14; x++)
|
||||
{
|
||||
bitmap.pix16(row + y, col * 14 + x) = bits & (1 << (x % 4)) ? fg : 0;
|
||||
}
|
||||
}
|
||||
|
||||
bits = (code >> 4) & 0x0F;
|
||||
for (y = 4; y < 8; y++)
|
||||
{
|
||||
for (x = 0; x < 14; x++)
|
||||
bitmap.pix16(row + y, col * 14 + x) = bits & (1 << (x % 4)) ? fg : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void a2_video_device::dlores_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow)
|
||||
{
|
||||
int row, col, y;
|
||||
UINT8 code, auxcode;
|
||||
UINT32 start_address = m_page2 ? 0x0800 : 0x0400;
|
||||
UINT32 address;
|
||||
UINT16 *pixel;
|
||||
static const int aux_colors[16] = { 0, 2, 4, 6, 8, 0xa, 0xc, 0xe, 1, 3, 5, 7, 9, 0xb, 0xd, 0xf };
|
||||
int fg;
|
||||
|
||||
switch (m_sysconfig & 0x03)
|
||||
{
|
||||
case 0: fg = WHITE; break;
|
||||
case 1: fg = WHITE; break;
|
||||
case 2: fg = GREEN; break;
|
||||
case 3: fg = ORANGE; break;
|
||||
}
|
||||
|
||||
/* perform adjustments */
|
||||
beginrow = MAX(beginrow, cliprect.min_y - (cliprect.min_y % 8));
|
||||
endrow = MIN(endrow, cliprect.max_y - (cliprect.max_y % 8) + 7);
|
||||
|
||||
if (!(m_sysconfig & 0x03))
|
||||
{
|
||||
for (row = beginrow; row <= endrow; row += 8)
|
||||
{
|
||||
for (col = 0; col < 40; col++)
|
||||
{
|
||||
/* calculate adderss */
|
||||
address = start_address + ((((row/8) & 0x07) << 7) | (((row/8) & 0x18) * 5 + col));
|
||||
|
||||
/* perform the lookup */
|
||||
code = m_ram_ptr[address];
|
||||
auxcode = m_aux_ptr[address];
|
||||
|
||||
/* and now draw */
|
||||
for (y = 0; y < 4; y++)
|
||||
{
|
||||
UINT16 *vram = &bitmap.pix16(row + y, (col * 14));
|
||||
|
||||
*vram++ = aux_colors[(auxcode >> 0) & 0x0F];
|
||||
*vram++ = aux_colors[(auxcode >> 0) & 0x0F];
|
||||
*vram++ = aux_colors[(auxcode >> 0) & 0x0F];
|
||||
*vram++ = aux_colors[(auxcode >> 0) & 0x0F];
|
||||
*vram++ = aux_colors[(auxcode >> 0) & 0x0F];
|
||||
*vram++ = aux_colors[(auxcode >> 0) & 0x0F];
|
||||
*vram++ = aux_colors[(auxcode >> 0) & 0x0F];
|
||||
*vram++ = (code >> 0) & 0x0F;
|
||||
*vram++ = (code >> 0) & 0x0F;
|
||||
*vram++ = (code >> 0) & 0x0F;
|
||||
*vram++ = (code >> 0) & 0x0F;
|
||||
*vram++ = (code >> 0) & 0x0F;
|
||||
*vram++ = (code >> 0) & 0x0F;
|
||||
*vram++ = (code >> 0) & 0x0F;
|
||||
}
|
||||
for (y = 4; y < 8; y++)
|
||||
{
|
||||
UINT16 *vram = &bitmap.pix16(row + y, (col * 14));
|
||||
|
||||
*vram++ = aux_colors[(auxcode >> 4) & 0x0F];
|
||||
*vram++ = aux_colors[(auxcode >> 4) & 0x0F];
|
||||
*vram++ = aux_colors[(auxcode >> 4) & 0x0F];
|
||||
*vram++ = aux_colors[(auxcode >> 4) & 0x0F];
|
||||
*vram++ = aux_colors[(auxcode >> 4) & 0x0F];
|
||||
*vram++ = aux_colors[(auxcode >> 4) & 0x0F];
|
||||
*vram++ = aux_colors[(auxcode >> 4) & 0x0F];
|
||||
*vram++ = (code >> 4) & 0x0F;
|
||||
*vram++ = (code >> 4) & 0x0F;
|
||||
*vram++ = (code >> 4) & 0x0F;
|
||||
*vram++ = (code >> 4) & 0x0F;
|
||||
*vram++ = (code >> 4) & 0x0F;
|
||||
*vram++ = (code >> 4) & 0x0F;
|
||||
*vram++ = (code >> 4) & 0x0F;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (row = beginrow; row <= endrow; row += 8)
|
||||
{
|
||||
for (col = 0; col < 40; col++)
|
||||
{
|
||||
UINT8 bits, abits;
|
||||
|
||||
/* calculate adderss */
|
||||
address = start_address + ((((row/8) & 0x07) << 7) | (((row/8) & 0x18) * 5 + col));
|
||||
|
||||
/* perform the lookup */
|
||||
code = m_ram_ptr[address];
|
||||
auxcode = m_aux_ptr[address];
|
||||
|
||||
bits = (code >> 0) & 0x0F;
|
||||
abits = (auxcode >> 0) & 0x0F;
|
||||
|
||||
/* and now draw */
|
||||
for (y = 0; y < 4; y++)
|
||||
{
|
||||
UINT16 *vram = &bitmap.pix16(row + y, (col * 14));
|
||||
|
||||
*vram++ = abits & (1 << 0) ? fg : 0;
|
||||
*vram++ = abits & (1 << 1) ? fg : 0;
|
||||
*vram++ = abits & (1 << 2) ? fg : 0;
|
||||
*vram++ = abits & (1 << 3) ? fg : 0;
|
||||
*vram++ = abits & (1 << 0) ? fg : 0;
|
||||
*vram++ = abits & (1 << 1) ? fg : 0;
|
||||
*vram++ = abits & (1 << 2) ? fg : 0;
|
||||
*vram++ = bits & (1 << 0) ? fg : 0;
|
||||
*vram++ = bits & (1 << 1) ? fg : 0;
|
||||
*vram++ = bits & (1 << 2) ? fg : 0;
|
||||
*vram++ = bits & (1 << 3) ? fg : 0;
|
||||
*vram++ = bits & (1 << 0) ? fg : 0;
|
||||
*vram++ = bits & (1 << 1) ? fg : 0;
|
||||
*vram++ = bits & (1 << 2) ? fg : 0;
|
||||
}
|
||||
|
||||
bits = (code >> 4) & 0x0F;
|
||||
abits = (auxcode >> 4) & 0x0F;
|
||||
|
||||
for (y = 4; y < 8; y++)
|
||||
{
|
||||
UINT16 *vram = &bitmap.pix16(row + y, (col * 14));
|
||||
|
||||
*vram++ = abits & (1 << 0) ? fg : 0;
|
||||
*vram++ = abits & (1 << 1) ? fg : 0;
|
||||
*vram++ = abits & (1 << 2) ? fg : 0;
|
||||
*vram++ = abits & (1 << 3) ? fg : 0;
|
||||
*vram++ = abits & (1 << 0) ? fg : 0;
|
||||
*vram++ = abits & (1 << 1) ? fg : 0;
|
||||
*vram++ = abits & (1 << 2) ? fg : 0;
|
||||
*vram++ = bits & (1 << 0) ? fg : 0;
|
||||
*vram++ = bits & (1 << 1) ? fg : 0;
|
||||
*vram++ = bits & (1 << 2) ? fg : 0;
|
||||
*vram++ = bits & (1 << 3) ? fg : 0;
|
||||
*vram++ = bits & (1 << 0) ? fg : 0;
|
||||
*vram++ = bits & (1 << 1) ? fg : 0;
|
||||
*vram++ = bits & (1 << 2) ? fg : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void a2_video_device::text_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow)
|
||||
{
|
||||
int row, col;
|
||||
UINT32 start_address;
|
||||
UINT32 address;
|
||||
UINT8 *aux_page = m_ram_ptr;
|
||||
int fg;
|
||||
int bg = 0;
|
||||
|
||||
if (m_80col)
|
||||
{
|
||||
start_address = 0x400;
|
||||
if (m_aux_ptr)
|
||||
{
|
||||
aux_page = m_aux_ptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
start_address = m_page2 ? 0x800 : 0x400;
|
||||
}
|
||||
|
||||
beginrow = MAX(beginrow, cliprect.min_y - (cliprect.min_y % 8));
|
||||
endrow = MIN(endrow, cliprect.max_y - (cliprect.max_y % 8) + 7);
|
||||
|
||||
switch (m_sysconfig & 0x03)
|
||||
{
|
||||
case 0: fg = WHITE; break;
|
||||
case 1: fg = WHITE; break;
|
||||
case 2: fg = GREEN; break;
|
||||
case 3: fg = ORANGE; break;
|
||||
}
|
||||
|
||||
for (row = beginrow; row <= endrow; row += 8)
|
||||
{
|
||||
if (m_80col)
|
||||
{
|
||||
for (col = 0; col < 40; col++)
|
||||
{
|
||||
/* calculate address */
|
||||
address = start_address + ((((row/8) & 0x07) << 7) | (((row/8) & 0x18) * 5 + col));
|
||||
|
||||
plot_text_character(bitmap, col * 14, row, 1, aux_page[address],
|
||||
m_char_ptr, m_char_size, fg, bg);
|
||||
plot_text_character(bitmap, col * 14 + 7, row, 1, m_ram_ptr[address],
|
||||
m_char_ptr, m_char_size, fg, bg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (col = 0; col < 40; col++)
|
||||
{
|
||||
/* calculate address */
|
||||
address = start_address + ((((row/8) & 0x07) << 7) | (((row/8) & 0x18) * 5 + col));
|
||||
plot_text_character(bitmap, col * 14, row, 2, m_ram_ptr[address],
|
||||
m_char_ptr, m_char_size, fg, bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void a2_video_device::text_update_orig(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow)
|
||||
{
|
||||
int row, col;
|
||||
UINT32 start_address = m_page2 ? 0x800 : 0x400;
|
||||
UINT32 address;
|
||||
UINT8 *aux_page = m_ram_ptr;
|
||||
int fg;
|
||||
int bg = 0;
|
||||
|
||||
beginrow = MAX(beginrow, cliprect.min_y - (cliprect.min_y % 8));
|
||||
endrow = MIN(endrow, cliprect.max_y - (cliprect.max_y % 8) + 7);
|
||||
|
||||
switch (m_sysconfig & 0x03)
|
||||
{
|
||||
case 0: fg = WHITE; break;
|
||||
case 1: fg = WHITE; break;
|
||||
case 2: fg = GREEN; break;
|
||||
case 3: fg = ORANGE; break;
|
||||
}
|
||||
|
||||
for (row = beginrow; row <= endrow; row += 8)
|
||||
{
|
||||
for (col = 0; col < 40; col++)
|
||||
{
|
||||
/* calculate address */
|
||||
address = start_address + ((((row/8) & 0x07) << 7) | (((row/8) & 0x18) * 5 + col));
|
||||
plot_text_character_orig(bitmap, col * 14, row, 2, m_ram_ptr[address],
|
||||
m_char_ptr, m_char_size, fg, bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void a2_video_device::hgr_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow)
|
||||
{
|
||||
const UINT8 *vram;
|
||||
int row, col, b;
|
||||
int offset;
|
||||
UINT8 vram_row[42];
|
||||
UINT16 v;
|
||||
UINT16 *p;
|
||||
UINT32 w;
|
||||
UINT16 *artifact_map_ptr;
|
||||
int mon_type = m_sysconfig & 0x03;
|
||||
|
||||
/* sanity checks */
|
||||
if (beginrow < cliprect.min_y)
|
||||
beginrow = cliprect.min_y;
|
||||
if (endrow > cliprect.max_y)
|
||||
endrow = cliprect.max_y;
|
||||
if (endrow < beginrow)
|
||||
return;
|
||||
|
||||
vram = &m_ram_ptr[(m_page2 ? 0x4000 : 0x2000)];
|
||||
|
||||
vram_row[0] = 0;
|
||||
vram_row[41] = 0;
|
||||
|
||||
for (row = beginrow; row <= endrow; row++)
|
||||
{
|
||||
for (col = 0; col < 40; col++)
|
||||
{
|
||||
offset = ((((row/8) & 0x07) << 7) | (((row/8) & 0x18) * 5 + col)) | ((row & 7) << 10);
|
||||
vram_row[1+col] = vram[offset];
|
||||
}
|
||||
|
||||
p = &bitmap.pix16(row);
|
||||
|
||||
for (col = 0; col < 40; col++)
|
||||
{
|
||||
w = (((UINT32) vram_row[col+0] & 0x7f) << 0)
|
||||
| (((UINT32) vram_row[col+1] & 0x7f) << 7)
|
||||
| (((UINT32) vram_row[col+2] & 0x7f) << 14);
|
||||
|
||||
switch (mon_type)
|
||||
{
|
||||
case 0:
|
||||
artifact_map_ptr = &m_hires_artifact_map[((vram_row[col+1] & 0x80) >> 7) * 16];
|
||||
for (b = 0; b < 7; b++)
|
||||
{
|
||||
v = artifact_map_ptr[((w >> (b + 7-1)) & 0x07) | (((b ^ col) & 0x01) << 3)];
|
||||
*(p++) = v;
|
||||
*(p++) = v;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
w >>= 7;
|
||||
for (b = 0; b < 7; b++)
|
||||
{
|
||||
v = (w & 1);
|
||||
w >>= 1;
|
||||
*(p++) = v ? WHITE : BLACK;
|
||||
*(p++) = v ? WHITE : BLACK;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
w >>= 7;
|
||||
for (b = 0; b < 7; b++)
|
||||
{
|
||||
v = (w & 1);
|
||||
w >>= 1;
|
||||
*(p++) = v ? GREEN : BLACK;
|
||||
*(p++) = v ? GREEN : BLACK;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
w >>= 7;
|
||||
for (b = 0; b < 7; b++)
|
||||
{
|
||||
v = (w & 1);
|
||||
w >>= 1;
|
||||
*(p++) = v ? ORANGE : BLACK;
|
||||
*(p++) = v ? ORANGE : BLACK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// similar to regular A2 except page 2 is at $A000
|
||||
void a2_video_device::hgr_update_tk2000(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow)
|
||||
{
|
||||
const UINT8 *vram;
|
||||
int row, col, b;
|
||||
int offset;
|
||||
UINT8 vram_row[42];
|
||||
UINT16 v;
|
||||
UINT16 *p;
|
||||
UINT32 w;
|
||||
UINT16 *artifact_map_ptr;
|
||||
int mon_type = m_sysconfig & 0x03;
|
||||
|
||||
/* sanity checks */
|
||||
if (beginrow < cliprect.min_y)
|
||||
beginrow = cliprect.min_y;
|
||||
if (endrow > cliprect.max_y)
|
||||
endrow = cliprect.max_y;
|
||||
if (endrow < beginrow)
|
||||
return;
|
||||
|
||||
vram = &m_ram_ptr[(m_page2 ? 0xa000 : 0x2000)];
|
||||
|
||||
vram_row[0] = 0;
|
||||
vram_row[41] = 0;
|
||||
|
||||
for (row = beginrow; row <= endrow; row++)
|
||||
{
|
||||
for (col = 0; col < 40; col++)
|
||||
{
|
||||
offset = ((((row/8) & 0x07) << 7) | (((row/8) & 0x18) * 5 + col)) | ((row & 7) << 10);
|
||||
vram_row[1+col] = vram[offset];
|
||||
}
|
||||
|
||||
p = &bitmap.pix16(row);
|
||||
|
||||
for (col = 0; col < 40; col++)
|
||||
{
|
||||
w = (((UINT32) vram_row[col+0] & 0x7f) << 0)
|
||||
| (((UINT32) vram_row[col+1] & 0x7f) << 7)
|
||||
| (((UINT32) vram_row[col+2] & 0x7f) << 14);
|
||||
|
||||
switch (mon_type)
|
||||
{
|
||||
case 0:
|
||||
artifact_map_ptr = &m_hires_artifact_map[((vram_row[col+1] & 0x80) >> 7) * 16];
|
||||
for (b = 0; b < 7; b++)
|
||||
{
|
||||
v = artifact_map_ptr[((w >> (b + 7-1)) & 0x07) | (((b ^ col) & 0x01) << 3)];
|
||||
*(p++) = v;
|
||||
*(p++) = v;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
w >>= 7;
|
||||
for (b = 0; b < 7; b++)
|
||||
{
|
||||
v = (w & 1);
|
||||
w >>= 1;
|
||||
*(p++) = v ? WHITE : BLACK;
|
||||
*(p++) = v ? WHITE : BLACK;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
w >>= 7;
|
||||
for (b = 0; b < 7; b++)
|
||||
{
|
||||
v = (w & 1);
|
||||
w >>= 1;
|
||||
*(p++) = v ? GREEN : BLACK;
|
||||
*(p++) = v ? GREEN : BLACK;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
w >>= 7;
|
||||
for (b = 0; b < 7; b++)
|
||||
{
|
||||
v = (w & 1);
|
||||
w >>= 1;
|
||||
*(p++) = v ? ORANGE : BLACK;
|
||||
*(p++) = v ? ORANGE : BLACK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void a2_video_device::dhgr_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow)
|
||||
{
|
||||
const UINT8 *vram, *vaux;
|
||||
int row, col, b;
|
||||
int offset;
|
||||
UINT8 vram_row[82];
|
||||
UINT16 v;
|
||||
UINT16 *p;
|
||||
UINT32 w;
|
||||
int page = m_page2 ? 0x4000 : 0x2000;
|
||||
int mon_type = m_sysconfig & 0x03;
|
||||
|
||||
/* sanity checks */
|
||||
if (beginrow < cliprect.min_y)
|
||||
beginrow = cliprect.min_y;
|
||||
if (endrow > cliprect.max_y)
|
||||
endrow = cliprect.max_y;
|
||||
if (endrow < beginrow)
|
||||
return;
|
||||
|
||||
vram = &m_ram_ptr[page];
|
||||
if (m_aux_ptr)
|
||||
{
|
||||
vaux = m_aux_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
vaux = vram;
|
||||
}
|
||||
vaux += page;
|
||||
|
||||
vram_row[0] = 0;
|
||||
vram_row[81] = 0;
|
||||
|
||||
for (row = beginrow; row <= endrow; row++)
|
||||
{
|
||||
for (col = 0; col < 40; col++)
|
||||
{
|
||||
offset = ((((row/8) & 0x07) << 7) | (((row/8) & 0x18) * 5 + col)) | ((row & 7) << 10);
|
||||
vram_row[1+(col*2)+0] = vaux[offset];
|
||||
vram_row[1+(col*2)+1] = vram[offset];
|
||||
}
|
||||
|
||||
p = &bitmap.pix16(row);
|
||||
|
||||
for (col = 0; col < 80; col++)
|
||||
{
|
||||
w = (((UINT32) vram_row[col+0] & 0x7f) << 0)
|
||||
| (((UINT32) vram_row[col+1] & 0x7f) << 7)
|
||||
| (((UINT32) vram_row[col+2] & 0x7f) << 14);
|
||||
|
||||
switch (mon_type)
|
||||
{
|
||||
case 0:
|
||||
for (b = 0; b < 7; b++)
|
||||
{
|
||||
v = m_dhires_artifact_map[((((w >> (b + 7-1)) & 0x0F) * 0x11) >> (((2-(col*7+b))) & 0x03)) & 0x0F];
|
||||
*(p++) = v;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
w >>= 7;
|
||||
for (b = 0; b < 7; b++)
|
||||
{
|
||||
v = (w & 1);
|
||||
w >>= 1;
|
||||
*(p++) = v ? WHITE : BLACK;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
w >>= 7;
|
||||
for (b = 0; b < 7; b++)
|
||||
{
|
||||
v = (w & 1);
|
||||
w >>= 1;
|
||||
*(p++) = v ? GREEN : BLACK;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
w >>= 7;
|
||||
for (b = 0; b < 7; b++)
|
||||
{
|
||||
v = (w & 1);
|
||||
w >>= 1;
|
||||
*(p++) = v ? ORANGE : BLACK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* according to Steve Nickolas (author of Dapple), our original palette would
|
||||
* have been more appropriate for an Apple IIgs. So we've substituted in the
|
||||
* Robert Munafo palette instead, which is more accurate on 8-bit Apples
|
||||
*/
|
||||
static const rgb_t apple2_palette[] =
|
||||
{
|
||||
rgb_t::black,
|
||||
rgb_t(0xE3, 0x1E, 0x60), /* Dark Red */
|
||||
rgb_t(0x60, 0x4E, 0xBD), /* Dark Blue */
|
||||
rgb_t(0xFF, 0x44, 0xFD), /* Purple */
|
||||
rgb_t(0x00, 0xA3, 0x60), /* Dark Green */
|
||||
rgb_t(0x9C, 0x9C, 0x9C), /* Dark Gray */
|
||||
rgb_t(0x14, 0xCF, 0xFD), /* Medium Blue */
|
||||
rgb_t(0xD0, 0xC3, 0xFF), /* Light Blue */
|
||||
rgb_t(0x60, 0x72, 0x03), /* Brown */
|
||||
rgb_t(0xFF, 0x6A, 0x3C), /* Orange */
|
||||
rgb_t(0x9C, 0x9C, 0x9C), /* Light Grey */
|
||||
rgb_t(0xFF, 0xA0, 0xD0), /* Pink */
|
||||
rgb_t(0x14, 0xF5, 0x3C), /* Light Green */
|
||||
rgb_t(0xD0, 0xDD, 0x8D), /* Yellow */
|
||||
rgb_t(0x72, 0xFF, 0xD0), /* Aquamarine */
|
||||
rgb_t(0xFF, 0xFF, 0xFF) /* White */
|
||||
};
|
||||
|
||||
/* Initialize the palette */
|
||||
PALETTE_INIT_MEMBER(a2_video_device, apple2)
|
||||
{
|
||||
palette.set_pen_colors(0, apple2_palette, ARRAY_LENGTH(apple2_palette));
|
||||
}
|
||||
|
||||
|
||||
|
57
src/mess/video/apple2.h
Normal file
57
src/mess/video/apple2.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*********************************************************************
|
||||
|
||||
video/apple2.h - Video handling for 8-bit Apple IIs
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef __A2_VIDEO__
|
||||
#define __A2_VIDEO__
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
class a2_video_device :
|
||||
public device_t
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
a2_video_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
DECLARE_PALETTE_INIT(apple2);
|
||||
|
||||
bool m_page2;
|
||||
bool m_flash;
|
||||
bool m_mix;
|
||||
bool m_graphics;
|
||||
bool m_hires;
|
||||
bool m_dhires;
|
||||
bool m_80col;
|
||||
bool m_altcharset;
|
||||
UINT16 *m_hires_artifact_map;
|
||||
UINT16 *m_dhires_artifact_map;
|
||||
|
||||
UINT8 *m_ram_ptr, *m_aux_ptr, *m_char_ptr;
|
||||
int m_char_size;
|
||||
|
||||
int m_sysconfig;
|
||||
|
||||
void text_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow);
|
||||
void text_update_orig(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow);
|
||||
void lores_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow);
|
||||
void dlores_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow);
|
||||
void hgr_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow);
|
||||
void hgr_update_tk2000(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow);
|
||||
void dhgr_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int beginrow, int endrow);
|
||||
|
||||
protected:
|
||||
virtual void device_reset();
|
||||
virtual void device_start();
|
||||
|
||||
private:
|
||||
void plot_text_character(bitmap_ind16 &bitmap, int xpos, int ypos, int xscale, UINT32 code, const UINT8 *textgfx_data, UINT32 textgfx_datalen, int fg, int bg);
|
||||
void plot_text_character_orig(bitmap_ind16 &bitmap, int xpos, int ypos, int xscale, UINT32 code, const UINT8 *textgfx_data, UINT32 textgfx_datalen, int fg, int bg);
|
||||
};
|
||||
|
||||
// device type definition
|
||||
extern const device_type APPLE2_VIDEO;
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user