Moved lnw80 to its own driver.

This commit is contained in:
Robbbert 2021-04-01 20:34:23 +11:00
parent efa3521d7a
commit b44de86569
7 changed files with 1110 additions and 376 deletions

View File

@ -4050,6 +4050,7 @@ files {
MAME_DIR .. "src/mame/includes/dgnalpha.h", MAME_DIR .. "src/mame/includes/dgnalpha.h",
MAME_DIR .. "src/mame/video/gime.cpp", MAME_DIR .. "src/mame/video/gime.cpp",
MAME_DIR .. "src/mame/video/gime.h", MAME_DIR .. "src/mame/video/gime.h",
MAME_DIR .. "src/mame/drivers/lnw80.cpp",
MAME_DIR .. "src/mame/drivers/trs80.cpp", MAME_DIR .. "src/mame/drivers/trs80.cpp",
MAME_DIR .. "src/mame/includes/trs80.h", MAME_DIR .. "src/mame/includes/trs80.h",
MAME_DIR .. "src/mame/machine/trs80.cpp", MAME_DIR .. "src/mame/machine/trs80.cpp",

1077
src/mame/drivers/lnw80.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -5,31 +5,31 @@
/*************************************************************************** /***************************************************************************
TRS80 memory map TRS80 memory map
0000-2fff ROM R D0-D7 0000-2fff ROM R D0-D7
3000-37ff ROM on Model III R D0-D7 3000-37ff ROM on Model III R D0-D7
unused on Model I unused on Model I
37de UART status R/W D0-D7 37de UART status R/W D0-D7
37df UART data R/W D0-D7 37df UART data R/W D0-D7
37e0 interrupt latch address (lnw80 = for the realtime clock) 37e0 interrupt latch address
37e1 select disk drive 0 W 37e1 select disk drive 0 W
37e2 cassette drive latch address W 37e2 cassette drive latch address W
37e3 select disk drive 1 W 37e3 select disk drive 1 W
37e4 select which cassette unit W D0-D1 (D0 selects unit 1, D1 selects unit 2) 37e4 select which cassette unit W D0-D1 (D0 selects unit 1, D1 selects unit 2)
37e5 select disk drive 2 W 37e5 select disk drive 2 W
37e7 select disk drive 3 W 37e7 select disk drive 3 W
37e0-37e3 floppy motor W D0-D3 37e0-37e3 floppy motor W D0-D3
or floppy head select W D3 or floppy head select W D3
37e8 send a byte to printer W D0-D7 37e8 send a byte to printer W D0-D7
37e8 read printer status R D7 37e8 read printer status R D7
37ec-37ef FDC WD179x R/W D0-D7 37ec-37ef FDC FD1771 R/W D0-D7
37ec command W D0-D7 37ec command W D0-D7
37ec status R D0-D7 37ec status R D0-D7
37ed track R/W D0-D7 37ed track R/W D0-D7
37ee sector R/W D0-D7 37ee sector R/W D0-D7
37ef data R/W D0-D7 37ef data R/W D0-D7
3800-38ff keyboard matrix R D0-D7 3800-38ff keyboard matrix R D0-D7
3900-3bff unused - kbd mirrored 3900-3bff unused - kbd mirrored
3c00-3fff video RAM R/W D0-D5,D7 (or D0-D7) 3c00-3fff video RAM R/W D0-D5,D7 (or D0-D7)
4000-ffff RAM 4000-ffff RAM
Interrupts: Interrupts:
@ -39,11 +39,10 @@ NMI
Printer: Level II usually 37e8; System80 uses port FD. Printer: Level II usually 37e8; System80 uses port FD.
System80 has non-addressable dip switches to set the UART control register. System80 has non-addressable dip switches to set the UART control register.
System80 and LNW80 have non-addressable links to set the baud rate. Receive and Transmit clocks are tied together. System80 has non-addressable links to set the baud rate. Receive and Transmit clocks are tied together.
Cassette baud rates: Model I level I - 250 baud Cassette baud rates: Model I level I - 250 baud
Model I level II and all clones - 500 baud Model I level II and all clones - 500 baud
LNW-80 - 500 baud @1.77MHz and 1000 baud @4MHz.
I/O ports I/O ports
FF: FF:
@ -54,9 +53,6 @@ FF:
- bit 7 is for reading from a cassette - bit 7 is for reading from a cassette
FE: FE:
- bit 0 is for selecting inverse video of the whole screen on a lnw80
- bit 2 enables colour on a lnw80
- bit 3 is for selecting roms (low) or 16k hires area (high) on a lnw80
- bit 4 selects internal cassette player (low) or external unit (high) on a system-80 - bit 4 selects internal cassette player (low) or external unit (high) on a system-80
FD: FD:
@ -116,7 +112,6 @@ Not dumped (to our knowledge):
Not emulated: Not emulated:
TRS80 Japanese kana/ascii switch and alternate keyboard TRS80 Japanese kana/ascii switch and alternate keyboard
TRS80 Model III/4 Hard drive, Graphics board, Alternate Character set TRS80 Model III/4 Hard drive, Graphics board, Alternate Character set
LNW80 1.77 / 4.0 MHz switch (this is a physical switch)
Radionic has 16 colours with a byte at 350B controlling the operation. See manual. Radionic has 16 colours with a byte at 350B controlling the operation. See manual.
Virtual floppy disk formats are JV1, JV3, and DMK. JV3 is not emulated. Virtual floppy disk formats are JV1, JV3, and DMK. JV3 is not emulated.
@ -147,13 +142,6 @@ radionic: works
expansion-box? expansion-box?
uart uart
lnw80: works
add 1.77 / 4 MHz switch
find out if it really did support 32-cpl mode or not
hi-res and colour are coded but do not work
investigate expansion-box
none of my collection of lnw80-specific floppies will work; some crash MAME
2021-03-26 MT 07903 - most floppies no longer boot. 2021-03-26 MT 07903 - most floppies no longer boot.
Most machines have problems loading real tapes. Most machines have problems loading real tapes.
@ -168,6 +156,7 @@ lnw80: works
#include "speaker.h" #include "speaker.h"
#include "formats/trs80_dsk.h" #include "formats/trs80_dsk.h"
#include "formats/trs_cas.h"
#include "formats/dmk_dsk.h" #include "formats/dmk_dsk.h"
@ -231,35 +220,6 @@ void trs80_state::ht1080z_io(address_map &map)
map(0x1f, 0x1f).w("ay1", FUNC(ay8910_device::address_w)); map(0x1f, 0x1f).w("ay1", FUNC(ay8910_device::address_w));
} }
void trs80_state::lnw80_mem(address_map &map)
{
map(0x0000, 0x3fff).m(m_lnw_bank, FUNC(address_map_bank_device::amap8));
map(0x4000, 0xffff).ram();
}
void trs80_state::lnw_banked_mem(address_map &map)
{
map(0x0000, 0x2fff).rom().region("maincpu", 0);
map(0x37e0, 0x37e3).rw(FUNC(trs80_state::irq_status_r), FUNC(trs80_state::motor_w));
map(0x37e8, 0x37eb).rw(FUNC(trs80_state::printer_r), FUNC(trs80_state::printer_w));
map(0x37ec, 0x37ef).rw(FUNC(trs80_state::fdc_r), FUNC(trs80_state::fdc_w));
map(0x3800, 0x3bff).r(FUNC(trs80_state::keyboard_r));
map(0x3c00, 0x3fff).ram().share(m_p_videoram);
map(0x4000, 0x7fff).ram().share(m_p_gfxram);
}
void trs80_state::lnw80_io(address_map &map)
{
map.global_mask(0xff);
map.unmap_value_high();
map(0xe8, 0xe8).rw(FUNC(trs80_state::port_e8_r), FUNC(trs80_state::port_e8_w));
map(0xe9, 0xe9).portr("E9");
map(0xea, 0xea).rw(FUNC(trs80_state::port_ea_r), FUNC(trs80_state::port_ea_w));
map(0xeb, 0xeb).rw(m_uart, FUNC(ay31015_device::receive), FUNC(ay31015_device::transmit));
map(0xfe, 0xfe).rw(FUNC(trs80_state::lnw80_fe_r), FUNC(trs80_state::lnw80_fe_w));
map(0xff, 0xff).rw(FUNC(trs80_state::port_ff_r), FUNC(trs80_state::port_ff_w));
}
void trs80_state::radionic_mem(address_map &map) void trs80_state::radionic_mem(address_map &map)
{ {
m1_mem(map); m1_mem(map);
@ -373,8 +333,7 @@ static INPUT_PORTS_START( trs80 )
PORT_START("LINE7") PORT_START("LINE7")
PORT_BIT(0x01, 0x00, IPT_KEYBOARD) PORT_NAME("Left Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) PORT_BIT(0x01, 0x00, IPT_KEYBOARD) PORT_NAME("Left Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
PORT_BIT(0x10, 0x00, IPT_KEYBOARD) PORT_NAME("Control") PORT_CODE(KEYCODE_LCONTROL) // LNW80 only PORT_BIT(0xfe, 0x00, IPT_UNUSED)
PORT_BIT(0xee, 0x00, IPT_UNUSED)
INPUT_PORTS_END INPUT_PORTS_END
static INPUT_PORTS_START(trs80l2) static INPUT_PORTS_START(trs80l2)
@ -444,19 +403,6 @@ static const gfx_layout ht1080z_charlayout =
8*16 /* every char takes 16 bytes */ 8*16 /* every char takes 16 bytes */
}; };
static const gfx_layout lnw80_charlayout =
{
8, 8, /* 8 x 8 characters */
128, /* 128 characters */
1, /* 1 bits per pixel */
{ 0 }, /* no bitplanes */
/* x offsets */
{ 7, 5, 6, 1, 0, 2, 4, 3 },
/* y offsets */
{ 0*8, 512*8, 256*8, 768*8, 1*8, 513*8, 257*8, 769*8 },
8*2 /* every char takes 8 bytes */
};
static const gfx_layout radionic_charlayout = static const gfx_layout radionic_charlayout =
{ {
8, 16, /* 8 x 16 characters */ 8, 16, /* 8 x 16 characters */
@ -478,10 +424,6 @@ static GFXDECODE_START(gfx_ht1080z)
GFXDECODE_ENTRY( "chargen", 0, ht1080z_charlayout, 0, 1 ) GFXDECODE_ENTRY( "chargen", 0, ht1080z_charlayout, 0, 1 )
GFXDECODE_END GFXDECODE_END
static GFXDECODE_START(gfx_lnw80)
GFXDECODE_ENTRY( "chargen", 0, lnw80_charlayout, 0, 4 )
GFXDECODE_END
static GFXDECODE_START(gfx_radionic) static GFXDECODE_START(gfx_radionic)
GFXDECODE_ENTRY( "chargen", 0, radionic_charlayout, 0, 1 ) GFXDECODE_ENTRY( "chargen", 0, radionic_charlayout, 0, 1 )
GFXDECODE_END GFXDECODE_END
@ -600,35 +542,6 @@ void trs80_state::ht1080z(machine_config &config)
//ay1.port_b_read_callback(FUNC(trs80_state::...); //ay1.port_b_read_callback(FUNC(trs80_state::...);
} }
void trs80_state::lnw80(machine_config &config)
{
model1(config);
//m_maincpu->set_clock(16_MHz_XTAL / 4); // or 16MHz / 9; 4MHz or 1.77MHz operation selected by HI/LO switch
m_maincpu->set_clock(16_MHz_XTAL / 9); // need this so cassette can work
m_maincpu->set_addrmap(AS_PROGRAM, &trs80_state::lnw80_mem);
m_maincpu->set_addrmap(AS_IO, &trs80_state::lnw80_io);
ADDRESS_MAP_BANK(config, m_lnw_bank, 0);
m_lnw_bank->set_addrmap(0, &trs80_state::lnw_banked_mem);
m_lnw_bank->set_data_width(8);
m_lnw_bank->set_addr_width(16);
m_lnw_bank->set_stride(0x4000);
MCFG_MACHINE_RESET_OVERRIDE(trs80_state, lnw80)
subdevice<gfxdecode_device>("gfxdecode")->set_info(gfx_lnw80);
subdevice<palette_device>("palette")->set_entries(8).set_init(FUNC(trs80_state::lnw80_palette));
subdevice<screen_device>("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)
// 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
subdevice<screen_device>("screen")->set_screen_update(FUNC(trs80_state::screen_update_lnw80));
config.device_remove("brg");
CLOCK(config, m_uart_clock, 19200 * 16);
m_uart_clock->signal_handler().set(m_uart, FUNC(ay31015_device::write_rcp));
m_uart_clock->signal_handler().append(m_uart, FUNC(ay31015_device::write_tcp));
}
void trs80_state::radionic(machine_config &config) void trs80_state::radionic(machine_config &config)
{ {
model1(config); model1(config);
@ -711,20 +624,6 @@ ROM_END
#define rom_sys80p rom_sys80 #define rom_sys80p rom_sys80
ROM_START(lnw80)
ROM_REGION(0x3800, "maincpu",0)
ROM_LOAD("lnw_a.bin", 0x0000, 0x0800, CRC(e09f7e91) SHA1(cd28e72efcfebde6cf1c7dbec4a4880a69e683da))
ROM_LOAD("lnw_a1.bin", 0x0800, 0x0800, CRC(ac297d99) SHA1(ccf31d3f9d02c3b68a0ee3be4984424df0e83ab0))
ROM_LOAD("lnw_b.bin", 0x1000, 0x0800, CRC(c4303568) SHA1(13e3d81c6f0de0e93956fa58c465b5368ea51682))
ROM_LOAD("lnw_b1.bin", 0x1800, 0x0800, CRC(3a5ea239) SHA1(8c489670977892d7f2bfb098f5df0b4dfa8fbba6))
ROM_LOAD("lnw_c.bin", 0x2000, 0x0800, CRC(2ba025d7) SHA1(232efbe23c3f5c2c6655466ebc0a51cf3697be9b))
ROM_LOAD("lnw_c1.bin", 0x2800, 0x0800, CRC(ed547445) SHA1(20102de89a3ee4a65366bc2d62be94da984a156b))
ROM_REGION(0x0800, "chargen",0)
ROM_LOAD("lnw_chr.bin", 0x0000, 0x0800, CRC(c89b27df) SHA1(be2a009a07e4378d070002a558705e9a0de59389))
ROM_END
ROM_START(ht1080z) ROM_START(ht1080z)
ROM_REGION(0x3800, "maincpu",0) ROM_REGION(0x3800, "maincpu",0)
ROM_LOAD("ht1080z.rom", 0x0000, 0x3000, CRC(2bfef8f7) SHA1(7a350925fd05c20a3c95118c1ae56040c621be8f)) ROM_LOAD("ht1080z.rom", 0x0000, 0x3000, CRC(2bfef8f7) SHA1(7a350925fd05c20a3c95118c1ae56040c621be8f))
@ -772,7 +671,6 @@ COMP( 1978, trs80l2, 0, 0, model1, trs80l2, trs80_state, init_
COMP( 1983, radionic, trs80l2, 0, radionic, trs80l2, trs80_state, init_trs80, "Komtek", "Radionic", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) COMP( 1983, radionic, trs80l2, 0, radionic, trs80l2, trs80_state, init_trs80, "Komtek", "Radionic", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE )
COMP( 1980, sys80, trs80l2, 0, sys80, sys80, trs80_state, init_trs80l2, "EACA Computers Ltd", "System-80 (60 Hz)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) COMP( 1980, sys80, trs80l2, 0, sys80, sys80, trs80_state, init_trs80l2, "EACA Computers Ltd", "System-80 (60 Hz)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE )
COMP( 1980, sys80p, trs80l2, 0, sys80p, sys80, trs80_state, init_trs80l2, "EACA Computers Ltd", "System-80 (50 Hz)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) COMP( 1980, sys80p, trs80l2, 0, sys80p, sys80, trs80_state, init_trs80l2, "EACA Computers Ltd", "System-80 (50 Hz)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE )
COMP( 1981, lnw80, trs80l2, 0, lnw80, sys80, trs80_state, init_trs80, "LNW Research", "LNW-80", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE )
COMP( 1983, ht1080z, trs80l2, 0, ht1080z, sys80, trs80_state, init_trs80l2, "Hiradastechnika Szovetkezet", "HT-1080Z Series I", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) COMP( 1983, ht1080z, trs80l2, 0, ht1080z, sys80, trs80_state, init_trs80l2, "Hiradastechnika Szovetkezet", "HT-1080Z Series I", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE )
COMP( 1984, ht1080z2, trs80l2, 0, ht1080z, sys80, trs80_state, init_trs80l2, "Hiradastechnika Szovetkezet", "HT-1080Z Series II", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) COMP( 1984, ht1080z2, trs80l2, 0, ht1080z, sys80, trs80_state, init_trs80l2, "Hiradastechnika Szovetkezet", "HT-1080Z Series II", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE )
COMP( 1985, ht108064, trs80l2, 0, ht1080z, sys80, trs80_state, init_trs80, "Hiradastechnika Szovetkezet", "HT-1080Z/64", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) COMP( 1985, ht108064, trs80l2, 0, ht1080z, sys80, trs80_state, init_trs80, "Hiradastechnika Szovetkezet", "HT-1080Z/64", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE )

View File

@ -9,7 +9,6 @@
#include "bus/centronics/ctronics.h" #include "bus/centronics/ctronics.h"
#include "cpu/z80/z80.h" #include "cpu/z80/z80.h"
#include "machine/bankdev.h"
#include "imagedev/cassette.h" #include "imagedev/cassette.h"
#include "imagedev/floppy.h" #include "imagedev/floppy.h"
#include "imagedev/snapquik.h" #include "imagedev/snapquik.h"
@ -22,8 +21,6 @@
#include "sound/spkrdev.h" #include "sound/spkrdev.h"
#include "emupal.h" #include "emupal.h"
#include "formats/trs_cas.h"
class trs80_state : public driver_device class trs80_state : public driver_device
{ {
@ -34,8 +31,6 @@ public:
, m_region_maincpu(*this, "maincpu") , m_region_maincpu(*this, "maincpu")
, m_p_chargen(*this, "chargen") , m_p_chargen(*this, "chargen")
, m_p_videoram(*this, "videoram") , m_p_videoram(*this, "videoram")
, m_p_gfxram(*this, "gfxram") // LNW80 only
, m_lnw_bank(*this, "lnw_banked_mem") // LNW80 only
, m_centronics(*this, "centronics") , m_centronics(*this, "centronics")
, m_cent_data_out(*this, "cent_data_out") , m_cent_data_out(*this, "cent_data_out")
, m_cent_status_in(*this, "cent_status_in") , m_cent_status_in(*this, "cent_status_in")
@ -57,7 +52,6 @@ public:
void sys80(machine_config &config); void sys80(machine_config &config);
void sys80p(machine_config &config); void sys80p(machine_config &config);
void trs80(machine_config &config); void trs80(machine_config &config);
void lnw80(machine_config &config);
void radionic(machine_config &config); void radionic(machine_config &config);
void model1(machine_config &config); void model1(machine_config &config);
void ht1080z(machine_config &config); void ht1080z(machine_config &config);
@ -72,12 +66,10 @@ protected:
private: private:
static void floppy_formats(format_registration &fr); static void floppy_formats(format_registration &fr);
void port_ff_w(uint8_t data); void port_ff_w(uint8_t data);
void lnw80_fe_w(uint8_t data);
void sys80_fe_w(uint8_t data); void sys80_fe_w(uint8_t data);
void sys80_f8_w(uint8_t data); void sys80_f8_w(uint8_t data);
void port_ea_w(uint8_t data); void port_ea_w(uint8_t data);
void port_e8_w(uint8_t data); void port_e8_w(uint8_t data);
uint8_t lnw80_fe_r();
uint8_t port_ff_r(); uint8_t port_ff_r();
uint8_t sys80_f9_r(); uint8_t sys80_f9_r();
uint8_t port_ea_r(); uint8_t port_ea_r();
@ -96,16 +88,10 @@ private:
TIMER_CALLBACK_MEMBER(cassette_data_callback); TIMER_CALLBACK_MEMBER(cassette_data_callback);
DECLARE_WRITE_LINE_MEMBER(intrq_w); DECLARE_WRITE_LINE_MEMBER(intrq_w);
DECLARE_QUICKLOAD_LOAD_MEMBER(quickload_cb); DECLARE_QUICKLOAD_LOAD_MEMBER(quickload_cb);
DECLARE_MACHINE_RESET(lnw80);
void lnw80_palette(palette_device &palette) const;
uint32_t screen_update_trs80(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); uint32_t screen_update_trs80(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
uint32_t screen_update_ht1080z(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); uint32_t screen_update_ht1080z(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
uint32_t screen_update_lnw80(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
uint32_t screen_update_radionic(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); uint32_t screen_update_radionic(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);
void m1_io(address_map &map); void m1_io(address_map &map);
void m1_mem(address_map &map); void m1_mem(address_map &map);
void sys80_io(address_map &map); void sys80_io(address_map &map);
@ -119,7 +105,6 @@ private:
uint8_t m_mask; uint8_t m_mask;
uint8_t m_tape_unit; uint8_t m_tape_unit;
bool m_reg_load; bool m_reg_load;
u8 m_lnw_mode;
bool m_cassette_data; bool m_cassette_data;
emu_timer *m_cassette_data_timer; emu_timer *m_cassette_data_timer;
double m_old_cassette_val; double m_old_cassette_val;
@ -130,8 +115,6 @@ private:
required_memory_region m_region_maincpu; required_memory_region m_region_maincpu;
required_region_ptr<u8> m_p_chargen; required_region_ptr<u8> m_p_chargen;
optional_shared_ptr<u8> m_p_videoram; optional_shared_ptr<u8> m_p_videoram;
optional_shared_ptr<u8> m_p_gfxram;
optional_device<address_map_bank_device> m_lnw_bank;
optional_device<centronics_device> m_centronics; optional_device<centronics_device> m_centronics;
optional_device<output_latch_device> m_cent_data_out; optional_device<output_latch_device> m_cent_data_out;
optional_device<input_buffer_device> m_cent_status_in; optional_device<input_buffer_device> m_cent_status_in;

View File

@ -135,11 +135,6 @@ uint8_t trs80_state::sys80_f9_r()
return data; return data;
} }
uint8_t trs80_state::lnw80_fe_r()
{
return m_lnw_mode;
}
uint8_t trs80_state::port_ff_r() uint8_t trs80_state::port_ff_r()
{ {
/* ModeSel and cassette data /* ModeSel and cassette data
@ -165,20 +160,6 @@ void trs80_state::sys80_fe_w(uint8_t data)
m_tape_unit = BIT(data, 4) ? 2 : 1; m_tape_unit = BIT(data, 4) ? 2 : 1;
} }
/* lnw80 can switch out all the devices, roms and video ram to be replaced by graphics ram. */
void trs80_state::lnw80_fe_w(uint8_t data)
{
/* lnw80 video options
d3 bankswitch lower 16k between roms and hires ram (1=hires)
d2 enable colour \
d1 hres / these 2 are the bits from the MODE command of LNWBASIC
d0 inverse video (entire screen) */
m_lnw_mode = data;
m_lnw_bank->set_bank(BIT(data, 3));
}
void trs80_state::port_ff_w(uint8_t data) void trs80_state::port_ff_w(uint8_t data)
{ {
/* Standard output port of Model I /* Standard output port of Model I
@ -187,7 +168,6 @@ void trs80_state::port_ff_w(uint8_t data)
d1, d0 Cassette output */ d1, d0 Cassette output */
static const double levels[4] = { 0.0, 1.0, -1.0, 0.0 }; static const double levels[4] = { 0.0, 1.0, -1.0, 0.0 };
static bool init = 0;
m_cassette->change_state(BIT(data, 2) ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR ); m_cassette->change_state(BIT(data, 2) ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR );
m_cassette->output(levels[data & 3]); m_cassette->output(levels[data & 3]);
@ -195,13 +175,9 @@ void trs80_state::port_ff_w(uint8_t data)
m_mode = (m_mode & 0xfe) | BIT(data, 3); m_mode = (m_mode & 0xfe) | BIT(data, 3);
if (!init) static const double speaker_levels[4] = { 0.0, -1.0, 0.0, 1.0 };
{ m_speaker->set_levels(4, speaker_levels);
init = 1;
static double speaker_levels[4] = { 0.0, -1.0, 0.0, 1.0 };
m_speaker->set_levels(4, speaker_levels);
}
/* Speaker for System-80 MK II - only sounds if relay is off */ /* Speaker for System-80 MK II - only sounds if relay is off */
if (!(BIT(data, 2))) if (!(BIT(data, 2)))
m_speaker->level_w(data & 3); m_speaker->level_w(data & 3);
@ -349,7 +325,6 @@ void trs80_state::machine_start()
save_item(NAME(m_mask)); save_item(NAME(m_mask));
save_item(NAME(m_tape_unit)); save_item(NAME(m_tape_unit));
save_item(NAME(m_reg_load)); save_item(NAME(m_reg_load));
save_item(NAME(m_lnw_mode));
save_item(NAME(m_cassette_data)); save_item(NAME(m_cassette_data));
save_item(NAME(m_old_cassette_val)); save_item(NAME(m_old_cassette_val));
save_item(NAME(m_size_store)); save_item(NAME(m_size_store));
@ -375,14 +350,6 @@ void trs80_state::machine_reset()
} }
} }
MACHINE_RESET_MEMBER(trs80_state,lnw80)
{
machine_reset();
m_reg_load = 1;
m_lnw_mode = 0;
lnw80_fe_w(0);
}
/*************************************************************************** /***************************************************************************
PARAMETERS PARAMETERS

View File

@ -19800,6 +19800,9 @@ llc2 //
@source:lms46.cpp @source:lms46.cpp
lms46 // lms46 //
@source:lnw80.cpp
lnw80 // LNW Research LNW-80
@source:lockon.cpp @source:lockon.cpp
lockon // (c) 1986 Tatsumi lockon // (c) 1986 Tatsumi
lockonc // (c) 1986 Tatsumi lockonc // (c) 1986 Tatsumi
@ -41064,7 +41067,6 @@ shtscore
ht108064 // Hradstechnika Szvetkezet HT-1080Z/64 ht108064 // Hradstechnika Szvetkezet HT-1080Z/64
ht1080z // Hradstechnika Szvetkezet HT-1080Z ht1080z // Hradstechnika Szvetkezet HT-1080Z
ht1080z2 // Hradstechnika Szvetkezet HT-1080Z Series II ht1080z2 // Hradstechnika Szvetkezet HT-1080Z Series II
lnw80 // LNW Research LNW-80
radionic // Radionic radionic // Radionic
sys80 // EACA System 80 sys80 // EACA System 80
sys80p // EACA System 80 sys80p // EACA System 80

View File

@ -140,178 +140,6 @@ uint32_t trs80_state::screen_update_ht1080z(screen_device &screen, bitmap_ind16
return 0; return 0;
} }
/* 8-bit video, 64/80 characters per line = lnw80 */
uint32_t trs80_state::screen_update_lnw80(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;
uint8_t cols = BIT(m_lnw_mode, 1) ? 80 : 64;
/* Although the OS can select 32-character mode, it is not supported by hardware */
if (m_lnw_mode != m_size_store)
{
m_size_store = m_lnw_mode;
screen.set_visible_area(0, cols*6-1, 0, 16*12-1);
}
uint8_t bg=7,fg=0;
if (BIT(m_lnw_mode, 1))
{
bg = 0;
fg = 7;
}
switch (m_lnw_mode & 0x06)
{
case 0: // MODE 0
for (uint16_t y = 0; y < 16; y++)
{
for (uint16_t ra = 0; ra < 12; ra++)
{
uint16_t *p = &bitmap.pix(sy++);
for (uint16_t x = ma; x < ma + 64; x++)
{
uint8_t chr = m_p_videoram[x];
if (chr & 0x80)
{
uint8_t gfxbit = (ra & 0x0c)>>1;
/* Display one line of a lores character (6 pixels) */
*p++ = BIT(chr, gfxbit) ? fg : bg;
*p++ = BIT(chr, gfxbit) ? fg : bg;
*p++ = BIT(chr, gfxbit) ? fg : bg;
gfxbit++;
*p++ = BIT(chr, gfxbit) ? fg : bg;
*p++ = BIT(chr, gfxbit) ? fg : bg;
*p++ = BIT(chr, gfxbit) ? fg : bg;
}
else
{
/* get pattern of pixels for that character scanline */
uint8_t gfx;
if (ra < 8)
gfx = m_p_chargen[(chr<<1) | rows[ra] ];
else
gfx = 0;
/* Display a scanline of a character (6 pixels) */
*p++ = BIT(gfx, 2) ? fg : bg;
*p++ = BIT(gfx, 1) ? fg : bg;
*p++ = BIT(gfx, 6) ? fg : bg;
*p++ = BIT(gfx, 7) ? fg : bg;
*p++ = BIT(gfx, 5) ? fg : bg;
*p++ = BIT(gfx, 3) ? fg : bg;
}
}
}
ma+=64;
}
break;
case 0x02: // MODE 1
for (uint16_t y = 0; y < 0x400; y+=0x40)
{
for (uint16_t ra = 0; ra < 0x3000; ra+=0x400)
{
uint16_t *p = &bitmap.pix(sy++);
for (uint16_t x = 0; x < 0x40; x++)
{
uint8_t gfx = m_p_gfxram[ y | x | ra];
/* Display 6 pixels in normal region */
*p++ = BIT(gfx, 0) ? fg : bg;
*p++ = BIT(gfx, 1) ? fg : bg;
*p++ = BIT(gfx, 2) ? fg : bg;
*p++ = BIT(gfx, 3) ? fg : bg;
*p++ = BIT(gfx, 4) ? fg : bg;
*p++ = BIT(gfx, 5) ? fg : bg;
}
for (uint16_t x = 0; x < 0x10; x++)
{
uint8_t gfx = m_p_gfxram[ 0x3000 | x | (ra & 0xc00) | ((ra & 0x3000) >> 8)];
/* Display 6 pixels in extended region */
*p++ = BIT(gfx, 0) ? fg : bg;
*p++ = BIT(gfx, 1) ? fg : bg;
*p++ = BIT(gfx, 2) ? fg : bg;
*p++ = BIT(gfx, 3) ? fg : bg;
*p++ = BIT(gfx, 4) ? fg : bg;
*p++ = BIT(gfx, 5) ? fg : bg;
}
}
}
break;
case 0x04: // MODE 2
/* it seems the text video ram can have an effect in this mode,
not explained clearly, so not emulated */
for (uint16_t y = 0; y < 0x400; y+=0x40)
{
for (uint16_t ra = 0; ra < 0x3000; ra+=0x400)
{
uint16_t *p = &bitmap.pix(sy++);
for (uint16_t x = 0; x < 0x40; x++)
{
uint8_t gfx = m_p_gfxram[ y | x | ra];
/* Display 6 pixels in normal region */
fg = (gfx & 0x38) >> 3;
*p++ = fg;
*p++ = fg;
*p++ = fg;
fg = gfx & 0x07;
*p++ = fg;
*p++ = fg;
*p++ = fg;
}
}
}
break;
case 0x06: // MODE 3
/* the manual does not explain at all how colour is determined
for the extended area. Further, the background colour
is not mentioned anywhere. Black is assumed. */
for (uint16_t y = 0; y < 0x400; y+=0x40)
{
for (uint16_t ra = 0; ra < 0x3000; ra+=0x400)
{
uint16_t *p = &bitmap.pix(sy++);
for (uint16_t x = 0; x < 0x40; x++)
{
uint8_t gfx = m_p_gfxram[ y | x | ra];
fg = (m_p_videoram[ x | y ] & 0x38) >> 3;
/* Display 6 pixels in normal region */
*p++ = BIT(gfx, 0) ? fg : bg;
*p++ = BIT(gfx, 1) ? fg : bg;
*p++ = BIT(gfx, 2) ? fg : bg;
fg = m_p_videoram[ 0x3c00 | x | y ] & 0x07;
*p++ = BIT(gfx, 3) ? fg : bg;
*p++ = BIT(gfx, 4) ? fg : bg;
*p++ = BIT(gfx, 5) ? fg : bg;
}
for (uint16_t x = 0; x < 0x10; x++)
{
uint8_t gfx = m_p_gfxram[ 0x3000 | x | (ra & 0xc00) | ((ra & 0x3000) >> 8)];
fg = (m_p_gfxram[ 0x3c00 | x | y ] & 0x38) >> 3;
/* Display 6 pixels in extended region */
*p++ = BIT(gfx, 0) ? fg : bg;
*p++ = BIT(gfx, 1) ? fg : bg;
*p++ = BIT(gfx, 2) ? fg : bg;
fg = m_p_gfxram[ 0x3c00 | x | y ] & 0x07;
*p++ = BIT(gfx, 3) ? fg : bg;
*p++ = BIT(gfx, 4) ? fg : bg;
*p++ = BIT(gfx, 5) ? fg : bg;
}
}
}
break;
}
return 0;
}
/* lores characters are in the character generator. Each character is 8x16. */ /* lores characters are in the character generator. Each character is 8x16. */
uint32_t trs80_state::screen_update_radionic(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) uint32_t trs80_state::screen_update_radionic(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
@ -355,25 +183,3 @@ uint32_t trs80_state::screen_update_radionic(screen_device &screen, bitmap_ind16
return 0; return 0;
} }
/***************************************************************************
Palettes
***************************************************************************/
/* Levels are unknown - guessing */
static constexpr rgb_t lnw80_pens[] =
{
{ 220, 220, 220 }, // white
{ 0, 175, 0 }, // green
{ 200, 200, 0 }, // yellow
{ 255, 0, 0 }, // red
{ 255, 0, 255 }, // magenta
{ 0, 0, 175 }, // blue
{ 0, 255, 255 }, // cyan
{ 0, 0, 0 } // black
};
void trs80_state::lnw80_palette(palette_device &palette) const
{
palette.set_pen_colors(0, lnw80_pens);
}