/* 3b2_defs.h: AT&T 3B2 Model 400 system-specific logic implementation | |
Copyright (c) 2017, Seth J. Morabito | |
Permission is hereby granted, free of charge, to any person | |
obtaining a copy of this software and associated documentation | |
files (the "Software"), to deal in the Software without | |
restriction, including without limitation the rights to use, copy, | |
modify, merge, publish, distribute, sublicense, and/or sell copies | |
of the Software, and to permit persons to whom the Software is | |
furnished to do so, subject to the following conditions: | |
The above copyright notice and this permission notice shall be | |
included in all copies or substantial portions of the Software. | |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
SOFTWARE. | |
Except as contained in this notice, the name of the author shall | |
not be used in advertising or otherwise to promote the sale, use or | |
other dealings in this Software without prior written authorization | |
from the author. | |
*/ | |
#include "3b2_sys.h" | |
#include "3b2_cpu.h" | |
#include "3b2_iu.h" | |
#include "3b2_if.h" | |
#include "3b2_id.h" | |
#include "3b2_mmu.h" | |
#include "3b2_sysdev.h" | |
char sim_name[] = "AT&T 3B2 Model 400"; | |
REG *sim_PC = &cpu_reg[0]; | |
/* All opcodes are 1 or 2 bytes. Operands may be up to 6 bytes, and | |
there may be up to 3 operands, for a maximum of 20 bytes */ | |
int32 sim_emax = 20; | |
extern instr *cpu_instr; | |
DEVICE *sim_devices[] = { | |
&cpu_dev, | |
&mmu_dev, | |
&timer_dev, | |
&tod_dev, | |
&nvram_dev, | |
&csr_dev, | |
&tti_dev, | |
&tto_dev, | |
&contty_dev, | |
&iu_timer_dev, | |
&dmac_dev, | |
&if_dev, | |
&id_dev, | |
NULL | |
}; | |
const char *sim_stop_messages[] = { | |
"Unknown error", | |
"Reserved Instruction", | |
"Breakpoint", | |
"Invalid Opcode", | |
"IRQ", | |
"Exception/Trap", | |
"Exception Stack Too Deep", | |
"Unimplemented MMU Feature", | |
"System Powered Off" | |
}; | |
void full_reset() | |
{ | |
cpu_reset(&cpu_dev); | |
tti_reset(&tti_dev); | |
contty_reset(&contty_dev); | |
iu_timer_reset(&iu_timer_dev); | |
timer_reset(&timer_dev); | |
if_reset(&if_dev); | |
id_reset(&id_dev); | |
csr_reset(&csr_dev); | |
} | |
t_stat sim_load(FILE *fileref, CONST char *cptr, CONST char *fnam, int flag) | |
{ | |
int32 i; | |
uint32 addr = 0; | |
int32 cnt = 0; | |
if ((*cptr != 0) || (flag != 0)) { | |
return SCPE_ARG; | |
} | |
addr = R[NUM_PC]; | |
while ((i = getc (fileref)) != EOF) { | |
pwrite_b(addr, (uint8)i); | |
addr++; | |
cnt++; | |
} | |
printf ("%d Bytes loaded.\n", cnt); | |
return SCPE_OK; | |
} | |
t_stat parse_sym(CONST char *cptr, t_addr exta, UNIT *uptr, t_value *val, int32 sw) | |
{ | |
DEVICE *dptr; | |
t_stat r; | |
int32 k, num, vp; | |
int32 len = 4; | |
if (sw & (int32) SWMASK ('B')) { | |
len = 1; | |
} else if (sw & (int32) SWMASK ('H')) { | |
len = 2; | |
} else if (sw & (int32) SWMASK ('W')) { | |
len = 4; | |
} | |
// Parse cptr | |
num = (int32) get_uint(cptr, 16, WORD_MASK, &r); | |
if (r != SCPE_OK) { | |
return r; | |
} | |
if (uptr == NULL) { | |
uptr = &cpu_unit; | |
} | |
dptr = find_dev_from_unit(uptr); | |
if (dptr == NULL) { | |
return SCPE_IERR; | |
} | |
vp = 0; | |
for (k = len - 1; k >= 0; k--) { | |
val[vp++] = (num >> (k * 8)) & 0xff; | |
} | |
return -(vp - 1); | |
} | |
t_stat fprint_sym(FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw) | |
{ | |
uint32 len = 4; | |
int32 k, vp, num; | |
unsigned int c; | |
num = 0; | |
vp = 0; | |
if (sw & (int32) SWMASK('M')) { | |
return fprint_sym_m(of, addr, val); | |
} | |
if (sw & (int32) SWMASK ('B')) { | |
len = 1; | |
} else if (sw & (int32) SWMASK ('H')) { | |
len = 2; | |
} else if (sw & (int32) SWMASK ('W')) { | |
len = 4; | |
} | |
if (sw & (int32) SWMASK('C')) { | |
len = 16; | |
for (k = (int32) len - 1; k >= 0; k--) { | |
c = (unsigned int)val[vp++]; | |
if (c >= 0x20 && c < 0x7f) { | |
fprintf(of, "%c", c); | |
} else { | |
fprintf(of, "."); | |
} | |
} | |
return -(vp - 1); | |
} | |
for (k = len - 1; k >= 0; k--) { | |
num = num | (((int32) val[vp++]) << (k * 8)); | |
} | |
fprint_val(of, (uint32) num, 16, len * 8, PV_RZRO); | |
return -(vp - 1); | |
} |