mirror of
https://github.com/holub/mame
synced 2025-04-23 08:49:55 +03:00
(nw) sbrain : can boot from floppy, added keyboard, notes.
This commit is contained in:
parent
5c7b332c33
commit
89f6068745
@ -6,6 +6,8 @@ Intertec SuperBrain
|
||||
|
||||
2013-08-19 Skeleton
|
||||
|
||||
Intertec Compustar terminal appears to have identical hardware. Need roms for it.
|
||||
|
||||
Chips: 2x Z80; FD1791; 2x 8251; 8255; BR1941; CRT8002; KR3600; DP8350
|
||||
Xtals: 16.0, 10.92, 5.0688
|
||||
Disk parameters: 512 bytes x 10 sectors x 35 tracks. 1 and 2-sided disks supported.
|
||||
@ -18,20 +20,20 @@ The main cpu does a busreq to gain access to the sub cpu's 1k static ram. When t
|
||||
responds with busack, then the main cpu switches bank2. In emulation, it isn't actually
|
||||
necessary to stop the sub cpu because of other handshaking. Our Z80 emulation doesn't
|
||||
support the busack signal anyway, so we just assume it is granted immediately.
|
||||
When booted, the time (corrupted) is displayed at top right. You need to run TIME hh:mm:ss
|
||||
to set the time (TIME.COM must be on the disk).
|
||||
|
||||
The schematic in parts is difficult to read. Some assumptions have been made.
|
||||
|
||||
To Do:
|
||||
- Without a disk in, it should display a message to insert a disk. Doesn't happen.
|
||||
It thinks a disk is in and tries to execute garbage in the disk buffer instead.
|
||||
- Port 08 is largely a guess.
|
||||
- No work done on the keyboard. Should be able to hook up the generic ascii keyboard.
|
||||
- No software available to try.
|
||||
- Bug in floppy code means the motor will turn off after a few seconds. It should stay on.
|
||||
- Without a disk in, it should display a message to insert a disk. Doesn't happen. May
|
||||
attempt to execute empty memory instead. (-bios 1, -bios 2)
|
||||
- Improve keyboard.
|
||||
- Video chips need to be emulated (CRT8002 and DP8350), attributes etc.
|
||||
- After each line of characters, an interrupt should be generated. 25 IRQs per screen.
|
||||
- Hook the outputs of the baud rate generator to the uarts.
|
||||
- Probably lots of other stuff.
|
||||
- PC0 when high will swap out lower 16k of RAM for the DP8350 device. The value of HL (the
|
||||
"memory" address) is the data (cursor location, top of screen, etc). The byte "written"
|
||||
to this address (d0,d1) is the command for the CRTC.
|
||||
|
||||
*************************************************************************************************************/
|
||||
|
||||
@ -42,6 +44,7 @@ To Do:
|
||||
#include "machine/i8251.h"
|
||||
#include "machine/i8255.h"
|
||||
#include "machine/wd_fdc.h"
|
||||
#include "machine/timer.h"
|
||||
#include "sound/beep.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
@ -68,6 +71,7 @@ public:
|
||||
, m_bankr0(*this, "bankr0")
|
||||
, m_bankw0(*this, "bankw0")
|
||||
, m_bank2(*this, "bank2")
|
||||
, m_keyboard(*this, "X%u", 0)
|
||||
{}
|
||||
|
||||
DECLARE_DRIVER_INIT(sbrain);
|
||||
@ -78,21 +82,26 @@ public:
|
||||
DECLARE_WRITE8_MEMBER(ppi_pb_w);
|
||||
DECLARE_READ8_MEMBER(ppi_pc_r);
|
||||
DECLARE_WRITE8_MEMBER(ppi_pc_w);
|
||||
DECLARE_READ8_MEMBER(port08_r);
|
||||
DECLARE_WRITE8_MEMBER(port08_w);
|
||||
DECLARE_READ8_MEMBER(port48_r);
|
||||
DECLARE_READ8_MEMBER(port50_r);
|
||||
DECLARE_READ8_MEMBER(port10_r);
|
||||
DECLARE_WRITE8_MEMBER(port10_w);
|
||||
DECLARE_WRITE8_MEMBER(baud_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(fr_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(ft_w);
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(kbd_scan);
|
||||
|
||||
private:
|
||||
uint8_t m_porta;
|
||||
uint8_t m_portb;
|
||||
uint8_t m_portc;
|
||||
uint8_t m_port08;
|
||||
bool m_busak;
|
||||
u8 m_keydown;
|
||||
u8 m_porta;
|
||||
u8 m_portb;
|
||||
u8 m_portc;
|
||||
u8 m_port10;
|
||||
u8 m_term_data;
|
||||
u8 m_framecnt;
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<cpu_device> m_subcpu;
|
||||
required_shared_ptr<uint8_t> m_p_videoram;
|
||||
required_shared_ptr<u8> m_p_videoram;
|
||||
required_region_ptr<u8> m_p_chargen;
|
||||
required_device<beep_device> m_beep;
|
||||
required_device<com8116_device> m_brg;
|
||||
@ -106,6 +115,7 @@ private:
|
||||
required_memory_bank m_bankr0;
|
||||
required_memory_bank m_bankw0;
|
||||
required_memory_bank m_bank2;
|
||||
required_ioport_array<10> m_keyboard;
|
||||
};
|
||||
|
||||
static ADDRESS_MAP_START( sbrain_mem, AS_PROGRAM, 8, sbrain_state )
|
||||
@ -120,8 +130,8 @@ static ADDRESS_MAP_START( sbrain_io, AS_IO, 8, sbrain_state )
|
||||
ADDRESS_MAP_GLOBAL_MASK(0xff)
|
||||
AM_RANGE(0x40, 0x40) AM_MIRROR(6) AM_DEVREADWRITE("uart0", i8251_device, data_r, data_w)
|
||||
AM_RANGE(0x41, 0x41) AM_MIRROR(6) AM_DEVREADWRITE("uart0", i8251_device, status_r, control_w)
|
||||
//AM_RANGE(0x48, 0x4f) chr_int_latch
|
||||
//AM_RANGE(0x50, 0x57) key_in
|
||||
AM_RANGE(0x48, 0x4f) AM_READ(port48_r) //chr_int_latch
|
||||
AM_RANGE(0x50, 0x57) AM_READ(port50_r)
|
||||
AM_RANGE(0x58, 0x58) AM_MIRROR(6) AM_DEVREADWRITE("uart1", i8251_device, data_r, data_w)
|
||||
AM_RANGE(0x59, 0x59) AM_MIRROR(6) AM_DEVREADWRITE("uart1", i8251_device, status_r, control_w)
|
||||
AM_RANGE(0x60, 0x67) AM_WRITE(baud_w)
|
||||
@ -135,18 +145,29 @@ ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START( sbrain_subio, AS_IO, 8, sbrain_state )
|
||||
ADDRESS_MAP_GLOBAL_MASK(0xff)
|
||||
AM_RANGE(0x08, 0x08) AM_READWRITE(port08_r,port08_w)
|
||||
AM_RANGE(0x10, 0x13) AM_DEVREADWRITE("fdc", fd1791_device, read, write)
|
||||
AM_RANGE(0x08, 0x0b) AM_DEVREADWRITE("fdc", fd1791_device, read, write)
|
||||
AM_RANGE(0x10, 0x10) AM_READWRITE(port10_r,port10_w)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
// bit 0 is wrong, maybe the whole byte is wrong
|
||||
READ8_MEMBER( sbrain_state::port08_r )
|
||||
|
||||
READ8_MEMBER( sbrain_state::port48_r )
|
||||
{
|
||||
return m_port08;
|
||||
m_maincpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE);
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
READ8_MEMBER( sbrain_state::port50_r )
|
||||
{
|
||||
return m_term_data;
|
||||
}
|
||||
|
||||
READ8_MEMBER( sbrain_state::port10_r )
|
||||
{
|
||||
return m_port10;
|
||||
}
|
||||
|
||||
/* Misc disk functions
|
||||
d0 : disk busy?
|
||||
d0 : ?
|
||||
d1 : SEL A (drive 0?)
|
||||
d2 : SEL B (drive 1?)
|
||||
d3 : SEL C
|
||||
@ -154,34 +175,23 @@ d4 : SEL D
|
||||
d5 : side select
|
||||
d6,7 : not used
|
||||
*/
|
||||
WRITE8_MEMBER( sbrain_state::port08_w )
|
||||
WRITE8_MEMBER( sbrain_state::port10_w )
|
||||
{
|
||||
m_port08 = data | 0xc0;
|
||||
m_port10 = data | 0xc0;
|
||||
|
||||
floppy_image_device *floppy = nullptr;
|
||||
if (BIT(m_port08, 1)) floppy = m_floppy0->get_device();
|
||||
if (BIT(m_port08, 2)) floppy = m_floppy1->get_device();
|
||||
if (BIT(m_port10, 1)) floppy = m_floppy0->get_device();
|
||||
if (BIT(m_port10, 2)) floppy = m_floppy1->get_device();
|
||||
|
||||
m_fdc->set_floppy(floppy);
|
||||
|
||||
if (floppy)
|
||||
{
|
||||
floppy->ss_w(BIT(m_port08, 5)); // might need inverting
|
||||
}
|
||||
floppy->ss_w(BIT(m_port10, 5));
|
||||
|
||||
// refresh motor on, hopefully this will keep them turning
|
||||
m_floppy0->get_device()->mon_w(0); // motors run all the time
|
||||
m_floppy1->get_device()->mon_w(0);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( sbrain_state::fr_w )
|
||||
{
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( sbrain_state::ft_w )
|
||||
{
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( sbrain_state::baud_w )
|
||||
{
|
||||
m_brg->str_w(data & 0x0f);
|
||||
@ -212,13 +222,17 @@ d1 : key held down
|
||||
d2 : Vert Blank
|
||||
d3 : not used
|
||||
d4 : /capslock
|
||||
d5 : disk is busy
|
||||
d5 : ?
|
||||
d6 : Ring Indicator line from main rs232 port, 1=normal, 0=set
|
||||
d7 : cpu2 /busak line
|
||||
*/
|
||||
READ8_MEMBER( sbrain_state::ppi_pb_r )
|
||||
{
|
||||
return m_portb | 0x50 | m_vs->read() | (BIT(m_port08, 0) << 5) | ((uint8_t)BIT(m_portc, 5) << 7);
|
||||
u8 vertsync = m_vs->read(); // bit 2
|
||||
u8 capslock = BIT(ioport("MODIFIERS")->read(), 0) << 4; // bit 4, capslock
|
||||
u8 p10d0 = BIT(m_port10, 0) << 5; // bit 5
|
||||
u8 busak = m_busak ? 128 : 0; // bit 7
|
||||
return busak | p10d0 | capslock | vertsync | m_keydown;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( sbrain_state::ppi_pb_w )
|
||||
@ -247,20 +261,197 @@ WRITE8_MEMBER( sbrain_state::ppi_pc_w )
|
||||
m_beep->set_state(BIT(data, 6));
|
||||
m_bankr0->set_entry(BIT(data, 2));
|
||||
m_bank2->set_entry(BIT(data, 4));
|
||||
if (!BIT(data, 7))
|
||||
m_keydown &= 2; // ack DR
|
||||
|
||||
m_subcpu->set_input_line(INPUT_LINE_RESET, BIT(data, 3) ? ASSERT_LINE : CLEAR_LINE);
|
||||
m_subcpu->set_input_line(Z80_INPUT_LINE_BUSRQ, BIT(data, 5) ? ASSERT_LINE : CLEAR_LINE); // ignored in z80.cpp
|
||||
m_busak = BIT(data, 5);
|
||||
}
|
||||
|
||||
u8 translate_table[3][10][8] = {
|
||||
// unshifted
|
||||
{
|
||||
{ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37 },
|
||||
{ 0x38, 0x39, 0x2e, 0x2c, 0x2d, 0x00, 0x00, 0x00 },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x09, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67 },
|
||||
{ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f },
|
||||
{ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77 },
|
||||
{ 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x7b, 0x03, 0x7f },
|
||||
{ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37 },
|
||||
{ 0x38, 0x39, 0x2d, 0x3d, 0x5c, 0x08, 0x0a, 0x0d },
|
||||
{ 0x1b, 0x00, 0x20, 0x3b, 0x27, 0x2c, 0x2e, 0x2f }
|
||||
},
|
||||
// shift
|
||||
{
|
||||
{ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37 },
|
||||
{ 0x38, 0x39, 0x2e, 0x2c, 0x2d, 0x00, 0x00, 0x00 },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x09, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47 },
|
||||
{ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f },
|
||||
{ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57 },
|
||||
{ 0x58, 0x59, 0x5a, 0x5d, 0x7c, 0x7d, 0x03, 0x7f },
|
||||
{ 0x29, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5e, 0x26 },
|
||||
{ 0x2a, 0x28, 0x5f, 0x2b, 0x7e, 0x08, 0x0a, 0x0d },
|
||||
{ 0x1b, 0x00, 0x20, 0x3a, 0x22, 0x3c, 0x3e, 0x3f }
|
||||
},
|
||||
// ctrl
|
||||
{
|
||||
{ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37 },
|
||||
{ 0x38, 0x39, 0x2e, 0x2c, 0x2d, 0x00, 0x00, 0x00 },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x09, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 },
|
||||
{ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
{ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
|
||||
{ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x03, 0x1f },
|
||||
{ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37 },
|
||||
{ 0x38, 0x39, 0x2d, 0x3d, 0x1e, 0x08, 0x0a, 0x0d },
|
||||
{ 0x1b, 0x00, 0x20, 0x3b, 0x27, 0x2c, 0x2e, 0x2f }
|
||||
}
|
||||
};
|
||||
|
||||
static INPUT_PORTS_START( sbrain )
|
||||
PORT_START("X0")
|
||||
PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Keypad 0") PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD))
|
||||
PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Keypad 1") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD))
|
||||
PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Keypad 2") PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD))
|
||||
PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Keypad 3") PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD))
|
||||
PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Keypad 4") PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD))
|
||||
PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Keypad 5") PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD))
|
||||
PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Keypad 6") PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD))
|
||||
PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Keypad 7") PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD))
|
||||
|
||||
PORT_START("X1")
|
||||
PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Keypad 8") PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD))
|
||||
PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Keypad 9") PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD))
|
||||
PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Keypad .") PORT_CODE(KEYCODE_DEL_PAD)
|
||||
PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Keypad ,") PORT_CODE(KEYCODE_ASTERISK)
|
||||
PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Keypad -") PORT_CODE(KEYCODE_MINUS_PAD)
|
||||
PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Insert") PORT_CODE(KEYCODE_ENTER_PAD)
|
||||
|
||||
PORT_START("X2")
|
||||
PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Left") PORT_CODE(KEYCODE_LEFT)
|
||||
PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Right") PORT_CODE(KEYCODE_RIGHT)
|
||||
PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Up") PORT_CODE(KEYCODE_UP)
|
||||
PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Down") PORT_CODE(KEYCODE_DOWN)
|
||||
|
||||
PORT_START("X3")
|
||||
PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9)
|
||||
PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A')
|
||||
PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B')
|
||||
PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C')
|
||||
PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D')
|
||||
PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E')
|
||||
PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F')
|
||||
PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G')
|
||||
|
||||
PORT_START("X4")
|
||||
PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H')
|
||||
PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I')
|
||||
PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J')
|
||||
PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K')
|
||||
PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L')
|
||||
PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M')
|
||||
PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N')
|
||||
PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O')
|
||||
|
||||
PORT_START("X5")
|
||||
PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P')
|
||||
PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q')
|
||||
PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R')
|
||||
PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S')
|
||||
PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T')
|
||||
PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U')
|
||||
PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V')
|
||||
PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W')
|
||||
|
||||
PORT_START("X6")
|
||||
PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X')
|
||||
PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y')
|
||||
PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z')
|
||||
PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("[ ]") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR(']')
|
||||
PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("\\ |") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|')
|
||||
PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("{ }") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('{') PORT_CHAR('}')
|
||||
PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Break") PORT_CODE(KEYCODE_END) PORT_CHAR(3)
|
||||
PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Delete") PORT_CODE(KEYCODE_DEL) PORT_CHAR(127)
|
||||
|
||||
PORT_START("X7")
|
||||
PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')')
|
||||
PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
|
||||
PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@')
|
||||
PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#')
|
||||
PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
|
||||
PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%')
|
||||
PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^')
|
||||
PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&')
|
||||
|
||||
PORT_START("X8")
|
||||
PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*')
|
||||
PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(')
|
||||
PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("- _") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_')
|
||||
PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("= +") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+')
|
||||
PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("\\ ~") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('\\') PORT_CHAR('~')
|
||||
PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Backspace") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8)
|
||||
PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Line Feed") PORT_CODE(KEYCODE_INSERT) PORT_CHAR(10)
|
||||
PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)
|
||||
|
||||
PORT_START("X9")
|
||||
PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Esc") PORT_CODE(KEYCODE_ESC)
|
||||
PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Here Is") PORT_CODE(KEYCODE_HOME)
|
||||
PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(32)
|
||||
PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("; :") PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':')
|
||||
PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("' \"") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('\"')
|
||||
PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(", <") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')
|
||||
PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(". >") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>')
|
||||
PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("/ ?") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?')
|
||||
|
||||
PORT_START("MODIFIERS")
|
||||
PORT_BIT(0x01,IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CapsLock") PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE
|
||||
PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
|
||||
PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_SHIFT_2)
|
||||
|
||||
/* vblank */
|
||||
PORT_START("VS")
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_CUSTOM) PORT_VBLANK("screen")
|
||||
INPUT_PORTS_END
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(sbrain_state::kbd_scan)
|
||||
{
|
||||
// m_keydown: d0 = 1 after key pressed, and is reset by pc7; d1 = 1 while a key is down.
|
||||
m_keydown &= 1;
|
||||
u8 i, j, keyin, mods = ioport("MODIFIERS")->read() & 6;
|
||||
u8 translate_set = 0;
|
||||
if (BIT(mods, 1))
|
||||
translate_set = 1;
|
||||
else
|
||||
if (BIT(mods, 2))
|
||||
translate_set = 2;
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
keyin = m_keyboard[i]->read();
|
||||
if (keyin)
|
||||
{
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
if (BIT(keyin, j))
|
||||
{
|
||||
u8 pressed = translate_table[translate_set][i][j];
|
||||
m_keydown = (m_term_data == pressed) ? (m_keydown | 2) : 3;
|
||||
m_term_data = pressed;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m_term_data = 0xff;
|
||||
}
|
||||
|
||||
DRIVER_INIT_MEMBER( sbrain_state, sbrain )
|
||||
{
|
||||
uint8_t *main = memregion("maincpu")->base();
|
||||
uint8_t *sub = memregion("subcpu")->base();
|
||||
u8 *main = memregion("maincpu")->base();
|
||||
u8 *sub = memregion("subcpu")->base();
|
||||
|
||||
m_bankr0->configure_entry(0, &main[0x0000]);
|
||||
m_bankr0->configure_entry(1, &sub[0x0000]);
|
||||
@ -275,16 +466,27 @@ SLOT_INTERFACE_END
|
||||
|
||||
MACHINE_RESET_MEMBER( sbrain_state, sbrain )
|
||||
{
|
||||
m_keydown = 0;
|
||||
m_bankr0->set_entry(1); // point at rom
|
||||
m_bankw0->set_entry(0); // always write to ram
|
||||
m_bank2->set_entry(1); // point at maincpu bank
|
||||
m_subcpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); // hold subcpu in reset
|
||||
}
|
||||
|
||||
uint32_t sbrain_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
u32 sbrain_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
uint8_t y,ra,chr,gfx;
|
||||
u8 y,ra,chr,gfx;
|
||||
uint16_t sy=0,ma=0,x;
|
||||
m_framecnt++;
|
||||
|
||||
// Where attributes come from:
|
||||
// - Most systems use ram for character-based attributes, but this one uses strictly hardware which would seem cumbersome
|
||||
// - d0,1 graphics from porta d0,d1
|
||||
// - d2 strike-through from porta d5
|
||||
// - d3 underline from porta d2
|
||||
// - d4 reverse-video from porta d7
|
||||
// - d5 blank from PC1 (scan-line based)
|
||||
// - d6 flash from bit 7 of each character
|
||||
|
||||
for (y = 0; y < 24; y++)
|
||||
{
|
||||
@ -299,8 +501,15 @@ uint32_t sbrain_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap
|
||||
{
|
||||
chr = m_p_videoram[x+ma];
|
||||
|
||||
if (chr) gfx = m_p_chargen[(chr<<4) | ra ];
|
||||
if (!BIT(chr, 7) || BIT(m_framecnt, 5))
|
||||
{
|
||||
chr &= 0x7f;
|
||||
|
||||
if (chr)
|
||||
gfx = m_p_chargen[(chr<<4) | ra ];
|
||||
}
|
||||
}
|
||||
|
||||
/* Display a scanline of a character */
|
||||
*p++ = BIT(gfx, 7);
|
||||
*p++ = BIT(gfx, 6);
|
||||
@ -322,11 +531,14 @@ static MACHINE_CONFIG_START( sbrain )
|
||||
MCFG_CPU_ADD("maincpu", Z80, XTAL_16MHz / 4)
|
||||
MCFG_CPU_PROGRAM_MAP(sbrain_mem)
|
||||
MCFG_CPU_IO_MAP(sbrain_io)
|
||||
MCFG_MACHINE_RESET_OVERRIDE(sbrain_state, sbrain)
|
||||
MCFG_CPU_VBLANK_INT_DRIVER("screen", sbrain_state, irq0_line_hold)
|
||||
|
||||
MCFG_CPU_ADD("subcpu", Z80, XTAL_16MHz / 4)
|
||||
MCFG_CPU_PROGRAM_MAP(sbrain_submem)
|
||||
MCFG_CPU_IO_MAP(sbrain_subio)
|
||||
|
||||
MCFG_MACHINE_RESET_OVERRIDE(sbrain_state, sbrain)
|
||||
|
||||
/* video hardware */
|
||||
MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::amber())
|
||||
MCFG_SCREEN_REFRESH_RATE(60)
|
||||
@ -356,21 +568,31 @@ static MACHINE_CONFIG_START( sbrain )
|
||||
|
||||
MCFG_DEVICE_ADD("uart1", I8251, 0)
|
||||
|
||||
MCFG_DEVICE_ADD("brg", COM8116, XTAL_5_0688MHz)
|
||||
MCFG_COM8116_FR_HANDLER(WRITELINE(sbrain_state, fr_w))
|
||||
MCFG_COM8116_FT_HANDLER(WRITELINE(sbrain_state, ft_w))
|
||||
MCFG_DEVICE_ADD("brg", COM8116, XTAL_5_0688MHz) // BR1941L
|
||||
MCFG_COM8116_FR_HANDLER(DEVWRITELINE("uart0", i8251_device, write_txc))
|
||||
MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("uart0", i8251_device, write_rxc))
|
||||
MCFG_COM8116_FT_HANDLER(DEVWRITELINE("uart1", i8251_device, write_txc))
|
||||
MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("uart1", i8251_device, write_rxc))
|
||||
|
||||
MCFG_FD1791_ADD("fdc", XTAL_16MHz / 16)
|
||||
MCFG_FLOPPY_DRIVE_ADD("fdc:0", sbrain_floppies, "525dd", floppy_image_device::default_floppy_formats)
|
||||
MCFG_FLOPPY_DRIVE_SOUND(true)
|
||||
MCFG_FLOPPY_DRIVE_ADD("fdc:1", sbrain_floppies, "525dd", floppy_image_device::default_floppy_formats)
|
||||
MCFG_FLOPPY_DRIVE_SOUND(true)
|
||||
|
||||
MCFG_TIMER_DRIVER_ADD_PERIODIC("timer_a", sbrain_state, kbd_scan, attotime::from_hz(15))
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
ROM_START( sbrain )
|
||||
ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF )
|
||||
|
||||
ROM_REGION( 0x10000, "subcpu", ROMREGION_ERASEFF )
|
||||
ROM_LOAD( "superbrain.bin", 0x0000, 0x0800, CRC(b6a2e6a5) SHA1(a646faaecb9ac45ee1a42764628e8971524d5c13) )
|
||||
|
||||
ROM_SYSTEM_BIOS( 0, "4_003", "4.003" )
|
||||
ROMX_LOAD( "4_003_vc8001.z69", 0x0000, 0x0800, CRC(3ce3cd53) SHA1(fb6ade6bd67de3d9f911a1a48481ca619bda65ae), ROM_BIOS(1) )
|
||||
ROM_SYSTEM_BIOS( 1, "3_1", "3.1" )
|
||||
ROMX_LOAD( "3_1.z69", 0x0000, 0x0800, CRC(b6a2e6a5) SHA1(a646faaecb9ac45ee1a42764628e8971524d5c13), ROM_BIOS(2) )
|
||||
ROM_SYSTEM_BIOS( 2, "3_05", "3.05" )
|
||||
ROMX_LOAD( "qd_3_05.z69", 0x0000, 0x0800, CRC(aedbe777) SHA1(9ee9ca3f05e11ceb80896f06c3a3ae352db214dc), ROM_BIOS(3) )
|
||||
// Using the chargen from 'c10' for now.
|
||||
ROM_REGION( 0x2000, "chargen", 0 )
|
||||
ROM_LOAD( "c10_char.bin", 0x0000, 0x2000, BAD_DUMP CRC(cb530b6f) SHA1(95590bbb433db9c4317f535723b29516b9b9fcbf))
|
||||
|
Loading…
Reference in New Issue
Block a user