|
|
Previous NeXT emulator
#include "configuration.h"
#include "m68000.h"
#include "dimension.hpp"
#include "nd_nbic.hpp"
#include "nd_mem.hpp"
#include "nd_sdl.hpp"
NextDimension::NextDimension(int slot) :
NextBusBoard(slot),
sdl(slot, (Uint32*)vram),
i860(this),
nbic(slot, ND_NBIC_ID),
mc(this),
dp(this),
dmcd(this),
dcsc0(this, 0),
dcsc1(this, 1),
rom_command(0),
rom_last_addr(0)
{
i860.uninit();
nbic.init();
mc.init();
dp.init();
mem_init();
i860.init();
sdl.init();
}
NextDimension::~NextDimension() {
i860.uninit();
sdl.destroy();
}
void NextDimension::reset(void) {
i860.set_run_func();
sdl.start_interrupts();
}
void NextDimension::pause(bool pause) {
i860.pause(pause);
sdl.pause(pause);
}
/* NeXTdimension board memory access (m68k) */
Uint32 NextDimension::board_lget(Uint32 addr) {
addr |= ND_BOARD_BITS;
Uint32 result = nd68k_longget(addr);
// (SC) delay m68k read on csr0 while in ROM (CS8=1)to give ND some time to start up.
if(addr == 0xFF800000 && (result & 0x02))
M68000_AddCycles(ConfigureParams.System.nCpuFreq * 100);
return result;
}
Uint16 NextDimension::board_wget(Uint32 addr) {
addr |= ND_BOARD_BITS;
return nd68k_wordget(addr);
}
Uint8 NextDimension::board_bget(Uint32 addr) {
addr |= ND_BOARD_BITS;
return nd68k_byteget(addr);
}
void NextDimension::board_lput(Uint32 addr, Uint32 l) {
addr |= ND_BOARD_BITS;
nd68k_longput(addr, l);
}
void NextDimension::board_wput(Uint32 addr, Uint16 w) {
addr |= ND_BOARD_BITS;
nd68k_wordput(addr, w);
}
void NextDimension::board_bput(Uint32 addr, Uint8 b) {
addr |= ND_BOARD_BITS;
nd68k_byteput(addr, b);
}
/* NeXTdimension slot memory access */
Uint32 NextDimension::slot_lget(Uint32 addr) {
addr |= ND_SLOT_BITS;
if (addr<ND_NBIC_SPACE) {
return nd68k_longget(addr);
} else {
return nbic.lget(addr);
}
}
Uint16 NextDimension::slot_wget(Uint32 addr) {
addr |= ND_SLOT_BITS;
if (addr<ND_NBIC_SPACE) {
return nd68k_wordget(addr);
} else {
return nbic.wget(addr);
}
}
Uint8 NextDimension::slot_bget(Uint32 addr) {
addr |= ND_SLOT_BITS;
if (addr<ND_NBIC_SPACE) {
return nd68k_byteget(addr);
} else {
return nbic.bget(addr);
}
}
void NextDimension::slot_lput(Uint32 addr, Uint32 l) {
addr |= ND_SLOT_BITS;
if (addr<ND_NBIC_SPACE) {
nd68k_longput(addr, l);
} else {
nbic.lput(addr, l);
}
}
void NextDimension::slot_wput(Uint32 addr, Uint16 w) {
addr |= ND_SLOT_BITS;
if (addr<ND_NBIC_SPACE) {
nd68k_wordput(addr, w);
} else {
nbic.wput(addr, w);
}
}
void NextDimension::slot_bput(Uint32 addr, Uint8 b) {
addr |= ND_SLOT_BITS;
if (addr<ND_NBIC_SPACE) {
nd68k_byteput(addr, b);
} else {
nbic.bput(addr, b);
}
}
void NextDimension::send_msg(int msg) {
host_lock(&m_port_lock);
m_port |= msg;
host_unlock(&m_port_lock);
}
/* NeXTdimension board memory access (i860) */
Uint8 NextDimension::i860_cs8get(NextDimension* nd, Uint32 addr) {
addr |= ND_BOARD_BITS;
return nd_cs8get(addr);
}
void NextDimension::i860_rd8_be(NextDimension* nd, Uint32 addr, Uint32* val) {
addr |= ND_BOARD_BITS;
*((Uint8*)val) = nd_byteget(addr);
}
void NextDimension::i860_rd16_be(NextDimension* nd, Uint32 addr, Uint32* val) {
addr |= ND_BOARD_BITS;
*((Uint16*)val) = nd_wordget(addr);
}
void NextDimension::i860_rd32_be(NextDimension* nd, Uint32 addr, Uint32* val) {
addr |= ND_BOARD_BITS;
val[0] = nd_longget(addr);
}
void NextDimension::i860_rd64_be(NextDimension* nd, Uint32 addr, Uint32* val) {
addr |= ND_BOARD_BITS;
val[0] = nd_longget(addr+4);
val[1] = nd_longget(addr+0);
}
void NextDimension::i860_rd128_be(NextDimension* nd, Uint32 addr, Uint32* val) {
addr |= ND_BOARD_BITS;
val[0] = nd_longget(addr+4);
val[1] = nd_longget(addr+0);
val[2] = nd_longget(addr+12);
val[3] = nd_longget(addr+8);
}
void NextDimension::i860_wr8_be(NextDimension* nd, Uint32 addr, const Uint32* val) {
addr |= ND_BOARD_BITS;
nd_byteput(addr, *((const Uint8*)val));
}
void NextDimension::i860_wr16_be(NextDimension* nd, Uint32 addr, const Uint32* val) {
addr |= ND_BOARD_BITS;
nd_wordput(addr, *((const Uint16*)val));
}
void NextDimension::i860_wr32_be(NextDimension* nd, Uint32 addr, const Uint32* val) {
addr |= ND_BOARD_BITS;
nd_longput(addr, val[0]);
}
void NextDimension::i860_wr64_be(NextDimension* nd, Uint32 addr, const Uint32* val) {
addr |= ND_BOARD_BITS;
nd_longput(addr+4, val[0]);
nd_longput(addr+0, val[1]);
}
void NextDimension::i860_wr128_be(NextDimension* nd, Uint32 addr, const Uint32* val) {
addr |= ND_BOARD_BITS;
nd_longput(addr+4, val[0]);
nd_longput(addr+0, val[1]);
nd_longput(addr+12, val[2]);
nd_longput(addr+8, val[3]);
}
void NextDimension::i860_rd8_le(NextDimension* nd, Uint32 addr, Uint32* val) {
addr |= ND_BOARD_BITS;
*((Uint8*)val) = nd_byteget(addr^7);
}
void NextDimension::i860_rd16_le(NextDimension* nd, Uint32 addr, Uint32* val) {
addr |= ND_BOARD_BITS;
*((Uint16*)val) = nd_wordget(addr^6);
}
void NextDimension::i860_rd32_le(NextDimension* nd, Uint32 addr, Uint32* val) {
addr |= ND_BOARD_BITS;
val[0] = nd_longget(addr^4);
}
void NextDimension::i860_rd64_le(NextDimension* nd, Uint32 addr, Uint32* val) {
addr |= ND_BOARD_BITS;
val[0] = nd_longget(addr+0);
val[1] = nd_longget(addr+4);
}
void NextDimension::i860_rd128_le(NextDimension* nd, Uint32 addr, Uint32* val) {
addr |= ND_BOARD_BITS;
val[0] = nd_longget(addr+0);
val[1] = nd_longget(addr+4);
val[2] = nd_longget(addr+8);
val[3] = nd_longget(addr+12);
}
void NextDimension::i860_wr8_le(NextDimension* nd, Uint32 addr, const Uint32* val) {
addr |= ND_BOARD_BITS;
nd_byteput(addr^7, *((const Uint8*)val));
}
void NextDimension::i860_wr16_le(NextDimension* nd, Uint32 addr, const Uint32* val) {
addr |= ND_BOARD_BITS;
nd_wordput(addr^6, *((const Uint16*)val));
}
void NextDimension::i860_wr32_le(NextDimension* nd, Uint32 addr, const Uint32* val) {
addr |= ND_BOARD_BITS;
nd_longput(addr^4, val[0]);
}
void NextDimension::i860_wr64_le(NextDimension* nd, Uint32 addr, const Uint32* val) {
addr |= ND_BOARD_BITS;
nd_longput(addr+0, val[0]);
nd_longput(addr+4, val[1]);
}
void NextDimension::i860_wr128_le(NextDimension* nd, Uint32 addr, const Uint32* val) {
addr |= ND_BOARD_BITS;
nd_longput(addr+0, val[0]);
nd_longput(addr+4, val[1]);
nd_longput(addr+8, val[2]);
nd_longput(addr+12, val[3]);
}
/* Message disaptcher - executed on i860 thread, safe to call i860 methods */
bool NextDimension::handle_msgs(void) {
host_lock(&m_port_lock);
int msg = m_port;
m_port = 0;
host_unlock(&m_port_lock);
if(msg & MSG_DISPLAY_BLANK)
set_blank_state(ND_DISPLAY, host_blank_state(slot, ND_DISPLAY));
if(msg & MSG_VIDEO_BLANK)
set_blank_state(ND_VIDEO, host_blank_state(slot, ND_VIDEO));
return i860.handle_msgs(msg);
}
void nd_start_debugger(void) {
FOR_EACH_SLOT(slot) {
IF_NEXT_DIMENSION(slot, nd) {
nd->send_msg(MSG_DBG_BREAK);
}
}
}
extern "C" {
void nd_display_blank(int slot) {
((NextDimension*)nextbus[slot])->send_msg(MSG_DISPLAY_BLANK);
}
void nd_video_blank(int slot) {
((NextDimension*)nextbus[slot])->send_msg(MSG_VIDEO_BLANK);
}
const char* nd_reports(int slot, double realTime, double hostTime) {
return ((NextDimension*)nextbus[slot])->i860.reports(realTime, hostTime);
}
Uint32* nd_vram_for_slot(int slot) {
IF_NEXT_DIMENSION(slot, nd)
return (Uint32*)nd->vram;
else
return NULL;
}
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.