From b6fe1df3fb8b663505ca25ba63efaffb49d16086 Mon Sep 17 00:00:00 2001 From: Michael Zapf Date: Thu, 13 Mar 2014 12:38:31 +0000 Subject: [PATCH] (MESS) Removed old-style token processing. (nw) --- src/mess/drivers/ti990_10.c | 55 +-- src/mess/drivers/ti990_4.c | 46 +- src/mess/machine/ti99/990_tap.c | 714 ++++++++++++++------------------ src/mess/machine/ti99/990_tap.h | 60 ++- src/mess/video/733_asr.c | 330 ++++++--------- src/mess/video/733_asr.h | 78 ++-- src/mess/video/911_vdt.c | 359 +++++++--------- src/mess/video/911_vdt.h | 72 +++- 8 files changed, 772 insertions(+), 942 deletions(-) diff --git a/src/mess/drivers/ti990_10.c b/src/mess/drivers/ti990_10.c index a5f0d71caef..395f1edabd9 100644 --- a/src/mess/drivers/ti990_10.c +++ b/src/mess/drivers/ti990_10.c @@ -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 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(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(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) diff --git a/src/mess/drivers/ti990_4.c b/src/mess/drivers/ti990_4.c index fdf6a7c1877..a8a79c74b72 100644 --- a/src/mess/drivers/ti990_4.c +++ b/src/mess/drivers/ti990_4.c @@ -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(m_terminal)->keyboard(); else - asr733_keyboard(m_terminal); + downcast(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(m_terminal)->refresh(bitmap, cliprect, 0, 0); else - asr733_refresh(m_terminal, bitmap, 0, 0); + downcast(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) diff --git a/src/mess/machine/ti99/990_tap.c b/src/mess/machine/ti99/990_tap.c index 57deb20d918..b551b066f16 100644 --- a/src/mess/machine/ti99/990_tap.c +++ b/src/mess/machine/ti99/990_tap.c @@ -30,34 +30,6 @@ #include "emu.h" #include "990_tap.h" -#include "devlegcy.h" - - -static void update_interrupt(device_t *device); - -#define MAX_TAPE_UNIT 4 - -struct tape_unit_t -{ - device_image_interface *img; /* image descriptor */ - unsigned int bot : 1; /* TRUE if we are at the beginning of tape */ - unsigned int eot : 1; /* TRUE if we are at the end of tape */ - unsigned int wp : 1; /* TRUE if tape is write-protected */ -}; - -struct tap_990_t -{ - UINT16 w[8]; - - const ti990_tpc_interface *intf; - - tape_unit_t t[MAX_TAPE_UNIT]; -}; - -struct ti990_tape_t -{ - int dummy; -}; enum { @@ -108,44 +80,21 @@ static const UINT16 w_mask[8] = 0xf3ff /* Don't overwrite reserved bits */ }; -static int tape_get_id(device_t *image) -{ - int drive =0; - if (strcmp(image->tag(), ":tape0") == 0) drive = 0; - if (strcmp(image->tag(), ":tape1") == 0) drive = 1; - if (strcmp(image->tag(), ":tape2") == 0) drive = 2; - if (strcmp(image->tag(), ":tape3") == 0) drive = 3; - return drive; -} - -/***************************************************************************** - INLINE FUNCTIONS -*****************************************************************************/ -INLINE tap_990_t *get_safe_token(device_t *device) -{ - assert(device != NULL); - assert(device->type() == TI990_TAPE_CTRL); - - return (tap_990_t *)downcast(device)->token(); -} - - /* Parse the tape select lines, and return the corresponding tape unit. (-1 if none) */ -static int cur_tape_unit(device_t *device) +int tap_990_device::cur_tape_unit() { int reply; - tap_990_t *tpc = get_safe_token(device); - if (tpc->w[6] & w6_unit0_sel) + if (m_w[6] & w6_unit0_sel) reply = 0; - else if (tpc->w[6] & w6_unit1_sel) + else if (m_w[6] & w6_unit1_sel) reply = 1; - else if (tpc->w[6] & w6_unit2_sel) + else if (m_w[6] & w6_unit2_sel) reply = 2; - else if (tpc->w[6] & w6_unit3_sel) + else if (m_w[6] & w6_unit3_sel) reply = 3; else reply = -1; @@ -159,19 +108,18 @@ static int cur_tape_unit(device_t *device) /* Update interrupt state */ -static void update_interrupt(device_t *device) +void tap_990_device::update_interrupt() { - tap_990_t *tpc = get_safe_token(device); - if (tpc->intf->interrupt_callback) - (*tpc->intf->interrupt_callback)(device->machine(), (tpc->w[7] & w7_idle) - && (((tpc->w[7] & w7_int_enable) && (tpc->w[7] & (w7_complete | w7_error))) - || ((tpc->w[0] & ~(tpc->w[0] >> 4)) & w0_rewind_mask))); + bool level = (m_w[7] & w7_idle) + && (((m_w[7] & w7_int_enable) && (m_w[7] & (w7_complete | w7_error))) + || ((m_w[0] & ~(m_w[0] >> 4)) & w0_rewind_mask)); + m_int_line(level); } /* Handle the read binary forward command: read the next record on tape. */ -static void cmd_read_binary_forward(device_t *device) +void tap_990_device::cmd_read_binary_forward() { UINT8 buffer[256]; int reclen; @@ -185,48 +133,48 @@ static void cmd_read_binary_forward(device_t *device) int bytes_to_read; int bytes_read; int i; - tap_990_t *tpc = get_safe_token(device); - int tap_sel = cur_tape_unit(device); + + int tap_sel = cur_tape_unit(); if (tap_sel == -1) { /* No idea what to report... */ - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); return; } - else if (! tpc->t[tap_sel].img->exists()) + else if (!m_tape[tap_sel].img->exists()) { /* offline */ - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_tape_error; - update_interrupt(device); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_tape_error; + update_interrupt(); return; } #if 0 else if (0) { /* rewind in progress */ - tpc->w[0] |= 0x80 >> tap_sel; - tpc->w[7] |= w7_idle | w7_error | w7_tape_error; - update_interrupt(device); + m_w[0] |= 0x80 >> tap_sel; + m_w[7] |= w7_idle | w7_error | w7_tape_error; + update_interrupt(); return; } #endif - tpc->t[tap_sel].bot = 0; + m_tape[tap_sel].bot = 0; - dma_address = ((((int) tpc->w[6]) << 16) | tpc->w[5]) & 0x1ffffe; - char_count = tpc->w[4]; - read_offset = tpc->w[3]; + dma_address = ((((int)m_w[6]) << 16) | m_w[5]) & 0x1ffffe; + char_count = m_w[4]; + read_offset = m_w[3]; - bytes_read = tpc->t[tap_sel].img->fread(buffer, 4); + bytes_read = m_tape[tap_sel].img->fread(buffer, 4); if (bytes_read != 4) { if (bytes_read == 0) { /* legitimate EOF */ - tpc->t[tap_sel].eot = 1; - tpc->w[0] |= w0_EOT; /* or should it be w0_command_timeout? */ - tpc->w[7] |= w7_idle | w7_error | w7_tape_error; - update_interrupt(device); + m_tape[tap_sel].eot = 1; + m_w[0] |= w0_EOT; /* or should it be w0_command_timeout? */ + m_w[7] |= w7_idle | w7_error | w7_tape_error; + update_interrupt(); goto update_registers; } else @@ -234,10 +182,10 @@ static void cmd_read_binary_forward(device_t *device) /* No idea what to report... */ /* eject tape to avoid catastrophes */ logerror("Tape error\n"); - tpc->t[tap_sel].img->unload(); - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_tape[tap_sel].img->unload(); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); goto update_registers; } } @@ -247,10 +195,10 @@ static void cmd_read_binary_forward(device_t *device) logerror("Tape error\n"); logerror("Tape format looks gooofy\n"); /* eject tape to avoid catastrophes */ - tpc->t[tap_sel].img->unload(); - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_tape[tap_sel].img->unload(); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); goto update_registers; } @@ -258,9 +206,9 @@ static void cmd_read_binary_forward(device_t *device) if (reclen == 0) { logerror("read binary forward: found EOF, requested %d\n", char_count); - tpc->w[0] |= w0_EOF; - tpc->w[7] |= w7_idle | w7_error | w7_tape_error; - update_interrupt(device); + m_w[0] |= w0_EOF; + m_w[7] |= w7_idle | w7_error | w7_tape_error; + update_interrupt(); goto update_registers; } @@ -271,13 +219,13 @@ static void cmd_read_binary_forward(device_t *device) /* skip up to read_offset bytes */ chunk_len = (read_offset > rec_count) ? rec_count : read_offset; - if (tpc->t[tap_sel].img->fseek(chunk_len, SEEK_CUR)) + if (m_tape[tap_sel].img->fseek(chunk_len, SEEK_CUR)) { /* eject tape */ logerror("Tape error\n"); - tpc->t[tap_sel].img->unload(); - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_tape[tap_sel].img->unload(); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); goto update_registers; } @@ -285,9 +233,9 @@ static void cmd_read_binary_forward(device_t *device) read_offset -= chunk_len; if (read_offset) { - tpc->w[0] |= w0_EOR; - tpc->w[7] |= w7_idle | w7_error | w7_tape_error; - update_interrupt(device); + m_w[0] |= w0_EOR; + m_w[7] |= w7_idle | w7_error | w7_tape_error; + update_interrupt(); goto skip_trailer; } @@ -297,7 +245,7 @@ static void cmd_read_binary_forward(device_t *device) for (; chunk_len>0; ) { bytes_to_read = (chunk_len < sizeof(buffer)) ? chunk_len : sizeof(buffer); - bytes_read = tpc->t[tap_sel].img->fread(buffer, bytes_to_read); + bytes_read = m_tape[tap_sel].img->fread(buffer, bytes_to_read); if (bytes_read & 1) { @@ -307,7 +255,7 @@ static void cmd_read_binary_forward(device_t *device) /* DMA */ for (i=0; imachine().device("maincpu")->memory().space(AS_PROGRAM).write_word(dma_address, (((int) buffer[i]) << 8) | buffer[i+1]); + machine().device("maincpu")->memory().space(AS_PROGRAM).write_word(dma_address, (((int) buffer[i]) << 8) | buffer[i+1]); dma_address = (dma_address + 2) & 0x1ffffe; } @@ -318,53 +266,53 @@ static void cmd_read_binary_forward(device_t *device) if (bytes_read != bytes_to_read) { /* eject tape */ logerror("Tape error\n"); - tpc->t[tap_sel].img->unload(); - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_tape[tap_sel].img->unload(); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); goto update_registers; } } if (char_count) { - tpc->w[0] |= w0_EOR; - tpc->w[7] |= w7_idle | w7_error | w7_tape_error; - update_interrupt(device); + m_w[0] |= w0_EOR; + m_w[7] |= w7_idle | w7_error | w7_tape_error; + update_interrupt(); goto skip_trailer; } if (rec_count) { /* skip end of record */ - if (tpc->t[tap_sel].img->fseek(rec_count, SEEK_CUR)) + if (m_tape[tap_sel].img->fseek(rec_count, SEEK_CUR)) { /* eject tape */ logerror("Tape error\n"); - tpc->t[tap_sel].img->unload(); - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_tape[tap_sel].img->unload(); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); goto update_registers; } } skip_trailer: - if (tpc->t[tap_sel].img->fread(buffer, 4) != 4) + if (m_tape[tap_sel].img->fread(buffer, 4) != 4) { /* eject tape */ logerror("Tape error\n"); - tpc->t[tap_sel].img->unload(); - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_tape[tap_sel].img->unload(); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); goto update_registers; } if (reclen != ((((int) buffer[1]) << 8) | buffer[0])) { /* eject tape */ logerror("Tape error\n"); - tpc->t[tap_sel].img->unload(); - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_tape[tap_sel].img->unload(); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); goto update_registers; } if (buffer[2] || buffer[3]) @@ -372,91 +320,91 @@ skip_trailer: logerror("Tape error\n"); logerror("Tape format looks gooofy\n"); /* eject tape to avoid catastrophes */ - tpc->t[tap_sel].img->unload(); - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_tape[tap_sel].img->unload(); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); goto update_registers; } - if (! (tpc->w[7] & w7_error)) + if (! (m_w[7] & w7_error)) { - tpc->w[7] |= w7_idle | w7_complete; - update_interrupt(device); + m_w[7] |= w7_idle | w7_complete; + update_interrupt(); } update_registers: - tpc->w[1] = rec_count & 0xffff; - tpc->w[2] = (rec_count >> 8) & 0xff; - tpc->w[3] = read_offset; - tpc->w[4] = char_count; - tpc->w[5] = (dma_address >> 1) & 0xffff; - tpc->w[6] = (tpc->w[6] & 0xffe0) | ((dma_address >> 17) & 0xf); + m_w[1] = rec_count & 0xffff; + m_w[2] = (rec_count >> 8) & 0xff; + m_w[3] = read_offset; + m_w[4] = char_count; + m_w[5] = (dma_address >> 1) & 0xffff; + m_w[6] = (m_w[6] & 0xffe0) | ((dma_address >> 17) & 0xf); } /* Handle the record skip forward command: skip a specified number of records. */ -static void cmd_record_skip_forward(device_t *device) +void tap_990_device::cmd_record_skip_forward() { UINT8 buffer[4]; int reclen; int record_count; int bytes_read; - tap_990_t *tpc = get_safe_token(device); - int tap_sel = cur_tape_unit(device); + + int tap_sel = cur_tape_unit(); if (tap_sel == -1) { /* No idea what to report... */ - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); return; } - else if (! tpc->t[tap_sel].img->exists()) + else if (! m_tape[tap_sel].img->exists()) { /* offline */ - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_tape_error; - update_interrupt(device); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_tape_error; + update_interrupt(); return; } #if 0 else if (0) { /* rewind in progress */ - tpc->w[0] |= 0x80 >> tap_sel; - tpc->w[7] |= w7_idle | w7_error | w7_tape_error; - update_interrupt(device); + m_w[0] |= 0x80 >> tap_sel; + m_w[7] |= w7_idle | w7_error | w7_tape_error; + update_interrupt(); return; } #endif - record_count = tpc->w[4]; + record_count = m_w[4]; if (record_count) - tpc->t[tap_sel].bot = 0; + m_tape[tap_sel].bot = 0; while (record_count > 0) { - bytes_read = tpc->t[tap_sel].img->fread(buffer, 4); + bytes_read = m_tape[tap_sel].img->fread(buffer, 4); if (bytes_read != 4) { if (bytes_read == 0) { /* legitimate EOF */ - tpc->t[tap_sel].eot = 1; - tpc->w[0] |= w0_EOT; /* or should it be w0_command_timeout? */ - tpc->w[7] |= w7_idle | w7_error | w7_tape_error; - update_interrupt(device); + m_tape[tap_sel].eot = 1; + m_w[0] |= w0_EOT; /* or should it be w0_command_timeout? */ + m_w[7] |= w7_idle | w7_error | w7_tape_error; + update_interrupt(); goto update_registers; } else { /* illegitimate EOF */ /* No idea what to report... */ /* eject tape to avoid catastrophes */ - tpc->t[tap_sel].img->unload(); - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_tape[tap_sel].img->unload(); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); goto update_registers; } } @@ -465,10 +413,10 @@ static void cmd_record_skip_forward(device_t *device) { /* no idea what these bytes mean */ logerror("Tape format looks gooofy\n"); /* eject tape to avoid catastrophes */ - tpc->t[tap_sel].img->unload(); - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_tape[tap_sel].img->unload(); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); goto update_registers; } @@ -476,64 +424,64 @@ static void cmd_record_skip_forward(device_t *device) if (reclen == 0) { logerror("record skip forward: found EOF\n"); - tpc->w[0] |= w0_EOF; - tpc->w[7] |= w7_idle | w7_error | w7_tape_error; - update_interrupt(device); + m_w[0] |= w0_EOF; + m_w[7] |= w7_idle | w7_error | w7_tape_error; + update_interrupt(); goto update_registers; } /* skip record data */ - if (tpc->t[tap_sel].img->fseek(reclen, SEEK_CUR)) + if (m_tape[tap_sel].img->fseek(reclen, SEEK_CUR)) { /* eject tape */ - tpc->t[tap_sel].img->unload(); - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_tape[tap_sel].img->unload(); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); goto update_registers; } - if (tpc->t[tap_sel].img->fread(buffer, 4) != 4) + if (m_tape[tap_sel].img->fread(buffer, 4) != 4) { /* eject tape */ - tpc->t[tap_sel].img->unload(); - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_tape[tap_sel].img->unload(); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); goto update_registers; } if (reclen != ((((int) buffer[1]) << 8) | buffer[0])) { /* eject tape */ - tpc->t[tap_sel].img->unload(); - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_tape[tap_sel].img->unload(); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); goto update_registers; } if (buffer[2] || buffer[3]) { /* no idea what these bytes mean */ logerror("Tape format looks gooofy\n"); /* eject tape to avoid catastrophes */ - tpc->t[tap_sel].img->unload(); - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_tape[tap_sel].img->unload(); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); goto update_registers; } record_count--; } - tpc->w[7] |= w7_idle | w7_complete; - update_interrupt(device); + m_w[7] |= w7_idle | w7_complete; + update_interrupt(); update_registers: - tpc->w[4] = record_count; + m_w[4] = record_count; } /* Handle the record skip reverse command: skip a specified number of records backwards. */ -static void cmd_record_skip_reverse(device_t *device) +void tap_990_device::cmd_record_skip_reverse() { UINT8 buffer[4]; int reclen; @@ -541,66 +489,66 @@ static void cmd_record_skip_reverse(device_t *device) int record_count; int bytes_read; - tap_990_t *tpc = get_safe_token(device); - int tap_sel = cur_tape_unit(device); + + int tap_sel = cur_tape_unit(); if (tap_sel == -1) { /* No idea what to report... */ - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); return; } - else if (! tpc->t[tap_sel].img->exists()) + else if (! m_tape[tap_sel].img->exists()) { /* offline */ - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_tape_error; - update_interrupt(device); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_tape_error; + update_interrupt(); return; } #if 0 else if (0) { /* rewind in progress */ - tpc->w[0] |= 0x80 >> tap_sel; - tpc->w[7] |= w7_idle | w7_error | w7_tape_error; - update_interrupt(device); + m_w[0] |= 0x80 >> tap_sel; + m_w[7] |= w7_idle | w7_error | w7_tape_error; + update_interrupt(); return; } #endif - record_count = tpc->w[4]; + record_count = m_w[4]; if (record_count) - tpc->t[tap_sel].eot = 0; + m_tape[tap_sel].eot = 0; while (record_count > 0) { - if (tpc->t[tap_sel].img->ftell() == 0) + if (m_tape[tap_sel].img->ftell() == 0) { /* bot */ - tpc->t[tap_sel].bot = 1; - tpc->w[0] |= w0_BOT; - tpc->w[7] |= w7_idle | w7_error | w7_tape_error; - update_interrupt(device); + m_tape[tap_sel].bot = 1; + m_w[0] |= w0_BOT; + m_w[7] |= w7_idle | w7_error | w7_tape_error; + update_interrupt(); goto update_registers; } - if (tpc->t[tap_sel].img->fseek(-4, SEEK_CUR)) + if (m_tape[tap_sel].img->fseek(-4, SEEK_CUR)) { /* eject tape */ - tpc->t[tap_sel].img->unload(); - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_tape[tap_sel].img->unload(); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); goto update_registers; } - bytes_read = tpc->t[tap_sel].img->fread(buffer, 4); + bytes_read = m_tape[tap_sel].img->fread(buffer, 4); if (bytes_read != 4) { /* illegitimate EOF */ /* No idea what to report... */ /* eject tape to avoid catastrophes */ - tpc->t[tap_sel].img->unload(); - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_tape[tap_sel].img->unload(); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); goto update_registers; } reclen = (((int) buffer[1]) << 8) | buffer[0]; @@ -608,10 +556,10 @@ static void cmd_record_skip_reverse(device_t *device) { /* no idea what these bytes mean */ logerror("Tape format looks gooofy\n"); /* eject tape to avoid catastrophes */ - tpc->t[tap_sel].img->unload(); - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_tape[tap_sel].img->unload(); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); goto update_registers; } @@ -619,286 +567,282 @@ static void cmd_record_skip_reverse(device_t *device) if (reclen == 0) { logerror("record skip reverse: found EOF\n"); - if (tpc->t[tap_sel].img->fseek(-4, SEEK_CUR)) + if (m_tape[tap_sel].img->fseek(-4, SEEK_CUR)) { /* eject tape */ - tpc->t[tap_sel].img->unload(); - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_tape[tap_sel].img->unload(); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); goto update_registers; } - tpc->w[0] |= w0_EOF; - tpc->w[7] |= w7_idle | w7_error | w7_tape_error; - update_interrupt(device); + m_w[0] |= w0_EOF; + m_w[7] |= w7_idle | w7_error | w7_tape_error; + update_interrupt(); goto update_registers; } - if (tpc->t[tap_sel].img->fseek(-reclen-8, SEEK_CUR)) + if (m_tape[tap_sel].img->fseek(-reclen-8, SEEK_CUR)) { /* eject tape */ - tpc->t[tap_sel].img->unload(); - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_tape[tap_sel].img->unload(); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); goto update_registers; } - if (tpc->t[tap_sel].img->fread(buffer, 4) != 4) + if (m_tape[tap_sel].img->fread(buffer, 4) != 4) { /* eject tape */ - tpc->t[tap_sel].img->unload(); - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_tape[tap_sel].img->unload(); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); goto update_registers; } if (reclen != ((((int) buffer[1]) << 8) | buffer[0])) { /* eject tape */ - tpc->t[tap_sel].img->unload(); - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_tape[tap_sel].img->unload(); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); goto update_registers; } if (buffer[2] || buffer[3]) { /* no idea what these bytes mean */ logerror("Tape format looks gooofy\n"); /* eject tape to avoid catastrophes */ - tpc->t[tap_sel].img->unload(); - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_tape[tap_sel].img->unload(); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); goto update_registers; } - if (tpc->t[tap_sel].img->fseek(-4, SEEK_CUR)) + if (m_tape[tap_sel].img->fseek(-4, SEEK_CUR)) { /* eject tape */ - tpc->t[tap_sel].img->unload(); - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_tape[tap_sel].img->unload(); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); goto update_registers; } record_count--; } - tpc->w[7] |= w7_idle | w7_complete; - update_interrupt(device); + m_w[7] |= w7_idle | w7_complete; + update_interrupt(); update_registers: - tpc->w[4] = record_count; + m_w[4] = record_count; } /* Handle the rewind command: rewind to BOT. */ -static void cmd_rewind(device_t *device) +void tap_990_device::cmd_rewind() { - tap_990_t *tpc = get_safe_token(device); - int tap_sel = cur_tape_unit(device); + int tap_sel = cur_tape_unit(); if (tap_sel == -1) { /* No idea what to report... */ - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); return; } - else if (! tpc->t[tap_sel].img->exists()) + else if (! m_tape[tap_sel].img->exists()) { /* offline */ - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_tape_error; - update_interrupt(device); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_tape_error; + update_interrupt(); return; } #if 0 else if (0) { /* rewind in progress */ - tpc->w[0] |= 0x80 >> tap_sel; - tpc->w[7] |= w7_idle | w7_error | w7_tape_error; - update_interrupt(device); + m_w[0] |= 0x80 >> tap_sel; + m_w[7] |= w7_idle | w7_error | w7_tape_error; + update_interrupt(); return; } #endif - tpc->t[tap_sel].eot = 0; + m_tape[tap_sel].eot = 0; - if (tpc->t[tap_sel].img->fseek(0, SEEK_SET)) + if (m_tape[tap_sel].img->fseek(0, SEEK_SET)) { /* eject tape */ - tpc->t[tap_sel].img->unload(); - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_tape[tap_sel].img->unload(); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); return; } - tpc->t[tap_sel].bot = 1; + m_tape[tap_sel].bot = 1; - tpc->w[7] |= w7_idle | w7_complete; - update_interrupt(device); + m_w[7] |= w7_idle | w7_complete; + update_interrupt(); } /* Handle the rewind and offline command: disable the tape unit. */ -static void cmd_rewind_and_offline(device_t *device) +void tap_990_device::cmd_rewind_and_offline() { - tap_990_t *tpc = get_safe_token(device); - int tap_sel = cur_tape_unit(device); + int tap_sel = cur_tape_unit(); if (tap_sel == -1) { /* No idea what to report... */ - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); return; } - else if (! tpc->t[tap_sel].img->exists()) + else if (! m_tape[tap_sel].img->exists()) { /* offline */ - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_tape_error; - update_interrupt(device); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_tape_error; + update_interrupt(); return; } #if 0 else if (0) { /* rewind in progress */ - tpc->w[0] |= 0x80 >> tap_sel; - tpc->w[7] |= w7_idle | w7_error | w7_tape_error; - update_interrupt(device); + m_w[0] |= 0x80 >> tap_sel; + m_w[7] |= w7_idle | w7_error | w7_tape_error; + update_interrupt(); return; } #endif /* eject tape */ - tpc->t[tap_sel].img->unload(); + m_tape[tap_sel].img->unload(); - tpc->w[7] |= w7_idle | w7_complete; - update_interrupt(device); + m_w[7] |= w7_idle | w7_complete; + update_interrupt(); } /* Handle the read transport status command: return the current tape status. */ -static void read_transport_status(device_t *device) +void tap_990_device::read_transport_status() { - tap_990_t *tpc = get_safe_token(device); - int tap_sel = cur_tape_unit(device); + int tap_sel = cur_tape_unit(); if (tap_sel == -1) { /* No idea what to report... */ - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); } - else if (! tpc->t[tap_sel].img->exists()) + else if (! m_tape[tap_sel].img->exists()) { /* offline */ - tpc->w[0] |= w0_offline; - tpc->w[7] |= w7_idle | w7_error | w7_tape_error; - update_interrupt(device); + m_w[0] |= w0_offline; + m_w[7] |= w7_idle | w7_error | w7_tape_error; + update_interrupt(); } #if 0 else if (0) { /* rewind in progress */ - tpc->w[0] |= /*...*/; - tpc->w[7] |= w7_idle | w7_error | w7_tape_error; - update_interrupt(device); + m_w[0] |= /*...*/; + m_w[7] |= w7_idle | w7_error | w7_tape_error; + update_interrupt(); } #endif else { /* no particular error condition */ - if (tpc->t[tap_sel].bot) - tpc->w[0] |= w0_BOT; - if (tpc->t[tap_sel].eot) - tpc->w[0] |= w0_EOT; - if (tpc->t[tap_sel].wp) - tpc->w[0] |= w0_write_ring; - tpc->w[7] |= w7_idle | w7_complete; - update_interrupt(device); + if (m_tape[tap_sel].bot) + m_w[0] |= w0_BOT; + if (m_tape[tap_sel].eot) + m_w[0] |= w0_EOT; + if (m_tape[tap_sel].wp) + m_w[0] |= w0_write_ring; + m_w[7] |= w7_idle | w7_complete; + update_interrupt(); } } /* Parse command code and execute the command. */ -static void execute_command(device_t *device) +void tap_990_device::execute_command() { /* hack */ - tap_990_t *tpc = get_safe_token(device); - tpc->w[0] &= 0xff; + m_w[0] &= 0xff; - switch ((tpc->w[6] & w6_command) >> 8) + switch ((m_w[6] & w6_command) >> 8) { case 0x00: case 0x0C: case 0x0E: /* NOP */ logerror("NOP\n"); - tpc->w[7] |= w7_idle | w7_complete; - update_interrupt(device); + m_w[7] |= w7_idle | w7_complete; + update_interrupt(); break; case 0x01: /* buffer sync: means nothing under emulation */ logerror("buffer sync\n"); - tpc->w[7] |= w7_idle | w7_complete; - update_interrupt(device); + m_w[7] |= w7_idle | w7_complete; + update_interrupt(); break; case 0x02: /* write EOF - not emulated */ logerror("write EOF\n"); /* ... */ - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); break; case 0x03: /* record skip reverse - not fully tested */ logerror("record skip reverse\n"); - cmd_record_skip_reverse(device); + cmd_record_skip_reverse(); break; case 0x04: /* read binary forward */ logerror("read binary forward\n"); - cmd_read_binary_forward(device); + cmd_read_binary_forward(); break; case 0x05: /* record skip forward - not tested */ logerror("record skip forward\n"); - cmd_record_skip_forward(device); + cmd_record_skip_forward(); break; case 0x06: /* write binary forward - not emulated */ logerror("write binary forward\n"); /* ... */ - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); break; case 0x07: /* erase - not emulated */ logerror("erase\n"); /* ... */ - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); break; case 0x08: case 0x09: /* read transport status */ logerror("read transport status\n"); - read_transport_status(device); + read_transport_status(); break; case 0x0A: /* rewind - not tested */ logerror("rewind\n"); - cmd_rewind(device); + cmd_rewind(); break; case 0x0B: /* rewind and offline - not tested */ logerror("rewind and offline\n"); - cmd_rewind_and_offline(device); + cmd_rewind_and_offline(); break; case 0x0F: /* extended control and status - not emulated */ logerror("extended control and status\n"); /* ... */ - tpc->w[7] |= w7_idle | w7_error | w7_hard_error; - update_interrupt(device); + m_w[7] |= w7_idle | w7_error | w7_hard_error; + update_interrupt(); break; } } @@ -907,11 +851,10 @@ static void execute_command(device_t *device) /* Read one register in TPCS space */ -READ16_DEVICE_HANDLER(ti990_tpc_r) +READ16_MEMBER( tap_990_device::read ) { - tap_990_t *tpc = get_safe_token(device); if (offset < 8) - return tpc->w[offset]; + return m_w[offset]; else return 0; } @@ -919,25 +862,24 @@ READ16_DEVICE_HANDLER(ti990_tpc_r) /* Write one register in TPCS space. Execute command if w7_idle is cleared. */ -WRITE16_DEVICE_HANDLER(ti990_tpc_w) +WRITE16_MEMBER( tap_990_device::write ) { - tap_990_t *tpc = get_safe_token(device); if (offset < 8) { /* write protect if a command is in progress */ - if (tpc->w[7] & w7_idle) + if (m_w[7] & w7_idle) { - UINT16 old_data = tpc->w[offset]; + UINT16 old_data = m_w[offset]; /* Only write writable bits AND honor byte accesses (ha!) */ - tpc->w[offset] = (tpc->w[offset] & ((~w_mask[offset]) | mem_mask)) | (data & w_mask[offset] & ~mem_mask); + m_w[offset] = (m_w[offset] & ((~w_mask[offset]) | mem_mask)) | (data & w_mask[offset] & ~mem_mask); if ((offset == 0) || (offset == 7)) - update_interrupt(device); + update_interrupt(); if ((offset == 7) && (old_data & w7_idle) && ! (data & w7_idle)) { /* idle has been cleared: start command execution */ - execute_command(device); + execute_command(); } } } @@ -968,12 +910,14 @@ protected: // device-level overrides virtual void device_config_complete(); virtual void device_start(); +private: + int tape_get_id(); }; const device_type TI990_TAPE = &device_creator; ti990_tape_image_device::ti990_tape_image_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, TI990_TAPE, "TI990 Magnetic Tape", tag, owner, clock, "ti990_tape_image", __FILE__), + : device_t(mconfig, TI990_TAPE, "TI-990 Magnetic Tape", tag, owner, clock, "ti990_tape_image", __FILE__), device_image_interface(mconfig, *this) { } @@ -985,17 +929,18 @@ void ti990_tape_image_device::device_config_complete() void ti990_tape_image_device::device_start() { - tape_unit_t *t; - tap_990_t *tpc = get_safe_token(owner()); - int id = tape_get_id(this); + tap_990_device* tpc = downcast(owner()); + tpc->set_tape(tape_get_id(), this, true, false, false); +} - t = &tpc->t[id]; - memset(t, 0, sizeof(*t)); - - t->img = this; - t->wp = 1; - t->bot = 0; - t->eot = 0; +int ti990_tape_image_device::tape_get_id() +{ + int drive =0; + if (strcmp(tag(), ":tape0") == 0) drive = 0; + if (strcmp(tag(), ":tape1") == 0) drive = 1; + if (strcmp(tag(), ":tape2") == 0) drive = 2; + if (strcmp(tag(), ":tape3") == 0) drive = 3; + return drive; } /* @@ -1003,17 +948,8 @@ void ti990_tape_image_device::device_start() */ bool ti990_tape_image_device::call_load() { - tape_unit_t *t; - tap_990_t *tpc = get_safe_token(owner()); - int id = tape_get_id(this); - - t = &tpc->t[id]; - memset(t, 0, sizeof(*t)); - - /* tell whether the image is writable */ - t->wp = is_readonly(); - - t->bot = 1; + tap_990_device* tpc = downcast(owner()); + tpc->set_tape(tape_get_id(), this, true, false, is_readonly()); return IMAGE_INIT_PASS; } @@ -1023,14 +959,8 @@ bool ti990_tape_image_device::call_load() */ void ti990_tape_image_device::call_unload() { - tape_unit_t *t; - tap_990_t *tpc = get_safe_token(owner()); - int id = tape_get_id(this); - - t = &tpc->t[id]; - t->wp = 1; - t->bot = 0; - t->eot = 0; + tap_990_device* tpc = downcast(owner()); + tpc->set_tape(tape_get_id(), this, false, false, true); } #define MCFG_TI990_TAPE_ADD(_tag) \ @@ -1044,37 +974,14 @@ static MACHINE_CONFIG_FRAGMENT( tap_990 ) MCFG_TI990_TAPE_ADD("tape3") MACHINE_CONFIG_END -/* - Init the tape controller core -*/ -static DEVICE_START(tap_990) -{ - tap_990_t *tpc = get_safe_token(device); - /* verify that we have an interface assigned */ - assert(device->static_config() != NULL); - - /* copy interface pointer */ - tpc->intf = (const ti990_tpc_interface*)device->static_config(); - - memset(tpc->w, 0, sizeof(tpc->w)); - /* The PE bit is always set for the MT3200 (but not MT1600) */ - /* According to MT3200 manual, w7 bit #4 (reserved) is always set */ - tpc->w[7] = w7_idle /*| w7_PE_format*/ | 0x0800; - - update_interrupt(device); -} - - const device_type TI990_TAPE_CTRL = &device_creator; tap_990_device::tap_990_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, TI990_TAPE_CTRL, "Generic TI990 Tape Controller", tag, owner, clock, "tap_990", __FILE__) + : device_t(mconfig, TI990_TAPE_CTRL, "Generic TI-990 Tape Controller", tag, owner, clock, "tap_990", __FILE__), + m_int_line(*this) { - m_token = global_alloc_clear(tap_990_t); } -tap_990_device::~tap_990_device() { global_free(m_token); } - //------------------------------------------------- // device_config_complete - perform any // operations now that the configuration is @@ -1091,7 +998,14 @@ void tap_990_device::device_config_complete() void tap_990_device::device_start() { - DEVICE_START_NAME( tap_990 )(this); + m_int_line.resolve(); + memset(m_w, 0, sizeof(m_w)); + + // The PE bit is always set for the MT3200 (but not MT1600) + // According to MT3200 manual, w7 bit #4 (reserved) is always set + m_w[7] = w7_idle /*| w7_PE_format*/ | 0x0800; + + update_interrupt(); } //------------------------------------------------- diff --git a/src/mess/machine/ti99/990_tap.h b/src/mess/machine/ti99/990_tap.h index 33b23a27183..4dbe244f578 100644 --- a/src/mess/machine/ti99/990_tap.h +++ b/src/mess/machine/ti99/990_tap.h @@ -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 static devcb2_base &static_set_int_callback(device_t &device, _Object object) + { + return downcast(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 ); diff --git a/src/mess/video/733_asr.c b/src/mess/video/733_asr.c index 39b844df0b7..33ae264615d 100644 --- a/src/mess/video/733_asr.c +++ b/src/mess/video/733_asr.c @@ -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(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(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(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; ybitmap, 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(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; } } diff --git a/src/mess/video/733_asr.h b/src/mess/video/733_asr.h index 27e24917c7f..7a97d0e0274 100644 --- a/src/mess/video/733_asr.h +++ b/src/mess/video/733_asr.h @@ -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 static devcb2_base &static_set_int_callback(device_t &device, _Object object) + { + return downcast(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 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 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 m_palette; + required_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 */ \ diff --git a/src/mess/video/911_vdt.c b/src/mess/video/911_vdt.c index 3b337e32608..f0c5a750053 100644 --- a/src/mess/video/911_vdt.c +++ b/src/mess/video/911_vdt.c @@ -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(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("beeper")->set_frequency(2000); -} - - -INLINE vdt_t *get_safe_token(device_t *device) -{ - assert(device != NULL); - assert(device->type() == VDT911); - - return (vdt_t *)downcast(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(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("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("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; idisplay_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; } } diff --git a/src/mess/video/911_vdt.h b/src/mess/video/911_vdt.h index 2bdcb3f1d2c..568efc95148 100644 --- a/src/mess/video/911_vdt.h +++ b/src/mess/video/911_vdt.h @@ -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 static devcb2_base &static_set_int_callback(device_t &device, _Object object) + { + return downcast(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(device).m_screen_size = size; + downcast(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 m_gfxdecode; - required_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 m_beeper; + required_device m_gfxdecode; + required_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);