summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/devices/video/tms9927.cpp26
-rw-r--r--src/devices/video/tms9927.h22
-rw-r--r--src/mame/drivers/intv.cpp17
-rw-r--r--src/mame/includes/intv.h17
-rw-r--r--src/mame/machine/intv.cpp656
-rw-r--r--src/mame/video/intv.cpp101
-rw-r--r--src/mame/video/stic.cpp2
7 files changed, 545 insertions, 296 deletions
diff --git a/src/devices/video/tms9927.cpp b/src/devices/video/tms9927.cpp
index b0553642316..3c36f644c69 100644
--- a/src/devices/video/tms9927.cpp
+++ b/src/devices/video/tms9927.cpp
@@ -16,8 +16,8 @@ static const uint8_t skew_bits_value[4] = { 0, 1, 2, 2 };
#define HCOUNT (m_reg[0] + 1)
#define INTERLACED ((m_reg[1] >> 7) & 0x01)
-#define HSYNC_WIDTH ((m_reg[1] >> 4) & 0x0f)
-#define HSYNC_DELAY ((m_reg[1] >> 0) & 0x07)
+#define HSYNC_WIDTH (((m_reg[1] >> 3) & 0x0f) + 1)
+#define HSYNC_DELAY (((m_reg[1] >> 0) & 0x07) + 1)
#define SCANS_PER_DATA_ROW (((m_reg[2] >> 3) & 0x0f) + 1)
#define CHARS_PER_DATA_ROW (chars_per_row_value[(m_reg[2] >> 0) & 0x07])
#define SKEW_BITS (skew_bits_value[(m_reg[3] >> 6) & 0x03])
@@ -45,6 +45,10 @@ tms9927_device::tms9927_device(const machine_config &mconfig, device_type type,
, device_video_interface(mconfig, *this)
, m_write_vsyn(*this)
, m_hpixels_per_column(0)
+ , m_overscan_left(0)
+ , m_overscan_right(0)
+ , m_overscan_top(0)
+ , m_overscan_bottom(0)
, m_selfload(*this, finder_base::DUMMY_TAG)
, m_reset(0)
{
@@ -108,7 +112,7 @@ void tms9927_device::device_reset()
void tms9927_device::device_stop()
{
- osd_printf_debug("TMS9937: Final params: (%d, %d, %d, %d, %d, %d, %d)\n",
+ osd_printf_debug("TMS9927: Final params: (%d, %d, %d, %d, %d, %d, %d)\n",
m_clock,
m_total_hpix,
0, m_visible_hpix,
@@ -194,7 +198,6 @@ void tms9927_device::generic_access(address_space &space, offs_t offset)
}
}
-
WRITE8_MEMBER( tms9927_device::write )
{
switch (offset)
@@ -270,8 +273,7 @@ int tms9927_device::cursor_bounds(rectangle &bounds)
void tms9927_device::recompute_parameters(bool postload)
{
- uint16_t offset_hpix, offset_vpix;
- attoseconds_t refresh;
+ attoseconds_t refresh;
rectangle visarea;
if (m_reset)
@@ -286,11 +288,8 @@ void tms9927_device::recompute_parameters(bool postload)
m_visible_vpix = DATA_ROWS_PER_FRAME * SCANS_PER_DATA_ROW;
m_start_datarow = (LAST_DISP_DATA_ROW + 1) % DATA_ROWS_PER_FRAME;
- /* determine the horizontal/vertical offsets */
- offset_hpix = HSYNC_DELAY * m_hpixels_per_column;
- offset_vpix = VERTICAL_DATA_START;
- osd_printf_debug("TMS9937: Total = %dx%d, Visible = %dx%d, Offset=%dx%d, Skew=%d, Upscroll=%d\n", m_total_hpix, m_total_vpix, m_visible_hpix, m_visible_vpix, offset_hpix, offset_vpix, SKEW_BITS, m_start_datarow);
+ osd_printf_debug("TMS9927: Total = %dx%d, Visible = %dx%d, Skew=%d, Upscroll=%d\n", m_total_hpix, m_total_vpix, m_visible_hpix, m_visible_vpix, SKEW_BITS, m_start_datarow);
/* see if it all makes sense */
m_valid_config = true;
@@ -310,10 +309,10 @@ void tms9927_device::recompute_parameters(bool postload)
/* update */
if (!m_valid_config)
return;
-
+
/* create a visible area */
- /* fix me: how do the offsets fit in here? */
- visarea.set(0, m_visible_hpix - 1, 0, m_visible_vpix - 1);
+ visarea.set(0, m_overscan_left + m_visible_hpix + m_overscan_right - 1,
+ 0, m_overscan_top + m_visible_vpix + m_overscan_bottom - 1);
refresh = HZ_TO_ATTOSECONDS(m_clock) * m_total_hpix * m_total_vpix;
@@ -321,4 +320,5 @@ void tms9927_device::recompute_parameters(bool postload)
m_vsyn = 0;
m_vsync_timer->adjust(m_screen->time_until_pos(0, 0));
+
}
diff --git a/src/devices/video/tms9927.h b/src/devices/video/tms9927.h
index eac4fdc8463..11a3648fbf8 100644
--- a/src/devices/video/tms9927.h
+++ b/src/devices/video/tms9927.h
@@ -19,7 +19,9 @@
#define MCFG_TMS9927_REGION(_tag) \
tms9927_device::set_region_tag(*device, "^" _tag);
-
+#define MCFG_TMS9927_OVERSCAN(_left, _right, _top, _bottom) \
+ tms9927_device::set_overscan(*device, _left, _right, _top, _bottom);
+
class tms9927_device : public device_t,
public device_video_interface
{
@@ -32,7 +34,14 @@ public:
static void set_char_width(device_t &device, int pixels) { downcast<tms9927_device &>(device).m_hpixels_per_column = pixels; }
static void set_region_tag(device_t &device, const char *tag) { downcast<tms9927_device &>(device).m_selfload.set_tag(tag); }
-
+ static void set_overscan(device_t &device, int left, int right, int top, int bottom) {
+ tms9927_device &dev = downcast<tms9927_device &>(device);
+ dev.m_overscan_left = left;
+ dev.m_overscan_right = right;
+ dev.m_overscan_top = top;
+ dev.m_overscan_bottom = bottom;
+ }
+
DECLARE_WRITE8_MEMBER(write);
DECLARE_READ8_MEMBER(read);
@@ -59,7 +68,11 @@ private:
devcb_write_line m_write_vsyn;
int m_hpixels_per_column; /* number of pixels per video memory address */
-
+ uint16_t m_overscan_left;
+ uint16_t m_overscan_right;
+ uint16_t m_overscan_top;
+ uint16_t m_overscan_bottom;
+
// internal state
optional_region_ptr<uint8_t> m_selfload;
@@ -68,12 +81,13 @@ private:
uint8_t m_reg[9];
uint8_t m_start_datarow;
uint8_t m_reset;
-
+
/* derived state; no need to save */
uint8_t m_valid_config;
uint16_t m_total_hpix, m_total_vpix;
uint16_t m_visible_hpix, m_visible_vpix;
+
int m_vsyn;
emu_timer *m_vsync_timer;
diff --git a/src/mame/drivers/intv.cpp b/src/mame/drivers/intv.cpp
index c73695c5d33..d29ffaf0e59 100644
--- a/src/mame/drivers/intv.cpp
+++ b/src/mame/drivers/intv.cpp
@@ -53,6 +53,7 @@ RO-3-9506 = 8KiB (4Kiw) self decoding address mask rom with external address dec
#include "emu.h"
#include "cpu/m6502/m6502.h"
#include "cpu/cp1610/cp1610.h"
+#include "video/tms9927.h"
#include "includes/intv.h"
#include "sound/ay8910.h"
#include "softlist.h"
@@ -236,7 +237,7 @@ static INPUT_PORTS_START( intvkbd )
PORT_START("ROW7")
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+')
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('O') PORT_CHAR(')')
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')')
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*')
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('\xA2')
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
@@ -409,8 +410,10 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( intvkbd2_mem , AS_PROGRAM, 8, intv_state )
ADDRESS_MAP_UNMAP_HIGH /* Required because of probing */
AM_RANGE(0x0000, 0x3fff) AM_READWRITE(intvkbd_dualport8_lsb_r, intvkbd_dualport8_lsb_w) /* Dual-port RAM */
- AM_RANGE(0x4000, 0x7fff) AM_READWRITE(intvkbd_dualport8_msb_r, intvkbd_dualport8_msb_w) /* Dual-port RAM */
- AM_RANGE(0xb7f8, 0xb7ff) AM_RAM /* ??? */
+ AM_RANGE(0x4000, 0x40bf) AM_READWRITE(intvkbd_io_r, intvkbd_io_w)
+ AM_RANGE(0x40c0, 0x40cf) AM_DEVREADWRITE("crtc", tms9927_device, read, write)
+ AM_RANGE(0x4200, 0x7fff) AM_READWRITE(intvkbd_dualport8_msb_r, intvkbd_dualport8_msb_w) /* Dual-port RAM */
+ AM_RANGE(0xb7f8, 0xb7ff) AM_READWRITE(intvkbd_periph_r, intvkbd_periph_w)
AM_RANGE(0xb800, 0xbfff) AM_RAM AM_SHARE("videoram") /* Text Display */
AM_RANGE(0xc000, 0xdfff) AM_ROM
AM_RANGE(0xe000, 0xffff) AM_READ(intvkb_iocart_r)
@@ -538,9 +541,13 @@ static MACHINE_CONFIG_DERIVED( intvkbd, intv )
MCFG_PALETTE_MODIFY("palette")
MCFG_PALETTE_INIT_OWNER(intv_state, intv)
+ /* crt controller */
+ MCFG_DEVICE_ADD("crtc", TMS9927, XTAL_7_15909MHz)
+ MCFG_TMS9927_CHAR_WIDTH(8)
+ MCFG_TMS9927_OVERSCAN(STIC_OVERSCAN_LEFT_WIDTH*STIC_X_SCALE*INTVKBD_X_SCALE, STIC_OVERSCAN_RIGHT_WIDTH*STIC_X_SCALE*INTVKBD_X_SCALE,
+ STIC_OVERSCAN_TOP_HEIGHT*STIC_Y_SCALE*INTVKBD_Y_SCALE, STIC_OVERSCAN_BOTTOM_HEIGHT*STIC_Y_SCALE*INTVKBD_Y_SCALE)
+
MCFG_SCREEN_MODIFY("screen")
- MCFG_SCREEN_SIZE((STIC_OVERSCAN_LEFT_WIDTH+STIC_BACKTAB_WIDTH*STIC_CARD_WIDTH-1+STIC_OVERSCAN_RIGHT_WIDTH)*STIC_X_SCALE*INTVKBD_X_SCALE, (STIC_OVERSCAN_TOP_HEIGHT+STIC_BACKTAB_HEIGHT*STIC_CARD_HEIGHT+STIC_OVERSCAN_BOTTOM_HEIGHT)*STIC_Y_SCALE*INTVKBD_Y_SCALE)
- MCFG_SCREEN_VISIBLE_AREA(0, (STIC_OVERSCAN_LEFT_WIDTH+STIC_BACKTAB_WIDTH*STIC_CARD_WIDTH-1+STIC_OVERSCAN_RIGHT_WIDTH)*STIC_X_SCALE*INTVKBD_X_SCALE-1, 0, (STIC_OVERSCAN_TOP_HEIGHT+STIC_BACKTAB_HEIGHT*STIC_CARD_HEIGHT+STIC_OVERSCAN_BOTTOM_HEIGHT)*STIC_Y_SCALE*INTVKBD_Y_SCALE-1)
MCFG_SCREEN_UPDATE_DRIVER(intv_state, screen_update_intvkbd)
/* I/O cartslots for BASIC */
diff --git a/src/mame/includes/intv.h b/src/mame/includes/intv.h
index 0b5b9ffdbcd..b5f0c2a335a 100644
--- a/src/mame/includes/intv.h
+++ b/src/mame/includes/intv.h
@@ -38,6 +38,7 @@ public:
m_maincpu(*this, "maincpu"),
m_sound(*this, "ay8914"),
m_stic(*this, "stic"),
+ m_crtc(*this, "crtc"),
m_cart(*this, "cartslot"),
m_intvkbd_dualport_ram(*this, "dualport_ram"),
m_videoram(*this, "videoram"),
@@ -54,6 +55,7 @@ public:
required_device<cpu_device> m_maincpu;
required_device<ay8914_device> m_sound;
required_device<stic_device> m_stic;
+ optional_device<tms9927_device> m_crtc;
optional_device<intv_cart_slot_device> m_cart;
optional_shared_ptr<uint16_t> m_intvkbd_dualport_ram;
optional_shared_ptr<uint8_t> m_videoram;
@@ -78,25 +80,26 @@ public:
uint8_t m_ram8[256];
// Keyboard Component
- DECLARE_READ8_MEMBER(intvkbd_tms9927_r);
- DECLARE_WRITE8_MEMBER(intvkbd_tms9927_w);
DECLARE_WRITE16_MEMBER(intvkbd_dualport16_w);
DECLARE_READ8_MEMBER(intvkbd_dualport8_lsb_r);
DECLARE_WRITE8_MEMBER(intvkbd_dualport8_lsb_w);
DECLARE_READ8_MEMBER(intvkbd_dualport8_msb_r);
DECLARE_WRITE8_MEMBER(intvkbd_dualport8_msb_w);
+ DECLARE_READ8_MEMBER(intvkbd_io_r);
+ DECLARE_WRITE8_MEMBER(intvkbd_io_w);
+ DECLARE_READ8_MEMBER(intvkbd_periph_r);
+ DECLARE_WRITE8_MEMBER(intvkbd_periph_w);
- uint8_t m_tms9927_num_rows;
- uint8_t m_tms9927_cursor_col;
- uint8_t m_tms9927_cursor_row;
- uint8_t m_tms9927_last_row;
+ bool m_printer_not_busy; // printer state
+ bool m_printer_no_paper; // printer state
+ bool m_printer_not_busy_enable; // printer interface state
int m_intvkbd_text_blanked;
int m_intvkbd_keyboard_col;
int m_tape_int_pending;
int m_tape_interrupts_enabled;
- int m_tape_unknown_write[6];
int m_tape_motor_mode;
+
DECLARE_DRIVER_INIT(intvecs);
DECLARE_DRIVER_INIT(intvkbd);
DECLARE_DRIVER_INIT(intv);
diff --git a/src/mame/machine/intv.cpp b/src/mame/machine/intv.cpp
index 38498eccce1..594e9336049 100644
--- a/src/mame/machine/intv.cpp
+++ b/src/mame/machine/intv.cpp
@@ -2,10 +2,11 @@
// copyright-holders:Nathan Woods,Frank Palazzolo
#include "emu.h"
#include "video/stic.h"
+#include "video/tms9927.h"
#include "includes/intv.h"
#include "cpu/cp1610/cp1610.h"
-
+// Dual Port Memory handlers
WRITE16_MEMBER( intv_state::intvkbd_dualport16_w )
{
@@ -35,215 +36,450 @@ WRITE8_MEMBER( intv_state::intvkbd_dualport8_lsb_w )
RAM[offset] = data;
}
+READ8_MEMBER( intv_state::intvkbd_dualport8_msb_r )
+{
+ return (m_intvkbd_dualport_ram[offset+0x200]&0x0300)>>8;
+}
+WRITE8_MEMBER( intv_state::intvkbd_dualport8_msb_w )
+{
+ unsigned int mask = m_intvkbd_dualport_ram[offset+0x200] & 0x00ff;
+ m_intvkbd_dualport_ram[offset+0x200] = mask | ((data<<8)&0x0300);
+}
-READ8_MEMBER( intv_state::intvkbd_dualport8_msb_r )
+// I/O for the Tape Drive
+// (to be moved to a device)
+struct tape_drive_state_type
{
- unsigned char rv;
+ /* read state */
+ int read_data; /* 0x4000 */
+ int ready; /* 0x4001 */
+ int leader_detect; /* 0x4002 */
+ int tape_missing; /* 0x4003 */
+ int playing; /* 0x4004 */
+ int no_data; /* 0x4005 */
+
+ /* write state */
+ int motor_state; /* 0x4020-0x4022 */
+ int writing; /* 0x4023 */
+ int audio_b_mute; /* 0x4024 */
+ int audio_a_mute; /* 0x4025 */
+ int channel_select; /* 0x4026 */
+ int erase; /* 0x4027 */
+ int write_data; /* 0x4040 */
+
+ /* bit_counter */
+ int bit_counter;
+} tape_drive;
+
+//static const char *const tape_motor_mode_desc[8] =
+//{
+// "IDLE", "IDLE", "IDLE", "IDLE",
+// "EJECT", "PLAY/RECORD", "REWIND", "FF"
+//};
+
+
+READ8_MEMBER( intv_state::intvkbd_io_r )
+{
+ unsigned char rv = 0x00;
- if (offset < 0x100)
+ switch (offset)
{
- switch (offset)
- {
- case 0x000:
- rv = m_io_test->read() & 0x80;
- logerror("TAPE: Read %02x from 0x40%02x - XOR Data?\n",rv,offset);
- break;
- case 0x001:
- rv = (m_io_test->read() & 0x40) << 1;
- logerror("TAPE: Read %02x from 0x40%02x - Sense 1?\n",rv,offset);
- break;
- case 0x002:
- rv = (m_io_test->read() & 0x20) << 2;
- logerror("TAPE: Read %02x from 0x40%02x - Sense 2?\n",rv,offset);
- break;
- case 0x003:
- rv = (m_io_test->read() & 0x10) << 3;
- logerror("TAPE: Read %02x from 0x40%02x - Tape Present\n",rv,offset);
- break;
- case 0x004:
- rv = (m_io_test->read() & 0x08) << 4;
- logerror("TAPE: Read %02x from 0x40%02x - Comp (339/1)\n",rv,offset);
- break;
- case 0x005:
- rv = (m_io_test->read() & 0x04) << 5;
- logerror("TAPE: Read %02x from 0x40%02x - Clocked Comp (339/13)\n",rv,offset);
- break;
- case 0x006:
- if (m_sr1_int_pending)
- rv = 0x00;
- else
- rv = 0x80;
- logerror("TAPE: Read %02x from 0x40%02x - SR1 Int Pending\n",rv,offset);
- break;
- case 0x007:
- if (m_tape_int_pending)
- rv = 0x00;
- else
- rv = 0x80;
- logerror("TAPE: Read %02x from 0x40%02x - Tape? Int Pending\n",rv,offset);
- break;
- case 0x060: /* Keyboard Read */
- rv = 0xff;
- if (m_intvkbd_keyboard_col < 10)
- rv = m_intv_keyboard[m_intvkbd_keyboard_col]->read();
- break;
- case 0x80:
+ // These next 8 locations all map to bit7
+ case 0x000:
+ // "Data from Cassette"
+ // Tape drive does the decoding to bits
+ //rv = m_io_test->read() & 0x80;
+ rv = tape_drive.read_data << 7;
+ break;
+ case 0x001:
+ // "Watermark"
+ // 0 = Drive Busy Executing Command?, 1 = Drive Ok?
+ //rv = (m_io_test->read() & 0x40) << 1;
+ rv = tape_drive.ready << 7;
+ break;
+ case 0x002:
+ // "End of Tape"
+ // 0 = Recordable surface, 1 = Leader Detect
+ // (Leader is transparent, optical sensor)
+ //rv = (m_io_test->read() & 0x20) << 2;
+ rv = tape_drive.leader_detect << 7;
+ //logerror("TAPE: Read %02x from 0x40%02x - Sense 2?\n",rv,offset);
+ break;
+ case 0x003:
+ // "Cassette Present"
+ // 0 = Tape Present, 1 = Tape Not Present
+ //rv = (m_io_test->read() & 0x10) << 3;
+ rv = tape_drive.tape_missing << 7;
+ //logerror("TAPE: Read %02x from 0x40%02x - Tape Present\n",rv,offset);
+ break;
+ case 0x004:
+ // "NOT Inter Record Gap (IRG)"
+ // 0 = Not Playing/Recording?, 1 = Playing/Recording?
+ //rv = (m_io_test->read() & 0x08) << 4;
+ rv = tape_drive.playing << 7;
+ //logerror("TAPE: Read %02x from 0x40%02x - Comp (339/1)\n",rv,offset);
+ break;
+ case 0x005:
+ // "Dropout"
+ // 0 = Data Detect, 1 = No Data
+ //rv = (m_io_test->read() & 0x04) << 5;
+ rv = tape_drive.no_data << 7;
+ //logerror("TAPE: Read %02x from 0x40%02x - Clocked Comp (339/13)\n",rv,offset);
+ break;
+ case 0x006:
+ // "NOT Clock Interrupt"
+ if (m_sr1_int_pending)
rv = 0x00;
- logerror("TAPE: Read %02x from 0x40%02x, clear tape int pending\n",rv,offset);
- m_tape_int_pending = 0;
- break;
- case 0xa0:
+ else
+ rv = 0x80;
+ //logerror("TAPE: Read %02x from 0x40%02x - SR1 Int Pending\n",rv,offset);
+ break;
+ case 0x007:
+ // "NOT Tape Interrupt"
+ if (m_tape_int_pending)
rv = 0x00;
- logerror("TAPE: Read %02x from 0x40%02x, clear SR1 int pending\n",rv,offset);
- m_sr1_int_pending = 0;
- break;
- case 0xc0:
- case 0xc1:
- case 0xc2:
- case 0xc3:
- case 0xc4:
- case 0xc5:
- case 0xc6:
- case 0xc7:
- case 0xc8:
- case 0xc9:
- case 0xca:
- case 0xcb:
- case 0xcc:
- case 0xcd:
- case 0xce:
- case 0xcf:
- /* TMS9927 regs */
- rv = intvkbd_tms9927_r(space, offset-0xc0);
- break;
- default:
- rv = (m_intvkbd_dualport_ram[offset]&0x0300)>>8;
- logerror("Unknown read %02x from 0x40%02x\n",rv,offset);
- break;
- }
- return rv;
+ else
+ rv = 0x80;
+ //logerror("TAPE: Read %02x from 0x40%02x - Tape? Int Pending\n",rv,offset);
+ break;
+ case 0x060:
+ // "Read Keyboard"
+ rv = 0xff;
+ if (m_intvkbd_keyboard_col < 10)
+ rv = m_intv_keyboard[m_intvkbd_keyboard_col]->read();
+ break;
+ case 0x80:
+ // "Clear Tape Interrupt"
+ rv = 0x00;
+ //logerror("TAPE: Read %02x from 0x40%02x, clear tape int pending\n",rv,offset);
+ m_tape_int_pending = 0;
+ break;
+ case 0xa0:
+ // "Clear Clock Interrupt"
+ rv = 0x00;
+ //logerror("TAPE: Read %02x from 0x40%02x, clear SR1 int pending\n",rv,offset);
+ m_sr1_int_pending = 0;
+ break;
+ default:
+ //logerror("Unknown read %02x from 0x40%02x\n",rv,offset);
+ break;
}
+ return rv;
+}
+
+WRITE8_MEMBER( intv_state::intvkbd_io_w )
+{
+ switch (offset)
+ {
+ // Bits from offset $20 to $47 are all bit0, write only
+ // These are all set to zero by system reset
+ case 0x020:
+ // "Tape Drive Control: Enable"
+ tape_drive.motor_state &= 3;
+ if (data & 1)
+ tape_drive.motor_state |= 4;
+ //logerror("TAPE: Motor Mode: %s\n",tape_motor_mode_desc[m_tape_motor_mode]);
+ break;
+ case 0x021:
+ // "Tape Drive Control: Forward"
+ tape_drive.motor_state &= 5;
+ if (data & 1)
+ tape_drive.motor_state |= 2;
+ //logerror("TAPE: Motor Mode: %s\n",tape_motor_mode_desc[m_tape_motor_mode]);
+ break;
+ case 0x022:
+ // "Tape Drive Control: Fast"
+ tape_drive.motor_state &= 6;
+ if (data & 1)
+ tape_drive.motor_state |= 1;
+ //logerror("TAPE: Motor Mode: %s\n",tape_motor_mode_desc[m_tape_motor_mode]);
+ break;
+ case 0x023:
+ // "Tape Drive Control: Record"
+ // 0=Read, 1=Write
+ tape_drive.writing = (data & 1);
+ break;
+ case 0x024:
+ // "Tape Drive Control: Mute 1"
+ // 0=Enable Channel B Audio, 1=Mute
+ tape_drive.audio_b_mute = (data & 1);
+ break;
+ case 0x025:
+ // "Tape Drive Control: Mute 2"
+ // 0=Enable Channel A Audio, 1=Mute
+ tape_drive.audio_a_mute = (data & 1);
+ break;
+ case 0x026:
+ // "Tape Drive Control: Mode"
+ // If read mode:
+ // 0=Read Channel B Data, 1 = Read Channel A Data
+ // If write mode:
+ // 0=Write Channel B data, 1 = Record Channel B Audio
+ tape_drive.channel_select = (data & 1);
+ case 0x027:
+ break;
+ // "Tape Drive Control: Erase"
+ tape_drive.erase = (data & 1);
+ break;
+ case 0x040:
+ // Data to Tape
+ tape_drive.write_data = (data & 1);
+ break;
+ case 0x041:
+ // "Tape Interrupt Enable"
+ //if (data & 1)
+ //logerror("TAPE: Tape Interrupts Enabled\n");
+ //else
+ //logerror("TAPE: Tape Interrupts Disabled\n");
+ m_tape_interrupts_enabled = (data & 1);
+ break;
+ case 0x042:
+ // "NOT External Interrupt Enable"
+ //if (data & 1)
+ //logerror("TAPE: Cart Bus Interrupts Disabled\n");
+ //else
+ //logerror("TAPE: Cart Bus Interrupts Enabled\n");
+ break;
+ case 0x043:
+ // "NOT Blank Screen"
+ if (data & 0x01)
+ m_intvkbd_text_blanked = 0;
+ else
+ m_intvkbd_text_blanked = 1;
+ break;
+ case 0x044:
+ m_intvkbd_keyboard_col &= 0x0e;
+ m_intvkbd_keyboard_col |= (data&0x01);
+ break;
+ case 0x045:
+ m_intvkbd_keyboard_col &= 0x0d;
+ m_intvkbd_keyboard_col |= ((data&0x01)<<1);
+ break;
+ case 0x046:
+ m_intvkbd_keyboard_col &= 0x0b;
+ m_intvkbd_keyboard_col |= ((data&0x01)<<2);
+ break;
+ case 0x047:
+ m_intvkbd_keyboard_col &= 0x07;
+ m_intvkbd_keyboard_col |= ((data&0x01)<<3);
+ break;
+ case 0x80:
+ // "Clear Tape Interrupt"
+ //logerror("TAPE: Write to 0x40%02x, clear tape int pending\n",offset);
+ m_tape_int_pending = 0;
+ break;
+ case 0xa0:
+ // "Clear Clock Interrupt"
+ //logerror("TAPE: Write to 0x40%02x, clear SR1 int pending\n",offset);
+ m_sr1_int_pending = 0;
+ break;
+ default:
+ //logerror("%04X: Unknown write %02x to 0x40%02x\n",space.device().safe_pc(),data,offset);
+ break;
+ }
+}
+
+#if 0
+static int max_bits = 0;
+static unsigned char *tape_data;
+
+void get_tape_bit(int position, int channel, int *data_present, int *data)
+{
+ int byte = (position >> 2)*2 + channel;
+ int data_present_mask = 1 << ((3-(position % 4))*2 + 1);
+ int data_mask = 1 << ((3-(position % 4))*2);
+
+ //printf("%d\t0x%02x 0x%02x\n",byte,data_present_mask,data_mask);
+
+ if (tape_data[byte] & data_present_mask)
+ *data_present = 1;
+ else
+ *data_present = 0;
+
+ if (tape_data[byte] & data_mask)
+ *data = 1;
else
- return (m_intvkbd_dualport_ram[offset]&0x0300)>>8;
+ *data = 0;
}
-static const char *const tape_motor_mode_desc[8] =
+void set_tape_bit(int position, int data)
{
- "IDLE", "IDLE", "IDLE", "IDLE",
- "EJECT", "PLAY/RECORD", "REWIND", "FF"
-};
+ int byte = (position >> 2)*2 + 1;
+ int data_present_mask = 1 << ((3-(position % 4))*2 + 1);
+ int data_mask = 1 << ((3-(position % 4))*2);
-WRITE8_MEMBER( intv_state::intvkbd_dualport8_msb_w )
+ tape_data[byte] |= data_present_mask;
+ if (data)
+ tape_data[byte] |= data_mask;
+ else
+ tape_data[byte] &= (~data_mask);
+}
+#endif
+
+#if defined(LATER)
+int intvkbd_tape_init(int id)
+{
+ FILE *tapefile;
+ int filesize;
+
+ if (!(tapefile = image_fopen (IO_CASSETTE, id, OSD_FILETYPE_IMAGE, OSD_FOPEN_READ)))
+ {
+ return INIT_FAIL;
+ }
+
+ filesize = osd_fsize(tapefile);
+ tape_data = (unsigned char *)malloc(filesize);
+ osd_fread(tapefile, tape_data, filesize);
+
+ osd_fclose(tapefile);
+
+ max_bits = 2*filesize;
+
+ tape_drive.tape_missing = 0;
+ tape_drive.leader_detect = 0;
+ tape_drive.ready = 1;
+
+ tape_drive.bit_counter = 0;
+ return INIT_PASS;
+}
+
+void intvkbd_tape_exit(int id)
{
- unsigned int mask;
+ FILE *tapefile;
+ int filesize;
- if (offset < 0x100)
+ if (tape_data)
{
- switch (offset)
+ if (!(tapefile = image_fopen (IO_CASSETTE, id, OSD_FILETYPE_IMAGE, OSD_FOPEN_RW)))
{
- case 0x020:
- m_tape_motor_mode &= 3;
- if (data & 1)
- m_tape_motor_mode |= 4;
- logerror("TAPE: Motor Mode: %s\n",tape_motor_mode_desc[m_tape_motor_mode]);
- break;
- case 0x021:
- m_tape_motor_mode &= 5;
- if (data & 1)
- m_tape_motor_mode |= 2;
- logerror("TAPE: Motor Mode: %s\n",tape_motor_mode_desc[m_tape_motor_mode]);
- break;
- case 0x022:
- m_tape_motor_mode &= 6;
- if (data & 1)
- m_tape_motor_mode |= 1;
- logerror("TAPE: Motor Mode: %s\n",tape_motor_mode_desc[m_tape_motor_mode]);
- break;
- case 0x023:
- case 0x024:
- case 0x025:
- case 0x026:
- case 0x027:
- m_tape_unknown_write[offset - 0x23] = (data & 1);
- break;
- case 0x040:
- m_tape_unknown_write[5] = (data & 1);
- break;
- case 0x041:
- if (data & 1)
- logerror("TAPE: Tape Interrupts Enabled\n");
- else
- logerror("TAPE: Tape Interrupts Disabled\n");
- m_tape_interrupts_enabled = (data & 1);
- break;
- case 0x042:
- if (data & 1)
- logerror("TAPE: Cart Bus Interrupts Disabled\n");
- else
- logerror("TAPE: Cart Bus Interrupts Enabled\n");
- break;
- case 0x043:
- if (data & 0x01)
- m_intvkbd_text_blanked = 0;
- else
- m_intvkbd_text_blanked = 1;
- break;
- case 0x044:
- m_intvkbd_keyboard_col &= 0x0e;
- m_intvkbd_keyboard_col |= (data&0x01);
- break;
- case 0x045:
- m_intvkbd_keyboard_col &= 0x0d;
- m_intvkbd_keyboard_col |= ((data&0x01)<<1);
- break;
- case 0x046:
- m_intvkbd_keyboard_col &= 0x0b;
- m_intvkbd_keyboard_col |= ((data&0x01)<<2);
- break;
- case 0x047:
- m_intvkbd_keyboard_col &= 0x07;
- m_intvkbd_keyboard_col |= ((data&0x01)<<3);
- break;
- case 0x80:
- logerror("TAPE: Write to 0x40%02x, clear tape int pending\n",offset);
- m_tape_int_pending = 0;
- break;
- case 0xa0:
- logerror("TAPE: Write to 0x40%02x, clear SR1 int pending\n",offset);
- m_sr1_int_pending = 0;
- break;
- case 0xc0:
- case 0xc1:
- case 0xc2:
- case 0xc3:
- case 0xc4:
- case 0xc5:
- case 0xc6:
- case 0xc7:
- case 0xc8:
- case 0xc9:
- case 0xca:
- case 0xcb:
- case 0xcc:
- case 0xcd:
- case 0xce:
- case 0xcf:
- /* TMS9927 regs */
- intvkbd_tms9927_w(space, offset-0xc0, data);
- break;
- default:
- logerror("%04X: Unknown write %02x to 0x40%02x\n",space.device().safe_pc(),data,offset);
- break;
+ filesize = osd_fsize(tapefile);
+ osd_fwrite(tapefile, tape_data, filesize);
+ osd_fclose(tapefile);
+
+ free(tape_data);
+ tape_data = 0;
+
+ max_bits = 0;
+ tape_drive.tape_missing = 1;
+ tape_drive.bit_counter = 0;
+ }
+ }
+}
+
+void update_tape_drive(void)
+{
+ /* temp */
+
+ if (tape_drive.writing)
+ {
+ if (tape_drive.channel_select == 0) /* data */
+ {
+ set_tape_bit(tape_drive.bit_counter,tape_drive.write_data);
+ }
+ else
+ {
+ /* recording audio - TBD */
}
}
else
{
- mask = m_intvkbd_dualport_ram[offset] & 0x00ff;
- m_intvkbd_dualport_ram[offset] = mask | ((data<<8)&0x0300);
+ int channel;
+ int data_present;
+ int data;
+
+ channel = tape_drive.channel_select ^ 1;
+
+ get_tape_bit(tape_drive.bit_counter,channel,&data_present,&data);
+
+ tape_drive.no_data = data_present ^ 1;
+ tape_drive.read_data = data;
+
+ /* temporary */
+ tape_drive.playing = data_present ^ 1;
+ }
+
+ if (tape_drive.motor_state == 5) /* Playing */
+ {
+ tape_drive.bit_counter++;
+ if (tape_drive.bit_counter >= max_bits)
+ tape_drive.bit_counter = max_bits-1;
+ }
+
+ if (tape_drive.motor_state == 6) /* Rewinding */
+ {
+ tape_drive.bit_counter-=4;
+ //tape_drive.bit_counter--;
+ if (tape_drive.bit_counter < 0)
+ tape_drive.bit_counter = 0;
}
+ if (tape_drive.motor_state == 7) /* FastFwd */
+ {
+ tape_drive.bit_counter+=2;
+ //tape_drive.bit_counter++;
+ if (tape_drive.bit_counter >= max_bits)
+ tape_drive.bit_counter = max_bits-1;
+ }
+
+ if ((tape_drive.bit_counter == 0) || (tape_drive.bit_counter == max_bits-1))
+ tape_drive.leader_detect = 1;
+ else
+ tape_drive.leader_detect = 0;
}
+#endif
+////////////
+
+READ8_MEMBER( intv_state::intvkbd_periph_r )
+{
+ uint8_t value = 0;
+ switch(offset) {
+ case 0x06:
+ if (m_printer_not_busy_enable)
+ if (m_printer_not_busy)
+ value |= 0x80;
+ if (m_printer_no_paper)
+ value |= 0x10;
+ //logerror("PeriphRead: 0x%04x->0x%02x\n",offset,value);
+
+ // After one query of busy,
+ // next time the state is not_busy
+ if (!m_printer_not_busy)
+ m_printer_not_busy = true;
+
+ return value;
+ break;
+ case 0x07:
+
+ default:
+ //logerror("PeriphRead: 0x%04x->0x%02x\n",offset,0xff);
+ return 0xff;
+ break;
+ }
+}
+
+WRITE8_MEMBER( intv_state::intvkbd_periph_w )
+{
+ switch(offset) {
+ case 0x06:
+ //logerror("PeriphWrite: 0x%04x->0x%02x\n",offset,data);
+ if (data & 0x20)
+ m_printer_not_busy_enable = true;
+ else
+ m_printer_not_busy_enable = false;
+ break;
+ case 0x07:
+ //logerror("Printing: 0x%02x, %c\n",data,data);
+ // For testing, print to stdout
+ fputc(data, stdout);
+ fflush(stdout);
+ m_printer_not_busy = false;
+ break;
+ default:
+ //logerror("PeriphWrite: 0x%04x->0x%02x\n",offset,data);
+ break;
+ }
+}
READ16_MEMBER( intv_state::intv_stic_r )
{
@@ -322,6 +558,13 @@ void intv_state::machine_reset()
/* Set initial PC */
m_maincpu->set_state_int(CP1610_R7, 0x1000);
+
+ if (m_is_keybd)
+ {
+ m_printer_not_busy = true; // printer state
+ m_printer_no_paper = false; // printer state
+ m_printer_not_busy_enable = false; // printer interface state
+ }
}
void intv_state::machine_start()
@@ -346,12 +589,7 @@ void intv_state::machine_start()
save_item(NAME(m_intvkbd_keyboard_col));
save_item(NAME(m_tape_int_pending));
save_item(NAME(m_tape_interrupts_enabled));
- save_item(NAME(m_tape_unknown_write));
save_item(NAME(m_tape_motor_mode));
- save_item(NAME(m_tms9927_num_rows));
- save_item(NAME(m_tms9927_cursor_col));
- save_item(NAME(m_tms9927_cursor_row));
- save_item(NAME(m_tms9927_last_row));
}
if (m_cart && m_cart->exists())
@@ -436,3 +674,39 @@ INTERRUPT_GEN_MEMBER(intv_state::intv_interrupt)
m_stic->screenrefresh();
}
+
+#if defined(LATER)
+
+INTERRUPT_GEN( intvkbd_interrupt2 )
+{
+ static int tape_interrupt_divider = 0;
+
+ tape_interrupt_divider++;
+ tape_interrupt_divider = tape_interrupt_divider % 50;
+
+ if (tape_interrupt_divider == 0)
+ {
+#if 0
+ update_tape_drive();
+
+ /* do sr1 interrupt plus possible tape interrupt */
+ if (tape_interrupts_enabled)
+ tape_int_pending = 1;
+#endif
+ sr1_int_pending = 1;
+ cpu_set_irq_line(1, 0, PULSE_LINE);
+ }
+ else
+ {
+ update_tape_drive();
+
+ /* do only possible tape interrupt */
+ if (tape_interrupts_enabled)
+ {
+ tape_int_pending = 1;
+ cpu_set_irq_line(1, 0, PULSE_LINE);
+ }
+ }
+
+}
+#endif
diff --git a/src/mame/video/intv.cpp b/src/mame/video/intv.cpp
index 29e769b85da..49d2360844e 100644
--- a/src/mame/video/intv.cpp
+++ b/src/mame/video/intv.cpp
@@ -1,108 +1,59 @@
// license:BSD-3-Clause
// copyright-holders:Nathan Woods,Frank Palazzolo
#include "emu.h"
+#include "video/tms9927.h"
#include "includes/intv.h"
void intv_state::video_start()
{
- m_tms9927_num_rows = 25;
}
-
-/* very rudimentary support for the tms9927 character generator IC */
-
-
-READ8_MEMBER( intv_state::intvkbd_tms9927_r )
-{
- uint8_t rv;
- switch (offset)
- {
- case 8:
- rv = m_tms9927_cursor_row;
- break;
- case 9:
- /* note: this is 1-based */
- rv = m_tms9927_cursor_col;
- break;
- case 11:
- m_tms9927_last_row = (m_tms9927_last_row + 1) % m_tms9927_num_rows;
- rv = m_tms9927_last_row;
- break;
- default:
- rv = 0;
- }
- return rv;
-}
-
-WRITE8_MEMBER( intv_state::intvkbd_tms9927_w )
-{
- switch (offset)
- {
- case 3:
- m_tms9927_num_rows = (data & 0x3f) + 1;
- break;
- case 6:
- m_tms9927_last_row = data;
- break;
- case 11:
- m_tms9927_last_row = (m_tms9927_last_row + 1) % m_tms9927_num_rows;
- break;
- case 12:
- /* note: this is 1-based */
- m_tms9927_cursor_col = data;
- break;
- case 13:
- m_tms9927_cursor_row = data;
- break;
- }
-}
-
-
uint32_t intv_state::screen_update_intv(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
m_stic->screen_update(screen, bitmap, cliprect);
return 0;
}
-
uint32_t intv_state::screen_update_intvkbd(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
- uint8_t *videoram = m_videoram;
- int x,y,offs;
- int current_row;
-// char c;
-
/* Draw the underlying INTV screen first */
m_stic->screen_update(screen, bitmap, cliprect);
/* if the intvkbd text is not blanked, overlay it */
if (!m_intvkbd_text_blanked)
{
- current_row = (m_tms9927_last_row + 1) % m_tms9927_num_rows;
- for(y=0;y<24;y++)
- {
- for(x=0;x<40;x++)
- {
- offs = current_row*64+x;
+ uint8_t *videoram = m_videoram;
+ int xoffset = STIC_OVERSCAN_LEFT_WIDTH*STIC_X_SCALE*INTVKBD_X_SCALE;
+ int yoffset = STIC_OVERSCAN_TOP_HEIGHT*STIC_Y_SCALE*INTVKBD_Y_SCALE;
+
+ rectangle cursor_rect;
+ m_crtc->cursor_bounds(cursor_rect);
+ int cursor_col = cursor_rect.min_x / 8;
+ int cursor_row = cursor_rect.min_y / 8;
- m_gfxdecode->gfx(0)->transpen(bitmap,cliprect,
- videoram[offs],
- 7, /* white */
- 0,0,
- x<<3,y<<3, 0);
- }
- if (current_row == m_tms9927_cursor_row)
- {
- /* draw the cursor as a solid white block */
- /* (should use a filled rect here!) */
+ int current_row = m_crtc->upscroll_offset() % 24;
+ for(int y=0;y<24;y++)
+ {
+ for(int x=0;x<40;x++)
+ {
+ if ((cursor_row == current_row) && (cursor_col == x+1)) {
+ /* draw the cursor as a solid white block */
m_gfxdecode->gfx(0)->transpen(bitmap,cliprect,
191, /* a block */
7, /* white */
0,0,
- (m_tms9927_cursor_col-1)<<3,y<<3, 0);
+ xoffset+(x<<3), yoffset+(y<<3), 0);
+ } else {
+ int offs = current_row*64+x;
+ m_gfxdecode->gfx(0)->transpen(bitmap,cliprect,
+ videoram[offs],
+ 7, /* white */
+ 0,0,
+ xoffset+(x<<3), yoffset+(y<<3), 0);
+ }
}
- current_row = (current_row + 1) % m_tms9927_num_rows;
+ current_row = (current_row + 1) % 24;
}
}
diff --git a/src/mame/video/stic.cpp b/src/mame/video/stic.cpp
index 20106936c97..705c895d9ae 100644
--- a/src/mame/video/stic.cpp
+++ b/src/mame/video/stic.cpp
@@ -924,7 +924,7 @@ WRITE16_MEMBER( stic_device::write )
case STIC_CSR + STIC_CSR1:
case STIC_CSR + STIC_CSR2:
case STIC_CSR + STIC_CSR3:
- logerror("Setting color_stack[%x] = %x (%x)\n", offset & (STIC_CSRS - 1),data & STIC_CSR_BG, space.device().safe_pc());
+ //logerror("Setting color_stack[%x] = %x (%x)\n", offset & (STIC_CSRS - 1),data & STIC_CSR_BG, space.device().safe_pc());
break;
// Border Color
case STIC_BCR: