summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Robbbert <Robbbert@users.noreply.github.com>2021-04-19 03:06:10 +1000
committer Robbbert <Robbbert@users.noreply.github.com>2021-04-19 03:06:10 +1000
commit1da36f8ce520c63fae756ca9ce5785067f5332ba (patch)
tree4c0ed727e61fec5a677c1fca08292d446fce9977
parent92ebbbaee111df6e9dfb0db28ab5069c39558e95 (diff)
lnw80: used derived class to reduce number of duplicate functions.
-rw-r--r--src/mame/drivers/lnw80.cpp426
1 files changed, 7 insertions, 419 deletions
diff --git a/src/mame/drivers/lnw80.cpp b/src/mame/drivers/lnw80.cpp
index 988f97c4a0e..efcc022b165 100644
--- a/src/mame/drivers/lnw80.cpp
+++ b/src/mame/drivers/lnw80.cpp
@@ -3,8 +3,7 @@
/***************************************************************************
Memory map
-0000-2fff ROM R D0-D7
-3000-37ff ROM R D0-D7
+0000-37ff ROM R D0-D7
37de UART status R/W D0-D7
37df UART data R/W D0-D7
37e0 for the realtime clock
@@ -79,50 +78,17 @@ To Do / Status:
*******************************************************************************************************/
#include "emu.h"
-#include "bus/centronics/ctronics.h"
-#include "cpu/z80/z80.h"
+#include "includes/trs80.h"
#include "machine/bankdev.h"
-#include "imagedev/cassette.h"
-#include "imagedev/floppy.h"
-#include "imagedev/snapquik.h"
-#include "machine/ay31015.h"
-#include "machine/clock.h"
-#include "bus/rs232/rs232.h"
-#include "machine/buffer.h"
-#include "machine/wd_fdc.h"
-#include "sound/spkrdev.h"
-#include "emupal.h"
-#include "screen.h"
-#include "speaker.h"
#include "formats/td0_dsk.h"
-#include "formats/trs80_dsk.h"
-class lnw80_state : public driver_device
+class lnw80_state : public trs80_state
{
public:
lnw80_state(const machine_config &mconfig, device_type type, const char *tag)
- : driver_device(mconfig, type, tag)
- , m_maincpu(*this, "maincpu")
- , m_region_maincpu(*this, "maincpu")
- , m_p_chargen(*this, "chargen")
- , m_p_videoram(*this, "videoram")
+ : trs80_state(mconfig, type, tag)
, m_p_gfxram(*this, "gfxram")
, m_lnw_bank(*this, "lnw_banked_mem")
- , m_centronics(*this, "centronics")
- , m_cent_data_out(*this, "cent_data_out")
- , m_cent_status_in(*this, "cent_status_in")
- , m_uart(*this, "uart")
- , m_uart_clock(*this, "uart_clock")
- , m_fdc(*this, "fdc")
- , m_floppy0(*this, "fdc:0")
- , m_floppy1(*this, "fdc:1")
- , m_floppy2(*this, "fdc:2")
- , m_floppy3(*this, "fdc:3")
- , m_speaker(*this, "speaker")
- , m_cassette(*this, "cassette")
- , m_io_baud(*this, "BAUD")
- , m_io_config(*this, "CONFIG")
- , m_io_keyboard(*this, "LINE%u", 0)
{ }
void lnw80(machine_config &config);
@@ -133,66 +99,18 @@ protected:
private:
static void floppy_formats(format_registration &fr);
- void port_ff_w(uint8_t data);
void lnw80_fe_w(uint8_t data);
- void port_ea_w(uint8_t data);
- void port_e8_w(uint8_t data);
uint8_t lnw80_fe_r();
- uint8_t port_ff_r();
- uint8_t port_ea_r();
- uint8_t port_e8_r();
- uint8_t irq_status_r();
- uint8_t printer_r();
- void printer_w(uint8_t data);
- void motor_w(uint8_t data);
- uint8_t keyboard_r(offs_t offset);
- u8 fdc_r(offs_t offset);
- void fdc_w(offs_t offset, u8 data);
-
- INTERRUPT_GEN_MEMBER(rtc_interrupt);
- INTERRUPT_GEN_MEMBER(fdc_interrupt);
- TIMER_CALLBACK_MEMBER(cassette_data_callback);
- DECLARE_WRITE_LINE_MEMBER(intrq_w);
- DECLARE_QUICKLOAD_LOAD_MEMBER(quickload_cb);
void lnw80_palette(palette_device &palette) const;
- uint32_t screen_update_lnw80(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void lnw80_io(address_map &map);
void lnw80_mem(address_map &map);
void lnw_banked_mem(address_map &map);
- bool m_mode;
- uint8_t m_irq;
- uint8_t m_mask;
- bool m_reg_load;
u8 m_lnw_mode;
- bool m_cassette_data;
- emu_timer *m_cassette_data_timer;
- double m_old_cassette_val;
- uint8_t m_size_store;
- uint16_t m_timeout;
- floppy_image_device *m_floppy;
- required_device<cpu_device> m_maincpu;
- required_memory_region m_region_maincpu;
- required_region_ptr<u8> m_p_chargen;
- required_shared_ptr<u8> m_p_videoram;
required_shared_ptr<u8> m_p_gfxram;
required_device<address_map_bank_device> m_lnw_bank;
- required_device<centronics_device> m_centronics;
- required_device<output_latch_device> m_cent_data_out;
- required_device<input_buffer_device> m_cent_status_in;
- required_device<ay31015_device> m_uart;
- required_device<clock_device> m_uart_clock;
- required_device<fd1771_device> m_fdc;
- required_device<floppy_connector> m_floppy0;
- required_device<floppy_connector> m_floppy1;
- required_device<floppy_connector> m_floppy2;
- required_device<floppy_connector> m_floppy3;
- required_device<speaker_sound_device> m_speaker;
- required_device<cassette_image_device> m_cassette;
- required_ioport m_io_baud;
- required_ioport m_io_config;
- required_ioport_array<8> m_io_keyboard;
};
@@ -363,21 +281,6 @@ static INPUT_PORTS_START( lnw80 )
PORT_DIPSETTING( 0x07, "19200")
INPUT_PORTS_END
-#define IRQ_M1_RTC 0x80 /* RTC on Model I */
-#define IRQ_M1_FDC 0x40 /* FDC on Model I */
-
-
-TIMER_CALLBACK_MEMBER(lnw80_state::cassette_data_callback)
-{
- double new_val = (m_cassette->input());
-
- /* Check for HI-LO transition */
- if ( m_old_cassette_val > -0.2 && new_val < -0.2 )
- m_cassette_data = true;
-
- m_old_cassette_val = new_val;
-}
-
/*************************************
*
@@ -386,98 +289,11 @@ TIMER_CALLBACK_MEMBER(lnw80_state::cassette_data_callback)
*************************************/
-uint8_t lnw80_state::port_e8_r()
-{
-/* not emulated
- d7 Clear-to-Send (CTS), Pin 5
- d6 Data-Set-Ready (DSR), pin 6
- d5 Carrier Detect (CD), pin 8
- d4 Ring Indicator (RI), pin 22
- d3,d2,d0 Not used
- d1 UART Receiver Input, pin 20 (pin 20 is also DTR) */
-
- return 0;
-}
-
-uint8_t lnw80_state::port_ea_r()
-{
-/* UART Status Register
- d7 Data Received ('1'=condition true)
- d6 Transmitter Holding Register empty ('1'=condition true)
- d5 Overrun Error ('1'=condition true)
- d4 Framing Error ('1'=condition true)
- d3 Parity Error ('1'=condition true)
- d2..d0 Not used */
-
- uint8_t data=7;
- m_uart->write_swe(0);
- data |= m_uart->tbmt_r() ? 0x40 : 0;
- data |= m_uart->dav_r( ) ? 0x80 : 0;
- data |= m_uart->or_r( ) ? 0x20 : 0;
- data |= m_uart->fe_r( ) ? 0x10 : 0;
- data |= m_uart->pe_r( ) ? 0x08 : 0;
- m_uart->write_swe(1);
-
- return data;
-}
-
-void lnw80_state::port_e8_w(uint8_t data)
-{
- m_reg_load = BIT(data, 1);
-}
-
-void lnw80_state::port_ea_w(uint8_t data)
-{
- if (m_reg_load)
-
-/* d2..d0 not emulated
- d7 Even Parity Enable ('1'=even, '0'=odd)
- d6='1',d5='1' for 8 bits
- d6='0',d5='1' for 7 bits
- d6='1',d5='0' for 6 bits
- d6='0',d5='0' for 5 bits
- d4 Stop Bit Select ('1'=two stop bits, '0'=one stop bit)
- d3 Parity Inhibit ('1'=disable; No parity, '0'=parity enabled)
- d2 Break ('0'=disable transmit data; continuous RS232 'SPACE' condition)
- d1 Request-to-Send (RTS), pin 4
- d0 Data-Terminal-Ready (DTR), pin 20 */
-
- {
- m_uart->write_cs(0);
- m_uart->write_nb1(BIT(data, 6));
- m_uart->write_nb2(BIT(data, 5));
- m_uart->write_tsb(BIT(data, 4));
- m_uart->write_eps(BIT(data, 7));
- m_uart->write_np(BIT(data, 3));
- m_uart->write_cs(1);
- }
- else
- {
-/* not emulated
- d7,d6 Not used
- d5 Secondary Unassigned, pin 18
- d4 Secondary Transmit Data, pin 14
- d3 Secondary Request-to-Send, pin 19
- d2 Break ('0'=disable transmit data; continuous RS232 'SPACE' condition)
- d1 Data-Terminal-Ready (DTR), pin 20
- d0 Request-to-Send (RTS), pin 4 */
-
- }
-}
-
uint8_t lnw80_state::lnw80_fe_r()
{
return m_lnw_mode;
}
-uint8_t lnw80_state::port_ff_r()
-{
-/* ModeSel and cassette data
- d7 cassette data from tape
- d6 modesel setting */
-
- return (m_mode ? 0 : 0x40) | (m_cassette_data ? 0x80 : 0) | 0x3f;
-}
/* lnw80 can switch out all the devices, roms and video ram to be replaced by graphics ram. */
void lnw80_state::lnw80_fe_w(uint8_t data)
@@ -493,147 +309,6 @@ void lnw80_state::lnw80_fe_w(uint8_t data)
m_lnw_bank->set_bank(BIT(data, 3));
}
-void lnw80_state::port_ff_w(uint8_t data)
-{
-/* Standard output port of Model I
- d3 ModeSel bit
- d2 Relay
- d1, d0 Cassette output */
-
- static const double levels[4] = { 0.0, 1.0, -1.0, 0.0 };
-
- m_cassette->change_state(BIT(data, 2) ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR );
- m_cassette->output(levels[data & 3]);
- m_cassette_data = false;
-
- m_mode = BIT(data, 3);
-
- static const double speaker_levels[4] = { 0.0, -1.0, 0.0, 1.0 };
- m_speaker->set_levels(4, speaker_levels);
- m_speaker->level_w(data & 3);
-}
-
-/*************************************
- *
- * Interrupt handlers.
- *
- *************************************/
-
-INTERRUPT_GEN_MEMBER(lnw80_state::rtc_interrupt)
-{
-/* This enables the processing of interrupts for the clock and the flashing cursor.
- The OS counts one tick for each interrupt. It is called 40 times per second. */
-
- m_irq |= IRQ_M1_RTC;
- m_maincpu->set_input_line(0, HOLD_LINE);
-
- // While we're here, let's countdown the motor timeout too.
- // Let's not... LDOS often freezes
-// if (m_timeout)
-// {
-// m_timeout--;
-// if (m_timeout == 0)
-// if (m_floppy)
-// m_floppy->mon_w(1); // motor off
-// }
-}
-
-
-WRITE_LINE_MEMBER(lnw80_state::intrq_w)
-{
- if (state)
- {
- m_irq |= IRQ_M1_FDC;
- m_maincpu->set_input_line(0, HOLD_LINE);
- }
- else
- m_irq &= ~IRQ_M1_FDC;
-}
-
-
-/*************************************
- * *
- * Memory handlers *
- * *
- *************************************/
-
-u8 lnw80_state::fdc_r(offs_t offset)
-{
- if ((offset == 0) && (!BIT(m_io_config->read(), 7)))
- return 0xff;
- else
- return m_fdc->read(offset) ^ 0xff;
-}
-
-void lnw80_state::fdc_w(offs_t offset, u8 data)
-{
- m_fdc->write(offset, data ^ 0xff);
-}
-
-uint8_t lnw80_state::printer_r()
-{
- return m_cent_status_in->read();
-}
-
-void lnw80_state::printer_w(uint8_t data)
-{
- m_cent_data_out->write(data);
- m_centronics->write_strobe(0);
- m_centronics->write_strobe(1);
-}
-
-uint8_t lnw80_state::irq_status_r()
-{
-/* (trs80l2) Whenever an interrupt occurs, 37E0 is read to see what devices require service.
- d7 = RTC
- d6 = FDC
- d2 = Communications (not emulated)
- All interrupting devices are serviced in a single interrupt. There is a mask byte,
- which is dealt with by the DOS. We take the opportunity to reset the cpu INT line. */
-
- u8 result = m_irq;
- m_maincpu->set_input_line(0, CLEAR_LINE);
- m_irq = 0;
- return result;
-}
-
-
-void lnw80_state::motor_w(uint8_t data)
-{
- m_floppy = nullptr;
-
- if (BIT(data, 0)) m_floppy = m_floppy0->get_device();
- if (BIT(data, 1)) m_floppy = m_floppy1->get_device();
- if (BIT(data, 2)) m_floppy = m_floppy2->get_device();
- if (BIT(data, 3)) m_floppy = m_floppy3->get_device();
-
- m_fdc->set_floppy(m_floppy);
-
- if (m_floppy)
- {
- m_floppy->mon_w(0);
- m_floppy->ss_w(BIT(data, 4));
- m_timeout = 200;
- }
-
- // switch to fm
- m_fdc->dden_w(1);
-}
-
-/*************************************
- * Keyboard *
- *************************************/
-uint8_t lnw80_state::keyboard_r(offs_t offset)
-{
- u8 i, result = 0;
-
- for (i = 0; i < 8; i++)
- if (BIT(offset, i))
- result |= m_io_keyboard[i]->read();
-
- return result;
-}
-
/*************************************
* Machine *
@@ -671,95 +346,8 @@ void lnw80_state::machine_reset()
lnw80_fe_w(0);
}
-
-/***************************************************************************
- PARAMETERS
-***************************************************************************/
-
-#define LOG 1
-
-#define CMD_TYPE_OBJECT_CODE 0x01
-#define CMD_TYPE_TRANSFER_ADDRESS 0x02
-#define CMD_TYPE_END_OF_PARTITIONED_DATA_SET_MEMBER 0x04
-#define CMD_TYPE_LOAD_MODULE_HEADER 0x05
-#define CMD_TYPE_PARTITIONED_DATA_SET_HEADER 0x06
-#define CMD_TYPE_PATCH_NAME_HEADER 0x07
-#define CMD_TYPE_ISAM_DIRECTORY_ENTRY 0x08
-#define CMD_TYPE_END_OF_ISAM_DIRECTORY_ENTRY 0x0a
-#define CMD_TYPE_PDS_DIRECTORY_ENTRY 0x0c
-#define CMD_TYPE_END_OF_PDS_DIRECTORY_ENTRY 0x0e
-#define CMD_TYPE_YANKED_LOAD_BLOCK 0x10
-#define CMD_TYPE_COPYRIGHT_BLOCK 0x1f
-
-/***************************************************************************
- IMPLEMENTATION
-***************************************************************************/
-
-QUICKLOAD_LOAD_MEMBER(lnw80_state::quickload_cb)
-{
- address_space &program = m_maincpu->space(AS_PROGRAM);
-
- uint8_t type, length;
- uint8_t data[0x100];
- uint8_t addr[2];
- void *ptr;
-
- while (!image.image_feof())
- {
- image.fread( &type, 1);
- image.fread( &length, 1);
-
- switch (type)
- {
- case CMD_TYPE_OBJECT_CODE: // 01 - block of data
- {
- length -= 2;
- u16 block_length = length ? length : 256;
- image.fread( &addr, 2);
- u16 address = (addr[1] << 8) | addr[0];
- if (LOG) logerror("/CMD object code block: address %04x length %u\n", address, block_length);
- if (address < 0x3c00)
- {
- image.message("Attempting to write outside of RAM");
- return image_init_result::FAIL;
- }
- ptr = program.get_write_ptr(address);
- image.fread( ptr, block_length);
- }
- break;
-
- case CMD_TYPE_TRANSFER_ADDRESS: // 02 - go address
- {
- image.fread( &addr, 2);
- u16 address = (addr[1] << 8) | addr[0];
- if (LOG) logerror("/CMD transfer address %04x\n", address);
- m_maincpu->set_state_int(Z80_PC, address);
- }
- return image_init_result::PASS;
-
- case CMD_TYPE_LOAD_MODULE_HEADER: // 05 - name
- image.fread( &data, length);
- if (LOG) logerror("/CMD load module header '%s'\n", data);
- break;
-
- case CMD_TYPE_COPYRIGHT_BLOCK: // 1F - copyright info
- image.fread( &data, length);
- if (LOG) logerror("/CMD copyright block '%s'\n", data);
- break;
-
- default:
- image.fread( &data, length);
- logerror("/CMD unsupported block type %u!\n", type);
- image.message("Unsupported or invalid block type");
- return image_init_result::FAIL;
- }
- }
-
- return image_init_result::PASS;
-}
-
/* 8-bit video, 64/80 characters per line = lnw80 */
-uint32_t lnw80_state::screen_update_lnw80(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+uint32_t lnw80_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
static const uint16_t rows[] = { 0, 0x200, 0x100, 0x300, 1, 0x201, 0x101, 0x301 };
uint16_t sy=0,ma=0;
@@ -996,7 +584,7 @@ void lnw80_state::lnw80(machine_config &config)
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
// LNW80 Theory of Operations gives H and V periods as 15.750kHz and 59.66Hz, probably due to rounding the calculated ~15.7468kHz to 4 figures
screen.set_raw(3.579545_MHz_XTAL * 3, 682, 0, 480, 264, 0, 192); // 10.738MHz generated by tank circuit (top left of page 2 of schematics)
- screen.set_screen_update(FUNC(lnw80_state::screen_update_lnw80));
+ screen.set_screen_update(FUNC(lnw80_state::screen_update));
screen.set_palette("palette");
PALETTE(config, "palette", FUNC(lnw80_state::lnw80_palette), 8);
GFXDECODE(config, "gfxdecode", "palette", gfx_lnw80);