Merge pull request #1949 from shattered/_6b4b431

IBM 6580 Displaywriter de-skeletonization [shattered]
This commit is contained in:
R. Belmont 2017-01-09 21:36:12 -05:00 committed by GitHub
commit a9143f121e
10 changed files with 1770 additions and 30 deletions

149
hash/ibm6580.xml Normal file
View File

@ -0,0 +1,149 @@
<?xml version="1.0"?>
<!DOCTYPE softwarelist SYSTEM "softwarelist.dtd">
<softwarelist name="ibm5170" description="IBM Displaywriter disk images">
<software name="abc0051">
<description>Displaywriter System Communications Diagnostics (ABC005-1, P/N 4466806)</description>
<year>1983</year>
<publisher>IBM</publisher>
<part name="flop1" interface="floppy_8">
<dataarea name="flop" size="188446">
<rom name="ABC0051.IMD" size="188446" crc="d23ce97e" sha1="065aa15d6815d86689c6ebdd5d6280527991209a" offset="0" />
</dataarea>
</part>
</software>
<software name="abc0051d">
<description>Displaywriter System Communications Diagnostics (ABC005-1, P/N 4466806)</description>
<year>1983</year>
<publisher>IBM</publisher>
<part name="flop1" interface="floppy_8">
<dataarea name="flop" size="188436">
<rom name="ABC0051D.IMD" size="188436" crc="8e546e77" sha1="ae0431e30ca85afcf1b6a08fafa47e471f7a8327" offset="0" />
</dataarea>
</part>
</software>
<software name="ced0122d">
<description>Displaywriter System Diagnostics (CED012-2D, P/N 4466805)</description>
<year>1983</year>
<publisher>IBM</publisher>
<part name="flop1" interface="floppy_8">
<dataarea name="flop" size="270354">
<rom name="CED0122D.IMD" size="270354" crc="a6070e50" sha1="62e4cd029ff178a092c932f9ec36321f174bae98" offset="0" />
</dataarea>
</part>
</software>
<software name="ced112d">
<description>Displaywriter System Diagnostics (CED011-2D)</description>
<year>198x</year>
<publisher>IBM</publisher>
<part name="flop1" interface="floppy_8">
<dataarea name="flop" size="262064">
<rom name="CED112D.IMD" size="262064" crc="afad5fc8" sha1="325817b9643739636b1be0bd1c8b79e855ef5f50" offset="0" />
</dataarea>
</part>
</software>
<software name="ced12a1">
<description>Displaywriter System Diagnostics (CED012A-1, P/N 6079274, SUB 4466804)</description>
<year>1983</year>
<publisher>IBM</publisher>
<part name="flop1" interface="floppy_8">
<dataarea name="flop" size="266999">
<rom name="CED12A1.IMD" size="266999" crc="f0f2cad9" sha1="69a70c9e988817eafab9caa486d8d5bcf5d80257" offset="0" />
</dataarea>
</part>
</software>
<software name="ced12a2d">
<description>Displaywriter System Diagnostics (CED012A-2D, P/N 6079275, SUB 4466805)</description>
<year>1983</year>
<publisher>IBM</publisher>
<part name="flop1" interface="floppy_8">
<dataarea name="flop" size="269785">
<rom name="CED12A2D.IMD" size="269785" crc="dd1c9531" sha1="c401a9e1fe6fda958fa56d3e6f26fe77585921ff" offset="0" />
</dataarea>
</part>
</software>
<software name="ced13a1">
<description>Displaywriter System Diagnostics (CED013A-1)</description>
<year>1983</year>
<publisher>IBM</publisher>
<part name="flop1" interface="floppy_8">
<dataarea name="flop" size="265686">
<rom name="CED13A1.IMD" size="265686" crc="e47023dc" sha1="bee94c1beec98b9a8d9487ab92e92605fd944c4b" offset="0" />
</dataarea>
</part>
</software>
<software name="ced13a2d">
<description>Displaywriter System Diagnostics (CED013A-2D, P/N 6079203)</description>
<year>1983</year>
<publisher>IBM</publisher>
<part name="flop1" interface="floppy_8">
<dataarea name="flop" size="269564">
<rom name="CED13A2D.IMD" size="269564" crc="25c29ca3" sha1="cfaec7942c28f71c80f2b28de735ffb17295b3c9" offset="0" />
</dataarea>
</part>
</software>
<software name="pdd12a1">
<description>Displaywriter Problem Determination Diskette (PDD012A-1, P/N 6079279, SUB 4466807)</description>
<year>1983</year>
<publisher>IBM</publisher>
<part name="flop1" interface="floppy_8">
<dataarea name="flop" size="239681">
<rom name="PDD12A1.IMD" size="239681" crc="c97a236b" sha1="b4d150eeb6f1244158896acbefe9ee28d305b6d8" offset="0" />
</dataarea>
</part>
</software>
<software name="pdd12a2d">
<description>Displaywriter Problem Determination Diskette (PDD012A-2D, P/N 6079280, SUB 4466808)</description>
<year>1983</year>
<publisher>IBM</publisher>
<part name="flop1" interface="floppy_8">
<dataarea name="flop" size="262167">
<rom name="PDD12A2D.IMD" size="262167" crc="ed546091" sha1="2f21c19c601a53ffb7436208827e170665c16fb2" offset="0" />
</dataarea>
</part>
</software>
<software name="pdd13a1">
<description>Displaywriter Problem Determination Diskette (PDD013-1)</description>
<year>1983</year>
<publisher>IBM</publisher>
<part name="flop1" interface="floppy_8">
<dataarea name="flop" size="248352">
<rom name="PDD13A1.IMD" size="248352" crc="5ea96ddb" sha1="7d2e1b821b056dc7248b4720fb6fabb27e3eeca9" offset="0" />
</dataarea>
</part>
</software>
<software name="1aanfa">
<description>Displaywriter Textpack 1 (1AANFA)</description>
<year>198x</year>
<publisher>IBM</publisher>
<part name="flop1" interface="floppy_8">
<dataarea name="flop" size="274586">
<rom name="TEXTAPACK1.IMD" size="274586" crc="d6e46d80" sha1="f75ab3f00341aa7df58b166b8d16d8c0b0a28cd5" offset="0" />
</dataarea>
</part>
</software>
</softwarelist>

View File

@ -2028,6 +2028,15 @@ files {
MAME_DIR .. "src/mame/drivers/hk68v10.cpp",
}
createMESSProjects(_target, _subtarget, "ibm6580")
files {
MAME_DIR .. "src/mame/drivers/ibm6580.cpp",
MAME_DIR .. "src/mame/machine/ibm6580_kbd.cpp",
MAME_DIR .. "src/mame/machine/ibm6580_kbd.h",
MAME_DIR .. "src/mame/machine/ibm6580_fdc.cpp",
MAME_DIR .. "src/mame/machine/ibm6580_fdc.h",
}
createMESSProjects(_target, _subtarget, "intel")
files {
MAME_DIR .. "src/mame/drivers/basic52.cpp",
@ -3306,7 +3315,6 @@ files {
MAME_DIR .. "src/mame/drivers/hunter2.cpp",
MAME_DIR .. "src/mame/drivers/i7000.cpp",
MAME_DIR .. "src/mame/drivers/ibm3153.cpp",
MAME_DIR .. "src/mame/drivers/ibm6580.cpp",
MAME_DIR .. "src/mame/drivers/icatel.cpp",
MAME_DIR .. "src/mame/drivers/ie15.cpp",
MAME_DIR .. "src/mame/machine/ie15_kbd.cpp",

View File

@ -110,6 +110,9 @@ const device_type TEAC_FD_55G = &device_creator<teac_fd_55g>;
// ALPS 5.25" drives
const device_type ALPS_3255190x = &device_creator<alps_3255190x>;
// IBM 8" drives
const device_type IBM_6360 = &device_creator<ibm_6360>;
const floppy_format_type floppy_image_device::default_floppy_formats[] = {
FLOPPY_D88_FORMAT,
@ -2258,3 +2261,34 @@ void alps_3255190x::handled_variants(uint32_t *variants, int &var_count) const
var_count = 0;
variants[var_count++] = floppy_image::SSSD;
}
//-------------------------------------------------
// IBM 6360 -- 8" single-sided single density
//-------------------------------------------------
ibm_6360::ibm_6360(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
floppy_image_device(mconfig, FLOPPY_8_SSSD, "8\" single density single sided floppy drive", tag, owner, clock, "ibm_6360", __FILE__)
{
}
ibm_6360::~ibm_6360()
{
}
//ol ibm_6360::trk00_r() { return true; }
void ibm_6360::setup_characteristics()
{
form_factor = floppy_image::FF_8;
tracks = 77;
sides = 1;
motor_always_on = true;
set_rpm(360);
}
void ibm_6360::handled_variants(uint32_t *variants, int &var_count) const
{
var_count = 0;
variants[var_count++] = floppy_image::SSSD;
}

View File

@ -245,6 +245,7 @@ DECLARE_FLOPPY_IMAGE_DEVICE(teac_fd_55e, "floppy_5_25")
DECLARE_FLOPPY_IMAGE_DEVICE(teac_fd_55f, "floppy_5_25")
DECLARE_FLOPPY_IMAGE_DEVICE(teac_fd_55g, "floppy_5_25")
DECLARE_FLOPPY_IMAGE_DEVICE(alps_3255190x, "floppy_5_25")
DECLARE_FLOPPY_IMAGE_DEVICE(ibm_6360, "floppy_8")
extern const device_type FLOPPYSOUND;
@ -340,5 +341,6 @@ extern const device_type TEAC_FD_55E;
extern const device_type TEAC_FD_55F;
extern const device_type TEAC_FD_55G;
extern const device_type ALPS_3255190x;
extern const device_type IBM_6360;
#endif /* FLOPPY_H */

View File

@ -1,104 +1,953 @@
// license:BSD-3-Clause
// copyright-holders:Robbbert
// copyright-holders:Robbbert, Sergey Svishchev
/***************************************************************************
IBM 6580 DisplayWriter.
IBM 6580 Displaywriter.
2013-08-19 Skeleton driver.
A green-screen dedicated word-processing workstation. It uses 8" floppy
disks. It could have up to 224k of ram. Consists of:
Electronics Module 6580
Display 3300
Keyboard 5330 [a "beamspring"-type]
Dual Diskette Unit 6360
Optional:
Printers: 5215, 5218, 5228
Printer Sharing feature
Mag Card Unit
Asynchronous and Bisynchronous communications features
66-line display and adapter (800x1056 px, 8x16 character cell)
A green-screen dedicated word-processing workstation. It uses 20cm floppy
disks. It could have up to 224k of ram.
ToDo:
- Everything!
- The roms need to be loaded properly.
- Chargen rom is not dumped.
All chips have IBM part numbers on them. F.e. on system board:
8493077 - 8086
4178619 - 8251A
4178617 - 8257-5
4178623 - 8259A
4178628 - 8255A-5
4178625 - 8253-5
IRQ levels per PSM p. 6-5
0 incoming data for printer sharing/3277 DE
1 transfer data to commo data link
2 printer and mag card data xfer
3 keyboard incoming data
4 diskette
5 (not in use)
6 software timer [50 ms period]
7 error on commo data link
nmi "or when a dump switch operation is initiated" ["memory record" button]
To do:
- verify all frequency sources, document ROM revisions
- memory size options
- bus errors, interrupts
- 92-key keyboard variant, keyboard click/beep, keyboard layouts
- 25-line video board (instant scroll, sub/superscripts, graphics mode)
- 66-line video board
- either emulate floppy board, or complete its HLE (drive select, etc.)
- add support for 8" drives with no track 0 sensor
(recalibrate command is expected to return 0x70 in ST0)
- double density floppies
- "memory record" (system dump) generation to floppies
- pass BAT with no errors (Basic Assurance Test)
- pass RNA with no errors (Resident Non-Automatic Test)
- pass PDD with no errors (Problem Determination Disk)
- pass CED with no errors (Customer Engineering Diagnostics)
- boot Textpack successfully (currently crashes with *90x* message)
Useful documents:
bitsavers://pdf/ibm/6580_Displaywriter/S241-6248-3_Displaywriter_Product_Support_Manual_Feb83.pdf
bitsavers://pdf/ibm/6580_Displaywriter/S241-6248-2_Displaywriter_6360_6580_Product_Support_Manual_May82.pdf
bitsavers://pdf/ibm/6580_Displaywriter/S241-6250-5_Displaywriter_6250_6580_Maintenance_Analysis_Procedures_May82.pdf
http://www.nostalgia8.nl/cpm/ibm/cpm6dwrm.pdf
http://www.kbdbabel.org/schematic/kbdbabel_doc_ibm_displaywriter.pdf
https://docs.google.com/spreadsheets/d/1SYY_HrBqKjSOX9W4fe5xUsjbfiCt0Umjpo4ZIwgG3Nk/edit?usp=sharing
Wanted:
Displaywriter System Manual S544-2023-0 (?) -- mentioned in US patents 4648071 and 5675827
"IBM Displaywriter System Printer Guide," Order No. S544-0861-2, Copyright 1980.
"Displaywriter System Product Support Manual," Order No. S241-6248-1, Copyright 1980
****************************************************************************/
#include "emu.h"
#include "bus/rs232/rs232.h"
#include "cpu/i86/i86.h"
#include "imagedev/floppy.h"
#include "machine/i8251.h"
#include "machine/i8255.h"
#include "machine/i8257.h"
#include "machine/pic8259.h"
#include "machine/pit8253.h"
#include "machine/ibm6580_kbd.h"
//nclude "machine/ibm6580_fdc.h"
#include "machine/upd765.h"
#include "ibm6580.lh"
#define I8086_TAG "i8086"
#define I8259A_TAG "i8259"
#define I8255A_TAG "i8255a"
#define I8253_TAG "i8253"
#define UPD765_TAG "upd765"
#define VERBOSE_DBG 2 /* general debug messages */
#define DBG_LOG(N,M,A) \
do { \
if(VERBOSE_DBG>=N) \
{ \
if( M ) \
logerror("%11.6f at %s: %-10s",machine().time().as_double(),machine().describe_context(),(char*)M ); \
logerror A; \
} \
} while (0)
uint8_t gfx_expand[16] = {
0x00, 0x03, 0x0c, 0x0f,
0x30, 0x33, 0x3c, 0x3f,
0xc0, 0xc3, 0xcc, 0xcf,
0xf0, 0xf3, 0xfc, 0xff
};
class ibm6580_state : public driver_device
{
public:
ibm6580_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_p_videoram(*this, "videoram")
, m_maincpu(*this, "maincpu")
, m_pic8259(*this, "pic8259")
, m_pit8253(*this, "pit8253")
, m_ppi8255(*this, "ppi8255")
, m_dma8257(*this, "dma8257")
, m_screen(*this, "screen")
, m_kbd(*this, "kbd")
, m_fdc(*this, UPD765_TAG)
, m_flop0(*this, UPD765_TAG ":0")
, m_flop1(*this, UPD765_TAG ":1")
{ }
const uint8_t *m_p_chargen;
DECLARE_PALETTE_INIT(ibm6580);
DECLARE_WRITE16_MEMBER(pic_latch_w);
DECLARE_WRITE16_MEMBER(unk_latch_w);
DECLARE_WRITE8_MEMBER(p40_w);
DECLARE_READ8_MEMBER(p40_r);
DECLARE_WRITE8_MEMBER(video_w);
DECLARE_READ8_MEMBER(video_r);
void vblank_w(screen_device &screen, bool state);
DECLARE_READ8_MEMBER(ppi_a_r);
DECLARE_WRITE8_MEMBER(led_w);
DECLARE_WRITE8_MEMBER(ppi_c_w);
DECLARE_READ8_MEMBER(ppi_c_r);
DECLARE_WRITE_LINE_MEMBER(kb_data_w);
DECLARE_WRITE_LINE_MEMBER(kb_clock_w);
DECLARE_WRITE_LINE_MEMBER(kb_strobe_w);
DECLARE_WRITE8_MEMBER(floppy_w);
DECLARE_READ8_MEMBER(floppy_r);
DECLARE_FLOPPY_FORMATS(floppy_formats);
DECLARE_WRITE_LINE_MEMBER(floppy_intrq);
DECLARE_WRITE_LINE_MEMBER(floppy_hdl);
DECLARE_WRITE8_MEMBER(dmapg_w);
DECLARE_WRITE_LINE_MEMBER(hrq_w);
DECLARE_READ8_MEMBER(memory_read_byte);
DECLARE_WRITE8_MEMBER(memory_write_byte);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
private:
virtual void machine_start() override;
virtual void machine_reset() override;
virtual void video_start() override;
const uint8_t *m_p_chargen;
uint8_t m_p40, m_p50, m_e000, m_kb_data, m_ppi_c;
bool m_kb_data_bit, m_kb_strobe;
util::fifo<uint8_t, 4> m_kb_fifo;
util::fifo<uint8_t, 4> m_floppy_mcu_sr, m_floppy_mcu_cr;
int m_floppy_mcu_cr_fifo;
uint8_t m_floppy_sr;
floppy_image_device *m_floppies[2];
floppy_image_device *m_floppy;
bool m_floppy_intrq, m_floppy_hdl, m_floppy_idle;
uint8_t m_dma0pg;
uint8_t floppy_mcu_command();
bool floppy_mcu_cr_full();
required_shared_ptr<uint16_t> m_p_videoram;
required_device<cpu_device> m_maincpu;
required_device<pic8259_device> m_pic8259;
required_device<pit8253_device> m_pit8253;
required_device<i8255_device> m_ppi8255;
required_device<i8257_device> m_dma8257;
required_device<screen_device> m_screen;
required_device<dw_keyboard_device> m_kbd;
required_device<upd765a_device> m_fdc;
required_device<floppy_connector> m_flop0;
required_device<floppy_connector> m_flop1;
};
WRITE8_MEMBER(ibm6580_state::p40_w)
{
DBG_LOG(2,"___", ("%02x <- %02x\n", 0x40 + (offset << 1), data));
switch (offset)
{
case 0:
m_p40 = data | 0x80;
break;
case 2:
if (data)
m_p40 |= 4;
break;
case 5:
// write_gate0 doesn't work -- counter is read back as 0
if (BIT(data, 2))
// hack. video test checks timer counter value and this lets it pass.
m_pit8253->set_clockin(0, (double)26880000);
else
m_pit8253->set_clockin(0, 0.0);
m_p50 = 0;
m_ppi_c = data;
break;
case 6:
m_dma0pg = data;
break;
case 8:
m_p50 = data;
break;
case 12:
if (data)
m_p40 &= ~0x14;
break;
}
}
READ8_MEMBER(ibm6580_state::p40_r)
{
uint8_t data = 0;
switch (offset)
{
case 0:
data = m_p40;
m_p40 &= ~4;
break;
case 8:
data = m_p50;
m_p50 = 1;
break;
}
DBG_LOG(3,"___", ("%02x == %02x\n", 0x40 + (offset << 1), data));
return data;
}
WRITE8_MEMBER(ibm6580_state::video_w)
{
DBG_LOG(2,"Video", ("%02x <- %02x\n", 0xe000 + (offset << 1), data));
switch (offset)
{
case 2:
// some kind of gate
m_e000 = data;
break;
}
}
READ8_MEMBER(ibm6580_state::video_r)
{
uint8_t data = 0;
switch (offset)
{
case 8:
data = 1; // 25-line video board ID. 66-line is 0x40.
data |= (m_screen->hblank() ? 8 : 0);
data |= (m_screen->vblank() ? 4 : 0);
// pure guesswork. 0x2, 0x10 and 0x20 are unknown video signals.
// 0x20 cannot be zero when 0x10 is zero.
data |= ((m_screen->vpos() < 2) ? 2 : 0);
if (m_e000) {
data |= (m_screen->vblank() ? 0x20 : 0);
data |= (m_screen->vblank() ? 0 : 0x10);
}
break;
}
if (offset != 8)
DBG_LOG(2,"Video", ("%02x == %02x\n", 0xe000 + (offset << 1), data));
return data;
}
void ibm6580_state::vblank_w(screen_device &screen, bool state)
{
// if (state)
// m_pic8259->ir6_w(state);
if (ioport("DUMP")->read())
m_p40 |= 4;
}
WRITE16_MEMBER(ibm6580_state::pic_latch_w)
{
DBG_LOG(2,"PIC", ("latch <- %02x\n", data));
if (data)
m_p40 |= 8;
m_pic8259->ir0_w(data == 2 ? ASSERT_LINE : CLEAR_LINE);
m_pic8259->ir1_w(data == 2 ? ASSERT_LINE : CLEAR_LINE);
m_pic8259->ir2_w(data == 2 ? ASSERT_LINE : CLEAR_LINE);
m_pic8259->ir3_w(data == 2 ? ASSERT_LINE : CLEAR_LINE);
m_pic8259->ir4_w(data == 2 ? ASSERT_LINE : CLEAR_LINE);
m_pic8259->ir5_w(data == 2 ? ASSERT_LINE : CLEAR_LINE);
m_pic8259->ir6_w(data == 2 ? ASSERT_LINE : CLEAR_LINE);
m_pic8259->ir7_w(data == 2 ? ASSERT_LINE : CLEAR_LINE);
}
WRITE16_MEMBER(ibm6580_state::unk_latch_w)
{
DBG_LOG(2,"UNK", ("latch <- %02x\n", data));
m_p40 |= 0x10;
}
WRITE8_MEMBER(ibm6580_state::led_w)
{
output().set_value("led5", BIT(data, 7));
output().set_value("led6", BIT(data, 6));
output().set_value("led7", BIT(data, 5));
output().set_value("led8", BIT(data, 4));
if (data & 0xf)
return;
switch (data >> 4)
{
case 0x1:
printf ("LED 0 0001: Parity Generator/Checker\n");
break;
case 0xe:
printf ("LED 0 1110: Base RAM\n");
break;
case 0x3:
printf ("LED 0 0011: Processor Extension Test\n");
break;
case 0x4:
printf ("LED 0 0100: Display RAM\n");
break;
case 0x5:
printf ("LED 0 0101: Display Adapter Timing Test, Video Test\n");
break;
case 0x6:
printf ("LED 0 0110: Keyboard Cable Test, Physical Keyboard Test\n");
break;
case 0x7:
printf ("LED 0 0111: DMA Controller Test\n");
break;
case 0x8:
printf ("LED 0 1000: Diskette Module Wrap Test, Adapter Test\n");
break;
case 0x9:
printf ("LED 0 1001: Extra RAM Test\n");
break;
case 0xa:
printf ("LED 0 1010: Bus Time-Out Test\n");
break;
case 0xc:
printf ("LED 0 1100: RAM Addressability Test\n");
break;
default:
// printf ("LED 0x%08x: unknown\n", data);
break;
}
}
WRITE8_MEMBER(ibm6580_state::ppi_c_w)
{
DBG_LOG(2,"PPI", ("Port C <- %02x\n", data));
// bit 5 -- acknowledge
// bit 6 -- reset
// bit 7 -- ?? gate
if (!BIT(data, 6)) {
m_kb_fifo.clear();
}
m_kbd->reset_w(!BIT(data, 6));
m_kbd->ack_w(BIT(data, 5));
}
READ8_MEMBER(ibm6580_state::ppi_c_r)
{
uint8_t data = 0;
data |= (m_kb_strobe << 3);
DBG_LOG(3,"PPI", ("Port C == %02x\n", data));
return data;
}
READ8_MEMBER(ibm6580_state::ppi_a_r)
{
uint8_t data = m_kb_fifo.dequeue();
DBG_LOG(2,"PPI", ("Port A == %02x (fifo full: %d)\n", data, m_kb_fifo.full()));
return data;
}
WRITE_LINE_MEMBER(ibm6580_state::kb_data_w)
{
m_kb_data_bit = !state;
}
WRITE_LINE_MEMBER(ibm6580_state::kb_clock_w)
{
if (!state)
m_kb_data = (m_kb_data >> 1) | (m_kb_data_bit << 7);
}
WRITE_LINE_MEMBER(ibm6580_state::kb_strobe_w)
{
m_kb_strobe = !state;
if (!state && BIT(m_ppi_c, 0)) {
m_kb_fifo.enqueue(m_kb_data);
DBG_LOG(1,"Kbd", ("enqueue %02x (fifo full: %d, m_ppi_c %02x)\n", m_kb_data, m_kb_fifo.full(), m_ppi_c));
}
}
WRITE_LINE_MEMBER(ibm6580_state::floppy_intrq)
{
m_floppy_intrq = state;
if (state)
m_floppy_idle = true;
}
WRITE_LINE_MEMBER(ibm6580_state::floppy_hdl)
{
m_floppy_hdl = !state;
}
WRITE_LINE_MEMBER(ibm6580_state::hrq_w)
{
m_maincpu->set_input_line(INPUT_LINE_HALT, state);
m_dma8257->hlda_w(state);
}
READ8_MEMBER(ibm6580_state::memory_read_byte)
{
address_space& prog_space = m_maincpu->space(AS_PROGRAM);
return prog_space.read_byte(offset | (m_dma0pg << 16));
}
WRITE8_MEMBER(ibm6580_state::memory_write_byte)
{
address_space& prog_space = m_maincpu->space(AS_PROGRAM);
prog_space.write_byte(offset | (m_dma0pg << 16), data);
}
bool ibm6580_state::floppy_mcu_cr_full()
{
uint8_t command = m_floppy_mcu_cr.peek();
if ((command & 1) && m_floppy_mcu_cr_fifo == 1)
return true;
if (command == 0x0c && m_floppy_mcu_cr_fifo == 4)
return true;
if (m_floppy_mcu_cr_fifo == 3)
return true;
else
return false;
}
uint8_t ibm6580_state::floppy_mcu_command()
{
uint8_t data = 0, command = m_floppy_mcu_cr.dequeue(), i;
DBG_LOG(2,"Floppy", ("mcu_command %02x\n", command));
m_floppy_mcu_sr.clear();
m_floppy_idle = true;
switch (command)
{
case 0:
m_fdc->soft_reset();
break;
// 3 bytes
case 4:
break;
// 1 byte -- get status?
case 5:
m_floppy_mcu_sr.enqueue(0x00);
if (m_flop0->get_device()->exists())
m_floppy_mcu_sr.enqueue( m_flop0->get_device()->idx_r() ? 0x08 : 0);
else
m_floppy_mcu_sr.enqueue(0x08);
break;
// 3 bytes, no return -- engage head
case 6:
m_floppy_mcu_cr.dequeue();
i = m_floppy_mcu_cr.dequeue();
m_floppy_hdl = i;
break;
// 1 byte -- read head engage signal
case 7:
m_floppy_mcu_sr.enqueue(0x00);
m_floppy_mcu_sr.enqueue(m_floppy_hdl);
break;
// 3 bytes
case 8:
break;
// 4 bytes -- used by cp/m. drive select?
case 0xc:
break;
// 1 byte -- get drive ready status?
case 0xd:
m_floppy_mcu_sr.enqueue(0x00);
i = 0;
if (m_flop0->get_device()->exists())
i |= m_flop0->get_device()->ready_r() ? 0 : 0x40;
if (m_flop1->get_device()->exists())
i |= m_flop1->get_device()->ready_r() ? 0 : 0x80;
m_floppy_mcu_sr.enqueue(i);
break;
// 3 bytes, no return -- recalibrate?
case 0xe:
m_floppy_mcu_cr.dequeue();
i = m_floppy_mcu_cr.dequeue();
#if 1
if (i & 1)
m_fdc->set_floppy(m_flop0->get_device());
else if (i & 2)
m_fdc->set_floppy(m_flop1->get_device());
#endif
break;
// 1 byte
case 0x13:
break;
// 1 byte
case 0x15:
break;
}
m_floppy_mcu_cr.clear();
m_floppy_mcu_cr_fifo = 0;
return data;
}
WRITE8_MEMBER(ibm6580_state::floppy_w)
{
DBG_LOG(2,"Floppy", ("%02x <- %02x\n", 0x8150 + (offset << 1), data));
switch (offset)
{
case 0: // 8150 -- mcu reset?
m_floppy_mcu_sr.enqueue(0x00);
m_floppy_mcu_sr.enqueue(0x00);
break;
case 1: // 8152
m_fdc->soft_reset();
break;
case 5: // 815A
m_fdc->fifo_w(space, offset, data);
if (m_floppy_idle);
m_floppy_idle = false;
break;
case 6: // 815C
m_floppy_mcu_cr.enqueue(data);
m_floppy_mcu_cr_fifo++;
if (floppy_mcu_cr_full())
floppy_mcu_command();
break;
}
}
READ8_MEMBER(ibm6580_state::floppy_r)
{
uint8_t data = 0;
switch (offset)
{
case 0: // 8150
// bit 4 -- ?? ready
// bit 5 -- mcu busy
// bit 6 -- ?? idle
if (m_floppy_mcu_sr.empty() && (m_floppy_idle || m_floppy_intrq))
data |= 0x40;
break;
case 4: // 8158
data = m_fdc->msr_r(space, offset);
break;
case 5: // 815a
data = m_fdc->fifo_r(space, offset);
case 6: // 815c
if (!m_floppy_mcu_sr.empty())
data = m_floppy_mcu_sr.dequeue();
break;
}
if (offset)
DBG_LOG(2,"Floppy", ("%02x == %02x\n", 0x8150 + (offset << 1), data));
else {
floppy_image_device *f = m_flop0->get_device();
if (f)
DBG_LOG(2,"Floppy", ("%02x == %02x (empty %d hdl %d + idle %d irq %d drq %d + dskchg %d idx %d cyl %d)\n",
0x8150 + (offset << 1), data,
m_floppy_mcu_sr.empty(), m_floppy_hdl,
m_floppy_idle, m_fdc->get_irq(), m_fdc->get_drq(),
f->dskchg_r(), f->idx_r(), f->get_cyl()
));
else
DBG_LOG(2,"Floppy", ("%02x == %02x (idle %d irq %d drq %d)\n",
0x8150 + (offset << 1), data,
m_floppy_idle, m_fdc->get_irq(), m_fdc->get_drq()
));
}
return data;
}
static ADDRESS_MAP_START(ibm6580_mem, AS_PROGRAM, 16, ibm6580_state)
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x00000,0xfdfff) AM_RAM
AM_RANGE(0xfe000,0xfffff) AM_ROM AM_REGION("user1", 0)
AM_RANGE(0x00000, 0x3ffff) AM_RAM // system RAM
AM_RANGE(0x90000, 0x90001) AM_WRITE(unk_latch_w)
AM_RANGE(0xef000, 0xeffff) AM_RAM AM_SHARE("videoram") // 66-line vram starts at 0xec000
AM_RANGE(0xfc000, 0xfffff) AM_ROM AM_REGION("user1", 0)
ADDRESS_MAP_END
static ADDRESS_MAP_START(ibm6580_io, AS_IO, 16, ibm6580_state)
//ADDRESS_MAP_UNMAP_HIGH
//ADDRESS_MAP_GLOBAL_MASK(0xff)
ADDRESS_MAP_UNMAP_HIGH
//
// AM_RANGE(0x0028, 0x0028) AM_DEVREADWRITE8("upd8251", i8251_device, data_r, data_w)
// AM_RANGE(0x0029, 0x0029) AM_DEVREADWRITE8("upd8251", i8251_device, status_r, control_w)
//
AM_RANGE(0x0000, 0x0007) AM_DEVREADWRITE8("pic8259", pic8259_device, read, write, 0x00ff)
AM_RANGE(0x0008, 0x000f) AM_WRITE (pic_latch_w)
AM_RANGE(0x0010, 0x0017) AM_DEVREADWRITE8("ppi8255", i8255_device, read, write, 0x00ff)
AM_RANGE(0x0020, 0x003f) AM_DEVREADWRITE8("dma8257", i8257_device, read, write, 0x00ff)
AM_RANGE(0x0040, 0x005f) AM_READWRITE8(p40_r, p40_w, 0x00ff)
AM_RANGE(0x0070, 0x007f) AM_UNMAP
AM_RANGE(0x0120, 0x0127) AM_DEVREADWRITE8("pit8253", pit8253_device, read, write, 0x00ff)
AM_RANGE(0x0140, 0x014f) AM_UNMAP
AM_RANGE(0x0160, 0x016f) AM_UNMAP
AM_RANGE(0x4000, 0x400f) AM_UNMAP
AM_RANGE(0x5000, 0x500f) AM_UNMAP
AM_RANGE(0x6000, 0x601f) AM_UNMAP
AM_RANGE(0x8060, 0x807f) AM_UNMAP
AM_RANGE(0x8150, 0x815f) AM_READWRITE8(floppy_r, floppy_w, 0x00ff) // HLE of floppy board
AM_RANGE(0x81a0, 0x81af) AM_UNMAP
AM_RANGE(0xc000, 0xc00f) AM_UNMAP
AM_RANGE(0xe000, 0xe02f) AM_READWRITE8(video_r, video_w, 0x00ff)
ADDRESS_MAP_END
/* Input ports */
static INPUT_PORTS_START( ibm6580 )
PORT_START("DUMP")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Memory Record") PORT_CODE(KEYCODE_PRTSCR) PORT_CHAR(UCHAR_MAMEKEY(PRTSCR))
INPUT_PORTS_END
uint32_t ibm6580_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
uint8_t y,ra,gfx,fg,bg,chr,attr;
uint16_t sy=0,ma=25,x,ca;
fg = 1; bg = 0;
for (y = 0; y < 25; y++)
{
for (ra = 0; ra < 16; ra++)
{
uint16_t *p = &bitmap.pix16(sy++);
// graphics mode
if (m_p_videoram[ma] & 0x100) {
for (x = ma; x < ma + 80; x++)
{
chr = m_p_videoram[x];
attr = m_p_videoram[x] >> 8;
switch (ra >> 1)
{
case 0:
gfx = gfx_expand[chr & 15];
break;
case 2:
gfx = gfx_expand[chr >> 4];
break;
case 4:
gfx = gfx_expand[attr & 15];
break;
case 6:
gfx = gfx_expand[attr >> 4];
break;
default:
gfx = 0;
break;
}
/* Display a scanline of a character */
*p++ = BIT(gfx, 7) ? fg : bg;
*p++ = BIT(gfx, 6) ? fg : bg;
*p++ = BIT(gfx, 5) ? fg : bg;
*p++ = BIT(gfx, 4) ? fg : bg;
*p++ = BIT(gfx, 3) ? fg : bg;
*p++ = BIT(gfx, 2) ? fg : bg;
*p++ = BIT(gfx, 1) ? fg : bg;
*p++ = BIT(gfx, 0) ? fg : bg;
}
} else {
// text mode
for (x = ma; x < ma + 80; x++)
{
chr = m_p_videoram[x];
attr = m_p_videoram[x] >> 8;
ca = (chr<<4);
// font 2
if (attr & 0x02)
ca += 0x1000;
#if 0
// superscript
if (attr & 0x20)
ca |= (ra < 13) ? ra + 3 : 0;
// subscript
if (attr & 0x20)
ca |= (ra > 2) ? ra - 3 : 0;
#endif
// underline
if (attr & 0x08 && ra == 13)
gfx = 0xff;
else
gfx = m_p_chargen[ca | ra];
// cursor
if (attr & 0x04 && ra == 14)
gfx = 0xff;
else
gfx = m_p_chargen[ca | ra];
// reverse video
if (attr & 0x10)
gfx ^= 255;
// intense
if (attr & 0x04)
fg = 2;
else
fg = 1;
/* Display a scanline of a character */
*p++ = BIT(gfx, 7) ? fg : bg;
*p++ = BIT(gfx, 6) ? fg : bg;
*p++ = BIT(gfx, 5) ? fg : bg;
*p++ = BIT(gfx, 4) ? fg : bg;
*p++ = BIT(gfx, 3) ? fg : bg;
*p++ = BIT(gfx, 2) ? fg : bg;
*p++ = BIT(gfx, 1) ? fg : bg;
*p++ = BIT(gfx, 0) ? fg : bg;
}
}
}
ma+=80;
}
return 0;
}
PALETTE_INIT_MEMBER( ibm6580_state, ibm6580 )
{
palette.set_pen_color(0, 0, 0, 0 ); /* Black */
palette.set_pen_color(1, 0, 255, 0 ); /* Full */
palette.set_pen_color(2, 0, 128, 0 ); /* Dimmed */
palette.set_pen_color(1, 0, 192, 0 ); /* Normal */
palette.set_pen_color(2, 0, 255, 0 ); /* Bright */
}
void ibm6580_state::machine_start()
{
m_fdc->set_rate(500000);
m_p_chargen = memregion("chargen")->base();
}
void ibm6580_state::machine_reset()
{
m_p_chargen = memregion("chargen")->base();
m_p40 = m_p50 = m_e000 = m_ppi_c = m_floppy_sr = 0;
m_kb_data_bit = false;
m_floppy_idle = true;
m_kb_fifo.clear();
m_pit8253->set_clockin(0, 0.0);
if (ioport("DUMP")->read())
m_p40 |= 4;
m_flop0->get_device()->mon_w(!m_flop0->get_device()->exists());
m_flop1->get_device()->mon_w(!m_flop1->get_device()->exists());
m_fdc->set_floppy(m_flop0->get_device());
m_floppy_mcu_sr.clear();
m_floppy_mcu_cr.clear();
m_floppy_mcu_cr_fifo = 0;
}
void ibm6580_state::video_start()
{
memset(m_p_videoram, 0x0, 0x1000);
}
FLOPPY_FORMATS_MEMBER( ibm6580_state::floppy_formats )
FLOPPY_HFE_FORMAT,
FLOPPY_IPF_FORMAT,
FLOPPY_MFI_FORMAT,
FLOPPY_TD0_FORMAT,
FLOPPY_IMD_FORMAT
FLOPPY_FORMATS_END0
static SLOT_INTERFACE_START( dw_floppies )
SLOT_INTERFACE( "8sssd", IBM_6360 )
SLOT_INTERFACE_END
static MACHINE_CONFIG_START( ibm6580, ibm6580_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", I8086, 4000000) // no idea
MCFG_CPU_ADD("maincpu", I8086, XTAL_14_7456MHz/3)
MCFG_CPU_PROGRAM_MAP(ibm6580_mem)
MCFG_CPU_IO_MAP(ibm6580_io)
MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE("pic8259", pic8259_device, inta_cb)
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(60)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
MCFG_SCREEN_RAW_PARAMS(XTAL_25MHz/2, 833, 0, 640, 428, 0, 400)
MCFG_SCREEN_UPDATE_DRIVER(ibm6580_state, screen_update)
MCFG_SCREEN_SIZE(640, 240)
MCFG_SCREEN_VISIBLE_AREA(0, 639, 0, 239)
MCFG_SCREEN_PALETTE("palette")
MCFG_SCREEN_VBLANK_DRIVER(ibm6580_state, vblank_w)
MCFG_DEFAULT_LAYOUT(layout_ibm6580)
MCFG_PALETTE_ADD("palette", 3)
MCFG_PALETTE_INIT_OWNER(ibm6580_state, ibm6580)
MCFG_PIC8259_ADD("pic8259", INPUTLINE("maincpu", 0), VCC, NOOP)
MCFG_DEVICE_ADD("ppi8255", I8255, 0)
MCFG_I8255_IN_PORTA_CB(READ8(ibm6580_state, ppi_a_r))
MCFG_I8255_OUT_PORTB_CB(WRITE8(ibm6580_state, led_w))
MCFG_I8255_OUT_PORTC_CB(WRITE8(ibm6580_state, ppi_c_w))
MCFG_I8255_IN_PORTC_CB(READ8(ibm6580_state, ppi_c_r))
MCFG_DEVICE_ADD("pit8253", PIT8253, 0)
MCFG_DEVICE_ADD("kbd", DW_KEYBOARD, 0)
MCFG_DW_KEYBOARD_OUT_DATA_HANDLER(WRITELINE(ibm6580_state, kb_data_w))
MCFG_DW_KEYBOARD_OUT_CLOCK_HANDLER(WRITELINE(ibm6580_state, kb_clock_w))
MCFG_DW_KEYBOARD_OUT_STROBE_HANDLER(WRITELINE(ibm6580_state, kb_strobe_w))
MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ppi8255", i8255_device, pc4_w))
MCFG_DEVICE_ADD("dma8257", I8257, XTAL_14_7456MHz/3)
MCFG_I8257_OUT_HRQ_CB(WRITELINE(ibm6580_state, hrq_w))
MCFG_I8257_OUT_TC_CB(DEVWRITELINE(UPD765_TAG, upd765a_device, tc_line_w))
MCFG_I8257_IN_MEMR_CB(READ8(ibm6580_state, memory_read_byte))
MCFG_I8257_OUT_MEMW_CB(WRITE8(ibm6580_state, memory_write_byte))
MCFG_I8257_IN_IOR_0_CB(DEVREAD8(UPD765_TAG, upd765a_device, mdma_r))
MCFG_I8257_OUT_IOW_0_CB(DEVWRITE8(UPD765_TAG, upd765a_device, mdma_w))
MCFG_UPD765A_ADD(UPD765_TAG, false, false)
MCFG_UPD765_INTRQ_CALLBACK(WRITELINE(ibm6580_state, floppy_intrq))
// MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("pic8259", pic8259_device, ir4_w))
MCFG_UPD765_DRQ_CALLBACK(DEVWRITELINE("dma8257", i8257_device, dreq0_w))
// MCFG_UPD765_HDL_CALLBACK(WRITELINE(ibm6580_state, floppy_hdl))
MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":0", dw_floppies, "8sssd", ibm6580_state::floppy_formats)
MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":1", dw_floppies, "8sssd", ibm6580_state::floppy_formats)
MCFG_SOFTWARE_LIST_ADD("flop_list", "ibm6580")
MACHINE_CONFIG_END
/* ROM definition */
ROM_START( ibm6580 )
ROM_REGION16_LE( 0x2000, "user1", 0 )
ROM_LOAD16_BYTE("8493823.bin", 0x0001, 0x1000, CRC(0bea066f) SHA1(8a42e24b609df7d9ca9cd52929702a61f7024635))
ROM_LOAD16_BYTE("8493822.bin", 0x0000, 0x1000, CRC(6e67f41a) SHA1(600fee505efe5cbcc8bdbab91d233378c7be4f12))
ROM_REGION16_LE( 0x4000, "user1", 0 )
ROM_DEFAULT_BIOS("old")
ROM_SYSTEM_BIOS(0, "old", "old bios")
ROMX_LOAD("8493823_8K.BIN", 0x0001, 0x2000, CRC(aa5524c0) SHA1(9938f2a82828b17966cb0be7fdbf73803c1f10d3),ROM_SKIP(1)|ROM_BIOS(1))
ROMX_LOAD("8493822_8K.BIN", 0x0000, 0x2000, CRC(90e7e73a) SHA1(d3ee7a4d2cb8f4920b5d95e8c7f4fef06599d24e),ROM_SKIP(1)|ROM_BIOS(1))
ROM_SYSTEM_BIOS(1, "new", "new bios")
// was downloaded via DDT86
ROMX_LOAD( "DWROM16KB.bin", 0x0000, 0x4000, BAD_DUMP CRC(ced87929) SHA1(907a46f288809bc93a1f59f3fbef18bd44be42d9),ROM_BIOS(2))
ROM_REGION( 0x2000, "chargen", 0 )
ROM_LOAD( "8493383.bin", 0x0000, 0x2000, NO_DUMP )
ROM_LOAD( "8493383_CHR.BIN", 0x0000, 0x2000, CRC(779044df) SHA1(95ec46f9edf4d44c5dd3c955c73e00754d58e180))
ROM_END
/* Driver */
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
COMP( 1980, ibm6580, 0, 0, ibm6580, ibm6580, driver_device, 0, "IBM", "IBM 6580 DisplayWriter", MACHINE_IS_SKELETON)
COMP( 1980, ibm6580, 0, 0, ibm6580, ibm6580, driver_device, 0, "IBM", "IBM 6580 Displaywriter", MACHINE_IS_SKELETON)

107
src/mame/layout/ibm6580.lay Normal file
View File

@ -0,0 +1,107 @@
<mamelayout version="2">
<element name="sysled" defstate="0">
<disk state="1">
<color red="0.55" green="0.0" blue="0.0" />
</disk>
<disk state="0">
<color red="0.15" green="0.0" blue="0.0" />
</disk>
</element>
<element name="l1">
<text string="A">
<color red="0.70" green="0.70" blue="0.70" />
</text>
</element>
<element name="l2">
<text string="B">
<color red="0.70" green="0.70" blue="0.70" />
</text>
</element>
<element name="l3">
<text string="C">
<color red="0.70" green="0.70" blue="0.70" />
</text>
</element>
<element name="l4">
<text string="D">
<color red="0.70" green="0.70" blue="0.70" />
</text>
</element>
<element name="l5">
<text string="E">
<color red="0.70" green="0.70" blue="0.70" />
</text>
</element>
<element name="l6">
<text string="F">
<color red="0.70" green="0.70" blue="0.70" />
</text>
</element>
<element name="l7">
<text string="G">
<color red="0.70" green="0.70" blue="0.70" />
</text>
</element>
<element name="l8">
<text string="H">
<color red="0.70" green="0.70" blue="0.70" />
</text>
</element>
<view name="Default Layout">
<screen index="0">
<bounds x="30" y="0" width="~scr0width~" height="~scr0height~" />
</screen>
<bezel name="led1" element="sysled">
<bounds x="15" y="76" width="10" height="10" />
</bezel>
<bezel name="led2" element="sysled">
<bounds x="15" y="96" width="10" height="10" />
</bezel>
<bezel name="led3" element="sysled">
<bounds x="15" y="116" width="10" height="10" />
</bezel>
<bezel name="led4" element="sysled">
<bounds x="15" y="136" width="10" height="10" />
</bezel>
<bezel name="led5" element="sysled">
<bounds x="15" y="156" width="10" height="10" />
</bezel>
<bezel name="led6" element="sysled">
<bounds x="15" y="176" width="10" height="10" />
</bezel>
<bezel name="led7" element="sysled">
<bounds x="15" y="196" width="10" height="10" />
</bezel>
<bezel name="led8" element="sysled">
<bounds x="15" y="216" width="10" height="10" />
</bezel>
<bezel name="label1" element="l1">
<bounds x="0" y="73" width="15" height="16" />
</bezel>
<bezel name="label2" element="l2">
<bounds x="0" y="93" width="15" height="16" />
</bezel>
<bezel name="label3" element="l3">
<bounds x="0" y="113" width="15" height="16" />
</bezel>
<bezel name="label4" element="l4">
<bounds x="0" y="133" width="15" height="16" />
</bezel>
<bezel name="label5" element="l5">
<bounds x="0" y="153" width="15" height="16" />
</bezel>
<bezel name="label6" element="l6">
<bounds x="0" y="173" width="15" height="16" />
</bezel>
<bezel name="label7" element="l7">
<bounds x="0" y="193" width="15" height="16" />
</bezel>
<bezel name="label8" element="l8">
<bounds x="0" y="213" width="15" height="16" />
</bezel>
</view>
</mamelayout>

View File

@ -0,0 +1,146 @@
// license:BSD-3-Clause
// copyright-holders:Sergey Svishchev
#include "ibm6580_fdc.h"
#define VERBOSE_DBG 2 /* general debug messages */
#define DBG_LOG(N,M,A) \
do { \
if(VERBOSE_DBG>=N) \
{ \
if( M ) \
logerror("%11.6f at %s: %-10s",machine().time().as_double(),machine().describe_context(),(char*)M ); \
logerror A; \
} \
} while (0)
const device_type DW_FDC = &device_creator<dw_fdc_device>;
ROM_START( dw_fdc )
ROM_REGION(0x800, "mcu", 0)
ROM_LOAD("4430030_FLP_8041.BIN", 0x0000, 0x400, CRC(2bb96799) SHA1(e30b0f2d790197f290858eab74ad5e151ded78c3))
ROM_END
const tiny_rom_entry *dw_fdc_device::device_rom_region() const
{
return ROM_NAME( dw_fdc );
}
static ADDRESS_MAP_START( dw_fdc_io, AS_IO, 8, dw_fdc_device )
// AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS) AM_READWRITE(bus_r, bus_w)
AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_WRITE(p1_w)
AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_WRITE(p2_w)
// AM_RANGE(MCS48_PORT_T0, MCS48_PORT_T0) AM_READ(t0_r)
AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_READ(t1_r)
ADDRESS_MAP_END
static MACHINE_CONFIG_FRAGMENT( dw_fdc )
MCFG_CPU_ADD("mcu", I8048, XTAL_24MHz/4) // divisor is unverified
MCFG_CPU_IO_MAP(dw_fdc_io)
MCFG_DEVICE_ADD("ppi8255", I8255, 0)
MCFG_UPD765A_ADD("upd765", false, false)
// MCFG_UPD765_INTRQ_CALLBACK(DEVWRITELINE("pic8259", pic8259_device, ir4_w))
// MCFG_UPD765_DRQ_CALLBACK(DEVWRITELINE("dma8257", dma8257_device, XXX))
// MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":0", wangpc_floppies, "525dd", wangpc_state::floppy_formats)
// MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":1", wangpc_floppies, "525dd", wangpc_state::floppy_formats)
MACHINE_CONFIG_END
machine_config_constructor dw_fdc_device::device_mconfig_additions() const
{
return MACHINE_CONFIG_NAME( dw_fdc );
}
dw_fdc_device::dw_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, DW_FDC, "IBM Displaywriter Floppy", tag, owner, clock, "dw_kbd", __FILE__)
, m_out_data(*this)
, m_out_clock(*this)
, m_out_strobe(*this)
, m_mcu(*this, "mcu")
{
}
void dw_fdc_device::device_start()
{
m_out_data.resolve_safe();
m_out_clock.resolve_safe();
m_out_strobe.resolve_safe();
m_reset_timer = timer_alloc();
}
void dw_fdc_device::device_reset()
{
m_p1 = m_p2 = m_t0 = m_t1 = 0;
}
void dw_fdc_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
m_mcu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
}
WRITE8_MEMBER( dw_fdc_device::p1_w )
{
m_p1 = data;
DBG_LOG(2,"p1",( "<- %02x\n", data, m_p1));
}
WRITE8_MEMBER( dw_fdc_device::p2_w )
{
m_p2 = data;
DBG_LOG(2,"p2",( "<- %02x\n", data));
}
READ8_MEMBER( dw_fdc_device::p2_r )
{
uint8_t data = m_p2;
DBG_LOG(2,"p2",( "== %02x\n", data));
return data;
}
READ8_MEMBER( dw_fdc_device::t0_r )
{
DBG_LOG(2,"t0",( "== %d\n", m_t0));
return m_t0;
}
READ8_MEMBER( dw_fdc_device::t1_r )
{
DBG_LOG(2,"t1",( "== %d\n", m_t1));
return m_t1;
}
WRITE8_MEMBER( dw_fdc_device::bus_w )
{
m_bus = data;
}
READ8_MEMBER( dw_fdc_device::bus_r )
{
return m_bus;
}
WRITE_LINE_MEMBER( dw_fdc_device::reset_w )
{
if(!state)
m_reset_timer->adjust(attotime::from_msec(50));
else
{
m_reset_timer->adjust(attotime::never);
m_mcu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE);
}
}
WRITE_LINE_MEMBER( dw_fdc_device::ack_w )
{
m_t0 = state;
}

View File

@ -0,0 +1,60 @@
// license:BSD-3-Clause
// copyright-holders:Sergey Svishchev
#ifndef DWFDC_H_
#define DWFDC_H_
#include "emu.h"
#include "cpu/mcs48/mcs48.h"
#include "machine/i8255.h"
#include "machine/upd765.h"
#define MCFG_DW_FDC_OUT_DATA_HANDLER(_devcb) \
devcb = &dw_fdc_device::set_out_data_handler(*device, DEVCB_##_devcb);
#define MCFG_DW_FDC_OUT_CLOCK_HANDLER(_devcb) \
devcb = &dw_fdc_device::set_out_clock_handler(*device, DEVCB_##_devcb);
#define MCFG_DW_FDC_OUT_STROBE_HANDLER(_devcb) \
devcb = &dw_fdc_device::set_out_strobe_handler(*device, DEVCB_##_devcb);
class dw_fdc_device : public device_t
{
public:
dw_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
template<class _Object> static devcb_base &set_out_data_handler(device_t &device, _Object object) { return downcast<dw_fdc_device &>(device).m_out_data.set_callback(object); }
template<class _Object> static devcb_base &set_out_clock_handler(device_t &device, _Object object) { return downcast<dw_fdc_device &>(device).m_out_clock.set_callback(object); }
template<class _Object> static devcb_base &set_out_strobe_handler(device_t &device, _Object object) { return downcast<dw_fdc_device &>(device).m_out_strobe.set_callback(object); }
virtual const tiny_rom_entry *device_rom_region() const override;
virtual machine_config_constructor device_mconfig_additions() const override;
void device_start() override;
void device_reset() override;
void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
DECLARE_WRITE8_MEMBER(bus_w);
DECLARE_READ8_MEMBER(bus_r);
DECLARE_WRITE8_MEMBER(p1_w);
DECLARE_WRITE8_MEMBER(p2_w);
DECLARE_READ8_MEMBER(p2_r);
DECLARE_READ8_MEMBER(t0_r);
DECLARE_READ8_MEMBER(t1_r);
DECLARE_WRITE_LINE_MEMBER(reset_w);
DECLARE_WRITE_LINE_MEMBER(ack_w);
private:
uint8_t m_dip, m_bus, m_t0, m_t1, m_p1, m_p2;
emu_timer *m_reset_timer;
devcb_write_line m_out_data;
devcb_write_line m_out_clock;
devcb_write_line m_out_strobe;
required_device<cpu_device> m_mcu;
};
extern const device_type DW_FDC;
#endif /* DWFDC_H_ */

View File

@ -0,0 +1,325 @@
// license:BSD-3-Clause
// copyright-holders:Sergey Svishchev
#include "ibm6580_kbd.h"
#define VERBOSE_DBG 0 /* general debug messages */
#define DBG_LOG(N,M,A) \
do { \
if(VERBOSE_DBG>=N) \
{ \
if( M ) \
logerror("%11.6f at %s: %-10s",machine().time().as_double(),machine().describe_context(),(char*)M ); \
logerror A; \
} \
} while (0)
const device_type DW_KEYBOARD = &device_creator<dw_keyboard_device>;
ROM_START( dw_keyboard )
ROM_REGION(0x800, "mcu", 0)
ROM_LOAD("4333923_KB_8048.BIN", 0x0000, 0x400, CRC(7850e3a0) SHA1(3183d93e34707f4b24f4f71db658c3cf317a631a))
ROM_END
const tiny_rom_entry *dw_keyboard_device::device_rom_region() const
{
return ROM_NAME( dw_keyboard );
}
static ADDRESS_MAP_START( dw_keyboard_io, AS_IO, 8, dw_keyboard_device )
AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS) AM_READWRITE(bus_r, bus_w)
AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_WRITE(p1_w)
AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_READWRITE(p2_r, p2_w)
AM_RANGE(MCS48_PORT_T0, MCS48_PORT_T0) AM_READ(t0_r)
AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_READ(t1_r)
ADDRESS_MAP_END
static MACHINE_CONFIG_FRAGMENT( dw_keyboard )
MCFG_CPU_ADD("mcu", I8049, XTAL_6MHz) // XXX RC oscillator
MCFG_CPU_IO_MAP(dw_keyboard_io)
MACHINE_CONFIG_END
machine_config_constructor dw_keyboard_device::device_mconfig_additions() const
{
return MACHINE_CONFIG_NAME( dw_keyboard );
}
INPUT_PORTS_START( dw_keyboard )
/*
* Keyboard Arrangement Options -- p. 5-12 of Product Support Manual '83
* Keyboard Matrix -- p. 5-6 ('83) and p. 26 ('82)
*/
PORT_START("DIP")
PORT_DIPNAME( 0xff, 1, "Layout" )
PORT_DIPSETTING( 1, "U.S." )
PORT_DIPSETTING( 250, "U.S. Dvorak" )
PORT_START("COL.0")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Unknown 81")
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Unknown 77")
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Unknown 73")
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Spell")
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Line Adj")
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Page End")
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Find")
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Go To")
PORT_START("COL.1")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Right") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Down") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN))
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Get")
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Move") PORT_CODE(KEYCODE_PGDN) PORT_CHAR(UCHAR_MAMEKEY(PGDN))
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Del") PORT_CODE(KEYCODE_DEL) PORT_CHAR(UCHAR_MAMEKEY(DEL))
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Chg Fmt")
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Up") PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP))
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Left") PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT))
PORT_START("COL.2")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("RShift") PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Index")
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Bksp") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8)
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_START("COL.3")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("/ ?") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?')
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("3 2") PORT_CODE(KEYCODE_BACKSLASH)
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("[ ]") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('[') PORT_CHAR(']')
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+')
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_')
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("1/4 1/2") PORT_CODE(KEYCODE_OPENBRACE)
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"')
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Enter") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD))
PORT_START("COL.4")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',')
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':')
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P')
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')')
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(')
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O')
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L')
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(".") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.')
PORT_START("COL.5")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N')
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K')
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I')
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*')
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&')
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U')
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J')
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M')
PORT_START("COL.6")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V')
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H')
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y')
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^')
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%')
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T')
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G')
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B')
PORT_START("COL.7")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X')
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F')
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R')
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#')
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E')
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D')
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C')
PORT_START("COL.8")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Paragraph")
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S')
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W')
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@')
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q')
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A')
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z')
PORT_START("COL.9")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("LShift") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Lock") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK))
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TAB) PORT_CHAR('\t')
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Plusminus") PORT_CODE(KEYCODE_TILDE)
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Code") PORT_CODE(KEYCODE_LALT) PORT_CHAR(UCHAR_MAMEKEY(LALT))
PORT_START("COL.10")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Msg")
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Unknown 4")
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Unknown 83")
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Unknown 2")
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Print")
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')
PORT_START("COL.11")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("End") PORT_CODE(KEYCODE_END) PORT_CHAR(UCHAR_MAMEKEY(END))
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Unknown 3")
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Unknown 82")
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Unknown 1")
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Reqst")
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
INPUT_PORTS_END
ioport_constructor dw_keyboard_device::device_input_ports() const
{
return INPUT_PORTS_NAME( dw_keyboard );
}
dw_keyboard_device::dw_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, DW_KEYBOARD, "IBM Displaywriter Keyboard", tag, owner, clock, "dw_kbd", __FILE__)
, m_kbd(*this, "COL.%u", 0)
, m_out_data(*this)
, m_out_clock(*this)
, m_out_strobe(*this)
, m_mcu(*this, "mcu")
{
}
void dw_keyboard_device::device_start()
{
m_out_data.resolve_safe();
m_out_clock.resolve_safe();
m_out_strobe.resolve_safe();
m_reset_timer = timer_alloc();
}
void dw_keyboard_device::device_reset()
{
}
void dw_keyboard_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
m_mcu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
}
WRITE8_MEMBER( dw_keyboard_device::p1_w )
{
m_drive = data;
DBG_LOG(2,"p1",( "<- %02x = drive %04x\n", data, m_drive));
}
WRITE8_MEMBER( dw_keyboard_device::p2_w )
{
if (BIT(m_p2 ^ data, 3) && BIT(data, 3)) {
m_sense = data & 7;
}
m_p2 = data;
m_drive = ((data & 0xf0) << 4);
DBG_LOG(2,"p2",( "<- %02x = drive %04x sense row %d\n", data, m_drive, data & 7));
}
READ8_MEMBER( dw_keyboard_device::p2_r )
{
uint8_t data = m_p2;
DBG_LOG(2,"p2",( "== %02x\n", data));
return data;
}
READ8_MEMBER( dw_keyboard_device::t0_r )
{
DBG_LOG(3,"t0",( "== %d\n", m_ack));
return m_ack;
}
READ8_MEMBER( dw_keyboard_device::t1_r )
{
DBG_LOG(2,"t1",( "== %d\n", m_keylatch));
return m_keylatch;
}
WRITE8_MEMBER( dw_keyboard_device::bus_w )
{
int i, sense = 0;
/*
bit description
0 Serial data
1 Serial data strobe
2 NC
3 NC
4 Serial data clock
5 (dip)
6 (dip)
7 NC on kbdbabel schematic, in use by firmware XXX
*/
if ((data & 0x72) != 0x72)
DBG_LOG(1,"bus",( "<- %02x = send %d strobe %d clock %d | dip clk %d dip load %d\n",
data, BIT(data, 0), BIT(data, 1), BIT(data, 4), BIT(data, 5), BIT(data, 6)));
m_bus = data;
m_out_data(BIT(data, 0));
m_out_strobe(BIT(data, 1));
m_out_clock(BIT(data, 4));
if (BIT(data, 7)) {
for (i = 0; i < 12; i++) {
if (BIT(m_drive, i)) {
sense |= m_kbd[i]->read();
break;
}
}
m_keylatch = BIT(sense, m_sense);
if (m_keylatch)
DBG_LOG(1,"bus",("key %02x pressed (drive %04x sense %x)\n", (i << 3) | m_sense, m_drive, m_sense));
}
if (!BIT(data, 6)) {
m_dip = ~ioport("DIP")->read();
DBG_LOG(1,"bus",("loaded DIP switch setting 0x%02x\n", m_dip));
m_mcu->set_input_line(MCS48_INPUT_IRQ, m_dip & 1 ? ASSERT_LINE : CLEAR_LINE);
}
if (!BIT(data, 5)) {
m_dip >>= 1;
m_mcu->set_input_line(MCS48_INPUT_IRQ, m_dip & 1 ? ASSERT_LINE : CLEAR_LINE);
}
}
READ8_MEMBER( dw_keyboard_device::bus_r )
{
return m_bus;
}
WRITE_LINE_MEMBER( dw_keyboard_device::reset_w )
{
if(!state)
m_reset_timer->adjust(attotime::from_msec(50));
else
{
m_reset_timer->adjust(attotime::never);
m_mcu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE);
}
}
WRITE_LINE_MEMBER( dw_keyboard_device::ack_w )
{
m_ack = state;
}

View File

@ -0,0 +1,60 @@
// license:BSD-3-Clause
// copyright-holders:Sergey Svishchev
#ifndef DWKBD_H_
#define DWKBD_H_
#include "emu.h"
#include "cpu/mcs48/mcs48.h"
#define MCFG_DW_KEYBOARD_OUT_DATA_HANDLER(_devcb) \
devcb = &dw_keyboard_device::set_out_data_handler(*device, DEVCB_##_devcb);
#define MCFG_DW_KEYBOARD_OUT_CLOCK_HANDLER(_devcb) \
devcb = &dw_keyboard_device::set_out_clock_handler(*device, DEVCB_##_devcb);
#define MCFG_DW_KEYBOARD_OUT_STROBE_HANDLER(_devcb) \
devcb = &dw_keyboard_device::set_out_strobe_handler(*device, DEVCB_##_devcb);
class dw_keyboard_device : public device_t
{
public:
dw_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
template<class _Object> static devcb_base &set_out_data_handler(device_t &device, _Object object) { return downcast<dw_keyboard_device &>(device).m_out_data.set_callback(object); }
template<class _Object> static devcb_base &set_out_clock_handler(device_t &device, _Object object) { return downcast<dw_keyboard_device &>(device).m_out_clock.set_callback(object); }
template<class _Object> static devcb_base &set_out_strobe_handler(device_t &device, _Object object) { return downcast<dw_keyboard_device &>(device).m_out_strobe.set_callback(object); }
virtual const tiny_rom_entry *device_rom_region() const override;
virtual machine_config_constructor device_mconfig_additions() const override;
virtual ioport_constructor device_input_ports() const override;
void device_start() override;
void device_reset() override;
void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
DECLARE_WRITE8_MEMBER(bus_w);
DECLARE_READ8_MEMBER(bus_r);
DECLARE_WRITE8_MEMBER(p1_w);
DECLARE_WRITE8_MEMBER(p2_w);
DECLARE_READ8_MEMBER(p2_r);
DECLARE_READ8_MEMBER(t0_r);
DECLARE_READ8_MEMBER(t1_r);
DECLARE_WRITE_LINE_MEMBER(reset_w);
DECLARE_WRITE_LINE_MEMBER(ack_w);
private:
uint8_t m_dip, m_bus, m_p2;
int m_drive, m_sense;
bool m_keylatch, m_ack;
emu_timer *m_reset_timer;
required_ioport_array<12> m_kbd;
devcb_write_line m_out_data;
devcb_write_line m_out_clock;
devcb_write_line m_out_strobe;
required_device<cpu_device> m_mcu;
};
extern const device_type DW_KEYBOARD;
#endif /* DWKBD_H_ */