summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Patrick Mackinlay <pmackinlay@hotmail.com>2020-11-02 18:03:52 +0700
committer Patrick Mackinlay <pmackinlay@hotmail.com>2020-11-02 18:03:52 +0700
commitf4172ded3ec6f3b877ab813f6453d6d1907c1c00 (patch)
tree4c811b1abcb95b5b48758084b9adf557b642d1f0 /src
parent8cc1effdfbd6c9a4d967ede5c7c6d800770a4016 (diff)
ceres: wip checkpoint
* implement the mouse * connect the fpu * crude hard/floppy disk controller hle * add debugger rom * boots oberon from hard disk image
Diffstat (limited to 'src')
-rw-r--r--src/mame/drivers/ceres.cpp236
1 files changed, 192 insertions, 44 deletions
diff --git a/src/mame/drivers/ceres.cpp b/src/mame/drivers/ceres.cpp
index ace6ea7b186..5a0174cbf14 100644
--- a/src/mame/drivers/ceres.cpp
+++ b/src/mame/drivers/ceres.cpp
@@ -9,11 +9,8 @@
*
* TODO:
* - startup/reset memory map
- * - i/o device mapping
- * - interrupt acknowledge
* - WD1002-05 Winchester/Floppy Disk Controller (WFC)
* - keyboard
- * - mouse
*/
#include "emu.h"
@@ -23,7 +20,7 @@
#include "machine/ram.h"
// various hardware
-//#include "machine/ns32081.h"
+#include "machine/ns32081.h"
//#include "machine/ns32082.h"
#include "machine/mc68681.h"
#include "machine/z80scc.h"
@@ -33,6 +30,7 @@
// busses and connectors
#include "bus/rs232/rs232.h"
+#include "imagedev/harddriv.h"
#include "imagedev/floppy.h"
// video
@@ -41,12 +39,15 @@
#define VERBOSE 0
#include "logmacro.h"
+namespace {
+
class ceres1_state : public driver_device
{
public:
ceres1_state(machine_config const &mconfig, device_type type, char const *tag)
: driver_device(mconfig, type, tag)
, m_cpu(*this, "cpu")
+ , m_fpu(*this, "fpu")
, m_ram(*this, "ram")
, m_uart(*this, "uart")
, m_serial(*this, "v24")
@@ -54,7 +55,8 @@ public:
, m_rtc(*this, "rtc")
, m_icu(*this, "icu")
, m_fdc(*this, "fdc")
- , m_fdd(*this, "fdc:0:35dd")
+ , m_fdd(*this, "fdc:%u:fdd", 0U)
+ , m_hdd(*this, "hdd%u", 0U)
, m_screen(*this, "screen")
, m_vram(*this, "vram")
{
@@ -76,11 +78,17 @@ public:
void wfc_w(offs_t offset, u8 data);
u8 wfc_r(offs_t offset);
+ void wfc_command(u8 command);
+ int get_lbasector(hard_disk_file *hdf);
+
+ DECLARE_INPUT_CHANGED_MEMBER(mouse_x);
+ DECLARE_INPUT_CHANGED_MEMBER(mouse_y);
protected:
DECLARE_FLOPPY_FORMATS(floppy_formats);
required_device<ns32032_device> m_cpu;
+ required_device<ns32081_device> m_fpu;
required_device<ram_device> m_ram;
required_device<scn2681_device> m_uart;
@@ -90,12 +98,35 @@ protected:
required_device<am9519_device> m_icu;
required_device<wd2797_device> m_fdc;
- required_device<floppy_image_device> m_fdd;
+ optional_device_array<floppy_image_device, 4> m_fdd;
+ optional_device_array<harddisk_image_device, 3> m_hdd;
required_device<screen_device> m_screen;
required_shared_ptr<u32> m_vram;
u8 m_dcr;
+ u16 m_mouse_x;
+ u16 m_mouse_y;
+
+ enum wfc_status : u8
+ {
+ WFC_S_ERR = 0x01, // error
+ WFC_S_CD = 0x04, // corrected data
+ WFC_S_DRQ = 0x08, // data request
+ WFC_S_SC = 0x10, // seek complete
+ WFC_S_WF = 0x20, // write fault
+ WFC_S_RDY = 0x40, // drive ready
+ WFC_S_BSY = 0x80, // busy
+ };
+ u8 m_wfc_sram[2048];
+ unsigned m_wfc_offset;
+ u8 m_wfc_error;
+ u8 m_wfc_precomp;
+ u8 m_wfc_count;
+ u8 m_wfc_sector;
+ u16 m_wfc_cylinder;
+ u8 m_wfc_sdh;
+ u8 m_wfc_status;
};
void ceres1_state::machine_start()
@@ -106,20 +137,28 @@ void ceres1_state::machine_start()
void ceres1_state::machine_reset()
{
m_dcr = 0;
+ m_mouse_x = 0;
+ m_mouse_y = 0;
+
+ m_wfc_offset = 0;
+ m_wfc_status = WFC_S_RDY;
}
void ceres1_state::wfc_w(offs_t offset, u8 data)
{
switch (offset)
{
- case 0: LOG("wfc_w data 0x%02x\n", offset, data); break;
- case 1: LOG("wfc_w write precomp 0x%02x\n", offset, data); break;
- case 2: LOG("wfc_w sector count 0x%02x\n", offset, data); break;
- case 3: LOG("wfc_w sector number 0x%02x\n", offset, data); break;
- case 4: LOG("wfc_w cylinder low 0x%02x\n", offset, data); break;
- case 5: LOG("wfc_w cylinder high 0x%02x\n", offset, data); break;
- case 6: LOG("wfc_w size/drive/head 0x%02x\n", offset, data); break;
- case 7: LOG("wfc_w command 0x%02x\n", offset, data); break;
+ case 0:
+ m_wfc_sram[m_wfc_offset++] = data;
+ m_wfc_offset &= 0x3ff;
+ break;
+ case 1: m_wfc_precomp = data; break;
+ case 2: m_wfc_count = data; break;
+ case 3: m_wfc_sector = data; break;
+ case 4: m_wfc_cylinder = (m_wfc_cylinder & 0xff00) | data; break;
+ case 5: m_wfc_cylinder = u16(data) << 8 | (m_wfc_cylinder & 0xff); break;
+ case 6: m_wfc_sdh = data; break;
+ case 7: wfc_command(data); break;
}
}
@@ -130,22 +169,72 @@ u8 ceres1_state::wfc_r(offs_t offset)
switch (offset)
{
case 0: // data
- case 1: // error
- case 2: // sector count
- case 3: // sector number
- case 4: // cylinder low
- case 5: // cylinder high
- case 6: // size/drive/head
+ data = m_wfc_sram[m_wfc_offset++];
+ m_wfc_offset &= 0x3ff;
break;
+ case 1: data = m_wfc_error; break;
+ case 2: data = m_wfc_count; break;
+ case 3: data = m_wfc_sector; break;
+ case 4: data = u8(m_wfc_cylinder); break;
+ case 5: data = m_wfc_cylinder >> 8; break;
+ case 6: data = m_wfc_sdh; break;
+ case 7: data = m_wfc_status; m_icu->ireq3_w(0); break;
+ }
- case 7: // status
- //data = 0x40; // drive ready
+ return data;
+}
+
+void ceres1_state::wfc_command(u8 command)
+{
+ m_wfc_status |= WFC_S_BSY;
+ m_wfc_status &= ~WFC_S_ERR;
+ m_wfc_error = 0;
+
+ hard_disk_file *hdf = m_hdd[(m_wfc_sdh >> 3) & 3]->get_hard_disk_file();
+
+ switch (command >> 4)
+ {
+ case 1:
+ // restore
+ break;
+ case 2:
+ LOG("read sector drive %d chs %d,%d,%d count %d\n",
+ (m_wfc_sdh >> 3) & 3, m_wfc_cylinder & 0x3ff, (m_wfc_sdh >> 0) & 7, m_wfc_sector, m_wfc_count);
+ hard_disk_read(hdf, get_lbasector(hdf), m_wfc_sram);
+ m_wfc_offset = 0;
+ break;
+ case 3:
+ LOG("write sector drive %d chs %d,%d,%d count %d\n",
+ (m_wfc_sdh >> 3) & 3, m_wfc_cylinder & 0x3ff, (m_wfc_sdh >> 0) & 7, m_wfc_sector, m_wfc_count);
+ hard_disk_write(hdf, get_lbasector(hdf), m_wfc_sram);
+ m_wfc_offset = 0;
+ break;
+ case 4:
+ // scan id
+ break;
+ case 5:
+ // write format id
+ break;
+ case 7:
+ // seek
break;
}
- LOG("wfc_r reg %d data 0x%02x\n", offset, data);
+ m_wfc_status &= ~WFC_S_BSY;
+ m_icu->ireq3_w(1);
+}
- return data;
+int ceres1_state::get_lbasector(hard_disk_file *hdf)
+{
+ hard_disk_info const *info = hard_disk_get_info(hdf);
+
+ int lbasector = m_wfc_cylinder & 0x3ff;
+ lbasector *= info->heads;
+ lbasector += (m_wfc_sdh >> 0) & 7;
+ lbasector *= info->sectors;
+ lbasector += m_wfc_sector;
+
+ return lbasector;
}
template <unsigned ST> void ceres1_state::cpu_map(address_map &map)
@@ -155,22 +244,70 @@ template <unsigned ST> void ceres1_state::cpu_map(address_map &map)
map(0xe00000, 0xe3ffff).ram().share("vram");
map(0xf80000, 0xf87fff).rom().region("eprom", 0);
+
map(0xfffa00, 0xfffa00).lw8(
[this](u8 data)
{
m_dcr = data & 7;
}, "dcr_w");
+ map(0xfffc00, 0xfffc1f).rw(FUNC(ceres1_state::wfc_r), FUNC(ceres1_state::wfc_w)).umask32(0xff);
+ map(0xfffc40, 0xfffc7f).lrw32(
+ [this]() { m_cpu->set_input_line(INPUT_LINE_NMI, 0); return 0; }, "parity_clear",
+ [this](u32 data) { m_cpu->set_input_line(INPUT_LINE_NMI, 0); }, "parity_clear");
+ map(0xfffc80, 0xfffc80).rw(m_rtc, FUNC(m3002_device::read), FUNC(m3002_device::write));
+ map(0xfffd00, 0xfffd01).lr16([this]() { return m_mouse_x; }, "mouse_x");
+ map(0xfffd04, 0xfffd05).lr16([this]() { return m_mouse_y; }, "mouse_y");
+ map(0xfffd08, 0xfffd0b).portr("mouse_buttons");
+ map(0xfffd40, 0xfffd7f).rw(m_uart, FUNC(scn2681_device::read), FUNC(scn2681_device::write)).umask32(0xff);
+ map(0xfffd80, 0xfffd8f).rw(m_scc, FUNC(z80scc_device::ab_dc_r), FUNC(z80scc_device::ab_dc_w)).umask32(0xff);
map(0xfffdc0, 0xfffdc3).portr("SW1");
map(0xfffdc0, 0xfffdc0).lw8(
[this](u8 data)
{
m_cpu->space(0).install_ram(0, m_ram->mask(), m_ram->pointer());
}, "bt_ff_w");
+ if (ST == 4)
+ map(0xfffe00, 0xfffe00).lr8([this]() { return m_icu->acknowledge(); }, "iack");
+ map(0xfffe08, 0xfffe08).rw(m_icu, FUNC(am9519_device::data_r), FUNC(am9519_device::data_w));
+ map(0xfffe0c, 0xfffe0c).rw(m_icu, FUNC(am9519_device::stat_r), FUNC(am9519_device::cmd_w));
+}
- map(0xfffc00, 0xfffc1f).rw(FUNC(ceres1_state::wfc_r), FUNC(ceres1_state::wfc_w)).umask32(0xff);
+INPUT_CHANGED_MEMBER(ceres1_state::mouse_x)
+{
+ // compute x delta
+ int delta = newval - oldval;
+ if (delta > 0x80)
+ delta -= 0x100;
+ else if (delta < -0x80)
+ delta += 0x100;
+
+ m_mouse_x = std::max(0, std::min(m_mouse_x + delta, 1023));
+}
+
+INPUT_CHANGED_MEMBER(ceres1_state::mouse_y)
+{
+ // compute y delta
+ int delta = newval - oldval;
+ if (delta > 0x80)
+ delta -= 0x100;
+ else if (delta < -0x80)
+ delta += 0x100;
+
+ m_mouse_y = std::max(0, std::min(m_mouse_y - delta, 799));
}
static INPUT_PORTS_START(ceres1)
+ PORT_START("mouse_x")
+ PORT_BIT(0xff, 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_PLAYER(1) PORT_CHANGED_MEMBER(DEVICE_SELF, ceres1_state, mouse_x, 0)
+
+ PORT_START("mouse_y")
+ PORT_BIT(0xff, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_PLAYER(1) PORT_CHANGED_MEMBER(DEVICE_SELF, ceres1_state, mouse_y, 0)
+
+ PORT_START("mouse_buttons")
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Mouse Left Button") PORT_CODE(MOUSECODE_BUTTON1)
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_NAME("Mouse Middle Button") PORT_CODE(MOUSECODE_BUTTON3)
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_BUTTON3) PORT_NAME("Mouse Right Button") PORT_CODE(MOUSECODE_BUTTON2)
+
PORT_START("SW1")
PORT_DIPNAME(0x80, 0x00, "Diagnostic") PORT_DIPLOCATION("SW1:1")
PORT_DIPSETTING(0x00, DEF_STR(On))
@@ -198,25 +335,24 @@ void ceres1_state::ceres1(machine_config &config)
{
NS32032(config, m_cpu, 10_MHz_XTAL);
m_cpu->set_addrmap(0, &ceres1_state::cpu_map<0>);
- m_cpu->set_addrmap(6, &ceres1_state::cpu_map<6>);
+ m_cpu->set_addrmap(4, &ceres1_state::cpu_map<4>);
+
+ NS32081(config, m_fpu, 10_MHz_XTAL);
+ m_cpu->set_fpu(m_fpu);
RAM(config, m_ram);
- m_ram->set_default_size("2MiB");
+ m_ram->set_default_size("4MiB");
m_ram->set_default_value(0);
- m_ram->set_extra_options("4MiB,6MiB,8MiB");
+ m_ram->set_extra_options("2MiB,6MiB,8MiB");
// TODO: port A txd/rxd connect to keyboard
SCN2681(config, m_uart, 3.6864_MHz_XTAL);
- m_uart->irq_cb().set(m_icu, FUNC(am9519_device::ireq2_w));
- m_uart->outport_cb().set(
- [this](u8 data)
- {
- m_serial->write_dtr(BIT(data, 0));
- m_serial->write_rts(BIT(data, 1));
- m_icu->ireq0_w(BIT(data, 3));
- m_icu->ireq4_w(BIT(data, 4));
- });
- m_uart->b_tx_cb().set(m_serial, FUNC(rs232_port_device::write_txd));
+ m_uart->irq_cb().set(m_icu, FUNC(am9519_device::ireq2_w)).invert();
+ m_uart->b_tx_cb().set(m_serial, FUNC(rs232_port_device::write_txd)).invert();
+ m_uart->outport_cb().set(m_serial, FUNC(rs232_port_device::write_dtr)).bit(0).invert();
+ m_uart->outport_cb().set(m_serial, FUNC(rs232_port_device::write_rts)).bit(1).invert();
+ m_uart->outport_cb().set(m_icu, FUNC(am9519_device::ireq0_w)).bit(3);
+ m_uart->outport_cb().set(m_icu, FUNC(am9519_device::ireq4_w)).bit(4);
RS232_PORT(config, m_serial, default_rs232_devices, nullptr);
m_serial->rxd_handler().set(m_uart, FUNC(scn2681_device::rx_b_w));
@@ -227,7 +363,7 @@ void ceres1_state::ceres1(machine_config &config)
// TODO: RS-485 ports "na" and "nb"
SCC8530N(config, m_scc, 6_MHz_XTAL);
m_scc->configure_channels(m_uart->clock(), 0, m_uart->clock(), 0);
- m_scc->out_int_callback().set(m_icu, FUNC(am9519_device::ireq1_w));
+ m_scc->out_int_callback().set(m_icu, FUNC(am9519_device::ireq1_w)).invert();
M3002(config, m_rtc, 32.768_kHz_XTAL);
m_rtc->irq_out().set(m_icu, FUNC(am9519_device::ireq5_w));
@@ -236,8 +372,12 @@ void ceres1_state::ceres1(machine_config &config)
m_icu->out_int_callback().set_inputline(m_cpu, INPUT_LINE_IRQ0);
// TODO: WD1002-05 Winchester/Floppy Disk Controller (WFC)
- WD2797(config, m_fdc, 0);
- FLOPPY_CONNECTOR(config, "fdc:0", "35dd", FLOPPY_35_DD, true, floppy_formats).enable_sound(false);
+ HARDDISK(config, m_hdd[0], 0);
+ HARDDISK(config, m_hdd[1], 0);
+ HARDDISK(config, m_hdd[2], 0);
+
+ WD2797(config, m_fdc, 20_MHz_XTAL / 20);
+ FLOPPY_CONNECTOR(config, "fdc:0", "fdd", FLOPPY_35_DD, true, floppy_formats);
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_raw(70'000'000, 1344, 0, 1024, 838, 0, 800);
@@ -258,7 +398,7 @@ u32 ceres1_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, rec
u32 const data = m_vram[offset++] ^ invert;
for (unsigned i = 0; i < 32; i++)
- bitmap.pix(y, x + i) = BIT(data, 31 - i) ? rgb_t::white() : rgb_t::black();
+ bitmap.pix(y, x + i) = BIT(data, i) ? rgb_t::white() : rgb_t::black();
}
}
}
@@ -267,17 +407,25 @@ u32 ceres1_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, rec
}
FLOPPY_FORMATS_MEMBER(ceres1_state::floppy_formats)
- {}
+ FLOPPY_IMD_FORMAT
FLOPPY_FORMATS_END
ROM_START(ceres1)
ROM_REGION32_LE(0x8000, "eprom", 0)
- ROM_SYSTEM_BIOS(0, "ceres1", "30.6.89")
+ ROM_SYSTEM_BIOS(0, "300689", "30.6.89")
ROMX_LOAD("by0_u44__30_6_89.u44", 0x0000, 0x2000, CRC(8e1559fe) SHA1(2e11c144fd698b9576816f5cfb003c46ab9ce43b), ROM_BIOS(0) | ROM_SKIP(3))
ROMX_LOAD("by1_u43__30_6_89.u43", 0x0001, 0x2000, CRC(18625b0c) SHA1(3319043507b7eeb488ecd839708032f968e6e53e), ROM_BIOS(0) | ROM_SKIP(3))
ROMX_LOAD("by2_u42__30_6_89.u42", 0x0002, 0x2000, CRC(a56497c5) SHA1(85858bea9fd27031ee0191b1d508c7469a384f10), ROM_BIOS(0) | ROM_SKIP(3))
ROMX_LOAD("by3_u41__30_6_89.u41", 0x0003, 0x2000, CRC(6b628912) SHA1(f76ea089e8bf82f572f27def344b5174e577ebbb), ROM_BIOS(0) | ROM_SKIP(3))
+
+ ROM_SYSTEM_BIOS(1, "231087", "CBUG-Ceres32 V231087 Release 3.2")
+ ROMX_LOAD("cbug32__by0__23_10_87.u44", 0x0000, 0x2000, CRC(177bab38) SHA1(ce8c9edbcd142b638a4e906b1d88b6770ac41702), ROM_BIOS(1) | ROM_SKIP(3))
+ ROMX_LOAD("cbug32__by1__23_10_87.u43", 0x0001, 0x2000, CRC(4ed51850) SHA1(66b2ee07c88bfa3adac1d75eab463e7f280220a3), ROM_BIOS(1) | ROM_SKIP(3))
+ ROMX_LOAD("cbug32__by2__23_10_87.u42", 0x0002, 0x2000, CRC(a05cdf91) SHA1(509b97bfb9e4631a3c6e9af27458d1099903a0ff), ROM_BIOS(1) | ROM_SKIP(3))
+ ROMX_LOAD("cbug32__by3__23_10_87.u41", 0x0003, 0x2000, CRC(7e3fd512) SHA1(77a9590490f8fd2212b79cd6c4f81b8f46d6b486), ROM_BIOS(1) | ROM_SKIP(3))
ROM_END
+}
+
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
COMP(1986, ceres1, 0, 0, ceres1, ceres1, ceres1_state, empty_init, "Eidgenössische Technische Hochschule Zürich", "Ceres-1", MACHINE_NOT_WORKING)