(MESS) Removed old-style token processing. (nw)

This commit is contained in:
Michael Zapf 2014-03-13 12:38:31 +00:00
parent 73ffc8509d
commit b6fe1df3fb
8 changed files with 772 additions and 942 deletions

View File

@ -90,6 +90,10 @@ public:
virtual void machine_reset();
virtual void video_start();
UINT32 screen_update_ti990_10(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER( vdt_interrupt );
DECLARE_WRITE_LINE_MEMBER( tape_interrupt );
INTERRUPT_GEN_MEMBER(ti990_10_line_interrupt);
void idle_callback(int state);
required_device<cpu_device> m_maincpu;
@ -104,16 +108,13 @@ void ti990_10_state::machine_start()
void ti990_10_state::machine_reset()
{
ti990_hold_load(machine());
ti990_reset_int();
ti990_hdc_init(machine(), ti990_set_int13);
}
INTERRUPT_GEN_MEMBER(ti990_10_state::ti990_10_line_interrupt)
{
vdt911_keyboard(m_terminal);
downcast<vdt911_device*>(m_terminal)->keyboard();
ti990_line_interrupt(machine());
}
@ -144,16 +145,6 @@ static void lrex_callback(device_t *device)
We emulate a single VDT911 CRT terminal.
*/
static const vdt911_init_params_t vdt911_intf =
{
char_1920,
vdt911_model_US/*vdt911_model_UK*//*vdt911_model_French*//*vdt911_model_French*/
/*vdt911_model_German*//*vdt911_model_Swedish*//*vdt911_model_Norwegian*/
/*vdt911_model_Japanese*//*vdt911_model_Arabic*//*vdt911_model_FrenchWP*/,
ti990_set_int10
};
void ti990_10_state::video_start()
{
m_terminal = machine().device("vdt911");
@ -161,10 +152,15 @@ void ti990_10_state::video_start()
UINT32 ti990_10_state::screen_update_ti990_10(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
vdt911_refresh(m_terminal, bitmap, cliprect, 0, 0);
downcast<vdt911_device*>(m_terminal)->refresh(bitmap, cliprect, 0, 0);
return 0;
}
WRITE_LINE_MEMBER(ti990_10_state::vdt_interrupt)
{
// set_int10(state);
}
/*
Memory map - see description above
*/
@ -175,7 +171,7 @@ static ADDRESS_MAP_START(ti990_10_memmap, AS_PROGRAM, 16, ti990_10_state )
AM_RANGE(0x100000, 0x1ff7ff) AM_NOP /* free TILINE space */
AM_RANGE(0x1ff800, 0x1ff81f) AM_READWRITE_LEGACY(ti990_hdc_r, ti990_hdc_w) /* disk controller TPCS */
AM_RANGE(0x1ff820, 0x1ff87f) AM_NOP /* free TPCS */
AM_RANGE(0x1ff880, 0x1ff89f) AM_DEVREADWRITE_LEGACY("tpc",ti990_tpc_r, ti990_tpc_w) /* tape controller TPCS */
AM_RANGE(0x1ff880, 0x1ff89f) AM_DEVREADWRITE("tpc", tap_990_device, read, write) /* tape controller TPCS */
AM_RANGE(0x1ff8a0, 0x1ffbff) AM_NOP /* free TPCS */
AM_RANGE(0x1ffc00, 0x1fffff) AM_ROM /* LOAD ROM */
@ -187,8 +183,8 @@ ADDRESS_MAP_END
*/
static ADDRESS_MAP_START(ti990_10_io, AS_IO, 8, ti990_10_state )
AM_RANGE(0x10, 0x11) AM_DEVREAD_LEGACY("vdt911", vdt911_cru_r)
AM_RANGE(0x80, 0x8f) AM_DEVWRITE_LEGACY("vdt911", vdt911_cru_w)
AM_RANGE(0x10, 0x11) AM_DEVREAD("vdt911", vdt911_device, cru_r)
AM_RANGE(0x80, 0x8f) AM_DEVWRITE("vdt911", vdt911_device, cru_w)
AM_RANGE(0x1fa, 0x1fb) AM_NOP // AM_READ_LEGACY(ti990_10_mapper_cru_r)
AM_RANGE(0x1fc, 0x1fd) AM_NOP // AM_READ_LEGACY(ti990_10_eir_cru_r)
AM_RANGE(0x1fe, 0x1ff) AM_READ_LEGACY(ti990_panel_read)
@ -199,20 +195,12 @@ static ADDRESS_MAP_START(ti990_10_io, AS_IO, 8, ti990_10_state )
ADDRESS_MAP_END
/*
static const ti990_10reset_param reset_params =
Callback from the tape controller.
*/
WRITE_LINE_MEMBER(ti990_10_state::tape_interrupt)
{
NULL,
rset_callback,
lrex_callback,
ti990_ckon_ckof_callback,
ti990_set_int2
}; */
static const ti990_tpc_interface ti990_tpc =
{
ti990_set_int9
};
// set_int9(state);
}
static TMS99xx_CONFIG( cpuconf )
{
@ -241,7 +229,7 @@ static MACHINE_CONFIG_START( ti990_10, ti990_10_state )
MCFG_SCREEN_UPDATE_DRIVER(ti990_10_state, screen_update_ti990_10)
MCFG_SCREEN_PALETTE("vdt911:palette")
MCFG_VDT911_VIDEO_ADD("vdt911", vdt911_intf)
MCFG_VDT911_VIDEO_ADD("vdt911", WRITELINE(ti990_10_state, vdt_interrupt), char_1920, vdt911_model_US)
/* 911 VDT has a beep tone generator */
MCFG_SPEAKER_STANDARD_MONO("mono")
@ -250,7 +238,7 @@ static MACHINE_CONFIG_START( ti990_10, ti990_10_state )
MCFG_FRAGMENT_ADD( ti990_hdc )
MCFG_TI990_TAPE_CTRL_ADD("tpc",ti990_tpc)
MCFG_TI990_TAPE_CTRL_ADD("tpc", WRITELINE(ti990_10_state, tape_interrupt))
MACHINE_CONFIG_END
@ -306,7 +294,6 @@ DRIVER_INIT_MEMBER(ti990_10_state,ti990_10)
memmove(memregion("maincpu")->base()+0x1FFC00, memregion("maincpu")->base()+0x1FFC00+(page*0x400), 0x400);
#endif
vdt911_init(machine());
}
static INPUT_PORTS_START(ti990_10)

View File

@ -62,6 +62,8 @@ public:
DECLARE_WRITE8_MEMBER( external_operation );
DECLARE_READ8_MEMBER( interrupt_level );
DECLARE_WRITE_LINE_MEMBER( fd_interrupt );
DECLARE_WRITE_LINE_MEMBER( asr_interrupt );
DECLARE_WRITE_LINE_MEMBER( vdt_interrupt );
DECLARE_DRIVER_INIT(ti990_4);
DECLARE_DRIVER_INIT(ti990_4v);
@ -182,31 +184,22 @@ WRITE_LINE_MEMBER(ti990_4_state::fd_interrupt)
INTERRUPT_GEN_MEMBER(ti990_4_state::ti990_4_line_interrupt)
{
if (m_video)
vdt911_keyboard(m_terminal);
downcast<vdt911_device*>(m_terminal)->keyboard();
else
asr733_keyboard(m_terminal);
downcast<asr733_device*>(m_terminal)->keyboard();
line_interrupt();
}
/*
TI990/4 video emulation.
We emulate a single VDT911 CRT terminal.
*/
void ti990_vdt_int(running_machine &machine, int state)
WRITE_LINE_MEMBER(ti990_4_state::vdt_interrupt)
{
// set_int3
set_int3(state);
}
static const vdt911_init_params_t vdt911_intf =
{
char_1920,
vdt911_model_US,
ti990_vdt_int
};
void ti990_4_state::video_start()
{
if (m_video)
@ -218,17 +211,20 @@ void ti990_4_state::video_start()
UINT32 ti990_4_state::screen_update_ti990_4(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
if (m_video)
vdt911_refresh(m_terminal, bitmap, cliprect, 0, 0);
downcast<vdt911_device*>(m_terminal)->refresh(bitmap, cliprect, 0, 0);
else
asr733_refresh(m_terminal, bitmap, 0, 0);
downcast<asr733_device*>(m_terminal)->refresh(bitmap, 0, 0);
return 0;
}
static const asr733_init_params_t asr733_intf =
/*
Callback from the terminal.
*/
WRITE_LINE_MEMBER(ti990_4_state::asr_interrupt)
{
// set_int6
};
set_int6(state);
}
WRITE8_MEMBER( ti990_4_state::external_operation )
{
@ -298,8 +294,8 @@ ADDRESS_MAP_END
*/
static ADDRESS_MAP_START(cru_map, AS_IO, 8, ti990_4_state )
AM_RANGE(0x00, 0x01) AM_DEVREAD_LEGACY("asr733", asr733_cru_r)
AM_RANGE(0x00, 0x0f) AM_DEVWRITE_LEGACY("asr733", asr733_cru_w)
AM_RANGE(0x00, 0x01) AM_DEVREAD("asr733", asr733_device, cru_r)
AM_RANGE(0x00, 0x0f) AM_DEVWRITE("asr733", asr733_device, cru_w)
AM_RANGE(0x08, 0x0b) AM_DEVREAD( "fd800", fd800_legacy_device, cru_r )
AM_RANGE(0x40, 0x5f) AM_DEVWRITE( "fd800", fd800_legacy_device, cru_w )
@ -309,8 +305,8 @@ static ADDRESS_MAP_START(cru_map, AS_IO, 8, ti990_4_state )
ADDRESS_MAP_END
static ADDRESS_MAP_START(cru_map_v, AS_IO, 8, ti990_4_state )
AM_RANGE(0x10, 0x11) AM_DEVREAD_LEGACY("vdt911", vdt911_cru_r)
AM_RANGE(0x80, 0x8f) AM_DEVWRITE_LEGACY("vdt911", vdt911_cru_w)
AM_RANGE(0x10, 0x11) AM_DEVREAD("vdt911", vdt911_device, cru_r)
AM_RANGE(0x80, 0x8f) AM_DEVWRITE("vdt911", vdt911_device, cru_w)
AM_RANGE(0x08, 0x0b) AM_DEVREAD( "fd800", fd800_legacy_device, cru_r )
AM_RANGE(0x40, 0x5f) AM_DEVWRITE( "fd800", fd800_legacy_device, cru_w )
@ -356,14 +352,12 @@ DRIVER_INIT_MEMBER(ti990_4_state, ti990_4)
{
m_video = false;
m_nmi_timer = timer_alloc(NMI_TIMER_ID);
asr733_init(machine());
}
DRIVER_INIT_MEMBER(ti990_4_state, ti990_4v)
{
m_video = true;
m_nmi_timer = timer_alloc(NMI_TIMER_ID);
vdt911_init(machine());
}
static INPUT_PORTS_START(ti990_4)
@ -390,7 +384,7 @@ static MACHINE_CONFIG_START( ti990_4, ti990_4_state )
MCFG_SCREEN_SIZE(640, 480)
MCFG_SCREEN_VISIBLE_AREA(0, 640-1, 0, 480-1)
MCFG_SCREEN_PALETTE("asr733:palette")
MCFG_ASR733_VIDEO_ADD("asr733", asr733_intf)
MCFG_ASR733_VIDEO_ADD("asr733", WRITELINE(ti990_4_state, asr_interrupt))
// Floppy controller
MCFG_FD800_ADD("fd800", WRITELINE(ti990_4_state, fd_interrupt))
@ -413,7 +407,7 @@ static MACHINE_CONFIG_START( ti990_4v, ti990_4_state )
MCFG_SCREEN_SIZE(560, 280)
MCFG_SCREEN_VISIBLE_AREA(0, 560-1, 0, /*250*/280-1)
MCFG_SCREEN_PALETTE("vdt911:palette")
MCFG_VDT911_VIDEO_ADD("vdt911", vdt911_intf)
MCFG_VDT911_VIDEO_ADD("vdt911", WRITELINE(ti990_4_state, vdt_interrupt), char_1920, vdt911_model_US)
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD("beeper", BEEP, 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)

File diff suppressed because it is too large Load Diff

View File

@ -1,42 +1,62 @@
/*
990_tap.h: include file for 990_tap.c
*/
extern DECLARE_READ16_DEVICE_HANDLER(ti990_tpc_r);
extern DECLARE_WRITE16_DEVICE_HANDLER(ti990_tpc_w);
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
extern const device_type TI990_TAPE_CTRL;
#define MAX_TAPE_UNIT 4
struct ti990_tpc_interface
struct tape_unit_t
{
void (*interrupt_callback)(running_machine &machine, int state);
device_image_interface *img; // image descriptor
bool bot; // TRUE if we are at the beginning of tape
bool eot; // TRUE if we are at the end of tape
bool wp; // TRUE if tape is write-protected
};
/***************************************************************************
MACROS
***************************************************************************/
class tap_990_device : public device_t
{
public:
tap_990_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~tap_990_device();
template<class _Object> static devcb2_base &static_set_int_callback(device_t &device, _Object object)
{
return downcast<tap_990_device &>(device).m_int_line.set_callback(object);
}
DECLARE_READ16_MEMBER( read );
DECLARE_WRITE16_MEMBER( write );
void set_tape(int id, device_image_interface *img, bool bot, bool eot, bool wp)
{
m_tape[id].img = img;
m_tape[id].bot = bot;
m_tape[id].eot = eot;
m_tape[id].wp = wp;
}
// access to legacy token
struct tap_990_t *token() const { assert(m_token != NULL); return m_token; }
protected:
// device-level overrides
virtual void device_config_complete();
virtual void device_start();
virtual machine_config_constructor device_mconfig_additions() const;
private:
// internal state
struct tap_990_t *m_token;
int cur_tape_unit();
void update_interrupt();
void cmd_read_binary_forward();
void cmd_record_skip_forward();
void cmd_record_skip_reverse();
void cmd_rewind();
void cmd_rewind_and_offline();
void read_transport_status();
void execute_command();
devcb2_write_line m_int_line;
UINT16 m_w[8];
tape_unit_t m_tape[MAX_TAPE_UNIT];
};
extern const device_type TI990_TAPE_CTRL;
#define MCFG_TI990_TAPE_CTRL_ADD(_tag, _intrf) \
#define MCFG_TI990_TAPE_CTRL_ADD(_tag, _intcallb) \
MCFG_DEVICE_ADD((_tag), TI990_TAPE_CTRL, 0)\
MCFG_DEVICE_CONFIG(_intrf)
devcb = &tap_990_device::static_set_int_callback( *device, DEVCB2_##_intcallb );

View File

@ -18,11 +18,13 @@
* implement tape interface?
Raphael Nabet 2003
Rewritten as class
Michael Zapf, 2014
*/
#include "emu.h"
#include "733_asr.h"
#include "devlegcy.h"
enum
{
@ -35,34 +37,6 @@ enum
asr_scroll_step = 8
};
struct asr_t
{
#if 0
UINT8 OutQueue[ASROutQueueSize];
int OutQueueHead;
int OutQueueLen;
#endif
UINT8 recv_buf;
UINT8 xmit_buf;
UINT8 status;
UINT8 mode;
UINT8 last_key_pressed;
int last_modifier_state;
unsigned char repeat_timer;
int new_status_flag;
int x;
void (*int_callback)(running_machine &, int state);
bitmap_ind16 *bitmap;
gfxdecode_device *m_gfxdecode;
palette_device *m_palette;
};
enum
{
AS_wrq_mask = 1 << 3,
@ -101,11 +75,45 @@ PALETTE_INIT_MEMBER(asr733_device, asr733)
palette.set_pen_color(1,rgb_t::black); /* black */
}
/*
Initialize the asr core
*/
void asr733_init(running_machine &machine)
const device_type ASR733 = &device_creator<asr733_device>;
asr733_device::asr733_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, ASR733, "733 ASR", tag, owner, clock, "asr733", __FILE__),
m_palette(*this, "palette"),
m_gfxdecode(*this, "gfxdecode"),
m_int_line(*this)
{
}
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void asr733_device::device_config_complete()
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void asr733_device::device_start()
{
screen_device *screen = machine().first_screen();
int width = screen->width();
int height = screen->height();
const rectangle &visarea = screen->visible_area();
m_last_key_pressed = 0x80;
m_bitmap = auto_bitmap_ind16_alloc(machine(), width, height);
m_bitmap->fill(0, visarea);
m_int_line.resolve();
UINT8 *dst;
static const unsigned char fontdata6x8[asrfontdata_size] =
@ -160,129 +168,53 @@ void asr733_init(running_machine &machine)
0x00,0x68,0xb0,0x00,0x00,0x00,0x00,0x00,0x20,0x50,0x20,0x50,0xa8,0x50,0x00,0x00
};
dst = machine.root_device().memregion(asr733_chr_region)->base();
dst = machine().root_device().memregion(asr733_chr_region)->base();
memcpy(dst, fontdata6x8, asrfontdata_size);
}
INLINE asr_t *get_safe_token(device_t *device)
{
assert(device != NULL);
assert(device->type() == ASR733);
return (asr_t *)downcast<asr733_device *>(device)->token();
}
static DEVICE_START( asr733 )
{
asr_t *asr = get_safe_token(device);
const asr733_init_params_t *params = (const asr733_init_params_t *)device->static_config();
screen_device *screen = device->machine().first_screen();
int width = screen->width();
int height = screen->height();
const rectangle &visarea = screen->visible_area();
asr->last_key_pressed = 0x80;
asr->bitmap = auto_bitmap_ind16_alloc(device->machine(), width, height);
asr->bitmap->fill(0, visarea);
asr->int_callback = params->int_callback;
}
static void asr_field_interrupt(device_t *device)
{
asr_t *asr = get_safe_token(device);
if ((asr->mode & AM_enint_mask) && (asr->new_status_flag)) /* right??? */
{
asr->status |= AS_int_mask;
if (asr->int_callback)
(*asr->int_callback)(device->machine(), 1);
}
else
{
asr->status &= ~AS_int_mask;
if (asr->int_callback)
(*asr->int_callback)(device->machine(), 0);
}
}
static DEVICE_RESET( asr733 )
{
asr_t *asr = get_safe_token(device);
/*asr->OutQueueLen = 0;*/
asr->status = AS_dsr_mask | AS_wrq_mask;
asr->mode = 0;
asr_field_interrupt(device);
}
const device_type ASR733 = &device_creator<asr733_device>;
asr733_device::asr733_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, ASR733, "733 ASR", tag, owner, clock, "asr733", __FILE__),
m_palette(*this, "palette"),
m_gfxdecode(*this, "gfxdecode")
{
m_token = global_alloc_clear(asr_t);
}
asr733_device::~asr733_device() { global_free(m_token); }
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void asr733_device::device_config_complete()
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void asr733_device::device_start()
{
asr_t *asr = get_safe_token(this);
asr->m_gfxdecode = m_gfxdecode;
asr->m_palette = m_palette;
DEVICE_START_NAME( asr733 )(this);
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void asr733_device::device_reset()
{
DEVICE_RESET_NAME( asr733 )(this);
/*m_OutQueueLen = 0;*/
m_status = AS_dsr_mask | AS_wrq_mask;
m_mode = 0;
set_interrupt_line();
}
void asr733_device::set_interrupt_line()
{
if ((m_mode & AM_enint_mask) && (m_new_status_flag)) /* right??? */
{
m_status |= AS_int_mask;
m_int_line(ASSERT_LINE);
}
else
{
m_status &= ~AS_int_mask;
m_int_line(CLEAR_LINE);
}
}
/* write a single char on screen */
static void asr_draw_char(device_t *device, int character, int x, int y, int color)
void asr733_device::draw_char(int character, int x, int y, int color)
{
asr_t *asr = get_safe_token(device);
asr->m_gfxdecode->gfx(0)->opaque(*asr->m_palette,*asr->bitmap,asr->bitmap->cliprect(), character-32, color, 0, 0,
x+1, y);
m_gfxdecode->gfx(0)->opaque(*m_palette, *m_bitmap, m_bitmap->cliprect(), character-32, color, 0, 0, x+1, y);
}
static void asr_linefeed(device_t *device)
void asr733_device::linefeed()
{
asr_t *asr = get_safe_token(device);
UINT8 buf[asr_window_width];
int y;
for (y=asr_window_offset_y; y<asr_window_offset_y+asr_window_height-asr_scroll_step; y++)
for (int y=asr_window_offset_y; y<asr_window_offset_y+asr_window_height-asr_scroll_step; y++)
{
extract_scanline8(*asr->bitmap, asr_window_offset_x, y+asr_scroll_step, asr_window_width, buf);
draw_scanline8(*asr->bitmap, asr_window_offset_x, y, asr_window_width, buf,downcast<asr733_device *>(device)->m_palette->pens());
extract_scanline8(*m_bitmap, asr_window_offset_x, y+asr_scroll_step, asr_window_width, buf);
draw_scanline8(*m_bitmap, asr_window_offset_x, y, asr_window_width, buf, m_palette->pens());
}
const rectangle asr_scroll_clear_window(
@ -291,13 +223,11 @@ static void asr_linefeed(device_t *device)
asr_window_offset_y+asr_window_height-asr_scroll_step, /* min_y */
asr_window_offset_y+asr_window_height-1 /* max_y */
);
asr->bitmap->fill(0, asr_scroll_clear_window);
m_bitmap->fill(0, asr_scroll_clear_window);
}
static void asr_transmit(device_t *device, UINT8 data)
void asr733_device::transmit(UINT8 data)
{
asr_t *asr = get_safe_token(device);
switch (data)
{
/* aux device control chars */
@ -329,18 +259,18 @@ static void asr_transmit(device_t *device, UINT8 data)
case 0x08:
/* BS: backspace */
if (asr->x > 0)
asr->x--;
if (m_x > 0)
m_x--;
break;
case 0x0A:
/* LF: line feed */
asr_linefeed(device);
linefeed();
break;
case 0x0D:
/* CR: carriage return */
asr->x = 0;
m_x = 0;
break;
@ -349,34 +279,33 @@ static void asr_transmit(device_t *device, UINT8 data)
/* ignore control characters */
break;
if (asr->x == 80)
if (m_x == 80)
{
asr->x = 0;
asr_linefeed(device);
m_x = 0;
linefeed();
}
asr_draw_char(device, data, asr_window_offset_x+asr->x*8, asr_window_offset_y+asr_window_height-8, 0);
asr->x++;
draw_char(data, asr_window_offset_x + m_x*8, asr_window_offset_y+asr_window_height-8, 0);
m_x++;
break;
}
asr->status |= AS_wrq_mask;
asr->new_status_flag = 1; /* right??? */
asr_field_interrupt(device);
m_status |= AS_wrq_mask;
m_new_status_flag = 1; /* right??? */
set_interrupt_line();
}
#if 0
static void asr_receive_callback(int dummy)
void asr733_device::receive_callback(int dummy)
{
asr_t *asr = get_safe_token(device);
(void) dummy;
asr->recv_buf = asr->OutQueue[asr->OutQueueHead];
asr->OutQueueHead = (asr->OutQueueHead + 1) % ASROutQueueSize;
asr->OutQueueLen--;
m_recv_buf = m_OutQueue[m_OutQueueHead];
m_OutQueueHead = (m_OutQueueHead + 1) % ASROutQueueSize;
m_OutQueueLen--;
asr->status |= AS_rrq_mask;
asr->new_status_flag = 1; /* right??? */
asr_field_interrupt(device);
m_status |= AS_rrq_mask;
m_new_status_flag = 1; /* right??? */
set_interrupt_line();
}
#endif
@ -392,21 +321,20 @@ static void asr_receive_callback(int dummy)
14: DSR data set ready, 1 if online
15: INT interrupt, 1 if interrupt
*/
READ8_DEVICE_HANDLER( asr733_cru_r )
READ8_MEMBER( asr733_device::cru_r )
{
asr_t *asr = get_safe_token(device);
int reply = 0;
switch (offset)
{
case 0:
/* receive buffer */
reply = asr->recv_buf;
reply = m_recv_buf;
break;
case 1:
/* status register */
reply = asr->status;
reply = m_status;
break;
}
@ -424,10 +352,8 @@ READ8_DEVICE_HANDLER( asr733_cru_r )
14: enable interrupts, 1 to enable interrupts
15: diagnostic mode, 0 for normal mode
*/
WRITE8_DEVICE_HANDLER( asr733_cru_w )
WRITE8_MEMBER( asr733_device::cru_w )
{
asr_t *asr = get_safe_token(device);
switch (offset)
{
case 0:
@ -440,11 +366,11 @@ WRITE8_DEVICE_HANDLER( asr733_cru_w )
case 7:
/* transmit buffer */
if (data)
asr->xmit_buf |= 1 << offset;
m_xmit_buf |= 1 << offset;
else
asr->xmit_buf &= ~ (1 << offset);
if ((offset == 7) && (asr->mode & AM_dtr_mask) && (asr->mode & AM_rts_mask)) /* right??? */
asr_transmit(device, asr->xmit_buf);
m_xmit_buf &= ~ (1 << offset);
if ((offset == 7) && (m_mode & AM_dtr_mask) && (m_mode & AM_rts_mask)) /* right??? */
transmit(m_xmit_buf);
break;
case 8: /* not used */
@ -455,22 +381,22 @@ WRITE8_DEVICE_HANDLER( asr733_cru_w )
case 14: /* enable interrupts, 1 to enable interrupts */
case 15: /* diagnostic mode, 0 for normal mode */
if (data)
asr->mode |= 1 << (offset - 8);
m_mode |= 1 << (offset - 8);
else
asr->mode &= ~ (1 << (offset - 8));
m_mode &= ~ (1 << (offset - 8));
if (offset == 14)
asr_field_interrupt(device);
set_interrupt_line();
break;
case 11: /* clear write request (write any value to execute) */
case 12: /* clear read request (write any value to execute) */
asr->status &= ~ (1 << (offset - 8));
asr_field_interrupt(device);
m_status &= ~ (1 << (offset - 8));
set_interrupt_line();
break;
case 13: /* clear new status flag - whatever it means (write any value to execute) */
asr->new_status_flag = 0;
asr_field_interrupt(device);
m_new_status_flag = 0;
set_interrupt_line();
break;
}
}
@ -478,10 +404,9 @@ WRITE8_DEVICE_HANDLER( asr733_cru_w )
/*
Video refresh
*/
void asr733_refresh(device_t *device, bitmap_ind16 &bitmap, int x, int y)
void asr733_device::refresh(bitmap_ind16 &bitmap, int x, int y)
{
asr_t *asr = get_safe_token(device);
copybitmap(bitmap, *asr->bitmap, 0, 0, x, y, asr->bitmap->cliprect());
copybitmap(bitmap, *m_bitmap, 0, 0, x, y, m_bitmap->cliprect());
}
@ -665,9 +590,8 @@ static const unsigned char key_translate[3][51] =
keyboard handler: should be called regularly by machine code, for instance
every Video Blank Interrupt.
*/
void asr733_keyboard(device_t *device)
void asr733_device::keyboard()
{
asr_t *asr = get_safe_token(device);
enum modifier_state_t
{
/* key modifier states */
@ -691,7 +615,7 @@ void asr733_keyboard(device_t *device)
/* for (i = 0; i < 6; i++) */
for (i = 0; i < 4; i++)
{
key_buf[i] = device->machine().root_device().ioport(keynames[i])->read();
key_buf[i] = machine().root_device().ioport(keynames[i])->read();
}
/* process key modifiers */
@ -712,40 +636,40 @@ void asr733_keyboard(device_t *device)
if (! repeat_mode)
/* reset REPEAT timer if the REPEAT key is not pressed */
asr->repeat_timer = 0;
m_repeat_timer = 0;
if ( ! (asr->last_key_pressed & 0x80) && (key_buf[asr->last_key_pressed >> 4] & (1 << (asr->last_key_pressed & 0xf))))
if ( !(m_last_key_pressed & 0x80) && (key_buf[m_last_key_pressed >> 4] & (1 << (m_last_key_pressed & 0xf))))
{
/* last key has not been released */
if (modifier_state == asr->last_modifier_state)
if (modifier_state == m_last_modifier_state)
{
/* handle REPEAT mode if applicable */
if ((repeat_mode) && (++asr->repeat_timer == repeat_delay))
if ((repeat_mode) && (++m_repeat_timer == repeat_delay))
{
if (asr->status & AS_rrq_mask)
if (m_status & AS_rrq_mask)
{ /* keyboard buffer full */
asr->repeat_timer--;
m_repeat_timer--;
}
else
{ /* repeat current key */
asr->status |= AS_rrq_mask;
asr->new_status_flag = 1; /* right??? */
asr_field_interrupt(device);
asr->repeat_timer = 0;
m_status |= AS_rrq_mask;
m_new_status_flag = 1; /* right??? */
set_interrupt_line();
m_repeat_timer = 0;
}
}
}
else
{
asr->repeat_timer = 0;
asr->last_modifier_state = special_debounce;
m_repeat_timer = 0;
m_last_modifier_state = special_debounce;
}
}
else
{
asr->last_key_pressed = 0x80;
m_last_key_pressed = 0x80;
if (asr->status & AS_rrq_mask)
if (m_status & AS_rrq_mask)
{ /* keyboard buffer full */
/* do nothing */
}
@ -758,13 +682,13 @@ void asr733_keyboard(device_t *device)
{
if (key_buf[i] & (1 << j))
{
asr->last_key_pressed = (i << 4) | j;
asr->last_modifier_state = modifier_state;
m_last_key_pressed = (i << 4) | j;
m_last_modifier_state = modifier_state;
asr->recv_buf = (int)key_translate[modifier_state][asr->last_key_pressed];
asr->status |= AS_rrq_mask;
asr->new_status_flag = 1; /* right??? */
asr_field_interrupt(device);
m_recv_buf = (int)key_translate[modifier_state][m_last_key_pressed];
m_status |= AS_rrq_mask;
m_new_status_flag = 1; /* right??? */
set_interrupt_line();
return;
}
}

View File

@ -5,54 +5,74 @@ enum
{
/* 8 bytes per character definition */
asr733_single_char_len = 8,
asr733_chr_region_len = 128*asr733_single_char_len
};
struct asr733_init_params_t
{
void (*int_callback)(running_machine &machine, int state);
};
void asr733_init(running_machine &machine);
class asr733_device : public device_t
{
public:
asr733_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~asr733_device();
DECLARE_PALETTE_INIT(asr733);
// access to legacy token
struct asr_t *token() const { assert(m_token != NULL); return m_token; }
DECLARE_READ8_MEMBER(cru_r);
DECLARE_WRITE8_MEMBER(cru_w);
void refresh(bitmap_ind16 &bitmap, int x, int y);
void keyboard();
template<class _Object> static devcb2_base &static_set_int_callback(device_t &device, _Object object)
{
return downcast<asr733_device &>(device).m_int_line.set_callback(object);
}
protected:
// device-level overrides
virtual void device_config_complete();
virtual void device_start();
virtual void device_reset();
virtual machine_config_constructor device_mconfig_additions() const;
public:
required_device<palette_device> m_palette;
void device_config_complete();
void device_start();
void device_reset();
machine_config_constructor device_mconfig_additions() const;
private:
// internal state
struct asr_t *m_token;
required_device<gfxdecode_device> m_gfxdecode;
#if 0
UINT8 m_OutQueue[ASROutQueueSize];
int m_OutQueueHead;
int m_OutQueueLen;
#endif
void set_interrupt_line();
void draw_char(int character, int x, int y, int color);
void linefeed();
void transmit(UINT8 data);
UINT8 m_recv_buf;
UINT8 m_xmit_buf;
UINT8 m_status;
UINT8 m_mode;
UINT8 m_last_key_pressed;
int m_last_modifier_state;
unsigned char m_repeat_timer;
int m_new_status_flag;
int m_x;
bitmap_ind16* m_bitmap;
required_device<palette_device> m_palette;
required_device<gfxdecode_device> m_gfxdecode;
devcb2_write_line m_int_line;
};
extern const device_type ASR733;
#define MCFG_ASR733_VIDEO_ADD(_tag, _intcallb) \
MCFG_DEVICE_ADD(_tag, ASR733, 0) \
devcb = &asr733_device::static_set_int_callback( *device, DEVCB2_##_intcallb );
#define MCFG_ASR733_VIDEO_ADD(_tag, _intf) \
MCFG_DEVICE_ADD(_tag, ASR733, 0) \
MCFG_DEVICE_CONFIG(_intf)
DECLARE_READ8_DEVICE_HANDLER(asr733_cru_r);
DECLARE_WRITE8_DEVICE_HANDLER(asr733_cru_w);
void asr733_refresh(device_t *device, bitmap_ind16 &bitmap, int x, int y);
void asr733_keyboard(device_t *device);
#define ASR733_KEY_PORTS \
PORT_START("KEY0") /* keys 1-16 */ \

View File

@ -14,10 +14,6 @@ TODO:
#include "911_vdt.h"
#include "911_chr.h"
#include "911_key.h"
#include "sound/beep.h"
#include "devlegcy.h"
#define MAX_VDT 1
@ -80,55 +76,17 @@ static const unsigned short vdt911_palette[] =
2, 1 /* low intensity, reverse */
};
struct vdt_t
{
vdt911_screen_size_t screen_size; /* char_960 for 960-char, 12-line model; char_1920 for 1920-char, 24-line model */
vdt911_model_t model; /* country code */
void (*int_callback)(running_machine &machine, int state); /* interrupt callback, called when the state of irq changes */
UINT8 data_reg; /* vdt911 write buffer */
UINT8 display_RAM[2048]; /* vdt911 char buffer (1kbyte for 960-char model, 2kbytes for 1920-char model) */
unsigned int cursor_address; /* current cursor address (controlled by the computer, affects both display and I/O protocol) */
unsigned int cursor_address_mask; /* 1023 for 960-char model, 2047 for 1920-char model */
emu_timer *beep_timer; /* beep clock (beeps ends when timer times out) */
/*void *blink_clock;*/ /* cursor blink clock */
UINT8 keyboard_data; /* last code pressed on keyboard */
unsigned int keyboard_data_ready : 1; /* true if there is a new code in keyboard_data */
unsigned int keyboard_interrupt_enable : 1; /* true when keybord interrupts are enabled */
unsigned int display_enable : 1; /* screen is black when false */
unsigned int dual_intensity_enable : 1; /* if true, MSBit of ASCII codes controls character highlight */
unsigned int display_cursor : 1; /* if true, the current cursor location is displayed on screen */
unsigned int blinking_cursor_enable : 1;/* if true, the cursor will blink when displayed */
unsigned int blink_state : 1; /* current cursor blink state */
unsigned int word_select : 1; /* CRU interface mode */
unsigned int previous_word_select : 1; /* value of word_select is saved here */
UINT8 last_key_pressed;
int last_modifier_state;
char foreign_mode;
gfxdecode_device * m_gfxdecode;
palette_device * m_palette;
};
/*
Macros for model features
*/
/* TRUE for japanese and arabic terminals, which use 8-bit charcodes and keyboard shift modes */
#define USES_8BIT_CHARCODES(vdt) ((vdt->model == vdt911_model_Japanese) /*|| (vdt->model == vdt911_model_Arabic)*/)
#define USES_8BIT_CHARCODES() ((m_model == vdt911_model_Japanese) /*|| (vdt->model == vdt911_model_Arabic)*/)
/* TRUE for keyboards which have this extra key (on the left of TAB/SKIP)
(Most localized keyboards have it) */
#define HAS_EXTRA_KEY_67(vdt) (! ((vdt->model == vdt911_model_US) || (vdt->model == vdt911_model_UK) || (vdt->model == vdt911_model_French)))
#define HAS_EXTRA_KEY_67() (! ((m_model == vdt911_model_US) || (m_model == vdt911_model_UK) || (m_model == vdt911_model_French)))
/* TRUE for keyboards which have this extra key (on the right of space),
AND do not use it as a modifier */
#define HAS_EXTRA_KEY_91(vdt) ((vdt->model == vdt911_model_German) || (vdt->model == vdt911_model_Swedish) || (vdt->model == vdt911_model_Norwegian))
static TIMER_CALLBACK(blink_callback);
static TIMER_CALLBACK(beep_callback);
#define HAS_EXTRA_KEY_91() ((m_model == vdt911_model_German) || (m_model == vdt911_model_Swedish) || (m_model == vdt911_model_Norwegian))
/*
Initialize vdt911 palette
@ -173,13 +131,58 @@ static void apply_char_overrides(int nb_char_overrides, const char_override_t ch
}
}
/*
Initialize the 911 vdt core
*/
void vdt911_init(running_machine &machine)
const device_type VDT911 = &device_creator<vdt911_device>;
vdt911_device::vdt911_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, VDT911, "911 VDT", tag, owner, clock, "vdt911", __FILE__),
m_beeper(*this, ":beeper"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
m_int_line(*this)
{
}
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void vdt911_device::device_config_complete()
{
}
enum
{
BLINK_TIMER,
BEEP_TIMER
};
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void vdt911_device::device_start()
{
m_last_key_pressed = 0x80;
if (m_screen_size == char_960)
m_cursor_address_mask = 0x3ff; /* 1kb of RAM */
else
m_cursor_address_mask = 0x7ff; /* 2 kb of RAM */
/* set up cursor blink clock. 2Hz frequency -> .25s half-period. */
/*m_blink_clock =*/
// m_beeper->set_frequency(2000);
m_blink_timer = timer_alloc(BLINK_TIMER);
m_beep_timer = timer_alloc(BEEP_TIMER);
m_blink_timer->adjust(attotime::from_msec(0), 0, attotime::from_msec(250));
UINT8 *base;
UINT8 *chr = machine.root_device().memregion(vdt911_chr_region)->base();
UINT8 *chr = machine().root_device().memregion(vdt911_chr_region)->base();
/* set up US character definitions */
base = chr+vdt911_US_chr_offset;
@ -229,120 +232,42 @@ void vdt911_init(running_machine &machine)
apply_char_overrides(sizeof(frenchWP_overrides)/sizeof(char_override_t), frenchWP_overrides, base);
}
static TIMER_CALLBACK(setup_beep)
{
machine.device<beep_device>("beeper")->set_frequency(2000);
}
INLINE vdt_t *get_safe_token(device_t *device)
{
assert(device != NULL);
assert(device->type() == VDT911);
return (vdt_t *)downcast<vdt911_device *>(device)->token();
}
/*
Initialize one 911 vdt controller/terminal
Time callbacks
*/
static DEVICE_START( vdt911 )
void vdt911_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
vdt_t *vdt = get_safe_token(device);
const vdt911_init_params_t *params = (const vdt911_init_params_t *)device->static_config();
vdt->last_key_pressed = 0x80;
vdt->screen_size = params->screen_size;
vdt->model = params->model;
vdt->int_callback = params->int_callback;
if (vdt->screen_size == char_960)
vdt->cursor_address_mask = 0x3ff; /* 1kb of RAM */
else
vdt->cursor_address_mask = 0x7ff; /* 2 kb of RAM */
device->machine().scheduler().timer_set(attotime::zero, FUNC(setup_beep), 0, vdt);
/* set up cursor blink clock. 2Hz frequency -> .25s half-period. */
/*vdt->blink_clock =*/ device->machine().scheduler().timer_pulse(attotime::from_msec(250), FUNC(blink_callback), 0, vdt);
/* alloc beep timer */
vdt->beep_timer = device->machine().scheduler().timer_alloc(FUNC(beep_callback));
}
const device_type VDT911 = &device_creator<vdt911_device>;
vdt911_device::vdt911_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, VDT911, "911 VDT", tag, owner, clock, "vdt911", __FILE__),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette")
{
m_token = global_alloc_clear(vdt_t);
}
vdt911_device::~vdt911_device() { global_free(m_token); }
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void vdt911_device::device_config_complete()
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void vdt911_device::device_start()
{
vdt_t *vdt = get_safe_token(this);
vdt->m_gfxdecode = m_gfxdecode;
vdt->m_palette = m_palette;
DEVICE_START_NAME( vdt911 )(this);
}
/*
timer callback to toggle blink state
*/
static TIMER_CALLBACK(blink_callback)
{
vdt_t *vdt = (vdt_t *)ptr;
vdt->blink_state = !vdt->blink_state;
}
/*
timer callback to stop beep generator
*/
static TIMER_CALLBACK(beep_callback)
{
machine.device<beep_device>("beeper")->set_state(0);
switch (id)
{
case BLINK_TIMER:
m_blink_state = !m_blink_state;
break;
case BEEP_TIMER:
m_beeper->set_state(0);
break;
}
}
/*
CRU interface read
*/
READ8_DEVICE_HANDLER( vdt911_cru_r )
READ8_MEMBER( vdt911_device::cru_r )
{
vdt_t *vdt = get_safe_token(device);
int reply=0;
offset &= 0x1;
if (! vdt->word_select)
if (!m_word_select)
{ /* select word 0 */
switch (offset)
{
case 0:
reply = vdt->display_RAM[vdt->cursor_address];
reply = m_display_RAM[m_cursor_address];
break;
case 1:
reply = vdt->keyboard_data & 0x7f;
if (vdt->keyboard_data_ready)
reply = m_keyboard_data & 0x7f;
if (m_keyboard_data_ready)
reply |= 0x80;
break;
}
@ -352,20 +277,20 @@ READ8_DEVICE_HANDLER( vdt911_cru_r )
switch (offset)
{
case 0:
reply = vdt->cursor_address & 0xff;
reply = m_cursor_address & 0xff;
break;
case 1:
reply = (vdt->cursor_address >> 8) & 0x07;
if (vdt->keyboard_data & 0x80)
reply = (m_cursor_address >> 8) & 0x07;
if (m_keyboard_data & 0x80)
reply |= 0x08;
/*if (! vdt->terminal_ready)
/*if (!m_terminal_ready)
reply |= 0x10;*/
if (vdt->previous_word_select)
if (m_previous_word_select)
reply |= 0x20;
/*if (vdt->keyboard_parity_error)
/*if (m_keyboard_parity_error)
reply |= 0x40;*/
if (vdt->keyboard_data_ready)
if (m_keyboard_data_ready)
reply |= 0x80;
break;
}
@ -377,12 +302,11 @@ READ8_DEVICE_HANDLER( vdt911_cru_r )
/*
CRU interface write
*/
WRITE8_DEVICE_HANDLER( vdt911_cru_w )
WRITE8_MEMBER( vdt911_device::cru_w )
{
vdt_t *vdt = get_safe_token(device);
offset &= 0xf;
if (! vdt->word_select)
if (!m_word_select)
{ /* select word 0 */
switch (offset)
{
@ -396,14 +320,14 @@ WRITE8_DEVICE_HANDLER( vdt911_cru_w )
case 0x7:
/* display memory write data */
if (data)
vdt->data_reg |= (1 << offset);
m_data_reg |= (1 << offset);
else
vdt->data_reg &= ~ (1 << offset);
m_data_reg &= ~ (1 << offset);
break;
case 0x8:
/* write data strobe */
vdt->display_RAM[vdt->cursor_address] = vdt->data_reg;
m_display_RAM[m_cursor_address] = m_data_reg;
break;
case 0x9:
@ -414,37 +338,37 @@ WRITE8_DEVICE_HANDLER( vdt911_cru_w )
case 0xa:
/* cursor move */
if (data)
vdt->cursor_address--;
m_cursor_address--;
else
vdt->cursor_address++;
vdt->cursor_address &= vdt->cursor_address_mask;
m_cursor_address++;
m_cursor_address &= m_cursor_address_mask;
break;
case 0xb:
/* blinking cursor enable */
vdt->blinking_cursor_enable = data;
m_blinking_cursor_enable = data;
break;
case 0xc:
/* keyboard interrupt enable */
vdt->keyboard_interrupt_enable = data;
(*vdt->int_callback)(space.machine(), vdt->keyboard_interrupt_enable && vdt->keyboard_data_ready);
m_keyboard_interrupt_enable = data;
m_int_line(m_keyboard_interrupt_enable && m_keyboard_data_ready);
break;
case 0xd:
/* dual intensity enable */
vdt->dual_intensity_enable = data;
m_dual_intensity_enable = data;
break;
case 0xe:
/* display enable */
vdt->display_enable = data;
m_display_enable = data;
break;
case 0xf:
/* select word */
vdt->previous_word_select = vdt->word_select;
vdt->word_select = data;
m_previous_word_select = m_word_select;
m_word_select = data;
break;
}
}
@ -465,10 +389,10 @@ WRITE8_DEVICE_HANDLER( vdt911_cru_w )
case 0xa:
/* cursor address */
if (data)
vdt->cursor_address |= (1 << offset);
m_cursor_address |= (1 << offset);
else
vdt->cursor_address &= ~ (1 << offset);
vdt->cursor_address &= vdt->cursor_address_mask;
m_cursor_address &= ~ (1 << offset);
m_cursor_address &= m_cursor_address_mask;
break;
case 0xb:
@ -477,31 +401,30 @@ WRITE8_DEVICE_HANDLER( vdt911_cru_w )
case 0xc:
/* display cursor */
vdt->display_cursor = data;
m_display_cursor = data;
break;
case 0xd:
/* keyboard acknowledge */
if (vdt->keyboard_data_ready)
if (m_keyboard_data_ready)
{
vdt->keyboard_data_ready = 0;
if (vdt->keyboard_interrupt_enable)
(*vdt->int_callback)(space.machine(), 0);
m_keyboard_data_ready = 0;
if (m_keyboard_interrupt_enable)
m_int_line(CLEAR_LINE);
}
/*vdt->keyboard_parity_error = 0;*/
/*m_keyboard_parity_error = 0;*/
break;
case 0xe:
/* beep enable strobe - not tested */
space.machine().device<beep_device>("beeper")->set_state(1);
vdt->beep_timer->adjust(attotime::from_usec(300));
m_beeper->set_state(1);
m_beep_timer->adjust(attotime::from_usec(300));
break;
case 0xf:
/* select word */
vdt->previous_word_select = vdt->word_select;
vdt->word_select = data;
m_previous_word_select = m_word_select;
m_word_select = data;
break;
}
}
@ -510,12 +433,12 @@ WRITE8_DEVICE_HANDLER( vdt911_cru_w )
/*
Video refresh
*/
void vdt911_refresh(device_t *device, bitmap_ind16 &bitmap, const rectangle &cliprect, int x, int y)
void vdt911_device::refresh(bitmap_ind16 &bitmap, const rectangle &cliprect, int x, int y)
{
vdt_t *vdt = get_safe_token(device);
gfx_element *gfx = vdt->m_gfxdecode->gfx(vdt->model);
int height = (vdt->screen_size == char_960) ? 12 : /*25*/24;
int use_8bit_charcodes = USES_8BIT_CHARCODES(vdt);
gfx_element *gfx = m_gfxdecode->gfx(m_model);
int height = (m_screen_size == char_960) ? 12 : /*25*/24;
int use_8bit_charcodes = USES_8BIT_CHARCODES();
int address = 0;
int i, j;
int cur_char;
@ -524,34 +447,36 @@ void vdt911_refresh(device_t *device, bitmap_ind16 &bitmap, const rectangle &cli
/*if (use_8bit_charcodes)
color = vdt->dual_intensity_enable ? 1 : 0;*/
if (! vdt->display_enable)
if (!m_display_enable)
{
rectangle my_rect(x, x + 80*7 - 1, y, y + height*10 - 1);
bitmap.fill(0, my_rect);
}
else
{
for (i=0; i<height; i++)
{
for (j=0; j<80; j++)
{
cur_char = vdt->display_RAM[address];
cur_char = m_display_RAM[address];
/* does dual intensity work with 8-bit character set? */
color = (vdt->dual_intensity_enable && (cur_char & 0x80)) ? 1 : 0;
if (! use_8bit_charcodes)
color = (m_dual_intensity_enable && (cur_char & 0x80)) ? 1 : 0;
if (!use_8bit_charcodes)
cur_char &= 0x7f;
/* display cursor in reverse video */
if ((address == vdt->cursor_address) && vdt->display_cursor
&& ((! vdt->blinking_cursor_enable) || vdt->blink_state))
color += 2;
if ((address == m_cursor_address) && m_display_cursor
&& ((!m_blinking_cursor_enable) || m_blink_state))
color += 2;
address++;
gfx->opaque(*vdt->m_palette,bitmap,cliprect, cur_char, color, 0, 0,
x+j*7, y+i*10);
gfx->opaque(*m_palette, bitmap, cliprect, cur_char, color, 0, 0,
x+j*7, y+i*10);
}
}
}
}
static const unsigned char (*const key_translate[])[91] =
@ -580,10 +505,8 @@ static const unsigned char (*const key_translate[])[91] =
keyboard handler: should be called regularly by machine code, for instance
every Video Blank Interrupt.
*/
void vdt911_keyboard(device_t *device)
void vdt911_device::keyboard()
{
vdt_t *vdt = get_safe_token(device);
enum modifier_state_t
{
/* states for western keyboards and katakana/arabic keyboards in romaji/latin mode */
@ -607,14 +530,14 @@ void vdt911_keyboard(device_t *device)
/* read current key state */
for (i = 0; i < 6; i++)
{
key_buf[i] = device->machine().root_device().ioport(keynames[i])->read();
key_buf[i] = machine().root_device().ioport(keynames[i])->read();
}
/* parse modifier keys */
if ((USES_8BIT_CHARCODES(vdt))
&& ((key_buf[5] & 0x0400) || ((!(key_buf[5] & 0x0100)) && vdt->foreign_mode)))
if ((USES_8BIT_CHARCODES())
&& ((key_buf[5] & 0x0400) || ((!(key_buf[5] & 0x0100)) && m_foreign_mode)))
{ /* we are in katakana/arabic mode */
vdt->foreign_mode = TRUE;
m_foreign_mode = true;
if ((key_buf[4] & 0x0400) || (key_buf[5] & 0x0020))
modifier_state = foreign_shift;
@ -624,7 +547,7 @@ void vdt911_keyboard(device_t *device)
else
{ /* we are using a western keyboard, or a katakana/arabic keyboard in
romaji/latin mode */
vdt->foreign_mode = FALSE;
m_foreign_mode = false;
if (key_buf[3] & 0x0040)
modifier_state = control;
@ -649,10 +572,10 @@ void vdt911_keyboard(device_t *device)
key_buf[5] &= ~0x0120;
/* remove unused keys */
if (! HAS_EXTRA_KEY_91(vdt))
if (! HAS_EXTRA_KEY_91())
key_buf[5] &= ~0x0400;
if (! HAS_EXTRA_KEY_67(vdt))
if (! HAS_EXTRA_KEY_67())
key_buf[4] &= ~0x0004;
@ -660,21 +583,21 @@ void vdt911_keyboard(device_t *device)
/* reset REPEAT timer if the REPEAT key is not pressed */
repeat_timer = 0;
if (! (vdt->last_key_pressed & 0x80) && (key_buf[vdt->last_key_pressed >> 4] & (1 << (vdt->last_key_pressed & 0xf))))
if (!(m_last_key_pressed & 0x80) && (key_buf[m_last_key_pressed >> 4] & (1 << (m_last_key_pressed & 0xf))))
{
/* last key has not been released */
if (modifier_state == vdt->last_modifier_state)
if (modifier_state == m_last_modifier_state)
{
/* handle REPEAT mode if applicable */
if ((repeat_mode) && (++repeat_timer == repeat_delay))
{
if (vdt->keyboard_data_ready)
if (m_keyboard_data_ready)
{ /* keyboard buffer full */
repeat_timer--;
}
else
{ /* repeat current key */
vdt->keyboard_data_ready = 1;
m_keyboard_data_ready = 1;
repeat_timer = 0;
}
}
@ -682,14 +605,14 @@ void vdt911_keyboard(device_t *device)
else
{
repeat_timer = 0;
vdt->last_modifier_state = special_debounce;
m_last_modifier_state = special_debounce;
}
}
else
{
vdt->last_key_pressed = 0x80;
m_last_key_pressed = 0x80;
if (vdt->keyboard_data_ready)
if (m_keyboard_data_ready)
{ /* keyboard buffer full */
/* do nothing */
}
@ -701,13 +624,13 @@ void vdt911_keyboard(device_t *device)
{
if (key_buf[i] & (1 << j))
{
vdt->last_key_pressed = (i << 4) | j;
vdt->last_modifier_state = modifier_state;
m_last_key_pressed = (i << 4) | j;
m_last_modifier_state = modifier_state;
vdt->keyboard_data = (int)key_translate[vdt->model][modifier_state][vdt->last_key_pressed];
vdt->keyboard_data_ready = 1;
if (vdt->keyboard_interrupt_enable)
(*vdt->int_callback)(device->machine(), 1);
m_keyboard_data = (int)key_translate[m_model][modifier_state][m_last_key_pressed];
m_keyboard_data_ready = 1;
if (m_keyboard_interrupt_enable)
m_int_line(ASSERT_LINE);
return;
}
}

View File

@ -1,6 +1,7 @@
#include "sound/beep.h"
#define vdt911_chr_region ":gfx1"
enum
{
/* 10 bytes per character definition */
@ -38,36 +39,83 @@ struct vdt911_init_params_t
void (*int_callback)(running_machine &machine, int state);
};
void vdt911_init(running_machine &machine);
class vdt911_device : public device_t
{
public:
vdt911_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~vdt911_device();
DECLARE_READ8_MEMBER(cru_r);
DECLARE_WRITE8_MEMBER(cru_w);
DECLARE_PALETTE_INIT(vdt911);
// access to legacy token
struct vdt_t *token() const { assert(m_token != NULL); return m_token; }
template<class _Object> static devcb2_base &static_set_int_callback(device_t &device, _Object object)
{
return downcast<vdt911_device &>(device).m_int_line.set_callback(object);
}
static void static_set_params(device_t &device, vdt911_screen_size_t size, vdt911_model_t model)
{
downcast<vdt911_device &>(device).m_screen_size = size;
downcast<vdt911_device &>(device).m_model = model;
}
void refresh(bitmap_ind16 &bitmap, const rectangle &cliprect, int x, int y);
void keyboard();
protected:
// device-level overrides
virtual void device_config_complete();
virtual void device_start();
virtual machine_config_constructor device_mconfig_additions() const;
void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
private:
// internal state
struct vdt_t *m_token;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
vdt911_screen_size_t m_screen_size; // char_960 for 960-char, 12-line model; char_1920 for 1920-char, 24-line model
vdt911_model_t m_model; // country code
UINT8 m_data_reg; // dt911 write buffer
UINT8 m_display_RAM[2048]; // vdt911 char buffer (1kbyte for 960-char model, 2kbytes for 1920-char model)
unsigned int m_cursor_address; // current cursor address (controlled by the computer, affects both display and I/O protocol)
unsigned int m_cursor_address_mask; // 1023 for 960-char model, 2047 for 1920-char model
emu_timer *m_beep_timer; // beep clock (beeps ends when timer times out)
emu_timer *m_blink_timer; // cursor blink clock
UINT8 m_keyboard_data; // last code pressed on keyboard
bool m_keyboard_data_ready; // true if there is a new code in keyboard_data
bool m_keyboard_interrupt_enable; // true when keybord interrupts are enabled
bool m_display_enable; // screen is black when false
bool m_dual_intensity_enable; // if true, MSBit of ASCII codes controls character highlight
bool m_display_cursor; // if true, the current cursor location is displayed on screen
bool m_blinking_cursor_enable; // if true, the cursor will blink when displayed
bool m_blink_state; // current cursor blink state
bool m_word_select; // CRU interface mode
bool m_previous_word_select; // value of word_select is saved here
UINT8 m_last_key_pressed;
int m_last_modifier_state;
char m_foreign_mode;
required_device<beep_device> m_beeper;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
devcb2_write_line m_int_line;
};
extern const device_type VDT911;
#define MCFG_VDT911_VIDEO_ADD(_tag, _intcallb, _size, _model) \
MCFG_DEVICE_ADD(_tag, VDT911, 0) \
devcb = &vdt911_device::static_set_int_callback( *device, DEVCB2_##_intcallb ); \
vdt911_device::static_set_params( *device, _size, _model);
#define MCFG_VDT911_VIDEO_ADD(_tag, _intf) \
MCFG_DEVICE_ADD(_tag, VDT911, 0) \
MCFG_DEVICE_CONFIG(_intf)
DECLARE_READ8_DEVICE_HANDLER(vdt911_cru_r);