mirror of
https://github.com/holub/mame
synced 2025-10-06 09:00:04 +03:00
1224 lines
34 KiB
C
1224 lines
34 KiB
C
/***************************************************************************
|
|
|
|
NeXT
|
|
|
|
TODO:
|
|
|
|
- Hook up the sound output, it is shared with the keyboard port
|
|
|
|
- Implement more of the scc and its dma interactions so that the
|
|
start up test passes, but not before sound out is done (if the scc
|
|
test passes all the other test pass up to sound out which
|
|
infloops)
|
|
|
|
- Really implement the MO, it's only faking it for the startup test right now
|
|
|
|
- Fix the networking
|
|
|
|
- Find out why netbsd goes to hell even before loading the kernel
|
|
|
|
Memory map and other bits can be found here:
|
|
http://fxr.watson.org/fxr/source/arch/next68k/include/cpu.h?v=NETBSD5#L366
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
#include "includes/next.h"
|
|
#include "formats/pc_dsk.h"
|
|
#include "formats/mfi_dsk.h"
|
|
#include "machine/nscsi_cd.h"
|
|
#include "machine/nscsi_hd.h"
|
|
|
|
UINT32 next_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
|
{
|
|
// We don't handle partial updates, but we don't generate them either :-)
|
|
if(cliprect.min_x || cliprect.min_y || cliprect.max_x+1 != screen_sx || cliprect.max_y+1 != screen_sy)
|
|
return 0;
|
|
|
|
// 0,1,2,4=0b000000, 3=2c000000, 5,8,9=0c000000
|
|
// 1152x832 (0,1,2,3c,4)
|
|
// 1120x832 (8)
|
|
// 832x624 (5c,9c)
|
|
if(screen_color) {
|
|
const UINT32 *vr = vram;
|
|
for(int y=0; y<screen_sy; y++) {
|
|
UINT32 *pix = reinterpret_cast<UINT32 *>(bitmap.raw_pixptr(y));
|
|
for(int x=0; x<screen_sx; x+=2) {
|
|
UINT32 v = *vr++;
|
|
for(int xi=0; xi<2; xi++) {
|
|
UINT16 pen = (v >> (16-(xi*16))) & 0xffff;
|
|
UINT32 r = (pen & 0xf000) >> 12;
|
|
UINT32 g = (pen & 0x0f00) >> 8;
|
|
UINT32 b = (pen & 0x00f0) >> 4;
|
|
UINT32 col = (r << 20) | (r << 16) | (g << 12) | (g << 8) | (b << 4) | b;
|
|
*pix++ = col;
|
|
}
|
|
}
|
|
vr += screen_skip;
|
|
}
|
|
} else {
|
|
static UINT32 colors[4] = { 0xffffff, 0xaaaaaa, 0x555555, 0x000000 };
|
|
const UINT32 *vr = vram;
|
|
for(int y=0; y<screen_sy; y++) {
|
|
UINT32 *pix = reinterpret_cast<UINT32 *>(bitmap.raw_pixptr(y));
|
|
for(int x=0; x<screen_sx; x+=16) {
|
|
UINT32 v = *vr++;
|
|
for(int xi=0; xi<16; xi++)
|
|
*pix++ = colors[(v >> (30-(xi*2))) & 0x3];
|
|
}
|
|
vr += screen_skip;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Dummy catcher for any unknown r/w */
|
|
READ8_MEMBER( next_state::io_r )
|
|
{
|
|
if(!space.debugger_access())
|
|
printf("io_r %08x (%08x)\n",offset+0x02000000, space.device().safe_pc());
|
|
|
|
if(offset == 0xc0)
|
|
return 0;
|
|
|
|
return 0xff;
|
|
}
|
|
|
|
WRITE8_MEMBER( next_state::io_w )
|
|
{
|
|
if(!space.debugger_access())
|
|
printf("io_w %08x, %02x (%08x)\n",offset+0x02000000,data, space.device().safe_pc());
|
|
}
|
|
|
|
/* map ROM at 0x01000000-0x0101ffff? */
|
|
READ32_MEMBER( next_state::rom_map_r )
|
|
{
|
|
if(0 && !space.debugger_access())
|
|
printf("%08x ROM MAP?\n",space.device().safe_pc());
|
|
return 0x01000000;
|
|
}
|
|
|
|
READ32_MEMBER( next_state::scr2_r )
|
|
{
|
|
if(0 && !space.debugger_access())
|
|
printf("%08x\n",space.device().safe_pc());
|
|
/*
|
|
x--- ---- ---- ---- ---- ---- ---- ---- dsp reset
|
|
-x-- ---- ---- ---- ---- ---- ---- ---- dsp block end
|
|
--x- ---- ---- ---- ---- ---- ---- ---- dsp unpacked
|
|
---x ---- ---- ---- ---- ---- ---- ---- dsp mode b
|
|
---- x--- ---- ---- ---- ---- ---- ---- dsp mode a
|
|
---- -x-- ---- ---- ---- ---- ---- ---- remote int
|
|
---- ---x ---- ---- ---- ---- ---- ---- local int
|
|
---- ---- ---x ---- ---- ---- ---- ---- dram 256k
|
|
---- ---- ---- ---x ---- ---- ---- ---- dram 1m
|
|
---- ---- ---- ---- x--- ---- ---- ---- "timer on ipl7"
|
|
---- ---- ---- ---- -xxx ---- ---- ---- rom waitstates
|
|
---- ---- ---- ---- ---- x--- ---- ---- ROM 1M
|
|
---- ---- ---- ---- ---- -x-- ---- ---- MCS1850 rtdata
|
|
---- ---- ---- ---- ---- --x- ---- ---- MCS1850 rtclk
|
|
---- ---- ---- ---- ---- ---x ---- ---- MCS1850 rtce
|
|
---- ---- ---- ---- ---- ---- x--- ---- rom overlay
|
|
---- ---- ---- ---- ---- ---- -x-- ---- dsp ie
|
|
---- ---- ---- ---- ---- ---- --x- ---- mem en
|
|
---- ---- ---- ---- ---- ---- ---- ---x led
|
|
|
|
68040-25, 100ns, 32M: 00000c80
|
|
68040-25, 100ns, 20M: 00ff0c80
|
|
|
|
*/
|
|
|
|
UINT32 data = scr2 & 0xfffffbff;
|
|
|
|
data |= rtc->sdo_r() << 10;
|
|
|
|
return data;
|
|
}
|
|
|
|
WRITE32_MEMBER( next_state::scr2_w )
|
|
{
|
|
if(0 && !space.debugger_access())
|
|
printf("scr2_w %08x (%08x)\n", data, space.device().safe_pc());
|
|
COMBINE_DATA(&scr2);
|
|
|
|
rtc->ce_w(BIT(scr2, 8));
|
|
rtc->sdi_w(BIT(scr2, 10));
|
|
rtc->sck_w(BIT(scr2, 9));
|
|
irq_set(0, scr2 & 0x01000000);
|
|
irq_set(1, scr2 & 0x02000000);
|
|
}
|
|
|
|
READ32_MEMBER( next_state::scr1_r )
|
|
{
|
|
/*
|
|
xxxx ---- ---- ---- ---- ---- ---- ---- slot ID
|
|
---- ---- xxxx xxxx ---- ---- ---- ---- DMA type
|
|
---- ---- ---- ---- xxxx ---- ---- ---- machine type
|
|
---- ---- ---- ---- ---- xxxx ---- ---- board revision
|
|
---- ---- ---- ---- ---- ---- -xx- ---- video mem speed
|
|
---- ---- ---- ---- ---- ---- ---x x--- mem speed
|
|
---- ---- ---- ---- ---- ---- ---- -xxx cpu speed 16/20/25/33/40/50/66/80
|
|
|
|
machine types:
|
|
0 NeXT_CUBE
|
|
1 NeXT_WARP9
|
|
2 NeXT_X15
|
|
3 NeXT_WARP9C
|
|
4 NeXT_Turbo
|
|
5 NeXT_TurboC
|
|
6 Unknown
|
|
7 Unknown
|
|
8 NeXT_TurboCube
|
|
9 NeXT_TurboCubeC
|
|
|
|
68040-25: 00011102
|
|
68040-25: 00013002 (non-turbo, color)
|
|
*/
|
|
|
|
return scr1;
|
|
}
|
|
|
|
// Interrupt subsystem
|
|
// source bit level
|
|
// nmi 31 7 *
|
|
// pfail 30 7
|
|
// timer 29 6 *
|
|
// enetxdma 28 6 *
|
|
// enetrdma 27 6 *
|
|
// scsidma 26 6 *
|
|
// diskdma 25 6
|
|
// prndma 24 6 *
|
|
// sndoutdma 23 6
|
|
// sndindma 22 6
|
|
// sccdma 21 6
|
|
// dspdma 20 6
|
|
// m2rdma 19 6
|
|
// r2mdma 18 6
|
|
// scc 17 5
|
|
// remote 16 5 *
|
|
// bus 15 5 *
|
|
// dsp4 14 4
|
|
// disk/cvid 13 3
|
|
// scsi 12 3 *
|
|
// printer 11 3
|
|
// enetx 10 3 *
|
|
// enetr 9 3
|
|
// soundovr 8 3 *
|
|
// phone 7 3 * -- floppy
|
|
// dsp3 6 3
|
|
// video 5 3
|
|
// monitor 4 3
|
|
// kbdmouse 3 3 *
|
|
// power 2 3 *
|
|
// softint1 1 2 *
|
|
// softint0 0 1 *
|
|
|
|
void next_state::irq_set(int id, bool raise)
|
|
{
|
|
UINT32 mask = 1U << id;
|
|
UINT32 old_status = irq_status;
|
|
if(raise)
|
|
irq_status |= mask;
|
|
else
|
|
irq_status &= ~mask;
|
|
if(old_status != irq_status)
|
|
irq_check();
|
|
}
|
|
|
|
|
|
READ32_MEMBER( next_state::irq_status_r )
|
|
{
|
|
return irq_status;
|
|
}
|
|
|
|
READ32_MEMBER( next_state::irq_mask_r )
|
|
{
|
|
return irq_mask;
|
|
}
|
|
|
|
WRITE32_MEMBER( next_state::irq_mask_w )
|
|
{
|
|
COMBINE_DATA(&irq_mask);
|
|
irq_check();
|
|
}
|
|
|
|
void next_state::irq_check()
|
|
{
|
|
UINT32 act = irq_status & (irq_mask | 0x80000000);
|
|
int bit;
|
|
for(bit=31; bit >= 0 && !(act & (1U << bit)); bit--);
|
|
|
|
int level;
|
|
if (bit < 0) level = 0;
|
|
else if(bit < 1) level = 1;
|
|
else if(bit < 2) level = 2;
|
|
else if(bit < 14) level = 3;
|
|
else if(bit < 15) level = 4;
|
|
else if(bit < 18) level = 5;
|
|
else if(bit < 30) level = 6;
|
|
else level = 7;
|
|
|
|
logerror("IRQ info %08x/%08x - %d\n", irq_status, irq_mask, level);
|
|
|
|
if(level != irq_level) {
|
|
maincpu->set_input_line(irq_level, CLEAR_LINE);
|
|
maincpu->set_input_line_and_vector(level, ASSERT_LINE, M68K_INT_ACK_AUTOVECTOR);
|
|
irq_level = level;
|
|
}
|
|
}
|
|
|
|
const char *next_state::dma_targets[0x20] = {
|
|
0, "scsi", 0, 0, "soundout", "disk", 0, 0,
|
|
"soundin", "printer", 0, 0, "scc", "dsp", 0, 0,
|
|
"s-enetx", "enetx", 0, 0, "s-enetr", "enetr", 0, 0,
|
|
"video", 0, 0, 0, "r2m", "m2r", 0, 0
|
|
};
|
|
|
|
const int next_state::dma_irqs[0x20] = {
|
|
-1, 26, -1, -1, 23, 25, -1, -1, 22, 24, -1, -1, 21, 20, -1, -1,
|
|
-1, 28, -1, -1, -1, 27, -1, -1, 5, -1, -1, -1, 18, 19, -1, -1
|
|
};
|
|
|
|
const bool next_state::dma_has_saved[0x20] = {
|
|
false, false, false, false, false, false, false, false,
|
|
false, false, false, false, false, false, false, false,
|
|
false, true, false, false, false, true, false, false,
|
|
false, false, false, false, false, false, false, false,
|
|
};
|
|
|
|
const char *next_state::dma_name(int slot)
|
|
{
|
|
static char buf[32];
|
|
if(dma_targets[slot])
|
|
return dma_targets[slot];
|
|
sprintf(buf, "<%02x>", slot);
|
|
return buf;
|
|
}
|
|
|
|
void next_state::dma_drq_w(int slot, bool state)
|
|
{
|
|
// fprintf(stderr, "DMA drq_w %d, %d\n", slot, state);
|
|
dma_slot &ds = dma_slots[slot];
|
|
ds.drq = state;
|
|
if(state && (ds.state & DMA_ENABLE)) {
|
|
address_space &space = maincpu->space(AS_PROGRAM);
|
|
if(ds.state & DMA_READ) {
|
|
while(ds.drq) {
|
|
dma_check_update(slot);
|
|
UINT8 val;
|
|
bool eof;
|
|
bool err;
|
|
dma_read(slot, val, eof, err);
|
|
if(err) {
|
|
ds.state = (ds.state & ~DMA_ENABLE) | DMA_BUSEXC;
|
|
logerror("DMA: bus error on read slot %d\n", slot);
|
|
return;
|
|
}
|
|
space.write_byte(ds.current++, val);
|
|
dma_check_end(slot, eof);
|
|
if(!(ds.state & DMA_ENABLE))
|
|
return;
|
|
}
|
|
} else {
|
|
while(ds.drq) {
|
|
dma_check_update(slot);
|
|
UINT8 val = space.read_byte(ds.current++);
|
|
bool eof = ds.current == (ds.limit & 0x7fffffff) && (ds.limit & 0x80000000);
|
|
bool err;
|
|
dma_write(slot, val, eof, err);
|
|
if(err) {
|
|
ds.state = (ds.state & ~DMA_ENABLE) | DMA_BUSEXC;
|
|
logerror("DMA: bus error on write slot %d\n", slot);
|
|
return;
|
|
}
|
|
dma_check_end(slot, false);
|
|
if(!(ds.state & DMA_ENABLE))
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void next_state::dma_read(int slot, UINT8 &val, bool &eof, bool &err)
|
|
{
|
|
err = false;
|
|
eof = false;
|
|
switch(slot) {
|
|
case 1:
|
|
if(fdc && fdc->get_drq()) {
|
|
val = fdc->dma_r();
|
|
if(eof) {
|
|
fdc->tc_w(true);
|
|
fdc->tc_w(false);
|
|
}
|
|
} else
|
|
val = scsi->dma_r();
|
|
break;
|
|
|
|
case 5:
|
|
val = mo->dma_r();
|
|
break;
|
|
|
|
case 21:
|
|
net->rx_dma_r(val, eof);
|
|
logerror("dma read net %02x %s\n", val, eof ? "eof" : "");
|
|
break;
|
|
|
|
default:
|
|
err = true;
|
|
val = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void next_state::dma_write(int slot, UINT8 data, bool eof, bool &err)
|
|
{
|
|
err = false;
|
|
switch(slot) {
|
|
case 1:
|
|
if(fdc && fdc->get_drq()) {
|
|
fdc->dma_w(data);
|
|
if(eof) {
|
|
fdc->tc_w(true);
|
|
fdc->tc_w(false);
|
|
}
|
|
} else
|
|
scsi->dma_w(data);
|
|
break;
|
|
|
|
case 4:
|
|
break;
|
|
|
|
case 5:
|
|
mo->dma_w(data);
|
|
break;
|
|
|
|
case 17:
|
|
net->tx_dma_w(data, eof);
|
|
break;
|
|
|
|
default:
|
|
err = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void next_state::dma_check_update(int slot)
|
|
{
|
|
dma_slot &ds = dma_slots[slot];
|
|
if(ds.restart) {
|
|
ds.current = ds.start;
|
|
ds.restart = false;
|
|
}
|
|
}
|
|
|
|
void next_state::dma_end(int slot)
|
|
{
|
|
dma_slot &ds = dma_slots[slot];
|
|
if(dma_has_saved[slot]) {
|
|
dma_slot &ds1 = dma_slots[(slot-1) & 31];
|
|
ds1.current = ds.start;
|
|
ds1.limit = ds.current;
|
|
}
|
|
|
|
if(!ds.supdate)
|
|
ds.state &= ~DMA_ENABLE;
|
|
else {
|
|
ds.start = ds.chain_start;
|
|
ds.limit = ds.chain_limit;
|
|
ds.restart = true;
|
|
ds.supdate = false;
|
|
ds.state &= ~DMA_SUPDATE;
|
|
}
|
|
ds.state |= DMA_COMPLETE;
|
|
logerror("dma end slot %d irq %d\n", slot, dma_irqs[slot]);
|
|
if(dma_irqs[slot] >= 0)
|
|
irq_set(dma_irqs[slot], true);
|
|
}
|
|
|
|
void next_state::dma_check_end(int slot, bool eof)
|
|
{
|
|
dma_slot &ds = dma_slots[slot];
|
|
if(eof || ds.current == (ds.limit & 0x7fffffff))
|
|
dma_end(slot);
|
|
}
|
|
|
|
READ32_MEMBER( next_state::dma_regs_r)
|
|
{
|
|
int slot = offset >> 2;
|
|
int reg = offset & 3;
|
|
|
|
UINT32 res;
|
|
|
|
switch(reg) {
|
|
case 0:
|
|
res = dma_slots[slot].current;
|
|
break;
|
|
case 1:
|
|
res = dma_slots[slot].limit;
|
|
break;
|
|
case 2:
|
|
res = dma_slots[slot].chain_start;
|
|
break;
|
|
case 3: default:
|
|
res = dma_slots[slot].chain_limit;
|
|
break;
|
|
}
|
|
|
|
const char *name = dma_name(slot);
|
|
logerror("dma_regs_r %s:%d %08x (%08x)\n", name, reg, res, space.device().safe_pc());
|
|
|
|
return res;
|
|
}
|
|
|
|
WRITE32_MEMBER( next_state::dma_regs_w)
|
|
{
|
|
int slot = offset >> 2;
|
|
int reg = offset & 3;
|
|
|
|
const char *name = dma_name(slot);
|
|
|
|
logerror("dma_regs_w %s:%d %08x (%08x)\n", name, reg, data, space.device().safe_pc());
|
|
switch(reg) {
|
|
case 0:
|
|
dma_slots[slot].start = data;
|
|
dma_slots[slot].current = data;
|
|
break;
|
|
case 1:
|
|
dma_slots[slot].limit = data;
|
|
break;
|
|
case 2:
|
|
dma_slots[slot].chain_start = data;
|
|
break;
|
|
case 3:
|
|
dma_slots[slot].chain_limit = data;
|
|
break;
|
|
}
|
|
}
|
|
|
|
READ32_MEMBER( next_state::dma_ctrl_r)
|
|
{
|
|
int slot = offset >> 2;
|
|
int reg = offset & 3;
|
|
|
|
const char *name = dma_name(slot);
|
|
|
|
if(space.device().safe_pc() != 0x409bb4e)
|
|
logerror("dma_ctrl_r %s:%d %02x (%08x)\n", name, reg, dma_slots[slot].state, space.device().safe_pc());
|
|
|
|
return reg ? 0 : dma_slots[slot].state << 24;
|
|
}
|
|
|
|
WRITE32_MEMBER( next_state::dma_ctrl_w)
|
|
{
|
|
int slot = offset >> 2;
|
|
int reg = offset & 3;
|
|
const char *name = dma_name(slot);
|
|
logerror("dma_ctrl_w %s:%d %08x @ %08x (%08x)\n", name, reg, data, mem_mask, space.device().safe_pc());
|
|
if(!reg) {
|
|
if(ACCESSING_BITS_16_23)
|
|
dma_do_ctrl_w(slot, data >> 16);
|
|
else if(ACCESSING_BITS_24_31)
|
|
dma_do_ctrl_w(slot, data >> 24);
|
|
}
|
|
}
|
|
|
|
void next_state::dma_do_ctrl_w(int slot, UINT8 data)
|
|
{
|
|
const char *name = dma_name(slot);
|
|
#if 0
|
|
fprintf(stderr, "dma_ctrl_w %s %02x (%08x)\n", name, data, maincpu->pc());
|
|
|
|
fprintf(stderr, " ->%s%s%s%s%s%s%s\n",
|
|
data & DMA_SETENABLE ? " enable" : "",
|
|
data & DMA_SETSUPDATE ? " supdate" : "",
|
|
data & DMA_SETREAD ? " read" : "",
|
|
data & DMA_CLRCOMPLETE ? " complete" : "",
|
|
data & DMA_RESET ? " reset" : "",
|
|
data & DMA_INITBUF ? " initbuf" : "",
|
|
data & DMA_INITBUFTURBO ? " initbufturbo" : "");
|
|
#endif
|
|
if(data & DMA_SETENABLE)
|
|
logerror("dma enable %s %s %08x (%08x)\n", name, data & DMA_SETREAD ? "read" : "write", (dma_slots[slot].limit-dma_slots[slot].start) & 0x7fffffff, maincpu->pc());
|
|
|
|
dma_slot &ds = dma_slots[slot];
|
|
if(data & (DMA_RESET|DMA_INITBUF|DMA_INITBUFTURBO)) {
|
|
ds.state = 0;
|
|
if(dma_irqs[slot] >= 0)
|
|
irq_set(dma_irqs[slot], false);
|
|
}
|
|
if(data & DMA_SETSUPDATE) {
|
|
ds.state |= DMA_SUPDATE;
|
|
ds.supdate = true;
|
|
}
|
|
if(data & DMA_SETREAD)
|
|
ds.state |= DMA_READ;
|
|
if(data & DMA_CLRCOMPLETE) {
|
|
ds.state &= ~DMA_COMPLETE;
|
|
if(dma_irqs[slot] >= 0)
|
|
irq_set(dma_irqs[slot], false);
|
|
}
|
|
if(data & DMA_SETENABLE) {
|
|
ds.state |= DMA_ENABLE;
|
|
// fprintf(stderr, "dma slot %d drq=%s\n", slot, ds.drq ? "on" : "off");
|
|
if(ds.drq)
|
|
dma_drq_w(slot, ds.drq);
|
|
}
|
|
}
|
|
|
|
const int next_state::scsi_clocks[4] = { 10000000, 12000000, 20000000, 16000000 };
|
|
|
|
READ32_MEMBER( next_state::scsictrl_r )
|
|
{
|
|
UINT32 res = (scsictrl << 24) | (scsistat << 16);
|
|
logerror("scsictrl_read %08x @ %08x (%08x)\n", res, mem_mask, space.device().safe_pc());
|
|
return res;
|
|
}
|
|
|
|
WRITE32_MEMBER( next_state::scsictrl_w )
|
|
{
|
|
if(ACCESSING_BITS_24_31) {
|
|
scsictrl = data >> 24;
|
|
if(scsictrl & 0x02)
|
|
scsi->reset();
|
|
device_t::static_set_clock(*scsi, scsi_clocks[scsictrl >> 6]);
|
|
|
|
logerror("SCSIctrl %dMHz int=%s dma=%s dmadir=%s%s%s dest=%s (%08x)\n",
|
|
scsi_clocks[scsictrl >> 6]/1000000,
|
|
scsictrl & 0x20 ? "on" : "off",
|
|
scsictrl & 0x10 ? "on" : "off",
|
|
scsictrl & 0x08 ? "read" : "write",
|
|
scsictrl & 0x04 ? " flush" : "",
|
|
scsictrl & 0x02 ? " reset" : "",
|
|
scsictrl & 0x01 ? "wd3392" : "ncr5390",
|
|
space.device().safe_pc());
|
|
}
|
|
if(ACCESSING_BITS_16_23) {
|
|
scsistat = data >> 16;
|
|
logerror("SCSIstat %02x (%08x)\n", data, space.device().safe_pc());
|
|
}
|
|
}
|
|
|
|
READ32_MEMBER( next_state::event_counter_r)
|
|
{
|
|
// Event counters, around that time, are usually fixed-frequency counters.
|
|
// This one being 1MHz seems to make sense
|
|
|
|
// The v74 rom seems pretty convinced that it's 20 bits only.
|
|
|
|
if(ACCESSING_BITS_24_31)
|
|
eventc_latch = machine().time().as_ticks(1000000) & 0xfffff;
|
|
return eventc_latch;
|
|
}
|
|
|
|
READ32_MEMBER( next_state::dsp_r)
|
|
{
|
|
return 0x7fffffff;
|
|
}
|
|
|
|
WRITE32_MEMBER( next_state::fdc_control_w )
|
|
{
|
|
logerror("FDC write %02x (%08x)\n", data >> 24, space.device().safe_pc());
|
|
}
|
|
|
|
READ32_MEMBER( next_state::fdc_control_r )
|
|
{
|
|
// Type of floppy present
|
|
// 0 = no floppy in drive
|
|
// 1 = ed
|
|
// 2 = hd
|
|
// 3 = dd
|
|
|
|
// The rom strangely can't boot on anything else than ED, it has
|
|
// code for the other densities but forces ED for some mysterious
|
|
// reason. The kernel otoh behaves as expected.
|
|
|
|
if(fdc) {
|
|
floppy_image_device *fdev = machine().device<floppy_connector>(":fdc:0")->get_device();
|
|
if(fdev->exists()) {
|
|
UINT32 variant = fdev->get_variant();
|
|
switch(variant) {
|
|
case floppy_image::SSSD:
|
|
case floppy_image::SSDD:
|
|
case floppy_image::DSDD:
|
|
return 3 << 24;
|
|
|
|
case floppy_image::DSHD:
|
|
return 2 << 24;
|
|
|
|
case floppy_image::DSED:
|
|
return 1 << 24;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0 << 24;
|
|
}
|
|
|
|
READ32_MEMBER( next_state::phy_r )
|
|
{
|
|
logerror("phy_r %d %08x (%08x)\n", offset, phy[offset], space.device().safe_pc());
|
|
return phy[offset] | (0 << 24);
|
|
}
|
|
|
|
WRITE32_MEMBER( next_state::phy_w )
|
|
{
|
|
COMBINE_DATA(phy+offset);
|
|
logerror("phy_w %d %08x (%08x)\n", offset, phy[offset], space.device().safe_pc());
|
|
}
|
|
|
|
void next_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
|
{
|
|
irq_set(29, true);
|
|
timer_data = timer_next_data;
|
|
if(timer_ctrl & 0x40000000)
|
|
timer_start();
|
|
else
|
|
timer_ctrl &= 0x7fffffff;
|
|
}
|
|
|
|
READ32_MEMBER( next_state::timer_data_r )
|
|
{
|
|
if(timer_ctrl & 0x80000000)
|
|
timer_update();
|
|
return timer_data;
|
|
}
|
|
|
|
WRITE32_MEMBER( next_state::timer_data_w )
|
|
{
|
|
if(timer_ctrl & 0x80000000) {
|
|
COMBINE_DATA(&timer_next_data);
|
|
timer_next_data &= 0xffff0000;
|
|
} else {
|
|
COMBINE_DATA(&timer_data);
|
|
timer_data &= 0xffff0000;
|
|
}
|
|
}
|
|
|
|
READ32_MEMBER( next_state::timer_ctrl_r )
|
|
{
|
|
irq_set(29, false);
|
|
return timer_ctrl;
|
|
}
|
|
|
|
WRITE32_MEMBER( next_state::timer_ctrl_w )
|
|
{
|
|
bool oldact = timer_ctrl & 0x80000000;
|
|
COMBINE_DATA(&timer_ctrl);
|
|
bool newact = timer_ctrl & 0x80000000;
|
|
if(oldact != newact) {
|
|
if(oldact) {
|
|
timer_update();
|
|
irq_set(29, false);
|
|
} else {
|
|
timer_next_data = timer_data;
|
|
timer_start();
|
|
}
|
|
}
|
|
}
|
|
|
|
void next_state::timer_update()
|
|
{
|
|
int delta = timer_vbase - (machine().time() - timer_tbase).as_ticks(1000000);
|
|
if(delta < 0)
|
|
delta = 0;
|
|
timer_data = delta << 16;
|
|
}
|
|
|
|
void next_state::timer_start()
|
|
{
|
|
timer_tbase = machine().time();
|
|
timer_vbase = timer_data >> 16;
|
|
timer_tm->adjust(attotime::from_usec(timer_vbase));
|
|
}
|
|
|
|
WRITE_LINE_MEMBER(next_state::scc_irq)
|
|
{
|
|
irq_set(17, state);
|
|
}
|
|
|
|
WRITE_LINE_MEMBER(next_state::keyboard_irq)
|
|
{
|
|
irq_set(3, state);
|
|
}
|
|
|
|
WRITE_LINE_MEMBER(next_state::power_irq)
|
|
{
|
|
irq_set(2, state);
|
|
}
|
|
|
|
WRITE_LINE_MEMBER(next_state::nmi_irq)
|
|
{
|
|
irq_set(31, state);
|
|
}
|
|
|
|
WRITE_LINE_MEMBER(next_state::fdc_irq)
|
|
{
|
|
irq_set(7, state);
|
|
}
|
|
|
|
WRITE_LINE_MEMBER(next_state::fdc_drq)
|
|
{
|
|
dma_drq_w(1, state);
|
|
}
|
|
|
|
WRITE_LINE_MEMBER(next_state::net_tx_irq)
|
|
{
|
|
irq_set(10, state);
|
|
}
|
|
|
|
WRITE_LINE_MEMBER(next_state::net_rx_irq)
|
|
{
|
|
irq_set(9, state);
|
|
}
|
|
|
|
WRITE_LINE_MEMBER(next_state::net_tx_drq)
|
|
{
|
|
dma_drq_w(17, state);
|
|
}
|
|
|
|
WRITE_LINE_MEMBER(next_state::net_rx_drq)
|
|
{
|
|
dma_drq_w(21, state);
|
|
}
|
|
|
|
WRITE_LINE_MEMBER(next_state::mo_irq)
|
|
{
|
|
irq_set(13, state);
|
|
}
|
|
|
|
WRITE_LINE_MEMBER(next_state::mo_drq)
|
|
{
|
|
dma_drq_w(5, state);
|
|
}
|
|
|
|
WRITE_LINE_MEMBER(next_state::scsi_irq)
|
|
{
|
|
irq_set(12, state);
|
|
}
|
|
|
|
WRITE_LINE_MEMBER(next_state::scsi_drq)
|
|
{
|
|
dma_drq_w(1, state);
|
|
}
|
|
|
|
WRITE8_MEMBER(next_state::ramdac_w)
|
|
{
|
|
switch(offset) {
|
|
case 0:
|
|
switch(data) {
|
|
case 0x05:
|
|
if(screen_color)
|
|
irq_set(13, false);
|
|
else
|
|
irq_set(5, false);
|
|
vbl_enabled = false;
|
|
break;
|
|
|
|
case 0x06:
|
|
vbl_enabled = true;
|
|
break;
|
|
|
|
default:
|
|
fprintf(stderr, "ramdac_w %d, %02x\n", offset, data);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
fprintf(stderr, "ramdac_w %d, %02x\n", offset, data);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void next_state::setup(UINT32 _scr1, int size_x, int size_y, int skip, bool color)
|
|
{
|
|
scr1 = _scr1;
|
|
screen_sx = size_x;
|
|
screen_sy = size_y;
|
|
screen_skip = skip;
|
|
screen_color = color;
|
|
}
|
|
|
|
void next_state::machine_start()
|
|
{
|
|
save_item(NAME(scr2));
|
|
save_item(NAME(irq_status));
|
|
save_item(NAME(irq_mask));
|
|
save_item(NAME(irq_level));
|
|
save_item(NAME(phy));
|
|
save_item(NAME(scsictrl));
|
|
save_item(NAME(scsistat));
|
|
save_item(NAME(timer_tbase));
|
|
save_item(NAME(timer_vbase));
|
|
save_item(NAME(timer_data));
|
|
save_item(NAME(timer_next_data));
|
|
save_item(NAME(timer_ctrl));
|
|
save_item(NAME(eventc_latch));
|
|
save_item(NAME(esp));
|
|
|
|
for(int i=0; i<0x20; i++) {
|
|
save_item(NAME(dma_slots[i].start), i);
|
|
save_item(NAME(dma_slots[i].limit), i);
|
|
save_item(NAME(dma_slots[i].chain_start), i);
|
|
save_item(NAME(dma_slots[i].chain_limit), i);
|
|
save_item(NAME(dma_slots[i].current), i);
|
|
save_item(NAME(dma_slots[i].state), i);
|
|
save_item(NAME(dma_slots[i].supdate), i);
|
|
save_item(NAME(dma_slots[i].restart), i);
|
|
save_item(NAME(dma_slots[i].drq), i);
|
|
}
|
|
|
|
timer_tm = timer_alloc(0);
|
|
|
|
system_time systime;
|
|
machine().base_datetime(systime);
|
|
rtc->set_counter(systime.time);
|
|
}
|
|
|
|
void next_state::machine_reset()
|
|
{
|
|
scr2 = 0;
|
|
irq_status = 0;
|
|
irq_mask = 0;
|
|
irq_level = 0;
|
|
esp = 0;
|
|
scsictrl = 0;
|
|
scsistat = 0;
|
|
phy[0] = phy[1] = 0;
|
|
eventc_latch = 0;
|
|
timer_vbase = 0;
|
|
timer_data = 0;
|
|
timer_next_data = 0;
|
|
timer_ctrl = 0;
|
|
vbl_enabled = true;
|
|
dma_drq_w(4, true); // soundout
|
|
}
|
|
|
|
void next_state::vblank_w(screen_device &screen, bool vblank_state)
|
|
{
|
|
if(vbl_enabled) {
|
|
if(screen_color)
|
|
irq_set(13, vblank_state);
|
|
else
|
|
irq_set(5, vblank_state);
|
|
}
|
|
}
|
|
|
|
static ADDRESS_MAP_START( next_mem, AS_PROGRAM, 32, next_state )
|
|
AM_RANGE(0x00000000, 0x0001ffff) AM_ROM AM_REGION("user1", 0)
|
|
AM_RANGE(0x01000000, 0x0101ffff) AM_ROM AM_REGION("user1", 0)
|
|
AM_RANGE(0x02000000, 0x020001ff) AM_MIRROR(0x300200) AM_READWRITE(dma_ctrl_r, dma_ctrl_w)
|
|
AM_RANGE(0x02004000, 0x020041ff) AM_MIRROR(0x300200) AM_READWRITE(dma_regs_r, dma_regs_w)
|
|
AM_RANGE(0x02006000, 0x0200600f) AM_MIRROR(0x300000) AM_DEVICE8("net", mb8795_device, map, 0xffffffff)
|
|
// AM_RANGE(0x02006010, 0x02006013) AM_MIRROR(0x300000) memory timing
|
|
AM_RANGE(0x02007000, 0x02007003) AM_MIRROR(0x300000) AM_READ(irq_status_r)
|
|
AM_RANGE(0x02007800, 0x02007803) AM_MIRROR(0x300000) AM_READWRITE(irq_mask_r,irq_mask_w)
|
|
AM_RANGE(0x02008000, 0x02008003) AM_MIRROR(0x300000) AM_READ(dsp_r)
|
|
AM_RANGE(0x0200c000, 0x0200c003) AM_MIRROR(0x300000) AM_READ(scr1_r)
|
|
AM_RANGE(0x0200c800, 0x0200c803) AM_MIRROR(0x300000) AM_READ(rom_map_r)
|
|
AM_RANGE(0x0200d000, 0x0200d003) AM_MIRROR(0x300000) AM_READWRITE(scr2_r,scr2_w)
|
|
// AM_RANGE(0x0200d800, 0x0200d803) AM_MIRROR(0x300000) RMTINT
|
|
AM_RANGE(0x0200e000, 0x0200e00b) AM_MIRROR(0x300000) AM_DEVICE("keyboard", nextkbd_device, amap)
|
|
// AM_RANGE(0x0200f000, 0x0200f003) AM_MIRROR(0x300000) printer
|
|
// AM_RANGE(0x02010000, 0x02010003) AM_MIRROR(0x300000) brightness
|
|
AM_RANGE(0x02012000, 0x0201201f) AM_MIRROR(0x300000) AM_DEVICE8("mo", nextmo_device, map, 0xffffffff)
|
|
AM_RANGE(0x02014000, 0x0201400f) AM_MIRROR(0x300000) AM_DEVICE8("scsibus:7:ncr5390", ncr5390_device, map, 0xffffffff)
|
|
AM_RANGE(0x02014020, 0x02014023) AM_MIRROR(0x300000) AM_READWRITE(scsictrl_r, scsictrl_w)
|
|
AM_RANGE(0x02016000, 0x02016003) AM_MIRROR(0x300000) AM_READWRITE(timer_data_r, timer_data_w)
|
|
AM_RANGE(0x02016004, 0x02016007) AM_MIRROR(0x300000) AM_READWRITE(timer_ctrl_r, timer_ctrl_w)
|
|
AM_RANGE(0x02018000, 0x02018003) AM_MIRROR(0x300000) AM_DEVREADWRITE8("scc", scc8530_t, reg_r, reg_w, 0xffffffff)
|
|
// AM_RANGE(0x02018004, 0x02018007) AM_MIRROR(0x300000) SCC CLK
|
|
// AM_RANGE(0x02018190, 0x02018197) AM_MIRROR(0x300000) warp 9c DRAM timing
|
|
// AM_RANGE(0x02018198, 0x0201819f) AM_MIRROR(0x300000) warp 9c VRAM timing
|
|
AM_RANGE(0x0201a000, 0x0201a003) AM_MIRROR(0x300000) AM_READ(event_counter_r) // EVENTC
|
|
// AM_RANGE(0x020c0000, 0x020c0004) AM_MIRROR(0x300000) BMAP
|
|
AM_RANGE(0x020c0030, 0x020c0037) AM_MIRROR(0x300000) AM_READWRITE(phy_r, phy_w)
|
|
AM_RANGE(0x04000000, 0x07ffffff) AM_RAM //work ram
|
|
// AM_RANGE(0x0c000000, 0x0c03ffff) video RAM w A+B-AB function
|
|
// AM_RANGE(0x0d000000, 0x0d03ffff) video RAM w (1-A)B function
|
|
// AM_RANGE(0x0e000000, 0x0e03ffff) video RAM w ceil(A+B) function
|
|
// AM_RANGE(0x0f000000, 0x0f03ffff) video RAM w AB function
|
|
// AM_RANGE(0x10000000, 0x1003ffff) main RAM w A+B-AB function
|
|
// AM_RANGE(0x14000000, 0x1403ffff) main RAM w (1-A)B function
|
|
// AM_RANGE(0x18000000, 0x1803ffff) main RAM w ceil(A+B) function
|
|
// AM_RANGE(0x1c000000, 0x1c03ffff) main RAM w AB function
|
|
ADDRESS_MAP_END
|
|
|
|
static ADDRESS_MAP_START( next_0b_m_nofdc_mem, AS_PROGRAM, 32, next_state )
|
|
AM_RANGE(0x0b000000, 0x0b03ffff) AM_RAM AM_SHARE("vram")
|
|
|
|
AM_IMPORT_FROM(next_mem)
|
|
ADDRESS_MAP_END
|
|
|
|
static ADDRESS_MAP_START( next_fdc_mem, AS_PROGRAM, 32, next_state )
|
|
AM_RANGE(0x02014100, 0x02014107) AM_MIRROR(0x300000) AM_DEVICE8("fdc", n82077aa_device, map, 0xffffffff)
|
|
AM_RANGE(0x02014108, 0x0201410b) AM_MIRROR(0x300000) AM_READWRITE(fdc_control_r, fdc_control_w)
|
|
|
|
AM_IMPORT_FROM(next_mem)
|
|
ADDRESS_MAP_END
|
|
|
|
static ADDRESS_MAP_START( next_0b_m_mem, AS_PROGRAM, 32, next_state )
|
|
AM_RANGE(0x0b000000, 0x0b03ffff) AM_RAM AM_SHARE("vram")
|
|
|
|
AM_IMPORT_FROM(next_fdc_mem)
|
|
ADDRESS_MAP_END
|
|
|
|
static ADDRESS_MAP_START( next_0c_m_mem, AS_PROGRAM, 32, next_state )
|
|
AM_RANGE(0x0c000000, 0x0c1fffff) AM_RAM AM_SHARE("vram")
|
|
|
|
AM_IMPORT_FROM(next_fdc_mem)
|
|
ADDRESS_MAP_END
|
|
|
|
static ADDRESS_MAP_START( next_0c_c_mem, AS_PROGRAM, 32, next_state )
|
|
AM_RANGE(0x0c000000, 0x0c1fffff) AM_RAM AM_SHARE("vram")
|
|
AM_RANGE(0x02018180, 0x02018183) AM_MIRROR(0x300000) AM_WRITE8(ramdac_w, 0xffffffff)
|
|
|
|
AM_IMPORT_FROM(next_fdc_mem)
|
|
ADDRESS_MAP_END
|
|
|
|
static ADDRESS_MAP_START( next_2c_c_mem, AS_PROGRAM, 32, next_state )
|
|
AM_RANGE(0x2c000000, 0x2c1fffff) AM_RAM AM_SHARE("vram")
|
|
AM_RANGE(0x02018180, 0x02018183) AM_MIRROR(0x300000) AM_WRITE8(ramdac_w, 0xffffffff)
|
|
|
|
AM_IMPORT_FROM(next_fdc_mem)
|
|
ADDRESS_MAP_END
|
|
|
|
|
|
/* Input ports */
|
|
static INPUT_PORTS_START( next )
|
|
INPUT_PORTS_END
|
|
|
|
FLOPPY_FORMATS_MEMBER( next_state::floppy_formats )
|
|
FLOPPY_PC_FORMAT
|
|
FLOPPY_FORMATS_END
|
|
|
|
static SLOT_INTERFACE_START( next_floppies )
|
|
SLOT_INTERFACE( "35ed", FLOPPY_35_ED )
|
|
SLOT_INTERFACE_END
|
|
|
|
static SLOT_INTERFACE_START( next_scsi_devices )
|
|
SLOT_INTERFACE("cdrom", NSCSI_CDROM)
|
|
SLOT_INTERFACE("harddisk", NSCSI_HARDDISK)
|
|
SLOT_INTERFACE_INTERNAL("ncr5390", NCR5390)
|
|
SLOT_INTERFACE_END
|
|
|
|
static MACHINE_CONFIG_FRAGMENT( ncr5390 )
|
|
MCFG_DEVICE_CLOCK(10000000)
|
|
MCFG_NCR5390_IRQ_HANDLER(DEVWRITELINE(":", next_state, scsi_irq))
|
|
MCFG_NCR5390_DRQ_HANDLER(DEVWRITELINE(":", next_state, scsi_drq))
|
|
MACHINE_CONFIG_END
|
|
|
|
static MACHINE_CONFIG_START( next_base, next_state )
|
|
|
|
/* video hardware */
|
|
MCFG_SCREEN_ADD("screen", RASTER)
|
|
MCFG_SCREEN_REFRESH_RATE(60)
|
|
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
|
|
MCFG_SCREEN_UPDATE_DRIVER(next_state, screen_update)
|
|
MCFG_SCREEN_SIZE(1120, 900)
|
|
MCFG_SCREEN_VISIBLE_AREA(0, 1120-1, 0, 832-1)
|
|
MCFG_SCREEN_VBLANK_DRIVER(next_state, vblank_w)
|
|
|
|
// devices
|
|
MCFG_NSCSI_BUS_ADD("scsibus")
|
|
MCFG_DEVICE_ADD("rtc", MCCS1850, XTAL_32_768kHz)
|
|
MCFG_DEVICE_ADD("scc", SCC8530, XTAL_25MHz)
|
|
MCFG_Z8530_INTRQ_CALLBACK(WRITELINE(next_state, scc_irq))
|
|
MCFG_DEVICE_ADD("keyboard", NEXTKBD, 0)
|
|
MCFG_NEXTKBD_INT_CHANGE_CALLBACK(WRITELINE(next_state, keyboard_irq))
|
|
MCFG_NEXTKBD_INT_POWER_CALLBACK(WRITELINE(next_state, power_irq))
|
|
MCFG_NEXTKBD_INT_NMI_CALLBACK(WRITELINE(next_state, nmi_irq))
|
|
MCFG_NSCSI_ADD("scsibus:0", next_scsi_devices, "harddisk", false)
|
|
MCFG_NSCSI_ADD("scsibus:1", next_scsi_devices, "cdrom", false)
|
|
MCFG_NSCSI_ADD("scsibus:2", next_scsi_devices, 0, false)
|
|
MCFG_NSCSI_ADD("scsibus:3", next_scsi_devices, 0, false)
|
|
MCFG_NSCSI_ADD("scsibus:4", next_scsi_devices, 0, false)
|
|
MCFG_NSCSI_ADD("scsibus:5", next_scsi_devices, 0, false)
|
|
MCFG_NSCSI_ADD("scsibus:6", next_scsi_devices, 0, false)
|
|
MCFG_NSCSI_ADD("scsibus:7", next_scsi_devices, "ncr5390", true)
|
|
MCFG_DEVICE_CARD_MACHINE_CONFIG("ncr5390", ncr5390)
|
|
|
|
MCFG_DEVICE_ADD("net", MB8795, 0)
|
|
MCFG_MB8795_TX_IRQ_CALLBACK(WRITELINE(next_state, net_tx_irq))
|
|
MCFG_MB8795_RX_IRQ_CALLBACK(WRITELINE(next_state, net_rx_irq))
|
|
MCFG_MB8795_TX_DRQ_CALLBACK(WRITELINE(next_state, net_tx_drq))
|
|
MCFG_MB8795_RX_DRQ_CALLBACK(WRITELINE(next_state, net_rx_drq))
|
|
|
|
MCFG_DEVICE_ADD("mo", NEXTMO, 0)
|
|
MCFG_NEXTMO_IRQ_CALLBACK(WRITELINE(next_state, mo_irq))
|
|
MCFG_NEXTMO_DRQ_CALLBACK(WRITELINE(next_state, mo_drq))
|
|
MACHINE_CONFIG_END
|
|
|
|
static MACHINE_CONFIG_DERIVED( next, next_base )
|
|
MCFG_CPU_ADD("maincpu", M68030, XTAL_25MHz)
|
|
MCFG_CPU_PROGRAM_MAP(next_0b_m_nofdc_mem)
|
|
MACHINE_CONFIG_END
|
|
|
|
static MACHINE_CONFIG_DERIVED( next_fdc_base, next_base )
|
|
MCFG_N82077AA_ADD("fdc", n82077aa_device::MODE_PS2)
|
|
MCFG_UPD765_INTRQ_CALLBACK(WRITELINE(next_state, fdc_irq))
|
|
MCFG_UPD765_DRQ_CALLBACK(WRITELINE(next_state, fdc_drq))
|
|
MCFG_FLOPPY_DRIVE_ADD("fdc:0", next_floppies, "35ed", next_state::floppy_formats)
|
|
|
|
// software list
|
|
MCFG_SOFTWARE_LIST_ADD("flop_list", "next")
|
|
MACHINE_CONFIG_END
|
|
|
|
static MACHINE_CONFIG_DERIVED( nexts, next_fdc_base )
|
|
MCFG_CPU_ADD("maincpu", M68040, XTAL_25MHz)
|
|
MCFG_CPU_PROGRAM_MAP(next_0b_m_mem)
|
|
MACHINE_CONFIG_END
|
|
|
|
static MACHINE_CONFIG_DERIVED( nexts2, next_fdc_base )
|
|
MCFG_CPU_ADD("maincpu", M68040, XTAL_25MHz)
|
|
MCFG_CPU_PROGRAM_MAP(next_0b_m_mem)
|
|
MACHINE_CONFIG_END
|
|
|
|
static MACHINE_CONFIG_DERIVED( nextsc, next_fdc_base )
|
|
MCFG_CPU_ADD("maincpu", M68040, XTAL_25MHz)
|
|
MCFG_CPU_PROGRAM_MAP(next_2c_c_mem)
|
|
MACHINE_CONFIG_END
|
|
|
|
static MACHINE_CONFIG_DERIVED( nextst, next_fdc_base )
|
|
MCFG_CPU_ADD("maincpu", M68040, XTAL_33MHz)
|
|
MCFG_CPU_PROGRAM_MAP(next_0b_m_mem)
|
|
MACHINE_CONFIG_END
|
|
|
|
static MACHINE_CONFIG_DERIVED( nextstc, next_fdc_base )
|
|
MCFG_CPU_ADD("maincpu", M68040, XTAL_33MHz)
|
|
MCFG_CPU_PROGRAM_MAP(next_0c_c_mem)
|
|
MCFG_SCREEN_MODIFY("screen")
|
|
MCFG_SCREEN_VISIBLE_AREA(0, 832-1, 0, 624-1)
|
|
MACHINE_CONFIG_END
|
|
|
|
static MACHINE_CONFIG_DERIVED( nextct, next_fdc_base )
|
|
MCFG_CPU_ADD("maincpu", M68040, XTAL_33MHz)
|
|
MCFG_CPU_PROGRAM_MAP(next_0c_m_mem)
|
|
MACHINE_CONFIG_END
|
|
|
|
static MACHINE_CONFIG_DERIVED( nextctc, next_fdc_base )
|
|
MCFG_CPU_ADD("maincpu", M68040, XTAL_33MHz)
|
|
MCFG_CPU_PROGRAM_MAP(next_0c_c_mem)
|
|
MCFG_SCREEN_MODIFY("screen")
|
|
MCFG_SCREEN_VISIBLE_AREA(0, 832-1, 0, 624-1)
|
|
MACHINE_CONFIG_END
|
|
|
|
/* ROM definition */
|
|
#define ROM_NEXT_V1 \
|
|
ROM_REGION32_BE( 0x20000, "user1", ROMREGION_ERASEFF ) \
|
|
ROM_SYSTEM_BIOS( 0, "v12", "v1.2" ) /* MAC address/serial number word at 0xC: 005AD0 */ \
|
|
ROMX_LOAD( "rev_1.2.bin", 0x0000, 0x10000, CRC(7070bd78) SHA1(e34418423da61545157e36b084e2068ad41c9e24), ROM_BIOS(1)) /* Label: "(C) 1990 NeXT, Inc. // All Rights Reserved. // Release 1.2 // 1142.02", underlabel exists but unknown */ \
|
|
ROM_SYSTEM_BIOS( 1, "v10", "v1.0 v41" ) /* MAC address/serial number word at 0xC: 003090 */ \
|
|
ROMX_LOAD( "rev_1.0_v41.bin", 0x0000, 0x10000, CRC(54df32b9) SHA1(06e3ecf09ab67a571186efd870e6b44028612371), ROM_BIOS(2)) /* Label: "(C) 1989 NeXT, Inc. // All Rights Reserved. // Release 1.0 // 1142.00", underlabel: "MYF // 1.0.41 // 0D5C" */ \
|
|
ROM_SYSTEM_BIOS( 2, "v10p", "v1.0 v41 alternate" ) /* MAC address/serial number word at 0xC: 0023D9 */ \
|
|
ROMX_LOAD( "rev_1.0_proto.bin", 0x0000, 0x10000, CRC(F44974F9) SHA1(09EAF9F5D47E379CFA0E4DC377758A97D2869DDC), ROM_BIOS(3)) /* Label: "(C) 1989 NeXT, Inc. // All Rights Reserved. // Release 1.0 // 1142.00", no underlabel */
|
|
|
|
#define ROM_NEXT_V2 \
|
|
ROM_REGION32_BE( 0x20000, "user1", ROMREGION_ERASEFF ) \
|
|
ROM_SYSTEM_BIOS( 0, "v25", "v2.5 v66" ) /* MAC address/serial number word at 0xC: 00F302 */ \
|
|
ROMX_LOAD( "rev_2.5_v66.bin", 0x0000, 0x20000, CRC(f47e0bfe) SHA1(b3534796abae238a0111299fc406a9349f7fee24), ROM_BIOS(1)) \
|
|
ROM_SYSTEM_BIOS( 1, "v24", "v2.4 v65" ) /* MAC address/serial number word at 0xC: 00A634 */ \
|
|
ROMX_LOAD( "rev_2.4_v65.bin", 0x0000, 0x20000, CRC(74e9e541) SHA1(67d195351288e90818336c3a84d55e6a070960d2), ROM_BIOS(2)) \
|
|
ROM_SYSTEM_BIOS( 2, "v22", "v2.2 v63" ) /* MAC address/serial number word at 0xC: 00894C */ \
|
|
ROMX_LOAD( "rev_2.2_v63.bin", 0x0000, 0x20000, CRC(739D7C07) SHA1(48FFE54CF2038782A92A0850337C5C6213C98571), ROM_BIOS(3)) /* Label: "(C) 1990 NeXT Computer, Inc. // All Rights Reserved. // Release 2.1 // 2918.AB" */ \
|
|
ROM_SYSTEM_BIOS( 3, "v21", "v2.1 v59" ) /* MAC address/serial number word at 0xC: 0072FE */ \
|
|
ROMX_LOAD( "rev_2.1_v59.bin", 0x0000, 0x20000, CRC(f20ef956) SHA1(09586c6de1ca73995f8c9b99870ee3cc9990933a), ROM_BIOS(4)) \
|
|
ROM_SYSTEM_BIOS( 4, "v12", "v1.2 v58" ) /* MAC address/serial number word at 0xC: 006372 */ \
|
|
ROMX_LOAD( "rev_1.2_v58.bin", 0x0000, 0x20000, CRC(B815B6A4) SHA1(97D8B09D03616E1487E69D26609487486DB28090), ROM_BIOS(5)) /* Label: "V58 // (C) 1990 NeXT, Inc. // All Rights Reserved // Release 1.2 // 1142.02" */
|
|
|
|
#define ROM_NEXT_V3 \
|
|
ROM_REGION32_BE( 0x20000, "user1", ROMREGION_ERASEFF ) \
|
|
ROM_SYSTEM_BIOS( 0, "v33", "v3.3 v74" ) /* MAC address/serial number word at 0xC: 123456 */ \
|
|
ROMX_LOAD( "rev_3.3_v74.bin", 0x0000, 0x20000, CRC(fbc3a2cd) SHA1(a9bef655f26f97562de366e4a33bb462e764c929), ROM_BIOS(1)) \
|
|
ROM_SYSTEM_BIOS( 1, "v32", "v3.2 v72" ) /* MAC address/serial number word at 0xC: 012f31 */ \
|
|
ROMX_LOAD( "rev_3.2_v72.bin", 0x0000, 0x20000, CRC(e750184f) SHA1(ccebf03ed090a79c36f761265ead6cd66fb04329), ROM_BIOS(2)) \
|
|
ROM_SYSTEM_BIOS( 2, "v30", "v3.0 v70" ) /* MAC address/serial number word at 0xC: 0106e8 */ \
|
|
ROMX_LOAD( "rev_3.0_v70.bin", 0x0000, 0x20000, CRC(37250453) SHA1(a7e42bd6a25c61903c8ca113d0b9a624325ee6cf), ROM_BIOS(3))
|
|
|
|
|
|
ROM_START(next)
|
|
ROM_NEXT_V1
|
|
ROM_END
|
|
|
|
ROM_START(nexts)
|
|
ROM_NEXT_V2
|
|
ROM_END
|
|
|
|
ROM_START(nexts2)
|
|
ROM_NEXT_V2
|
|
ROM_END
|
|
|
|
ROM_START(nextsc)
|
|
ROM_NEXT_V2
|
|
ROM_END
|
|
|
|
ROM_START(nextst)
|
|
ROM_NEXT_V3
|
|
ROM_END
|
|
|
|
ROM_START(nextstc)
|
|
ROM_NEXT_V3
|
|
ROM_END
|
|
|
|
ROM_START(nextct)
|
|
ROM_NEXT_V3
|
|
ROM_END
|
|
|
|
ROM_START(nextctc)
|
|
ROM_NEXT_V3
|
|
ROM_END
|
|
|
|
DRIVER_INIT_MEMBER(next_state,next)
|
|
{
|
|
setup(0x00010002, 1120, 832, 2, false);
|
|
}
|
|
|
|
DRIVER_INIT_MEMBER(next_state,nexts)
|
|
{
|
|
setup(0x00011002, 1120, 832, 2, false);
|
|
}
|
|
|
|
DRIVER_INIT_MEMBER(next_state,nexts2)
|
|
{
|
|
setup(0x00012102, 1120, 832, 2, false);
|
|
}
|
|
|
|
DRIVER_INIT_MEMBER(next_state,nextsc)
|
|
{
|
|
setup(0x00013102, 1120, 832, 16, true);
|
|
}
|
|
|
|
DRIVER_INIT_MEMBER(next_state,nextst)
|
|
{
|
|
setup(0x00014103, 1120, 832, 2, false);
|
|
}
|
|
|
|
DRIVER_INIT_MEMBER(next_state,nextstc)
|
|
{
|
|
setup(0x00015103, 832, 624, 0, true);
|
|
}
|
|
|
|
DRIVER_INIT_MEMBER(next_state,nextct)
|
|
{
|
|
setup(0x00018103, 1120, 832, 0, false);
|
|
}
|
|
|
|
DRIVER_INIT_MEMBER(next_state,nextctc)
|
|
{
|
|
setup(0x00019103, 832, 624, 0, true);
|
|
}
|
|
|
|
/* Driver */
|
|
|
|
/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */
|
|
COMP( 1987, next, 0, 0, next, next, next_state, next, "Next Software Inc", "NeXT Cube", GAME_NOT_WORKING | GAME_NO_SOUND)
|
|
COMP( 1990, nexts, 0, 0, nexts, next, next_state, nexts, "Next Software Inc", "NeXTstation", GAME_NOT_WORKING | GAME_NO_SOUND)
|
|
COMP( 1990, nexts2, nexts, 0, nexts2, next, next_state, nexts2, "Next Software Inc", "NeXTstation (X15 variant)", GAME_NOT_WORKING | GAME_NO_SOUND)
|
|
COMP( 1990, nextsc, nexts, 0, nextsc, next, next_state, nextsc, "Next Software Inc", "NeXTstation color", GAME_NOT_WORKING | GAME_NO_SOUND)
|
|
COMP( 1990, nextst, 0, 0, nextst, next, next_state, nextst, "Next Software Inc", "NeXTstation turbo", GAME_NOT_WORKING | GAME_NO_SOUND)
|
|
COMP( 1990, nextstc, nextst, 0, nextstc, next, next_state, nextstc, "Next Software Inc", "NeXTstation turbo color", GAME_NOT_WORKING | GAME_NO_SOUND)
|
|
COMP( ????, nextct, nextst, 0, nextct, next, next_state, nextct, "Next Software Inc", "NeXT Cube turbo", GAME_NOT_WORKING | GAME_NO_SOUND)
|
|
COMP( ????, nextctc, nextst, 0, nextctc, next, next_state, nextctc, "Next Software Inc", "NeXT Cube turbo color", GAME_NOT_WORKING | GAME_NO_SOUND)
|