abc806: Fixed memory banking allowing CP/M to boot. [Curt Coder]

This commit is contained in:
Curt Coder 2018-05-16 13:53:58 +03:00
parent 3dc30bab10
commit 8e796a2075
6 changed files with 180 additions and 197 deletions

View File

@ -14,20 +14,20 @@
</part>
</software>
<software name="cpm30" supported="no">
<description>CP/M Plus v3.0 - MYAB BIOS v0.9</description>
<software name="cpm30">
<description>CP/M Plus v3.0 (v0.9)</description>
<year>198?</year>
<publisher>&lt;unknown&gt;</publisher>
<part name="flop" interface="floppy_5_25">
<dataarea name="flop" size="297216">
<rom name="cpm30.td0" size="297216" crc="ccf77a0c" sha1="2563cc8c93c101f616f39620b3d7759a5062f97b" offset="0" />
<rom name="cpm30.td0" size="297216" crc="ccf77a0c" sha1="2563cc8c93c101f616f39620b3d7759a5062f97b" offset="0" status="baddump" />
</dataarea>
</part>
</software>
<software name="cpmplus3" supported="no">
<description>CP/M Plus v3.0</description>
<software name="cpm30_12" cloneof="cpm30">
<description>CP/M Plus v3.0 (v1.2)</description>
<year>198?</year>
<publisher>&lt;unknown&gt;</publisher>

View File

@ -150,6 +150,8 @@ Notes:
#include "emu.h"
#include "includes/abc80x.h"
#define LOG 0
//**************************************************************************
// SOUND
@ -204,11 +206,6 @@ void abc800_state::bankswitch()
}
}
//-------------------------------------------------
// bankswitch
//-------------------------------------------------
void abc802_state::bankswitch()
{
address_space &program = m_maincpu->space(AS_PROGRAM);
@ -226,138 +223,143 @@ void abc802_state::bankswitch()
}
}
//-------------------------------------------------
// bankswitch
//-------------------------------------------------
void abc806_state::bankswitch()
void abc806_state::read_pal_p4(offs_t offset, bool m1l, bool xml, offs_t &m, bool &romd, bool &ramd, bool &hre, bool &vr)
{
address_space &program = m_maincpu->space(AS_PROGRAM);
uint32_t videoram_mask = m_ram->size() - 0x8000 - 1;
int bank;
char bank_name[10];
uint8_t map = m_map[offset >> 12] ^ 0xff;
bool enl = BIT(map, 7);
if (!m_keydtr)
/*
uint16_t input = 1 << 14 | m_keydtr << 12 | xml << 9 | enl << 8 | m_eme << 7 | m1l << 6 | BIT(offset, 11) << 5 | BIT(offset, 12) << 4 | BIT(offset, 13) << 3 | BIT(offset, 14) << 2 | BIT(offset, 15) << 1 | 1;
int palout = m_pal->read(input);
romd = BIT(palout, 0);
ramd = BIT(palout, 7);
hre = BIT(palout, 4);
bool mux = BIT(palout, 6);
*/
romd = offset >= 0x8000;
ramd = offset < 0x8000;
hre = 0;
vr = (offset & 0xf800) != 0x7800;
bool mux = 0;
if (!m_keydtr && offset < 0x8000)
{
// 32K block mapping
uint32_t videoram_start = (m_hrs & 0xf0) << 11;
for (bank = 1; bank <= 8; bank++)
{
// 0x0000-0x7FFF is video RAM
uint16_t start_addr = 0x1000 * (bank - 1);
uint16_t end_addr = start_addr + 0xfff;
uint32_t videoram_offset = (videoram_start + start_addr) & videoram_mask;
sprintf(bank_name,"bank%d",bank);
//logerror("%04x-%04x: Video RAM %04x (32K)\n", start_addr, end_addr, videoram_offset);
program.install_readwrite_bank(start_addr, end_addr, bank_name);
membank(bank_name)->configure_entry(1, m_video_ram + videoram_offset);
membank(bank_name)->set_entry(1);
}
for (bank = 9; bank <= 16; bank++)
{
// 0x8000-0xFFFF is main RAM
uint16_t start_addr = 0x1000 * (bank - 1);
uint16_t end_addr = start_addr + 0xfff;
sprintf(bank_name,"bank%d",bank);
//logerror("%04x-%04x: Work RAM (32K)\n", start_addr, end_addr);
program.install_readwrite_bank(start_addr, end_addr, bank_name);
membank(bank_name)->set_entry(0);
}
}
else
{
// 4K block mapping
for (bank = 1; bank <= 16; bank++)
{
uint16_t start_addr = 0x1000 * (bank - 1);
uint16_t end_addr = start_addr + 0xfff;
uint8_t map = m_map[bank - 1];
uint32_t videoram_offset = ((map & 0x7f) << 12) & videoram_mask;
sprintf(bank_name,"bank%d",bank);
if (BIT(map, 7) && m_eme)
{
// map to video RAM
//logerror("%04x-%04x: Video RAM %04x (4K)\n", start_addr, end_addr, videoram_offset);
program.install_readwrite_bank(start_addr, end_addr, bank_name);
membank(bank_name)->configure_entry(1, m_video_ram + videoram_offset);
membank(bank_name)->set_entry(1);
}
else
{
// map to ROM/RAM
switch (bank)
{
case 1: case 2: case 3: case 4: case 5: case 6: case 7:
// ROM
//logerror("%04x-%04x: ROM (4K)\n", start_addr, end_addr);
program.install_read_bank(start_addr, end_addr, bank_name);
program.unmap_write(start_addr, end_addr);
membank(bank_name)->set_entry(0);
break;
case 8:
// ROM/char RAM
//logerror("%04x-%04x: ROM (4K)\n", start_addr, end_addr);
program.install_read_bank(0x7000, 0x77ff, bank_name);
program.unmap_write(0x7000, 0x77ff);
program.install_readwrite_handler(0x7800, 0x7fff, READ8_DELEGATE(abc806_state, charram_r), WRITE8_DELEGATE(abc806_state, charram_w));
membank(bank_name)->set_entry(0);
break;
default:
// work RAM
//logerror("%04x-%04x: Work RAM (4K)\n", start_addr, end_addr);
program.install_readwrite_bank(start_addr, end_addr, bank_name);
membank(bank_name)->set_entry(0);
break;
}
}
}
romd = 1;
hre = 1;
vr = 1;
mux = 0;
}
if (m_fetch_charram)
if (m_eme && !enl)
{
// 30K block mapping
romd = 1;
ramd = 1;
hre = 1;
vr = 1;
mux = 1;
}
uint32_t videoram_start = (m_hrs & 0xf0) << 11;
if (!m1l)
{
vr = 1;
}
/*
if (!m1l && (offset < 0x7800)
{
TODO 0..30k read from videoram if fetch opcode from 7800-7fff
romd = 1;
hre = 1;
mux = 0;
}
*/
size_t videoram_mask = m_ram->size() - 0x8001;
for (bank = 1; bank <= 8; bank++)
{
// 0x0000-0x77FF is video RAM
m = (mux ? ((map & 0x7f) << 12 | (offset & 0xfff)) : ((m_hrs & 0xf0) << 11 | (offset & 0x7fff))) & videoram_mask;
}
uint16_t start_addr = 0x1000 * (bank - 1);
uint16_t end_addr = start_addr + 0xfff;
uint32_t videoram_offset = (videoram_start + start_addr) & videoram_mask;
sprintf(bank_name,"bank%d",bank);
//logerror("%04x-%04x: Video RAM %04x (30K)\n", start_addr, end_addr, videoram_offset);
READ8_MEMBER( abc806_state::read )
{
uint8_t data = 0xff;
if (start_addr == 0x7000)
{
program.install_readwrite_bank(0x7000, 0x77ff, bank_name);
program.install_readwrite_handler(0x7800, 0x7fff, READ8_DELEGATE(abc806_state, charram_r), WRITE8_DELEGATE(abc806_state, charram_w));
}
else
{
program.install_readwrite_bank(start_addr, end_addr, bank_name);
}
offs_t m = 0;
bool m1l = 1, xml = 1, romd = 0, ramd = 0, hre = 0, vr = 1;
read_pal_p4(offset, m1l, xml, m, romd, ramd, hre, vr);
membank(bank_name)->configure_entry(1, m_video_ram + videoram_offset);
membank(bank_name)->set_entry(1);
}
if (!romd)
{
data = m_rom->base()[offset & 0x7fff];
}
if (!ramd)
{
data = m_ram->pointer()[offset & 0x7fff];
}
if (hre)
{
data = m_video_ram[m];
}
if (!vr)
{
data = charram_r(space, offset & 0x7ff);
}
return data;
}
READ8_MEMBER( abc806_state::m1_r )
{
uint8_t data = 0xff;
offs_t m = 0;
bool m1l = 0, xml = 1, romd = 0, ramd = 0, hre = 0, vr = 1;
read_pal_p4(offset, m1l, xml, m, romd, ramd, hre, vr);
if (!romd)
{
data = m_rom->base()[offset & 0x7fff];
}
if (!ramd)
{
data = m_ram->pointer()[offset & 0x7fff];
}
if (hre)
{
data = m_video_ram[m];
}
if (!vr)
{
data = charram_r(space, offset & 0x7ff);
}
return data;
}
WRITE8_MEMBER( abc806_state::write )
{
offs_t m = 0;
bool m1l = 1, xml = 1, romd = 0, ramd = 0, hre = 0, vr = 1;
read_pal_p4(offset, m1l, xml, m, romd, ramd, hre, vr);
if (!ramd)
{
m_ram->pointer()[offset & 0x7fff] = data;
}
if (hre)
{
m_video_ram[m] = data;
}
if (!vr)
{
charram_w(space, offset & 0x7ff, data);
}
}
@ -376,7 +378,7 @@ READ8_MEMBER( abc800_state::m1_r )
bankswitch();
}
return m_rom->base()[0x7800 | (offset & 0x7ff)];
return m_rom->base()[offset];
}
if (m_fetch_charram)
@ -398,7 +400,7 @@ READ8_MEMBER( abc800c_state::m1_r )
bankswitch();
}
return m_rom->base()[0x7c00 | (offset & 0x3ff)];
return m_rom->base()[offset];
}
if (m_fetch_charram)
@ -416,7 +418,7 @@ READ8_MEMBER( abc802_state::m1_r )
{
if (offset >= 0x7800 && offset < 0x8000)
{
return m_rom->base()[0x7800 | (offset & 0x7ff)];
return m_rom->base()[offset];
}
}
@ -459,9 +461,9 @@ WRITE8_MEMBER( abc806_state::mao_w )
int bank = offset >> 12;
m_map[bank] = data;
if (LOG) logerror("MAO %04x %02x %02x\n",offset,bank,data);
bankswitch();
m_map[bank] = data;
}
@ -588,23 +590,7 @@ void abc802_state::abc802_io(address_map &map)
void abc806_state::abc806_mem(address_map &map)
{
map.unmap_value_high();
map(0x0000, 0x0fff).bankrw("bank1");
map(0x1000, 0x1fff).bankrw("bank2");
map(0x2000, 0x2fff).bankrw("bank3");
map(0x3000, 0x3fff).bankrw("bank4");
map(0x4000, 0x4fff).bankrw("bank5");
map(0x5000, 0x5fff).bankrw("bank6");
map(0x6000, 0x6fff).bankrw("bank7");
map(0x7000, 0x7fff).bankrw("bank8");
map(0x8000, 0x8fff).bankrw("bank9");
map(0x9000, 0x9fff).bankrw("bank10");
map(0xa000, 0xafff).bankrw("bank11");
map(0xb000, 0xbfff).bankrw("bank12");
map(0xc000, 0xcfff).bankrw("bank13");
map(0xd000, 0xdfff).bankrw("bank14");
map(0xe000, 0xefff).bankrw("bank15");
map(0xf000, 0xffff).bankrw("bank16");
map(0x0000, 0xffff).rw(this, FUNC(abc806_state::read), FUNC(abc806_state::write));
}
@ -844,9 +830,9 @@ WRITE_LINE_MEMBER( abc802_state::mux80_40_w )
WRITE_LINE_MEMBER( abc806_state::keydtr_w )
{
m_keydtr = state;
if (LOG) logerror("%s KEYDTR %u\n",machine().describe_context(),state);
bankswitch();
m_keydtr = state;
}
@ -960,15 +946,6 @@ void abc806_state::machine_start()
uint32_t videoram_size = m_ram->size() - 0x8000;
m_video_ram.allocate(videoram_size);
// setup memory banks
for (int bank = 1; bank <= 16; bank++) {
char bank_name[10];
sprintf(bank_name,"bank%d",bank);
membank(bank_name)->configure_entry(0, m_rom->base() + (0x1000 * (bank - 1)));
membank(bank_name)->configure_entry(1, m_video_ram);
}
// register for state saving
save_item(NAME(m_fetch_charram));
save_item(NAME(m_sb));
@ -999,14 +976,16 @@ void abc806_state::machine_start()
void abc806_state::machine_reset()
{
// reset memory banks
for (int bank = 1; bank <= 16; bank++) {
char bank_name[10];
sprintf(bank_name,"bank%d",bank);
membank(bank_name)->set_entry(0);
}
m_sb = m_io_sb->read();
abc800_state::machine_reset();
m_dart->ria_w(1);
// 50/60 Hz
m_dart->ctsb_w(0); // 0 = 50Hz, 1 = 60Hz
m_dfd_in = 0;
m_hrs = 0;
// clear STO lines
for (int i = 0; i < 8; i++) {
@ -1270,8 +1249,8 @@ MACHINE_CONFIG_START(abc806_state::abc806)
// internal ram
MCFG_RAM_ADD(RAM_TAG)
MCFG_RAM_DEFAULT_SIZE("128K")
MCFG_RAM_EXTRA_OPTIONS("512K")
MCFG_RAM_DEFAULT_SIZE("160K")
MCFG_RAM_EXTRA_OPTIONS("544K")
// software list
MCFG_SOFTWARE_LIST_ADD("flop_list2", "abc806")
@ -1523,10 +1502,10 @@ ROM_START( abc806 )
1 I3
2 A15
3 A14
4 A13
5 A12
6 A11
7 MIL
4 B13
5 B12
6 B11
7 M1L
8 EME
9 ENL
10 GND
@ -1537,7 +1516,7 @@ ROM_START( abc806 )
15 KDL
16 >HRE
17 RKDL
18 MUX
18 >MUX
19 >RAMD
20 Vcc
*/

View File

@ -288,9 +288,12 @@ public:
virtual void video_start() override;
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
void bankswitch();
void read_pal_p4(offs_t offset, bool m1l, bool xml, offs_t &m, bool &romd, bool &ramd, bool &hre, bool &vr);
void hr_update(bitmap_rgb32 &bitmap, const rectangle &cliprect);
DECLARE_READ8_MEMBER( read );
DECLARE_WRITE8_MEMBER( write );
DECLARE_READ8_MEMBER( m1_r ) override;
DECLARE_READ8_MEMBER( mai_r );
DECLARE_WRITE8_MEMBER( mao_w );
DECLARE_WRITE8_MEMBER( hrs_w );

View File

@ -143,12 +143,12 @@ PALETTE_INIT_MEMBER( abc800c_state, abc800c )
{
palette.set_pen_color(0, rgb_t::black());
palette.set_pen_color(1, rgb_t(0xff, 0x00, 0x00)); // red
palette.set_pen_color(2, rgb_t(0x00, 0xff, 0x00)); // green
palette.set_pen_color(2, rgb_t::green());
palette.set_pen_color(3, rgb_t(0xff, 0xff, 0x00)); // yellow
palette.set_pen_color(4, rgb_t(0x00, 0x00, 0xff)); // blue
palette.set_pen_color(5, rgb_t(0xff, 0x00, 0xff)); // magenta
palette.set_pen_color(6, rgb_t(0x00, 0xff, 0xff)); // cyan
palette.set_pen_color(7, rgb_t(0xff, 0xff, 0xff)); // white
palette.set_pen_color(7, rgb_t::white());
}
@ -282,7 +282,7 @@ MACHINE_CONFIG_START(abc800m_state::abc800m_video)
MCFG_MC6845_SHOW_BORDER_AREA(true)
MCFG_MC6845_CHAR_WIDTH(ABC800_CHAR_WIDTH)
MCFG_MC6845_UPDATE_ROW_CB(abc800m_state, abc800m_update_row)
MCFG_MC6845_OUT_VSYNC_CB(WRITELINE(Z80DART_TAG, z80dart_device, rib_w))
MCFG_MC6845_OUT_VSYNC_CB(WRITELINE(Z80DART_TAG, z80dart_device, rib_w)) MCFG_DEVCB_XOR(1)
MCFG_SCREEN_ADD_MONOCHROME(SCREEN_TAG, RASTER, rgb_t(0xff, 0xff, 0x00))
MCFG_SCREEN_UPDATE_DRIVER(abc800m_state, screen_update)

View File

@ -171,9 +171,6 @@ WRITE_LINE_MEMBER( abc802_state::vs_w )
m_flshclk_ctr++;
}
}
// signal _DEW to DART
m_dart->rib_w(!state);
}
@ -187,6 +184,7 @@ MACHINE_CONFIG_START(abc802_state::abc802_video)
MCFG_MC6845_CHAR_WIDTH(ABC800_CHAR_WIDTH)
MCFG_MC6845_UPDATE_ROW_CB(abc802_state, abc802_update_row)
MCFG_MC6845_OUT_VSYNC_CB(WRITELINE(*this, abc802_state, vs_w))
MCFG_DEVCB_CHAIN_OUTPUT(WRITELINE(Z80DART_TAG, z80dart_device, rib_w)) MCFG_DEVCB_XOR(1)
MCFG_SCREEN_ADD_MONOCHROME(SCREEN_TAG, RASTER, rgb_t::amber())
MCFG_SCREEN_UPDATE_DEVICE(MC6845_TAG, mc6845_device, screen_update)

View File

@ -10,7 +10,7 @@
#include "includes/abc80x.h"
#include "screen.h"
#define LOG 0
#define HORIZONTAL_PORCH_HACK 109
#define VERTICAL_PORCH_HACK 27
@ -27,17 +27,19 @@ WRITE8_MEMBER( abc806_state::hrs_w )
bit signal description
0 VM14 visible screen memory area bit 0
1 VM15 visible screen memory area bit 1
2 VM16 visible screen memory area bit 2
3 VM17 visible screen memory area bit 3
4 F14 cpu accessible screen memory area bit 0
5 F15 cpu accessible screen memory area bit 1
6 F16 cpu accessible screen memory area bit 2
7 F17 cpu accessible screen memory area bit 3
0 VM15 visible screen memory area bit 0
1 VM16 visible screen memory area bit 1
2 VM17 visible screen memory area bit 2
3 VM18 visible screen memory area bit 3
4 F15 cpu accessible screen memory area bit 0
5 F16 cpu accessible screen memory area bit 1
6 F17 cpu accessible screen memory area bit 2
7 F18 cpu accessible screen memory area bit 3
*/
if (LOG) logerror("%s HRS %02x\n", machine().describe_context(), data);
m_hrs = data;
}
@ -122,7 +124,7 @@ READ8_MEMBER( abc806_state::cli_r )
uint16_t hru2_addr = (m_hru2_a8 << 8) | (offset >> 8);
uint8_t data = m_hru2_prom->base()[hru2_addr] & 0x0f;
logerror("HRU II %03x : %01x\n", hru2_addr, data);
if (LOG) logerror("HRU II %03x : %01x\n", hru2_addr, data);
data |= m_rtc->dio_r() << 7;
@ -167,6 +169,7 @@ WRITE8_MEMBER( abc806_state::sto_w )
{
case 0:
// external memory enable
if (LOG) logerror("%s EME %u\n", machine().describe_context(), level);
m_eme = level;
break;
case 1:
@ -461,12 +464,12 @@ PALETTE_INIT_MEMBER( abc806_state, abc806 )
{
palette.set_pen_color(0, rgb_t::black());
palette.set_pen_color(1, rgb_t(0xff, 0x00, 0x00)); // red
palette.set_pen_color(2, rgb_t(0x00, 0xff, 0x00)); // green
palette.set_pen_color(2, rgb_t::green());
palette.set_pen_color(3, rgb_t(0xff, 0xff, 0x00)); // yellow
palette.set_pen_color(4, rgb_t(0x00, 0x00, 0xff)); // blue
palette.set_pen_color(5, rgb_t(0xff, 0x00, 0xff)); // magenta
palette.set_pen_color(6, rgb_t(0x00, 0xff, 0xff)); // cyan
palette.set_pen_color(7, rgb_t(0xff, 0xff, 0xff)); // white
palette.set_pen_color(7, rgb_t::white());
}