nokia/mikromik: Allow model M7 to boot into self-test mode with hand-crafted MMU PROM, and start adding Winchester bits. [Curt Coder]

This commit is contained in:
Curt Coder 2024-05-01 19:06:58 +03:00
parent 81cfd3a3d4
commit 4352ebd18b
3 changed files with 110 additions and 116 deletions

View File

@ -57,8 +57,7 @@
TODO:
- accurate video timing
- floppy DRQ during RECALL = 0
- PCB layout
- PCB layouts
- NEC uPD7201 MPSC
- model M7 5MB hard disk
@ -66,7 +65,6 @@
#include "emu.h"
#include "mikromik.h"
#include "machine/74259.h"
#include "softlist_dev.h"
//#define VERBOSE 1
@ -147,17 +145,6 @@ void mm1_state::write(offs_t offset, uint8_t data)
}
//-------------------------------------------------
// a8_w -
//-------------------------------------------------
void mm1_state::a8_w(int state)
{
LOG("IC24 A8 %u\n", state);
m_a8 = state;
}
//-------------------------------------------------
// recall_w -
//-------------------------------------------------
@ -167,57 +154,11 @@ void mm1_state::recall_w(int state)
LOG("RECALL %u\n", state);
m_recall = state;
m_fdc->reset_w(state);
}
//-------------------------------------------------
// rx21_w -
//-------------------------------------------------
void mm1_state::rx21_w(int state)
{
m_rx21 = state;
}
//-------------------------------------------------
// tx21_w -
//-------------------------------------------------
void mm1_state::tx21_w(int state)
{
m_tx21 = state;
}
//-------------------------------------------------
// rcl_w -
//-------------------------------------------------
void mm1_state::rcl_w(int state)
{
m_rcl = state;
}
//-------------------------------------------------
// intc_w -
//-------------------------------------------------
void mm1_state::intc_w(int state)
{
m_intc = state;
}
//-------------------------------------------------
// llen_w -
//-------------------------------------------------
void mm1_state::llen_w(int state)
{
LOG("LLEN %u\n", state);
m_llen = state;
if (m_recall)
{
m_dmac->dreq3_w(false);
}
}
@ -238,6 +179,41 @@ void mm1_state::motor_on_w(int state)
}
//-------------------------------------------------
// switch_w -
//-------------------------------------------------
void mm1_state::switch_w(int state)
{
LOG("SWITCH %u\n", state);
m_switch = state;
if (m_switch)
{
// winchester
m_io->space().install_readwrite_handler(0x50, 0x50, read8sm_delegate(*this, FUNC(mm1_state::sasi_status_r)), write8sm_delegate(*this, FUNC(mm1_state::sasi_cmd_w)));
m_io->space().install_readwrite_handler(0x51, 0x51, emu::rw_delegate(*m_sasi, FUNC(nscsi_callback_device::read)), emu::rw_delegate(*m_sasi, FUNC(nscsi_callback_device::write)));
}
else
{
// floppy
m_io->space().install_device(0x50, 0x51, *m_fdc, &upd765a_device::map);
}
}
uint8_t mm1_state::sasi_status_r(offs_t offset)
{
LOG("SASI STATUS\n");
return 0xff;
}
void mm1_state::sasi_cmd_w(offs_t offset, uint8_t data)
{
LOG("SASI CMD %02x\n", data);
}
//**************************************************************************
// ADDRESS MAPS
@ -256,7 +232,7 @@ void mm1_state::mmu_io_map(address_map &map)
map(0x30, 0x33).mirror(0x0c).rw(m_pit, FUNC(pit8253_device::read), FUNC(pit8253_device::write));
map(0x40, 0x40).mirror(0x0f).rw(m_iop, FUNC(i8212_device::read), FUNC(i8212_device::write));
map(0x50, 0x51).mirror(0x0e).m(m_fdc, FUNC(upd765a_device::map));
map(0x60, 0x67).mirror(0x08).w("outlatch", FUNC(ls259_device::write_d0));
map(0x60, 0x67).mirror(0x08).w(m_outlatch, FUNC(ls259_device::write_d0));
}
void mm1_state::mm1g_mmu_io_map(address_map &map)
@ -401,12 +377,7 @@ void mm1_state::floppy_formats(format_registration &fr)
fr.add(FLOPPY_MM1_FORMAT);
}
static void mm1_floppies_320k(device_slot_interface &device)
{
device.option_add("525", FLOPPY_525_QD);
}
static void mm1_floppies_640k(device_slot_interface &device)
static void mm1m4_floppies(device_slot_interface &device)
{
device.option_add("525", FLOPPY_525_QD);
}
@ -423,13 +394,18 @@ static void mm1_floppies_640k(device_slot_interface &device)
void mm1_state::machine_start()
{
// register for state saving
save_item(NAME(m_llen));
// state saving
save_item(NAME(m_a8));
save_item(NAME(m_leen));
save_item(NAME(m_intc));
save_item(NAME(m_rx21));
save_item(NAME(m_tx21));
save_item(NAME(m_rcl));
save_item(NAME(m_recall));
save_item(NAME(m_dack3));
save_item(NAME(m_tc));
save_item(NAME(m_fdc_tc));
save_item(NAME(m_switch));
}
@ -458,15 +434,15 @@ void mm1_state::common(machine_config &config)
m_iop->int_wr_callback().set_inputline(m_maincpu, I8085_RST65_LINE);
m_iop->di_rd_callback().set(KB_TAG, FUNC(mm1_keyboard_device::read));
ls259_device &outlatch(LS259(config, "outlatch"));
outlatch.q_out_cb<0>().set(FUNC(mm1_state::a8_w)); // IC24 A8
outlatch.q_out_cb<1>().set(FUNC(mm1_state::recall_w)); // RECALL
outlatch.q_out_cb<2>().set(FUNC(mm1_state::rx21_w)); // _RV28/RX21
outlatch.q_out_cb<3>().set(FUNC(mm1_state::tx21_w)); // _TX21
outlatch.q_out_cb<4>().set(FUNC(mm1_state::rcl_w)); // _RCL
outlatch.q_out_cb<5>().set(FUNC(mm1_state::intc_w)); // _INTC
outlatch.q_out_cb<6>().set(FUNC(mm1_state::llen_w)); // LLEN
outlatch.q_out_cb<7>().set(FUNC(mm1_state::motor_on_w)); // MOTOR ON
LS259(config, m_outlatch);
m_outlatch->q_out_cb<0>().set(FUNC(mm1_state::a8_w)); // IC24 A8
m_outlatch->q_out_cb<1>().set(FUNC(mm1_state::recall_w)); // RECALL
m_outlatch->q_out_cb<2>().set(FUNC(mm1_state::rx21_w)); // _RV28/RX21
m_outlatch->q_out_cb<3>().set(FUNC(mm1_state::tx21_w)); // _TX21
m_outlatch->q_out_cb<4>().set(FUNC(mm1_state::rcl_w)); // _RCL
m_outlatch->q_out_cb<5>().set(FUNC(mm1_state::intc_w)); // _INTC
m_outlatch->q_out_cb<6>().set(FUNC(mm1_state::leen_w)); // LEEN
m_outlatch->q_out_cb<7>().set(FUNC(mm1_state::motor_on_w)); // MOTOR ON
AM9517A(config, m_dmac, 6.144_MHz_XTAL/2);
m_dmac->out_hreq_callback().set(FUNC(mm1_state::dma_hrq_w));
@ -531,8 +507,8 @@ void mm1_state::mm1g(machine_config &config)
void mm1_state::mm1_320k_dual(machine_config &config)
{
FLOPPY_CONNECTOR(config, UPD765_TAG ":0", mm1_floppies_320k, "525", mm1_state::floppy_formats).enable_sound(true);
FLOPPY_CONNECTOR(config, UPD765_TAG ":1", mm1_floppies_320k, "525", mm1_state::floppy_formats).enable_sound(true);
FLOPPY_CONNECTOR(config, UPD765_TAG ":0", mm1m4_floppies, "525", mm1_state::floppy_formats).enable_sound(true);
FLOPPY_CONNECTOR(config, UPD765_TAG ":1", mm1m4_floppies, "525", mm1_state::floppy_formats).enable_sound(true);
}
void mm1_state::mm1m4(machine_config &config)
@ -549,8 +525,8 @@ void mm1_state::mm1m4g(machine_config &config)
void mm1_state::mm1_640k_dual(machine_config &config)
{
FLOPPY_CONNECTOR(config, UPD765_TAG ":0", mm1_floppies_640k, "525", mm1_state::floppy_formats).enable_sound(true);
FLOPPY_CONNECTOR(config, UPD765_TAG ":1", mm1_floppies_640k, "525", mm1_state::floppy_formats).enable_sound(true);
FLOPPY_CONNECTOR(config, UPD765_TAG ":0", mm1m4_floppies, "525", mm1_state::floppy_formats).enable_sound(true);
FLOPPY_CONNECTOR(config, UPD765_TAG ":1", mm1m4_floppies, "525", mm1_state::floppy_formats).enable_sound(true);
}
void mm1_state::mm1m6(machine_config &config)
@ -565,25 +541,28 @@ void mm1_state::mm1m6g(machine_config &config)
mm1_640k_dual(config);
}
void mm1_state::mm1_640k(machine_config &config)
void mm1_state::mm1_640k_winchester(machine_config &config)
{
FLOPPY_CONNECTOR(config, UPD765_TAG ":0", mm1_floppies_640k, "525", mm1_state::floppy_formats).enable_sound(true);
FLOPPY_CONNECTOR(config, UPD765_TAG ":0", mm1m4_floppies, "525", mm1_state::floppy_formats).enable_sound(true);
NSCSI_BUS(config, "sasi");
NSCSI_CONNECTOR(config, "sasi:0", default_scsi_devices, "s1410");
NSCSI_CONNECTOR(config, "sasi:7", default_scsi_devices, "scsicb", true)
.option_add_internal("scsicb", NSCSI_CB);
m_outlatch->q_out_cb<7>().set(FUNC(mm1_state::switch_w));
}
void mm1_state::mm1m7(machine_config &config)
{
mm1(config);
mm1_640k(config);
// TODO hard disk
mm1_640k_winchester(config);
}
void mm1_state::mm1m7g(machine_config &config)
{
mm1g(config);
mm1_640k(config);
// TODO hard disk
mm1_640k_winchester(config);
}
@ -637,7 +616,7 @@ ROM_START( mm1m7 )
ROM_LOAD( "9057c.ic2", 0x0000, 0x2000, CRC(89bbc042) SHA1(7e8800c94934b81ce08b7af862e1159e0517684d) )
ROM_REGION( 0x200, "address", 0 ) // address decoder
ROM_LOAD( "720793a.ic24", 0x0000, 0x0200, CRC(deea87a6) SHA1(8f19e43252c9a0b1befd02fc9d34fe1437477f3a) )
ROM_LOAD( "726972b.ic24", 0x0000, 0x0200, BAD_DUMP CRC(2487d4ca) SHA1(e883a2e9540c31abba3d7f3bc23a48941f655ea0) )
ROM_REGION( 0x1000, "chargen", 0 ) // character generator
ROM_LOAD( "6807b.ic61", 0x0000, 0x1000, CRC(32b36220) SHA1(8fe7a181badea3f7e656dfaea21ee9e4c9baf0f1) )

View File

@ -5,13 +5,19 @@
#pragma once
#include "mm1kb.h"
#include "bus/nscsi/devices.h"
#include "bus/scsi/scsihd.h"
#include "bus/scsi/s1410.h"
#include "bus/rs232/rs232.h"
#include "cpu/i8085/i8085.h"
#include "imagedev/floppy.h"
#include "machine/74259.h"
#include "machine/am9517a.h"
#include "machine/bankdev.h"
#include "machine/i8212.h"
#include "mm1kb.h"
#include "machine/nscsi_bus.h"
#include "machine/nscsi_cb.h"
#include "machine/pit8253.h"
#include "machine/ram.h"
#include "machine/upd765.h"
@ -32,6 +38,7 @@
#define I8275_TAG "ic59"
#define UPD7201_TAG "ic11"
#define UPD7220_TAG "ic101"
#define LS249_TAG "ic48"
#define RS232_A_TAG "rs232a"
#define RS232_B_TAG "rs232b"
#define RS232_C_TAG "rs232c"
@ -51,8 +58,10 @@ public:
m_fdc(*this, UPD765_TAG),
m_mpsc(*this, UPD7201_TAG),
m_hgdc(*this, UPD7220_TAG),
m_outlatch(*this, LS249_TAG),
m_palette(*this, "palette"),
m_floppy(*this, UPD765_TAG ":%u:525", 0U),
m_sasi(*this, "sasi:7:scsicb"),
m_rs232a(*this, RS232_A_TAG),
m_rs232b(*this, RS232_B_TAG),
m_rs232c(*this, RS232_C_TAG),
@ -78,7 +87,7 @@ public:
void mm1m7(machine_config &config);
void mm1m7g(machine_config &config);
void mm1_320k_dual(machine_config &config);
void mm1_640k(machine_config &config);
void mm1_640k_winchester(machine_config &config);
void mm1_640k_dual(machine_config &config);
void mm1_video(machine_config &config);
void mm1g_video(machine_config &config);
@ -96,8 +105,10 @@ private:
required_device<upd765a_device> m_fdc;
required_device<upd7201_device> m_mpsc;
optional_device<upd7220_device> m_hgdc;
optional_device<ls259_device> m_outlatch;
required_device<palette_device> m_palette;
optional_device_array<floppy_image_device, 2> m_floppy;
optional_device<nscsi_callback_device> m_sasi;
required_device<rs232_port_device> m_rs232a;
required_device<rs232_port_device> m_rs232b;
required_device<rs232_port_device> m_rs232c;
@ -107,35 +118,39 @@ private:
required_memory_region m_char_rom;
optional_shared_ptr<uint16_t> m_video_ram;
int m_a8;
bool m_a8;
// video state
int m_llen = 0;
bool m_leen = 0;
// serial state
int m_intc = 0;
int m_rx21 = 0;
int m_tx21 = 0;
int m_rcl = 0;
bool m_intc = 0;
bool m_rx21 = 0;
bool m_tx21 = 0;
bool m_rcl = 0;
// floppy state
int m_recall;
int m_dack3;
int m_tc;
int m_fdc_tc;
bool m_recall;
bool m_dack3;
bool m_tc;
bool m_fdc_tc;
bool m_switch;
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
uint8_t read(offs_t offset);
void write(offs_t offset, uint8_t data);
void a8_w(int state);
void a8_w(int state) { m_a8 = state; }
void recall_w(int state);
void rx21_w(int state);
void tx21_w(int state);
void rcl_w(int state);
void intc_w(int state);
void llen_w(int state);
void rx21_w(int state) { m_rx21 = state; }
void tx21_w(int state) { m_tx21 = state; }
void rcl_w(int state) { m_rcl = state; }
void intc_w(int state) { m_intc = state; }
void leen_w(int state) { m_leen = state; }
void motor_on_w(int state);
void switch_w(int state);
uint8_t sasi_status_r(offs_t offset);
void sasi_cmd_w(offs_t offset, uint8_t data);
void dma_hrq_w(int state);
uint8_t mpsc_dack_r();
void mpsc_dack_w(uint8_t data);

View File

@ -18,7 +18,7 @@ I8275_DRAW_CHARACTER_MEMBER( mm1_state::crtc_display_pixels )
bool vsp = BIT(attrcode, VSP);
bool lten = BIT(attrcode, LTEN);
bool gpa0 = BIT(attrcode, GPA0); // general purpose attribute 0
int llen = m_llen; // light enable
int leen = m_leen; // light enable
bool compl_in = BIT(attrcode, RVV); // reverse video
bool hlt_in = BIT(attrcode, HLGT); // highlight
int color; // 0 = black, 1 = dk green, 2 = lt green; on MikroMikko 1, "highlight" is actually the darker shade of green
@ -40,7 +40,7 @@ I8275_DRAW_CHARACTER_MEMBER( mm1_state::crtc_display_pixels )
// Step 3: Fill in missing 2 pixels in the screen bitmap by repeating last column of the char bitmap
// (works better with MikroMikko 1 font than duplicating the first and the last column)
int qh = d7 & d6; // extend pixels on the right side only if there were two adjacent ones before shifting out the MSB
int video_in = ((((d7 & llen) | (vsp ? 0 : 1)) & (gpa0 ? 0 : 1)) & qh) | lten;
int video_in = ((((d7 & leen) | (vsp ? 0 : 1)) & (gpa0 ? 0 : 1)) & qh) | lten;
color = (hlt_in ? 1 : 2) * (video_in ^ compl_in);
bitmap.pix(y, x + 8) = m_palette->pen(color);
bitmap.pix(y, x + 9) = m_palette->pen(color);
@ -49,7 +49,7 @@ I8275_DRAW_CHARACTER_MEMBER( mm1_state::crtc_display_pixels )
for (int i = 0; i < 8; ++i) // ...and now the actual character bitmap bits for this scanline
{
int qh = BIT(data, i);
int video_in = ((((d7 & llen) | (vsp ? 0 : 1)) & (gpa0 ? 0 : 1)) & qh) | lten;
int video_in = ((((d7 & leen) | (vsp ? 0 : 1)) & (gpa0 ? 0 : 1)) & qh) | lten;
color = (hlt_in ? 1 : 2)*(video_in ^ compl_in);
bitmap.pix(y, x + i) = m_palette->pen(color);
}