(nw) amust : random musings

This commit is contained in:
Robbbert 2018-09-08 12:26:16 +10:00
parent 33e96886bd
commit 4297917206

View File

@ -1,17 +1,22 @@
// license:BSD-3-Clause // license:BSD-3-Clause
// copyright-holders:Robbbert // copyright-holders:Robbbert
/*************************************************************************** /*****************************************************************************************
Amust Compak - also known as Amust Executive 816. Amust Compak - also known as Amust Executive 816.
2014-03-21 Skeleton driver. [Robbbert] 2014-03-21 Skeleton driver. [Robbbert]
An unusual-looking CP/M computer. An unusual-looking CP/M computer. The screen is a tiny CRT not much bigger
than a modern smartphone.
Z-80A @ 4MHz; 64KB dynamic RAM (8x 4164); 2KB video ram (6116); 2x 13cm drives;
80 track DD with data capacity of 790KB; in a lockable Samsonite briefcase.
There are no manuals or schematics known to exist. There are no manuals or schematics known to exist.
The entire driver is guesswork. The entire driver is guesswork.
The board has LH0080 (Z80A), 2x 8251, 2x 8255, 8253, uPD765A and a HD46505SP-2. The board has LH0080 (Z80A), 2x 8251, 2x 8255, 8253, uPD765A and a HD46505SP-2.
The videoram is a 6116 RAM. There is a piezo beeper. There are 3 crystals, There is a piezo beeper. There are 3 crystals, X1 = 4.9152 (serial chips),
X1 = 4.9152 (serial chips?), X2 = 16 (CPU), X3 = 14.31818 MHz (Video?). X2 = 16 (CPU), X3 = 14.31818 MHz (Video).
There are numerous jumpers, all of which perform unknown functions. There are numerous jumpers, all of which perform unknown functions.
The keyboard is a plug-in unit, same idea as Kaypro and Zorba. It has these The keyboard is a plug-in unit, same idea as Kaypro and Zorba. It has these
@ -50,21 +55,6 @@ Two Side
Skew 1,3,5,2,4 Skew 1,3,5,2,4
Stuff that doesn't make sense:
------------------------------
1. To access the screen, it waits for IRQ presumably from sync pulse. It sets INT
mode 0 which means a page-zero jump, but doesn't write anything to the zero-page ram.
That's why I added a RETI at 0038 and set the vector to there. A bit later it writes
a jump at 0000. Then it sets the interrupting device to the fdc (not sure how yet),
then proceeds to overwrite all of page-zero with the disk contents. This of course
kills the jump it just wrote, and my RETI. So it runs into the weeds at high speed.
What should happen is after loading the boot sector succesfully it will jump to 0000,
otherwise it will write BOOT NG to the screen and you're in the monitor. The bios
contains no RETI instructions.
2. At F824 it copies itself to the same address which is presumably shadow ram. But
it never switches to it. The ram is physically in the machine.
Monitor Commands: Monitor Commands:
----------------- -----------------
B = Boot from floppy B = Boot from floppy
@ -73,12 +63,17 @@ B = Boot from floppy
ToDo: ToDo:
- Everything - Everything
- Need software - Floppy issues:
- Keyboard controller needs to be emulated - The loop to read a sector has no escape. The interrupt handler (which can't be found)
needs to take another path when the sector is complete.
- The loop uses "ini" to read a byte, but this doesn't clear DRQ, so memory rapidly fills
up with garbage, mostly FF.
- Keyboard controller needs to be emulated.
- If booting straight to CP/M, the load message should be in the middle of the screen. - If booting straight to CP/M, the load message should be in the middle of the screen.
- Looks like port 5 has a row of function keys or similar. Need to be added.
****************************************************************************/ *******************************************************************************************/
#include "emu.h" #include "emu.h"
#include "cpu/z80/z80.h" #include "cpu/z80/z80.h"
@ -120,7 +115,6 @@ private:
TIMER_BEEP_OFF TIMER_BEEP_OFF
}; };
DECLARE_MACHINE_RESET(amust);
DECLARE_READ8_MEMBER(port04_r); DECLARE_READ8_MEMBER(port04_r);
DECLARE_WRITE8_MEMBER(port04_w); DECLARE_WRITE8_MEMBER(port04_w);
DECLARE_READ8_MEMBER(port05_r); DECLARE_READ8_MEMBER(port05_r);
@ -132,18 +126,28 @@ private:
DECLARE_READ8_MEMBER(port0a_r); DECLARE_READ8_MEMBER(port0a_r);
DECLARE_WRITE8_MEMBER(port0a_w); DECLARE_WRITE8_MEMBER(port0a_w);
DECLARE_WRITE8_MEMBER(port0d_w); DECLARE_WRITE8_MEMBER(port0d_w);
DECLARE_WRITE_LINE_MEMBER(hsync_w);
DECLARE_WRITE_LINE_MEMBER(vsync_w);
DECLARE_WRITE_LINE_MEMBER(drq_w);
DECLARE_WRITE_LINE_MEMBER(intrq_w);
void kbd_put(u8 data); void kbd_put(u8 data);
INTERRUPT_GEN_MEMBER(irq_vs);
MC6845_UPDATE_ROW(crtc_update_row); MC6845_UPDATE_ROW(crtc_update_row);
void io_map(address_map &map); void io_map(address_map &map);
void mem_map(address_map &map); void mem_map(address_map &map);
void machine_reset() override;
void do_int();
u8 m_port04; u8 m_port04;
u8 m_port06; u8 m_port06;
u8 m_port08; u8 m_port08;
u8 m_port09;
u8 m_port0a; u8 m_port0a;
u8 m_term_data; u8 m_term_data;
bool m_drq;
//bool m_intrq;
bool m_hsync;
bool m_vsync;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
required_device<palette_device> m_palette; required_device<palette_device> m_palette;
required_device<cpu_device> m_maincpu; required_device<cpu_device> m_maincpu;
@ -211,21 +215,60 @@ static void amust_floppies(device_slot_interface &device)
static INPUT_PORTS_START( amust ) static INPUT_PORTS_START( amust )
PORT_START("P9") PORT_START("P9")
// bits 6,7 not used? // bits 6,7 not used?
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) // code @ FB83 // bit 5 - fdc intrq
PORT_DIPNAME( 0x01, 0x01, "Bit0" ) // code @ FC99
PORT_DIPSETTING( 0x01, DEF_STR( On ) )
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPNAME( 0x02, 0x02, "Bit1" )
PORT_DIPSETTING( 0x02, DEF_STR( On ) )
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPNAME( 0x04, 0x04, "Bit2" )
PORT_DIPSETTING( 0x04, DEF_STR( On ) )
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPNAME( 0x08, 0x08, "Bit3" )
PORT_DIPSETTING( 0x08, DEF_STR( On ) )
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPNAME( 0x10, 0x10, "Boot to Monitor" ) // code @ F895 PORT_DIPNAME( 0x10, 0x10, "Boot to Monitor" ) // code @ F895
PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x10, DEF_STR( On ) ) PORT_DIPSETTING( 0x10, DEF_STR( On ) )
PORT_DIPNAME( 0x0f, 0x01, "Unknown" ) // code @ FC99
PORT_DIPSETTING( 0x01, "1" )
PORT_DIPSETTING( 0x02, "2" )
PORT_DIPSETTING( 0x04, "3" )
PORT_DIPSETTING( 0x08, "4" )
INPUT_PORTS_END INPUT_PORTS_END
// bodgy void amust_state::do_int()
INTERRUPT_GEN_MEMBER( amust_state::irq_vs )
{ {
m_maincpu->set_input_line_and_vector(INPUT_LINE_IRQ0, ASSERT_LINE, 0xff); bool sync = m_hsync | m_vsync;
if ((BIT(m_port0a, 3) && sync) // when writing to the screen, only do it during blanking
|| (BIT(m_port0a, 5) && m_drq)) // when reading from floppy, only do it when DRQ is high.
{
//printf("%X,%X,%X ",m_port0a,sync,m_drq);
m_maincpu->set_input_line_and_vector(INPUT_LINE_IRQ0, ASSERT_LINE, 0x00);
}
else
m_maincpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE);
}
WRITE_LINE_MEMBER( amust_state::drq_w )
{
m_drq = state;
do_int();
m_fdc->tc_w(1);
}
WRITE_LINE_MEMBER( amust_state::intrq_w )
{
m_port09 = (m_port09 & 0xdf) | (state ? 0x20 : 0);
}
WRITE_LINE_MEMBER( amust_state::hsync_w )
{
m_hsync = state;
do_int();
}
WRITE_LINE_MEMBER( amust_state::vsync_w )
{
m_vsync = state;
do_int();
} }
READ8_MEMBER( amust_state::port04_r ) READ8_MEMBER( amust_state::port04_r )
@ -271,14 +314,14 @@ d1 -
d2 - d2 -
d3 - d3 -
d4 - H = go to monitor; L = boot from disk d4 - H = go to monitor; L = boot from disk
d5 - status of disk-related; loops till NZ d5 - status of fdc intrq; loops till NZ
d6 - d6 -
d7 - d7 -
*/ */
READ8_MEMBER( amust_state::port09_r ) READ8_MEMBER( amust_state::port09_r )
{ {
logerror("%s\n",machine().describe_context()); logerror("%s\n",machine().describe_context());
return ioport("P9")->read(); return (ioport("P9")->read() & 0x1f) | m_port09;
} }
READ8_MEMBER( amust_state::port0a_r ) READ8_MEMBER( amust_state::port0a_r )
@ -302,6 +345,14 @@ WRITE8_MEMBER( amust_state::port0a_w )
m_beep->set_state(1); m_beep->set_state(1);
timer_set(attotime::from_msec(150), TIMER_BEEP_OFF); timer_set(attotime::from_msec(150), TIMER_BEEP_OFF);
} }
floppy_image_device *floppy = m_floppy0->get_device();
m_fdc->set_floppy(floppy);
if (floppy)
{
floppy->mon_w(0);
//floppy->ss_w(0); // side 0? hopefully fdc does this
}
} }
WRITE8_MEMBER( amust_state::port0d_w ) WRITE8_MEMBER( amust_state::port0d_w )
@ -357,17 +408,20 @@ MC6845_UPDATE_ROW( amust_state::crtc_update_row )
} }
} }
MACHINE_RESET_MEMBER( amust_state, amust ) void amust_state::machine_reset()
{ {
membank("bankr0")->set_entry(0); // point at rom membank("bankr0")->set_entry(0); // point at rom
membank("bankw0")->set_entry(0); // always write to ram membank("bankw0")->set_entry(0); // always write to ram
address_space &space = m_maincpu->space(AS_PROGRAM);
space.write_byte(0x38, 0xed);
space.write_byte(0x39, 0x4d);
m_port04 = 0; m_port04 = 0;
m_port06 = 0; m_port06 = 0;
m_port08 = 0; m_port08 = 0;
m_port09 = 0;
m_port0a = 0; m_port0a = 0;
m_hsync = false;
m_vsync = false;
m_drq = false;
m_fdc->set_ready_line_connected(1); // always ready for minifloppy; controlled by fdc for 20cm
m_fdc->set_unscaled_clock(4000000); // 4MHz for minifloppy; 8MHz for 20cm
m_maincpu->set_state_int(Z80_PC, 0xf800); m_maincpu->set_state_int(Z80_PC, 0xf800);
} }
@ -385,8 +439,6 @@ MACHINE_CONFIG_START(amust_state::amust)
MCFG_DEVICE_ADD("maincpu",Z80, XTAL(16'000'000) / 4) MCFG_DEVICE_ADD("maincpu",Z80, XTAL(16'000'000) / 4)
MCFG_DEVICE_PROGRAM_MAP(mem_map) MCFG_DEVICE_PROGRAM_MAP(mem_map)
MCFG_DEVICE_IO_MAP(io_map) MCFG_DEVICE_IO_MAP(io_map)
MCFG_DEVICE_VBLANK_INT_DRIVER("screen", amust_state, irq_vs)
MCFG_MACHINE_RESET_OVERRIDE(amust_state, amust)
/* video hardware */ /* video hardware */
MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::green()) MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::green())
@ -408,8 +460,12 @@ MACHINE_CONFIG_START(amust_state::amust)
MCFG_MC6845_SHOW_BORDER_AREA(false) MCFG_MC6845_SHOW_BORDER_AREA(false)
MCFG_MC6845_CHAR_WIDTH(8) MCFG_MC6845_CHAR_WIDTH(8)
MCFG_MC6845_UPDATE_ROW_CB(amust_state, crtc_update_row) MCFG_MC6845_UPDATE_ROW_CB(amust_state, crtc_update_row)
MCFG_MC6845_OUT_HSYNC_CB(WRITELINE(*this, amust_state, hsync_w))
MCFG_MC6845_OUT_VSYNC_CB(WRITELINE(*this, amust_state, vsync_w))
MCFG_UPD765A_ADD("fdc", false, true) UPD765A(config, m_fdc, true, true);
m_fdc->drq_wr_callback().set(FUNC(amust_state::drq_w));
m_fdc->intrq_wr_callback().set(FUNC(amust_state::intrq_w));
MCFG_FLOPPY_DRIVE_ADD("fdc:0", amust_floppies, "525qd", floppy_image_device::default_floppy_formats) MCFG_FLOPPY_DRIVE_ADD("fdc:0", amust_floppies, "525qd", floppy_image_device::default_floppy_formats)
MCFG_FLOPPY_DRIVE_SOUND(true) MCFG_FLOPPY_DRIVE_SOUND(true)
MCFG_FLOPPY_DRIVE_ADD("fdc:1", amust_floppies, "525qd", floppy_image_device::default_floppy_formats) MCFG_FLOPPY_DRIVE_ADD("fdc:1", amust_floppies, "525qd", floppy_image_device::default_floppy_formats)
@ -454,13 +510,13 @@ MACHINE_CONFIG_END
/* ROM definition */ /* ROM definition */
ROM_START( amust ) ROM_START( amust )
ROM_REGION( 0x11000, "maincpu", ROMREGION_ERASEFF ) ROM_REGION( 0x11000, "maincpu", ROMREGION_ERASEFF )
ROM_LOAD( "mon_h.rom", 0x10000, 0x1000, CRC(10dceac6) SHA1(1ef80039063f7a6455563d59f1bcc23e09eca369) ) ROM_LOAD( "mon_h.ic25", 0x10000, 0x1000, CRC(10dceac6) SHA1(1ef80039063f7a6455563d59f1bcc23e09eca369) )
ROM_REGION( 0x800, "chargen", 0 ) ROM_REGION( 0x800, "chargen", 0 )
ROM_LOAD( "cg4.rom", 0x000, 0x800, CRC(52e7b9d8) SHA1(cc6d457634eb688ccef471f72bddf0424e64b045) ) ROM_LOAD( "cg4.ic74", 0x000, 0x800, CRC(52e7b9d8) SHA1(cc6d457634eb688ccef471f72bddf0424e64b045) )
ROM_REGION( 0x800, "keyboard", 0 ) ROM_REGION( 0x800, "keyboard", 0 )
ROM_LOAD( "kbd_3.rom", 0x000, 0x800, CRC(d9441b35) SHA1(ce250ab1e892a13fd75182703f259855388c6bf4) ) ROM_LOAD( "kbd_3.rom", 0x000, 0x800, CRC(d9441b35) SHA1(ce250ab1e892a13fd75182703f259855388c6bf4) )
ROM_REGION( 0x800, "videoram", ROMREGION_ERASE00 ) ROM_REGION( 0x800, "videoram", ROMREGION_ERASE00 )
ROM_END ROM_END