1
0
mirror of https://github.com/open-simh/simh.git synced 2026-04-28 21:07:43 +00:00

AltairZ80: M68K: Add support for memory-mapped I/O.

Allows the M68K CPU to take advantage of additional AltairZ80 peripherals.
This commit is contained in:
Howard M. Harte
2022-11-23 20:31:15 -08:00
committed by Paul Koning
parent 7094222ada
commit 6cd89205a3
2 changed files with 38 additions and 7 deletions

View File

@@ -145,6 +145,9 @@ extern uint8 MOPT[MAXBANKSIZE];
extern t_stat sim_instr_8086(void); extern t_stat sim_instr_8086(void);
extern void cpu8086reset(void); extern void cpu8086reset(void);
extern unsigned int m68k_cpu_read_byte_raw(unsigned int address);
void m68k_cpu_write_byte_raw(unsigned int address, unsigned int value);
/* function prototypes */ /* function prototypes */
static t_stat cpu_set_switcher (UNIT *uptr, int32 value, CONST char *cptr, void *desc); static t_stat cpu_set_switcher (UNIT *uptr, int32 value, CONST char *cptr, void *desc);
static t_stat cpu_reset_switcher(UNIT *uptr, int32 value, CONST char *cptr, void *desc); static t_stat cpu_reset_switcher(UNIT *uptr, int32 value, CONST char *cptr, void *desc);
@@ -278,11 +281,13 @@ typedef struct {
t_value op[INST_MAX_BYTES]; t_value op[INST_MAX_BYTES];
} insthist_t; } insthist_t;
static uint32 hst_p = 0; /* history pointer */ static uint32 hst_p = 0; /* history pointer */
static uint32 hst_lnt = 0; /* history length */ static uint32 hst_lnt = 0; /* history length */
static insthist_t *hst = NULL; /* instruction history */ static insthist_t *hst = NULL; /* instruction history */
uint32 m68k_registers[M68K_REG_CPU_TYPE + 1]; /* M68K CPU registers */ uint32 m68k_registers[M68K_REG_CPU_TYPE + 1]; /* M68K CPU registers */
uint32 mmiobase = 0xff0000; /* M68K MMIO base address */
uint32 mmiosize = 0x10000; /* M68K MMIO window size */
/* data structure for IN/OUT instructions */ /* data structure for IN/OUT instructions */
@@ -477,10 +482,14 @@ REG cpu_reg[] = {
}, /* 82 */ }, /* 82 */
{ HRDATAD(COMMONLOW,common_low, 1, "If set, use low memory for common area"), { HRDATAD(COMMONLOW,common_low, 1, "If set, use low memory for common area"),
}, /* 83 */ }, /* 83 */
{ HRDATAD(VECINT,vectorInterrupt, 2, "Vector Interrupt psuedo register"), { HRDATAD(VECINT,vectorInterrupt, 2, "Vector Interrupt pseudo register"),
}, /* 84 */ }, /* 84 */
{ BRDATAD (DATABUS, dataBus, 16, 8, MAX_INT_VECTORS, "Data bus pseudo register"), { BRDATAD (DATABUS, dataBus, 16, 8, MAX_INT_VECTORS, "Data bus pseudo register"),
REG_RO + REG_CIRC }, /* 85 */ REG_RO + REG_CIRC }, /* 85 */
{ HRDATAD(MMIOBASE, mmiobase, 24, "Base address for 68K Memory-mapped I/O"),
}, /* 86 */
{ HRDATAD(MMIOSIZE, mmiosize, 17, "Size of 68K Memory-mapped I/O window"),
}, /* 87 */
{ NULL } { NULL }
}; };
@@ -1962,6 +1971,8 @@ uint32 getCommon(void) {
uint8 GetBYTEWrapper(const uint32 Addr) { uint8 GetBYTEWrapper(const uint32 Addr) {
if (chiptype == CHIP_TYPE_8086) if (chiptype == CHIP_TYPE_8086)
return GetBYTEExtended(Addr); return GetBYTEExtended(Addr);
else if (chiptype == CHIP_TYPE_M68K)
return m68k_cpu_read_byte_raw(Addr);
else if (cpu_unit.flags & UNIT_CPU_MMU) else if (cpu_unit.flags & UNIT_CPU_MMU)
return GetBYTE(Addr); return GetBYTE(Addr);
else else
@@ -1972,6 +1983,8 @@ uint8 GetBYTEWrapper(const uint32 Addr) {
void PutBYTEWrapper(const uint32 Addr, const uint32 Value) { void PutBYTEWrapper(const uint32 Addr, const uint32 Value) {
if (chiptype == CHIP_TYPE_8086) if (chiptype == CHIP_TYPE_8086)
PutBYTEExtended(Addr, Value); PutBYTEExtended(Addr, Value);
else if (chiptype == CHIP_TYPE_M68K)
m68k_cpu_write_byte_raw(Addr, Value);
else if (cpu_unit.flags & UNIT_CPU_MMU) else if (cpu_unit.flags & UNIT_CPU_MMU)
PutBYTE(Addr, Value); PutBYTE(Addr, Value);
else else
@@ -1980,14 +1993,18 @@ void PutBYTEWrapper(const uint32 Addr, const uint32 Value) {
/* DMA memory access during a simulation, suggested by Tony Nicholson */ /* DMA memory access during a simulation, suggested by Tony Nicholson */
uint8 GetByteDMA(const uint32 Addr) { uint8 GetByteDMA(const uint32 Addr) {
if ((chiptype == CHIP_TYPE_8086) || (cpu_unit.flags & UNIT_CPU_MMU)) if (chiptype == CHIP_TYPE_M68K)
return m68k_cpu_read_byte_raw(Addr);
else if ((chiptype == CHIP_TYPE_8086) || (cpu_unit.flags & UNIT_CPU_MMU))
return GetBYTEExtended(Addr); return GetBYTEExtended(Addr);
else else
return MOPT[Addr & ADDRMASK]; return MOPT[Addr & ADDRMASK];
} }
void PutByteDMA(const uint32 Addr, const uint32 Value) { void PutByteDMA(const uint32 Addr, const uint32 Value) {
if ((chiptype == CHIP_TYPE_8086) || (cpu_unit.flags & UNIT_CPU_MMU)) if (chiptype == CHIP_TYPE_M68K)
m68k_cpu_write_byte_raw(Addr, Value);
else if ((chiptype == CHIP_TYPE_8086) || (cpu_unit.flags & UNIT_CPU_MMU))
PutBYTEExtended(Addr, Value); PutBYTEExtended(Addr, Value);
else else
MOPT[Addr & ADDRMASK] = Value & 0xff; MOPT[Addr & ADDRMASK] = Value & 0xff;

View File

@@ -154,10 +154,16 @@ extern int32 hdsk_read(void);
extern int32 hdsk_write(void); extern int32 hdsk_write(void);
extern int32 hdsk_flush(void); extern int32 hdsk_flush(void);
/* Interface to SIMH I/O devices */
extern void out(const uint32 Port, const uint32 Value);
extern uint32 in(const uint32 Port);
static uint32 m68k_fc; /* Current function code from CPU */ static uint32 m68k_fc; /* Current function code from CPU */
extern uint32 m68k_registers[M68K_REG_CPU_TYPE + 1]; extern uint32 m68k_registers[M68K_REG_CPU_TYPE + 1];
extern UNIT cpu_unit; extern UNIT cpu_unit;
extern uint32 mmiobase; /* M68K MMIO base address */
extern uint32 mmiosize; /* M68K MMIO window size */
#define M68K_BOOT_LENGTH (32 * 1024) /* size of bootstrap */ #define M68K_BOOT_LENGTH (32 * 1024) /* size of bootstrap */
#define M68K_BOOT_PC 0x000400 /* initial PC for boot */ #define M68K_BOOT_PC 0x000400 /* initial PC for boot */
@@ -350,6 +356,10 @@ unsigned int m68k_cpu_read_byte(unsigned int address) {
case MC6850_STAT: case MC6850_STAT:
return MC6850_status_read(); return MC6850_status_read();
default: default:
if ((address >= mmiobase) && (address < mmiobase + mmiosize)) {
/* Memory-mapped I/O */
return (in(address & 0xff) & 0xff);
}
break; break;
} }
if (address > M68K_MAX_RAM) { if (address > M68K_MAX_RAM) {
@@ -416,6 +426,10 @@ void m68k_cpu_write_byte(unsigned int address, unsigned int value) {
MC6850_control_write(value & 0xff); MC6850_control_write(value & 0xff);
return; return;
default: default:
if ((address >= mmiobase) && (address < mmiobase + mmiosize)) {
/* Memory-mapped I/O */
out(address & 0xff, value & 0xff);
}
break; break;
} }
if (address > M68K_MAX_RAM) { if (address > M68K_MAX_RAM) {