1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-03-03 10:05:54 +00:00

Ridge32: Adding floating point, ROS better at booting.

This commit is contained in:
Richard Cornwell
2020-09-17 20:46:57 -04:00
parent 3730d30bc5
commit fcfd7d4681
8 changed files with 1746 additions and 207 deletions

View File

@@ -31,12 +31,14 @@
#define UNIT_LDENA (0x1 << UNIT_V_LDENA)
#define TMR_RTC 0
#define VRT2 0
#define HIST_MAX 5000000
#define HIST_MIN 64
#define HIST_PC 0x1000000
#define HIST_TRAP 0x2000000
#define HIST_USER 0x4000000
#define HIST_PC 0x2000000
#define HIST_TRAP 0x4000000
#define HIST_USER 0x8000000
#define HIST_MASK 0x1ffffff
uint32 *M = NULL;
uint32 regs[16]; /* CPU Registers */
@@ -44,6 +46,7 @@ uint32 PC; /* Program counter */
uint32 sregs[16]; /* Special registers */
uint32 tlb[32]; /* Translation look aside buffer */
uint32 vrt[32]; /* VRT address for Modify */
uint32 link[32]; /* Link to next entry */
uint8 user; /* Set when in user mode */
uint8 wait; /* Wait for interrupt */
uint8 ext_irq; /* External interrupt pending */
@@ -78,7 +81,7 @@ int boot_sw; /* Boot device */
#define FMASK 0xffffffff
#define AMASK 0x00ffffff
#define MSIGN 0x80000000
#define WMASK 0x00fffffe
#define WMASK 0xfffffffe
int hst_lnt;
int hst_p;
@@ -204,57 +207,174 @@ int TransAddr(t_addr va, t_addr *pa, uint8 code, uint wr) {
uint32 seg = ((code) ? sregs[8] : sregs[9]) & 0xFFFF;
uint32 mat = (seg << 16) | (va >> 16);
uint32 addr;
uint32 tag;
uint32 lk;
#if VRT2
/* If not the same, walk through VRT to find correct page */
if ((vrt[entry] & 0x7000) != 0x7000 || tlb[entry] != mat) {
uint32 ntag = (((seg + page) & sregs[13]) << 3);
uint32 tag;
uint32 link;
do {
tag = (ntag + sregs[12]) >> 2;
addr = M[tag++];
link = M[tag];
ntag = (link >> 16);
sim_debug(DEBUG_EXP, &cpu_dev,
"Load trans: %08x %08x -> %08x %08x %08x\n", seg, va, tag, addr, link);
} while (addr != mat && ntag != 0);
/* Did we find entry? */
if (addr != mat || (link & 0x7000) != 0x7000) {
if ((vrt[entry] & 0x2) == 0 || tlb[entry] != mat) {
uint32 ntag = (((seg + page) & sregs[13]) << 2) + sregs[12];
ntag = M[ntag >> 2];
if (ntag == 0) {
/* Nope this is a fault */
sregs[1] = -1;
sregs[1] = FMASK;
sregs[2] = seg;
sregs[3] = va;
trapcode = PGFLT;
sim_debug(DEBUG_EXP, &cpu_dev,
"Page fault: %08x %08x -> %08x %08x %08x\n", seg, va, tag, addr, link);
sim_debug(DEBUG_EXP, &cpu_dev,
"Page fault: %08x %08x -> %08x %08x %08x\n",
seg, va, tag << 2, addr, lk);
return 1;
}
do {
tag = ntag >> 2;
addr = M[tag++];
ntag = M[tag++];
lk = M[tag];
sim_debug(DEBUG_EXP, &cpu_dev,
"Load trans: %08x %08x %08x -> %08x %08x %08x\n",
seg, va, mat, tag << 2, addr, lk);
} while (addr != mat && ntag != 0);
/* Did we find entry? */
if (addr != mat || (lk & 0x2) == 0) {
/* Nope this is a fault */
sregs[1] = FMASK;
sregs[2] = seg;
sregs[3] = va;
trapcode = PGFLT;
sim_debug(DEBUG_EXP, &cpu_dev,
"Page fault: %08x %08x -> %08x %08x %08x\n",
seg, va, tag << 2, addr, lk);
return 1;
}
/* Check for write access */
if (wr && (lk & 0x4) == 0) {
/* Nope this is a fault */
sregs[1] = FMASK-1;
sregs[2] = seg;
sregs[3] = va;
trapcode = PGFLT;
sim_debug(DEBUG_EXP, &cpu_dev,
"Write fault: %08x %08x -> %08x %08x %08x\n",
seg, va, tag << 2, addr, lk);
return 1;
}
/* Update reference and modify bits */
sim_debug(DEBUG_EXP, &cpu_dev,
"Load Tlb: %08x %08x -> %08x %08x %08x\n", seg, va, tag, addr, link);
link |= 0x8000;
lk |= 0x10;
if (wr)
link |= 0x800;
lk |= 0x1;
/* Update the tlb entry */
M[tag] = link;
tag -= sregs[12] >> 2; /* Subtract offset. */
tag <<= 16; /* Move to upper half */
tag |= link & 0xFFFF; /* Copy link over */
vrt[entry] = tag; /* Save for furture */
M[tag] = lk;
link[entry] = tag; /* Save pointer to tag for modify */
vrt[entry] = lk; /* Save for furture */
tlb[entry] = mat;
addr = link;
addr = lk;
sim_debug(DEBUG_EXP, &cpu_dev, "Load Tlb: %08x %08x -> %08x %08x %08x\n",
seg, va, tag << 2, addr, lk);
} else {
/* Update modify bit if not already set */
addr = vrt[entry]; /* Tag and flag bits */
/* Check for write access */
if (wr && (lk & 0x4) == 0) {
/* Nope this is a fault */
sregs[1] = FMASK-1;
sregs[2] = seg;
sregs[3] = va;
trapcode = PGFLT;
sim_debug(DEBUG_EXP, &cpu_dev,
"Write fault: %08x %08x -> %08x %08x %08x\n",
seg, va, tag << 2, addr, lk);
return 1;
}
if (wr && (addr & 0x1) == 0) {
tag = link[entry];
M[tag] |= 0x1;
vrt[entry] |= 0x1;
sim_debug(DEBUG_EXP, &cpu_dev,
"Mod Tlb: %08x %08x -> %08x %08x\n", seg, va, tag << 2, vrt[entry]);
}
}
*pa = ((addr & 0x7fff0000) >> 4) | (va & 0xfff);
#else
/* If not the same, walk through VRT to find correct page */
if ((vrt[entry] & 0x7000) == 0 || tlb[entry] != mat) {
uint32 ntag = (((seg + page) & sregs[13]) << 3);
do {
tag = (ntag + sregs[12]) >> 2;
addr = M[tag++];
lk = M[tag];
ntag = (lk >> 16);
sim_debug(DEBUG_EXP, &cpu_dev,
"Load trans: %08x %08x %08x -> %08x %08x %08x\n",
seg, va, mat, tag << 2, addr, lk);
} while (addr != mat && ntag != 0);
/* Did we find entry? */
if (addr != mat || (lk & 0x7000) == 0) {
/* Nope this is a fault */
sregs[1] = FMASK;
sregs[2] = seg;
sregs[3] = va;
trapcode = PGFLT;
sim_debug(DEBUG_EXP, &cpu_dev,
"Page fault: %08x %08x -> %08x %08x %08x\n",
seg, va, tag << 2, addr, lk);
return 1;
}
#if 0
/* Check if copy on write */
if (wr && (lk & 0x4000) == 0) {
/* Nope this is a fault */
/* Update the tlb entry */
M[tag] = lk | 0xc800;
sregs[1] = FMASK;
sregs[2] = seg;
sregs[3] = va;
trapcode = PGFLT;
sim_debug(DEBUG_EXP, &cpu_dev,
"Write fault: %08x %08x -> %08x %08x %08x\n",
seg, va, tag << 2, addr, lk);
return 1;
}
#endif
/* Update reference and modify bits */
lk |= 0x8000;
if (wr)
lk |= 0x800;
/* Update the tlb entry */
M[tag] = lk;
link[entry] = tag; /* Save pointer to tag for modify */
vrt[entry] = lk; /* Save for furture */
tlb[entry] = mat;
addr = lk;
sim_debug(DEBUG_EXP, &cpu_dev, "Load Tlb: %08x %08x -> %08x %08x %08x\n",
seg, va, tag << 2, addr, lk);
} else {
/* Update modify bit if not already set */
addr = vrt[entry]; /* Tag and flag bits */
#if 0
if (wr && (lk & 0x4000) == 0) {
/* Nope this is a fault */
M[tag] = lk | 0xc800;
sregs[1] = FMASK;
sregs[2] = seg;
sregs[3] = va;
trapcode = PGFLT;
sim_debug(DEBUG_EXP, &cpu_dev,
"Write fault: %08x %08x -> %08x %08x %08x\n",
seg, va, tag << 2, addr, lk);
return 1;
}
#endif
if (wr && (addr & 0x800) == 0) {
uint32 link = (vrt[entry] >> 16) & 0xffff;
link += sregs[12] >> 2;
M[link] |= 0x800;
tag = link[entry];
M[tag] |= 0x800;
vrt[entry] |= 0x800;
sim_debug(DEBUG_EXP, &cpu_dev,
"Mod Tlb: %08x %08x -> %08x %08x\n", seg, va, link, vrt[entry]);
sim_debug(DEBUG_EXP, &cpu_dev,
"Mod Tlb: %08x %08x -> %08x %08x\n", seg, va, tag << 2, vrt[entry]);
}
}
*pa = ((addr & 0x7ff) << 12) | (va & 0xfff);
#endif
sim_debug(DEBUG_EXP, &cpu_dev, "map: %08x %08x -> %08x\n", seg, va, *pa);
} else {
*pa = va & 0x7fffff;
}
@@ -263,21 +383,12 @@ int TransAddr(t_addr va, t_addr *pa, uint8 code, uint wr) {
/*
* Read a full word from memory, checking protection
* and alignment restrictions. Return 1 if failure, 0 if
* success.
* Return 1 if failure, 0 if success.
*/
int ReadFull(t_addr addr, uint32 *data, uint8 code) {
uint32 temp;
t_addr pa;
/* Check alignment */
if ((addr & 3) != 0) {
trapcode = DATAAL;
sregs[2] = code ? sregs[8] : sregs[9];
sregs[3] = addr;
return 1;
}
/* Validate address */
if (TransAddr(addr, &pa, code, 0))
return 1;
@@ -286,12 +397,19 @@ int ReadFull(t_addr addr, uint32 *data, uint8 code) {
if (pa >= MEMSIZE)
return 0;
if ((pa & 0xffffe0) == 0x3c0c0)
sim_debug(DEBUG_CMD, &cpu_dev, "Read %08x %08x\n", pa, M[pa >> 2]);
/* Actual read */
pa >>= 2;
*data = M[pa];
return 0;
}
/*
* Write a full word from memory, checking protection
* Return 1 if failure, 0 if success.
*/
int WriteFull(t_addr addr, uint32 data) {
int offset;
t_addr pa;
@@ -310,6 +428,10 @@ int WriteFull(t_addr addr, uint32 data) {
return 0;
}
/*
* Write a half word to memory, checking protection
* Return 1 if failure, 0 if success.
*/
int WriteHalf(t_addr addr, uint32 data) {
uint32 mask;
t_addr pa;
@@ -337,6 +459,10 @@ int WriteHalf(t_addr addr, uint32 data) {
return 0;
}
/*
* Write a byte to memory, checking protection
* Return 1 if failure, 0 if success.
*/
int WriteByte(t_addr addr, uint32 data) {
uint32 mask;
t_addr pa;
@@ -427,7 +553,7 @@ trap:
hst_p = hst_p + 1;
if (hst_p >= hst_lnt)
hst_p = 0;
hst[hst_p].pc = PC | HIST_TRAP;
hst[hst_p].pc = (PC & HIST_MASK) | HIST_TRAP;
hst[hst_p].addr = trapcode << 2;
}
trapcode = 0;
@@ -444,7 +570,7 @@ trap:
hst_p = hst_p + 1;
if (hst_p >= hst_lnt)
hst_p = 0;
hst[hst_p].pc = PC | HIST_TRAP;
hst[hst_p].pc = (PC & HIST_MASK) | HIST_TRAP;
hst[hst_p].addr = EXTIRQ << 2;
}
user = 0;
@@ -459,7 +585,7 @@ trap:
hst_p = hst_p + 1;
if (hst_p >= hst_lnt)
hst_p = 0;
hst[hst_p].pc = PC | HIST_TRAP;
hst[hst_p].pc = (PC & HIST_MASK) | HIST_TRAP;
hst[hst_p].addr = TIMER1 << 2;
}
user = 0;
@@ -476,7 +602,7 @@ trap:
hst_p = hst_p + 1;
if (hst_p >= hst_lnt)
hst_p = 0;
hst[hst_p].pc = PC | HIST_TRAP;
hst[hst_p].pc = (PC & HIST_MASK) | HIST_TRAP;
hst[hst_p].addr = TIMER2 << 2;
}
user = 0;
@@ -488,11 +614,11 @@ trap:
hst_p = hst_p + 1;
if (hst_p >= hst_lnt)
hst_p = 0;
hst[hst_p].pc = PC | HIST_PC | (user?HIST_USER:0);
hst[hst_p].pc = (PC & HIST_MASK) | HIST_PC | (user?HIST_USER:0);
}
/* Fetch the operator and possible displacement */
if (ReadFull(PC & ~3, &dest, 1)) {
if (ReadFull(PC, &dest, 1)) {
goto trap;
}
nPC = PC + 2;
@@ -504,7 +630,7 @@ trap:
/* Check if need displacment */
if (op & 0x80) {
/* In next word */
if (ReadFull((PC + 2) & ~3, &disp, 1)) {
if (ReadFull(PC + 2, &disp, 1)) {
goto trap;
}
/* Check if short displacement */
@@ -519,7 +645,7 @@ trap:
/* Check if long half of displacment */
if ((op & 0x90) == 0x90) {
/* Rest in high part of next word */
if (ReadFull((PC + 4) & ~3, &disp, 1)) {
if (ReadFull(PC + 4, &disp, 1)) {
goto trap;
}
/* Merge current lower and next upper */
@@ -561,6 +687,10 @@ trap:
"SR12=%08x SR13=%08x SR14=%08x SR15=%08x\n",
sregs[12], sregs[13], sregs[14], sregs[15]);
}
if (M[0xea28 >> 2] == 0xe901)
sim_debug(DEBUG_INST, &cpu_dev, "Location ea28 changed\n");
if (M[0xead0 >> 2] == 0xe901)
sim_debug(DEBUG_INST, &cpu_dev, "Location ead0 changed\n");
sim_debug(DEBUG_INST, &cpu_dev, "PC=%06x %c INST=%02x%02x ", PC,
(user) ? 'u': 'k', inst[0], inst[1]);
if (op & 0x80) {
@@ -665,8 +795,10 @@ trap:
src2 = (src2 & MSIGN) != 0;
if ((src1 && src2 && (dest & MSIGN) == 0) ||
(!src1 && !src2 && (dest & MSIGN) != 0)) {
if (trapwd & INTOVR) {
sregs[2] = 16;
if (user && trapwd & INTOVR) {
sregs[1] = op;
sregs[2] = (reg1 << 4) | reg2;
sregs[3] = 16;
trapcode = TRPWD;
}
}
@@ -686,7 +818,7 @@ trap:
(!src1 && !src2 && (dest & MSIGN) != 0)) {
regs[0] = 2;
}
if (src1 < src2) {
if ((uint32)dest < (uint32)src1) {
regs[0] |= 1;
}
if (temp) {
@@ -716,6 +848,22 @@ trap:
break;
case OP_EMPY:
dest = desth = 0;
if (src1 != 0 && src2 != 0) {
for (temp = 32; temp > 0; temp--) {
if (src1 & 1)
desth += src2;
src1 >>= 1;
dest >>= 1;
if (desth & 1)
dest |= MSIGN;
desth >>= 1;
}
}
regs[reg1] = desth;
regs[(reg1+1) & 0xf] = dest;
break;
case OP_MPYI:
case OP_MPY:
reg2 = 0;
@@ -740,8 +888,10 @@ trap:
}
}
if (op != OP_EMPY && desth != 0) {
if (trapwd & INTOVR) {
sregs[2] = 16;
if (user && trapwd & INTOVR) {
sregs[1] = op;
sregs[2] = (reg1 << 4) | reg2;
sregs[3] = 16;
trapcode = TRPWD;
}
}
@@ -763,8 +913,10 @@ trap:
hst[hst_p].src1h = src1h;
}
if (src2 == 0) {
if (trapwd & DIVZER) {
sregs[2] = 17;
if (user && trapwd & DIVZER) {
sregs[1] = op;
sregs[2] = (reg1 << 4) | reg2;
sregs[3] = 17;
trapcode = TRPWD;
}
break;
@@ -790,8 +942,10 @@ trap:
}
/* Check for overflow */
if ((dest & MSIGN) != 0) {
if (trapwd & INTOVR) {
sregs[2] = 16;
if (user && trapwd & INTOVR) {
sregs[1] = op;
sregs[2] = (reg1 << 4) | reg2;
sregs[3] = 16;
trapcode = TRPWD;
}
}
@@ -802,8 +956,10 @@ trap:
case OP_DIV:
case OP_REM:
if (src2 == 0) {
if (trapwd & DIVZER) {
sregs[2] = 17;
if (user && trapwd & DIVZER) {
sregs[1] = op;
sregs[2] = (reg1 << 4) | reg2;
sregs[3] = 17;
trapcode = TRPWD;
}
break;
@@ -840,8 +996,10 @@ trap:
}
/* Check for overflow */
if ((dest & MSIGN) != 0) {
if (trapwd & INTOVR) {
sregs[2] = 16;
if (user && trapwd & INTOVR) {
sregs[1] = op;
sregs[2] = (reg1 << 4) | reg2;
sregs[3] = 16;
trapcode = TRPWD;
}
goto trap;
@@ -858,7 +1016,7 @@ trap:
dest = (MSIGN >> (src2 & 037));
if (src2 & 040) {
if (op & 1)
regs[(reg1+1)& 0xf] |= dest;
regs[(reg1+1)&0xf] |= dest;
else
regs[(reg1+1)&0xf] &= ~dest;
} else {
@@ -881,6 +1039,7 @@ trap:
case OP_CHK:
if ((int32)src1 > (int32)src2) {
sregs[1] = op;
sregs[2] = reg1;
sregs[3] = reg2;
trapcode = CHKTRP;
@@ -889,6 +1048,7 @@ trap:
case OP_CHKI:
if (!((src1 & MSIGN) == 0 && src1 <= (int32)src2)) {
sregs[1] = op;
sregs[2] = reg1;
sregs[3] = reg2;
trapcode = CHKTRP;
@@ -914,7 +1074,7 @@ trap:
else if (src1 != src2)
dest = 1;
else
dest = 0;
dest = 0;
} else if ((int32)src1 < (int32)src2)
dest = FMASK;
else
@@ -947,8 +1107,10 @@ trap:
src2 &= 037;
while (src2 > 0) {
dest <<= 1;
if ((dest & MSIGN) != src2h && trapwd & INTOVR) {
sregs[2] = 16;
if ((dest & MSIGN) != src2h && user && trapwd & INTOVR) {
sregs[1] = op;
sregs[2] = (reg1 << 4) | reg2;
sregs[3] = 16;
trapcode = TRPWD;
}
src2--;
@@ -958,6 +1120,7 @@ trap:
case OP_DLSRI:
case OP_DLSR:
src1h = regs[(reg1 + 1) & 0xf];
src2 &= 077;
while(src2 > 0) {
src1h >>= 1;
@@ -972,6 +1135,7 @@ trap:
case OP_DLSLI:
case OP_DLSL:
src1h = regs[(reg1 + 1) & 0xf];
src2 &= 077;
while(src2 > 0) {
src1 <<= 1;
@@ -1047,32 +1211,110 @@ trap:
regs[reg1] = ((int32)src1) >= ((int32)src2);
break;
case OP_RNEG: /* Negate real */
if (src2 != 0)
src2 ^= MSIGN;
regs[reg1] = src2;
break;
case OP_DRNEG: /* Negate real */
src2h = regs[(reg2 + 1) & 0xf];
if (src2 != 0 && src2h != 0)
src2 ^= MSIGN;
regs[reg1] = src2;
regs[(reg2 + 1) & 0xf] = src2h;
break;
/* Floating point routines. */
case OP_FLOAT: /* Make integer real */
temp = rfloat(&regs[reg1], src2);
goto fptrap;
case OP_FIXT: /* Fix with truncate to integer */
case OP_FIXR: /* Fix with round to integer */
case OP_RNEG: /* Negate real */
case OP_RADD: /* Real add */
temp = rfix(&regs[reg1], src2, op & 1);
goto fptrap;
case OP_RSUB: /* Real subtract */
src2 ^= MSIGN;
/* Fall through */
case OP_RADD: /* Real add */
temp = radd(&regs[reg1], src1, src2);
goto fptrap;
case OP_RMPY: /* Real product */
temp = rmult(&regs[reg1], src1, src2);
goto fptrap;
case OP_RDIV: /* Real divide */
case OP_FLOAT: /* Make integer real */
temp = rdiv(&regs[reg1], src1, src2);
goto fptrap;
case OP_MAKERD: /* Convert real to double */
makerd(&regs[reg1], &regs[(reg1 + 1) & 0xf], src2);
break;
case OP_RCOMP: /* Compare two reals */
regs[reg1] = rcomp(src1, src2);
break;
case OP_DFLOAT: /* Convert integer to double */
temp = dfloat(&regs[reg1], &regs[(reg1 + 1) & 0xf], src2);
break;
case OP_DFIXT: /* Fix with trancate to integer */
case OP_DFIXR: /* Fix with round to integer */
case OP_DRNEG: /* Negate real */
case OP_DRADD: /* Double add */
case OP_DRSUB: /* Double subtract */
case OP_DRMPY: /* Double product */
case OP_DRDIV: /* Double divide */
src2h = regs[(reg2 + 1) & 0xf];
temp = dfix(&regs[reg1], src2, src2h, op & 1);
goto fptrap;
case OP_MAKEDR: /* Convert double to real */
case OP_DFLOAT: /* Convert integer to double */
src2h = regs[(reg2 + 1) & 0xf];
temp = makedr(&regs[reg1], src2, src2h);
goto fptrap;
case OP_DRSUB: /* Double subtract */
src2 ^= MSIGN;
/* Fall through */
case OP_DRADD: /* Double add */
src2h = regs[(reg2 + 1) & 0xf];
src1h = regs[(reg1 + 1) & 0xf];
temp = dradd(&regs[reg1], &regs[(reg1 + 1) & 0xf], src1, src1h, src2, src2h);
goto fptrap;
case OP_DRMPY: /* Double product */
src2h = regs[(reg2 + 1) & 0xf];
src1h = regs[(reg1 + 1) & 0xf];
temp = drmult(&regs[reg1], &regs[(reg1 + 1) & 0xf], src1, src1h, src2, src2h);
goto fptrap;
case OP_DRDIV: /* Double divide */
src2h = regs[(reg2 + 1) & 0xf];
src1h = regs[(reg1 + 1) & 0xf];
temp = drdiv(&regs[reg1], &regs[(reg1 + 1) & 0xf], src1, src1h, src2, src2h);
fptrap:
if (temp != 0 && user && (trapwd & (MSIGN >> temp)) != 0) {
sregs[1] = op;
sregs[2] = (reg1 << 4) | reg2;
sregs[3] = temp;
trapcode = TRPWD;
}
break;
case OP_DRCOMP: /* Compare two doubles */
src2h = regs[(reg2 + 1) & 0xf];
src1h = regs[(reg1 + 1) & 0xf];
regs[reg1] = drcomp(src1, src1h, src2, src2h);
break;
case OP_TRAP:
if ((MSIGN >> reg2) & trapwd) {
if ((user && (MSIGN >> reg2) & trapwd) || !user) {
sregs[1] = op;
sregs[2] = (reg1 << 4) | reg2;
sregs[3] = reg2;
trapcode = TRPWD;
sregs[2] = reg2;
}
break;
@@ -1105,6 +1347,7 @@ trap:
sregs[9] = M[pcb + 17] & 0xFFFF;
sregs[10] = M[pcb + 19];
sregs[15] = M[pcb + 16];
trapwd = sregs[10];
for (reg1 = 0;
reg1 < (sizeof(tlb)/sizeof(uint32));
reg1++)
@@ -1138,27 +1381,58 @@ trap:
case OP_TRANS:
case OP_DIRT:
src1 = regs[reg2]; /* Segment */
src2 = regs[(reg2 + 1) & 0xf]; /* VA */
if (user) {
goto priv_trap;
} else {
uint32 seg = regs[reg2]; /* Segment */
uint32 page = regs[(reg2 + 1) & 0xf] >> 12; /* Address = page */
uint32 mat = (seg << 16) | (page >> 4); /* Match word */
uint32 na = (((seg + page) & sregs[13]) << 3); /* Next address */
uint32 page = src2 >> 12; /* Address = page */
uint32 mat = (src1 << 16) | (page >> 4); /* Match word */
uint32 na; /* Next address */
uint32 a; /* Current address */
uint32 link; /* Link word */
uint32 l; /* Link word */
uint32 e; /* Entry */
src1 = regs[(reg2 + 1) & 0xf];
#if VRT2
na = (((src1 + page) & sregs[13]) << 2) + sregs[12];
na = M[na >> 2];
if (na == 0) {
regs[reg1] = FMASK;
break;
}
do {
a = na >> 2;
l = M[a++];
na = M[a++];
e = M[a];
sim_debug(DEBUG_EXP, &cpu_dev,
"Load trans: %08x %08x -> %08x %08x %08x\n",
src1, src2, a << 2, l, e);
} while (l != mat && na != 0);
/* Did we find entry? */
if (l != mat || (e & 0x2) == 0) {
regs[reg1] = FMASK;
} else {
/* Update reference and modify bits */
e |= 0x10;
if ((op & 1) != 0)
e |= 0x1;
/* Update the tlb entry */
M[a] = e;
regs[reg1] = ((e & 0x7fff0000) >> 4) | (src2 & 0xfff);
}
#else
na = (((src1 + page) & sregs[13]) << 3); /* Next address */
do {
a = (na + sregs[12]) >> 2;
link = M[a++];
l = M[a++];
e = M[a];
na = (e >> 16);
sim_debug(DEBUG_EXP, &cpu_dev,
"Load trans: %08x %08x -> %08x %08x %08x\n", seg, regs[(reg2 + 1) & 0xf], a, link, e);
} while (link != mat && na != 0);
sim_debug(DEBUG_EXP, &cpu_dev,
"Load trans: %08x %08x -> %08x %08x %08x\n",
src1, src2, a << 2, l, e);
} while (l != mat && na != 0);
/* Did we find entry? */
if (link != mat || (e & 0x7000) != 0x7000) {
if (l != mat || (e & 0x7000) == 0) {
regs[reg1] = FMASK;
} else {
/* Update reference and modify bits */
@@ -1166,8 +1440,9 @@ trap:
if ((op & 1) != 0)
e |= 0x800;
M[a] = e;
regs[reg1] = ((e & 0x7ff) << 12) | (src1 & 0xfff);
regs[reg1] = ((e & 0x7ff) << 12) | (src2 & 0xfff);
}
#endif
}
break;
@@ -1189,7 +1464,7 @@ trap:
case OP_MAINT:
/* Reg2 determines actual opcode */
if (user && (sregs[10] & 1) == 0) {
if (user && (trapwd & 1) == 0) {
priv_trap: sregs[1] = op;
sregs[2] = reg1;
sregs[3] = reg2;
@@ -1235,13 +1510,15 @@ priv_trap: sregs[1] = op;
break;
case 10: /* MACHINEID */
regs[reg1] = 0;
regs[(reg1 +1) & 0xf] = 0 | (VRT2 * 04);
break;
case 11: /* Version */
case 12: /* CREG */
regs[(reg1 + 1) & 0xf] = 1;
break;
case 13: /* RDLOG */
fprintf(stderr, "Maint %d %d %08x\n\r", reg1, reg2, src1);
fprintf(stderr, "Maint %d %d %08x\n\r", reg1, reg2, src1);
regs[reg1] = 0;
break;
@@ -1251,20 +1528,18 @@ priv_trap: sregs[1] = op;
break;
case OP_READ:
if (user && (sregs[10] & 1) == 0) {
if (user && (trapwd & 1) == 0) {
goto priv_trap;
} else {
src2 = regs[reg2];
dest = io_read(src2, &regs[(reg1+1) & 0xf]);
regs[reg1] = dest;
}
break;
case OP_WRITE:
if (user && (sregs[10] & 1) == 0) {
if (user && (trapwd & 1) == 0) {
goto priv_trap;
} else {
src2 = regs[reg2];
dest = io_write(src2, regs[reg1]);
regs[reg1] = dest;
}
@@ -1274,6 +1549,7 @@ priv_trap: sregs[1] = op;
if (user) {
trapcode = TRAP | (reg1 << 4) | reg2;
PC = nPC & WMASK; /* Low order bit can't be set */
// sregs[1] = trapcode & 0xff;
} else {
trapcode =KERVOL;
sregs[1] = op;
@@ -1411,9 +1687,9 @@ priv_trap: sregs[1] = op;
}
if (WriteFull(disp, src1))
break;
break;
sim_debug(DEBUG_INST, &cpu_dev,
"Write dbl: %08x %08x %08x\n", disp, src1, src1h);
"Write full: %08x %08x\n", disp, src1);
break;
case 0xa8: /* StoreD */
@@ -1449,7 +1725,7 @@ priv_trap: sregs[1] = op;
case 0xd0: /* LoadB */
case 0xd1: /* LoadB */
dest = 0;
if (ReadFull(disp & ~(3), &dest, code_seg))
if (ReadFull(disp, &dest, code_seg))
break;
sim_debug(DEBUG_INST, &cpu_dev,
"Read byte: %08x %08x\n", disp, dest);
@@ -1473,7 +1749,7 @@ priv_trap: sregs[1] = op;
sregs[3] = disp;
break;
}
if (ReadFull(disp & ~(3), &dest, code_seg))
if (ReadFull(disp, &dest, code_seg))
break;
sim_debug(DEBUG_INST, &cpu_dev,
"Read half: %08x %08x\n", disp, dest);
@@ -1491,7 +1767,14 @@ priv_trap: sregs[1] = op;
case 0xd6: /* Load */
case 0xd7: /* Load */
dest = 0;
if (ReadFull(disp & ~(0x3), &dest, code_seg))
/* Check alignment */
if ((disp & 3) != 0) {
trapcode = DATAAL;
sregs[2] = code_seg ? sregs[8] : sregs[9];
sregs[3] = disp;
break;
}
if (ReadFull(disp, &dest, code_seg))
break;
sim_debug(DEBUG_INST, &cpu_dev,
"Read full: %08x %08x\n", disp, dest);
@@ -1508,6 +1791,13 @@ priv_trap: sregs[1] = op;
case 0xd9: /* LoadD */
dest = 0;
desth = 0;
/* Check alignment */
if ((disp & 3) != 0) {
trapcode = DATAAL;
sregs[2] = code_seg ? sregs[8] : sregs[9];
sregs[3] = disp;
break;
}
if (ReadFull(disp, &dest, code_seg))
break;
if (ReadFull(disp+4, &desth, code_seg))
@@ -1607,7 +1897,7 @@ rtc_srv(UNIT * uptr)
uint32 ccb = sregs[11] >> 2;
uint32 s;
if ((sregs[14] & 1) == 0) {
M[(sregs[14] + 0x80) >> 2] ++;
M[(sregs[14] + 80) >> 2] ++;
} else {
M[ccb + 0x10F]++;
}
@@ -1621,8 +1911,8 @@ rtc_srv(UNIT * uptr)
if (s < M[ccb + 0x113])
M[ccb + 0x112] ++;
M[ccb + 0x113] = s;
sim_debug(DEBUG_EXP, &cpu_dev, "Timer: %08x t1=%08x t2=%08x d=%08x %08x\n",
M[ccb + 0x10F], M[ccb + 0x110], M[ccb + 0x111], M[ccb + 0x112], M[ccb+0x113]);
sim_debug(DEBUG_EXP, &cpu_dev, "Timer: %08x %08x t1=%08x t2=%08x d=%08x %08x\n",
sregs[14] + 80, M[ccb + 0x10F], M[ccb + 0x110], M[ccb + 0x111], M[ccb + 0x112], M[ccb+0x113]);
}
return SCPE_OK;
}
@@ -1766,8 +2056,7 @@ cpu_show_hist(FILE * st, UNIT * uptr, int32 val, CONST void *desc)
if (h->pc & HIST_PC) { /* instruction? */
int i;
fprintf(st, "%06x%c %06x %08x %08x %08x %02x%02x ",
h->pc & AMASK, (h->pc & HIST_USER) ? 'v':' ',
h->addr & AMASK,
h->pc & HIST_MASK, (h->pc & HIST_USER) ? 'v':' ', h->addr,
h->src1, h->src2, h->dest, h->inst[0], h->inst[1]);
if ((h->inst[0] & 0x80) != 0)
fprintf(st, "%02x%02x ", h->inst[2], h->inst[3]);
@@ -1778,13 +2067,13 @@ cpu_show_hist(FILE * st, UNIT * uptr, int32 val, CONST void *desc)
else
fprintf(st, " ");
fprintf(st, " ");
fprint_inst(st, h->pc & AMASK, h->inst);
fprint_inst(st, h->pc & HIST_MASK, h->inst);
fputc('\n', st); /* end line */
} /* end else instruction */
else if (h->pc & HIST_TRAP) { /* Trap */
int i;
fprintf(st, "%06x %06x\n",
h->pc & AMASK, h->addr & AMASK);
h->pc & HIST_MASK, h->addr);
} /* end else trap */
} /* end for */
return SCPE_OK;

View File

@@ -172,3 +172,18 @@ t_stat set_slot_num(UNIT * uptr, int32 val, CONST char *cptr, void *desc);
t_stat show_slot_num(FILE * st, UNIT * uptr, int32 v, CONST void *desc);
void fprint_inst(FILE *, t_addr addr, t_value *);
/* Floating point routines. */
int rfloat(uint32 *res, uint32 src1);
int rfix(uint32 *res, uint32 src, int round);
void makerd(uint32 *resl, uint32 *resh, uint32 src);
int rcomp(uint32 src1, uint32 src2);
int radd(uint32 *res, uint32 src1, uint32 src2);
int rmult(uint32 *res, uint32 src1, uint32 src2);
int rdiv(uint32 *res, uint32 src1, uint32 src2);
int dfloat(uint32 *resl, uint32 *resh, uint32 src1);
int dfix(uint32 *res, uint32 src, uint32 srch, int round);
int makedr(uint32 *res, uint32 src, uint32 srch);
int drcomp(uint32 src1, uint32 src1h, uint32 src2, uint32 src2h);
int dradd(uint32 *resl, uint32 *resh, uint32 src1, uint32 src1h, uint32 src2, uint32 src2h);
int drmult(uint32 *resl, uint32 *resh, uint32 src1, uint32 src1h, uint32 src2, uint32 src2h);
int drdiv(uint32 *resl, uint32 *resh, uint32 src1, uint32 src1h, uint32 src2, uint32 src2h);

View File

@@ -36,7 +36,7 @@
#define CMD u6
#define WR_INH 0x8000
#define WR_INH 0x100
#define DSK_RD 0 /* Read command */
#define DSK_WR 1 /* Write command */
#define DSK_VFY 2 /* Verify data */
@@ -47,6 +47,10 @@
#define DSK_WRF 7 /* Write full sector */
#define DSK_HDR 0xE /* Read headers */
#define DSK_CNT 0xfff000 /* Transfer count in sectors */
#define DSK_INC 0x001000 /* Increment per transfer */
#define DSK_SMSK 0x003000
/* DCB control block.
DCB + 0C0
@@ -201,6 +205,7 @@ dsk_write(uint32 dev, uint32 data)
int drive = cmd & 3;
int offset = drive << 6;;
int i;
uint8 buff[64];
/* Check if command can be accepted */
if (uptr->STATUS & 1) {
@@ -213,6 +218,7 @@ dsk_write(uint32 dev, uint32 data)
case 0x82:
case 0x83:
io_read_blk(uptr->DCB + offset, &buff[0], 64);
/* Find actual unit */
duptr = &dsk_unit[drive];
/* Read first word of DCB + 0xC0 */
@@ -241,10 +247,7 @@ dsk_write(uint32 dev, uint32 data)
ext_irq = 1;
return 0;
}
if (cmd == DSK_RDH)
sim_activate(duptr, 10);
else
sim_activate(duptr, 100);
sim_activate(duptr, 10);
break;
case 0xc0: /* Boot floppy left */
@@ -330,13 +333,21 @@ dsk_svc (UNIT *uptr)
int i;
int sc;
/* Check if disk attached */
if ((uptr->flags & UNIT_ATT) == 0) {
io_dcbwrite_byte(dcb, offset + 0x2, 1);
dsk_unit[0].STATUS = 0x400101 | (drive << 16);
ext_irq = 1;
return SCPE_OK;
}
if ((uptr->CMD & 0xf) != DSK_RDH && uptr->CYL != dsk_dcb[drive].cyl) {
/* Step in/out based on current cylinder, requested cylinder */
if (uptr->CYL < dsk_dcb[drive].cyl)
uptr->CYL++;
else if (uptr->CYL > dsk_dcb[drive].cyl)
uptr->CYL--;
sim_activate(uptr, 1000);
sim_activate(uptr, 500);
return SCPE_OK;
}
@@ -345,10 +356,14 @@ dsk_svc (UNIT *uptr)
switch (uptr->CMD & 0xf) {
case DSK_RD: /* Read command */
sim_debug(DEBUG_DETAIL, &dsk_dev,
"read sector %6x %4x %4d %d %2d\n",
dsk_dcb[drive].addr, dsk_dcb[drive].count, dsk_dcb[drive].cyl,
"read sector %08x %6x %4x %4d %d %2d\n",
uptr->CMD, dsk_dcb[drive].addr, dsk_dcb[drive].count, dsk_dcb[drive].cyl,
dsk_dcb[drive].hd, dsk_dcb[drive].sect);
(void)sim_fseek(uptr->fileref, da * SECT_SZ, SEEK_SET);
(void)sim_fseek(uptr->fileref, da * (SECT_SZ + LBL_SZ), SEEK_SET);
len = sim_fread(&dsk_sect_lab[0], 1, sizeof(dsk_sect_lab), uptr->fileref);
while (len < sizeof(dsk_sect_lab)) {
dsk_sect_lab[len++] = 0;
}
len = sim_fread(&dsk_buf, 1, sizeof(dsk_buf), uptr->fileref);
while (len < sizeof(dsk_buf)) {
dsk_buf[len++] = 0;
@@ -362,6 +377,7 @@ dsk_svc (UNIT *uptr)
sim_debug(DEBUG_DATA, &dsk_dev, "\n");
}
sim_debug(DEBUG_DATA, &dsk_dev, "\n");
io_dcbwrite_blk(dcb, offset + 0x10, &dsk_sect_lab[0], LBL_SZ);
io_write_blk(dsk_dcb[drive].addr, &dsk_buf[0], len);
dsk_dcb[drive].count -= len;
dsk_dcb[drive].xcount += len;
@@ -374,15 +390,26 @@ dsk_svc (UNIT *uptr)
ext_irq = 1;
break;
}
uptr->CMD += DSK_INC;
if ((uptr->CMD & DSK_SMSK) == 0) {
uint32 t;
i = ((uptr->CMD & DSK_CNT) >> 14) - 1;
t = io_dcbread_half(dcb, offset + 0x20 + (i * 2));
if (t != 0)
dsk_dcb[drive].addr = t << 8;
sim_debug(DEBUG_DETAIL, &dsk_dev, "Disk new address: %08x %x\n", t, i);
}
sim_activate(uptr, 100);
return SCPE_OK;
}
io_dcbwrite_addr(dcb, offset + 0x5, dsk_dcb[drive].addr);
io_dcbwrite_half(dcb, offset + 0x8, dsk_dcb[drive].count);
io_dcbwrite_byte(dcb, offset + 0xd, (dsk_dcb[drive].hd << 4) |
((dsk_dcb[drive].cyl >> 8) & 0xf));
io_dcbwrite_byte(dcb, offset + 0xe, dsk_dcb[drive].cyl & 0xff);
io_dcbwrite_byte(dcb, offset + 0xf, dsk_dcb[drive].sect);
// io_dcbwrite_addr(dcb, offset + 0x5, dsk_dcb[drive].addr);
// io_dcbwrite_half(dcb, offset + 0x8, dsk_dcb[drive].count);
// io_dcbwrite_byte(dcb, offset + 0xd, (dsk_dcb[drive].hd << 4) |
// ((dsk_dcb[drive].cyl >> 8) & 0xf));
// io_dcbwrite_byte(dcb, offset + 0xe, dsk_dcb[drive].cyl & 0xff);
// io_dcbwrite_byte(dcb, offset + 0xf, dsk_dcb[drive].sect);
io_dcbwrite_byte(dcb, offset + 0x4, 0);
io_dcbwrite_half(dcb, offset + 0xa, dsk_dcb[drive].xcount);
io_dcbwrite_byte(dcb, offset + 0x2, 0);
dsk_unit[0].STATUS = 0x400001 | (drive << 16);
@@ -391,10 +418,11 @@ dsk_svc (UNIT *uptr)
case DSK_WR: /* Write command */
sim_debug(DEBUG_DETAIL, &dsk_dev,
"write sector %6x %4x %4d %d %2d\n",
dsk_dcb[drive].addr, dsk_dcb[drive].count, dsk_dcb[drive].cyl,
"write sector %08x %6x %4x %4d %d %2d\n",
uptr->CMD, dsk_dcb[drive].addr, dsk_dcb[drive].count, dsk_dcb[drive].cyl,
dsk_dcb[drive].hd, dsk_dcb[drive].sect);
(void)sim_fseek(uptr->fileref, da * SECT_SZ, SEEK_SET);
(void)sim_fseek(uptr->fileref, da * (SECT_SZ + LBL_SZ), SEEK_SET);
io_dcbread_blk(dcb, offset + 0x10, &dsk_sect_lab[0], LBL_SZ);
len = sizeof(dsk_buf);
if (len > dsk_dcb[drive].count)
len = dsk_dcb[drive].count;
@@ -409,6 +437,7 @@ dsk_svc (UNIT *uptr)
sim_debug(DEBUG_DATA, &dsk_dev, "\n");
}
sim_debug(DEBUG_DATA, &dsk_dev, "\n");
len = sim_fwrite(&dsk_sect_lab, 1, sizeof(dsk_sect_lab), uptr->fileref);
len = sim_fwrite(&dsk_buf, 1, sizeof(dsk_buf), uptr->fileref);
if (len > dsk_dcb[drive].count)
len = dsk_dcb[drive].count;
@@ -424,15 +453,25 @@ dsk_svc (UNIT *uptr)
ext_irq = 1;
break;
}
uptr->CMD += DSK_INC;
if ((uptr->CMD & DSK_SMSK) == 0) {
uint32 t;
i = ((uptr->CMD & DSK_CNT) >> 14) - 1;
t = io_dcbread_half(dcb, offset + 0x20 + (i * 2));
if (t != 0)
dsk_dcb[drive].addr = t << 8;
sim_debug(DEBUG_DETAIL, &dsk_dev, "Disk new address: %08x %x\n", t, i);
}
sim_activate(uptr, 100);
return SCPE_OK;
}
io_dcbwrite_addr(dcb, offset + 0x5, dsk_dcb[drive].addr);
io_dcbwrite_half(dcb, offset + 0x8, dsk_dcb[drive].count);
io_dcbwrite_byte(dcb, offset + 0xd, (dsk_dcb[drive].hd << 4) |
((dsk_dcb[drive].cyl >> 8) & 0xf));
io_dcbwrite_byte(dcb, offset + 0xe, dsk_dcb[drive].cyl & 0xff);
io_dcbwrite_byte(dcb, offset + 0xf, dsk_dcb[drive].sect);
// io_dcbwrite_addr(dcb, offset + 0x5, dsk_dcb[drive].addr);
// io_dcbwrite_half(dcb, offset + 0x8, dsk_dcb[drive].count);
// io_dcbwrite_byte(dcb, offset + 0xd, (dsk_dcb[drive].hd << 4) |
// ((dsk_dcb[drive].cyl >> 8) & 0xf));
// io_dcbwrite_byte(dcb, offset + 0xe, dsk_dcb[drive].cyl & 0xff);
// io_dcbwrite_byte(dcb, offset + 0xf, dsk_dcb[drive].sect);
io_dcbwrite_byte(dcb, offset + 0x4, 0);
io_dcbwrite_half(dcb, offset + 0xa, dsk_dcb[drive].xcount);
io_dcbwrite_byte(dcb, offset + 0x2, 0);
dsk_unit[0].STATUS = 0x400001 | (drive << 16);
@@ -452,9 +491,11 @@ dsk_svc (UNIT *uptr)
dsk_dcb[drive].addr, dsk_dcb[drive].count, dsk_dcb[drive].hd,
dsk_dcb[drive].cyl, dsk_dcb[drive].sect);
da = ((dsk_dcb[drive].cyl * 7 + dsk_dcb[drive].hd) * 18);
(void)sim_fseek(uptr->fileref, da * SECT_SZ, SEEK_SET);
(void)sim_fseek(uptr->fileref, da * (SECT_SZ + LBL_SZ), SEEK_SET);
io_dcbread_blk(dcb, offset + 0x10, &dsk_sect_lab[0], LBL_SZ);
memset(&dsk_buf[0], 0, sizeof(dsk_buf));
for(sc = 0; sc < 18; sc ++) {
for(sc = 0; sc < dsk_type[type].sect; sc ++) {
len = sim_fwrite(&dsk_sect_lab, 1, sizeof(dsk_sect_lab), uptr->fileref);
len = sim_fwrite(&dsk_buf, 1, sizeof(dsk_buf), uptr->fileref);
}
io_dcbwrite_half(dcb, offset + 0xa, dsk_dcb[drive].count);
@@ -482,23 +523,26 @@ dsk_svc (UNIT *uptr)
"read fsector %6x %4x %4d %d %2d\n",
dsk_dcb[drive].addr, dsk_dcb[drive].count, dsk_dcb[drive].cyl,
dsk_dcb[drive].hd, dsk_dcb[drive].sect);
(void)sim_fseek(uptr->fileref, da * SECT_SZ, SEEK_SET);
memset(&dsk_buf[0], 0, LBL_SZ);
(void)sim_fseek(uptr->fileref, da * (SECT_SZ + LBL_SZ), SEEK_SET);
while (len < sizeof(dsk_sect_lab)) {
dsk_sect_lab[len++] = 0;
}
io_write_blk(dsk_dcb[drive].addr, &dsk_buf[0], LBL_SZ);
dsk_dcb[drive].addr += LBL_SZ;
len = sim_fread(&dsk_sect_lab, 1, sizeof(dsk_sect_lab), uptr->fileref);
len = sim_fread(&dsk_buf, 1, sizeof(dsk_buf), uptr->fileref);
while (len < sizeof(dsk_buf)) {
dsk_buf[len++] = 0;
}
sim_debug(DEBUG_DATA, &dsk_dev, "Disk Readfull\n");
for (i = 0; i < SECT_SZ; i++) {
sim_debug(DEBUG_DATA, &dsk_dev, "%02x ", dsk_buf[i]);
if ((i & 0xf) == 0xf)
sim_debug(DEBUG_DATA, &dsk_dev, "\n");
}
sim_debug(DEBUG_DATA, &dsk_dev, "\n");
sim_debug(DEBUG_DATA, &dsk_dev, "Disk Readfull\n");
for (i = 0; i < SECT_SZ; i++) {
sim_debug(DEBUG_DATA, &dsk_dev, "%02x ", dsk_buf[i]);
if ((i & 0xf) == 0xf)
sim_debug(DEBUG_DATA, &dsk_dev, "\n");
}
sim_debug(DEBUG_DATA, &dsk_dev, "\n");
io_write_blk(dsk_dcb[drive].addr, &dsk_buf[0], len);
dsk_dcb[drive].xcount += sizeof(dsk_sect_lab) + sizeof(dsk_buf) + 4;
dsk_dcb[drive].xcount = sizeof(dsk_sect_lab) + sizeof(dsk_buf) + 4;
io_dcbwrite_half(dcb, offset + 0xa, dsk_dcb[drive].xcount);
io_dcbwrite_byte(dcb, offset + 0x2, 0);
dsk_unit[0].STATUS = 0x400001 | (drive << 16);
@@ -510,19 +554,25 @@ dsk_svc (UNIT *uptr)
"Write fsector %6x %4x %4d %d %2d\n",
dsk_dcb[drive].addr, dsk_dcb[drive].count, dsk_dcb[drive].cyl,
dsk_dcb[drive].hd, dsk_dcb[drive].sect);
(void)sim_fseek(uptr->fileref, da * SECT_SZ, SEEK_SET);
io_read_blk(dsk_dcb[drive].addr, &dsk_buf[0], sizeof(dsk_sect_lab));
(void)sim_fseek(uptr->fileref, da * (SECT_SZ + LBL_SZ), SEEK_SET);
io_read_blk(dsk_dcb[drive].addr, &dsk_sect_lab[0], sizeof(dsk_sect_lab));
dsk_dcb[drive].addr += LBL_SZ;
io_read_blk(dsk_dcb[drive].addr, &dsk_buf[0], sizeof(dsk_buf));
sim_debug(DEBUG_DATA, &dsk_dev, "Disk Writefull\n");
for (i = 0; i < SECT_SZ; i++) {
sim_debug(DEBUG_DATA, &dsk_dev, "%02x ", dsk_buf[i]);
if ((i & 0xf) == 0xf)
sim_debug(DEBUG_DATA, &dsk_dev, "\n");
}
sim_debug(DEBUG_DATA, &dsk_dev, "\n");
sim_debug(DEBUG_DATA, &dsk_dev, "Disk Writefull\n");
for (i = 0; i < SECT_SZ; i++) {
sim_debug(DEBUG_DATA, &dsk_dev, "%02x ", dsk_buf[i]);
if ((i & 0xf) == 0xf)
sim_debug(DEBUG_DATA, &dsk_dev, "\n");
}
sim_debug(DEBUG_DATA, &dsk_dev, "\n");
dsk_dcb[drive].addr += SECT_SZ;
len = sim_fwrite(&dsk_sect_lab, 1, sizeof(dsk_sect_lab), uptr->fileref);
len = sim_fwrite(&dsk_buf, 1, sizeof(dsk_buf), uptr->fileref);
dsk_dcb[drive].xcount += len;
io_read_blk(dsk_dcb[drive].addr, &dsk_buf[0], 4);
sim_debug(DEBUG_DETAIL, &dsk_dev,
"Write fsector crc=%02x%02x%02x%02x\n",
dsk_buf[0], dsk_buf[1], dsk_buf[2], dsk_buf[3]);
dsk_dcb[drive].xcount = sizeof(dsk_sect_lab) + sizeof(dsk_buf) + 4;
io_dcbwrite_half(dcb, offset + 0xa, dsk_dcb[drive].xcount);
io_dcbwrite_byte(dcb, offset + 0x2, 0);
dsk_unit[0].STATUS = 0x400001 | (drive << 16);

View File

@@ -281,6 +281,7 @@ flp_write(uint32 dev, uint32 data)
sim_debug(DEBUG_EXP, &flp_dev, "Start cmd %2x\n", cmd);
if (cmd < 0x80) {
com_write_char(0, cmd);
sim_debug(DEBUG_EXP, &flp_dev, "print '%c'\n", isprint(cmd)? cmd: '.');
uptr->STATUS = (0x80 << 16);
} else if ((cmd & 0xc0) == 0xc0) {
switch (cmd) {
@@ -300,6 +301,7 @@ flp_write(uint32 dev, uint32 data)
case 0xc2: /* Read one char port 0 no irq */
uptr->STATUS = 2;
/* Fall through */
case 0xff: /* Read one char port 0 irq */
flp_unit[2].u3 = cmd;
break;
@@ -619,12 +621,14 @@ flp_svc (UNIT *uptr)
case CMD_WRDEL: /* Write delete */
case CMD_RDDEL: /* Read delete */
/* Make sure cylinder is correct */
#if 0
flp_dcb.stat[1] = 0;
flp_dcb.stat[2] = 0;
flp_dcb.stat[3] = flp_dcb.cmd[2]; /* C */
flp_dcb.stat[4] = flp_dcb.cmd[3]; /* H */
flp_dcb.stat[5] = flp_dcb.cmd[4]; /* R */
flp_dcb.stat[6] = flp_dcb.cmd[5]; /* N */
#endif
flp_dcb.stat_len = 7;
if (uptr->CYL != flp_dcb.cmd[2]) {
flp_dcb.stat[0] |= 0x40;
@@ -649,11 +653,12 @@ flp_svc (UNIT *uptr)
case PHASE_EXEC:
/* Transfer data to/from memory */
switch(flp_dcb.cmd[0] & 0xf) {
case CMD_RDDEL: /* Read delete */
case CMD_RDSEC: /* Read sector */
/* cyl head sect */
flags = 0;
if (sectRead((DISK_INFO *)uptr->up7, flp_dcb.stat[3],
flp_dcb.stat[4], flp_dcb.stat[5],
if (sectRead((DISK_INFO *)uptr->up7, flp_dcb.cmd[2],
flp_dcb.cmd[3], flp_dcb.cmd[4],
&flp_buf[0], sizeof(flp_buf), &flags, &len) != SCPE_OK) {
uptr->PHASE = PHASE_RES;
flp_dcb.stat[0] = 0x40;
@@ -661,15 +666,15 @@ flp_svc (UNIT *uptr)
return SCPE_OK;
}
sim_debug(DEBUG_DETAIL, &flp_dev, "Read a=%6x c=%4x h=%x t=%d s=%d l=%d\n\r",
flp_dcb.addr, flp_dcb.count, flp_dcb.stat[4], flp_dcb.stat[3], flp_dcb.stat[5], len);
flp_dcb.addr, flp_dcb.count, flp_dcb.cmd[3], flp_dcb.cmd[2], flp_dcb.cmd[4], len);
sim_debug(DEBUG_DATA, &dsk_dev, "Disk Read: %d bytes\n", len);
for (i = 0; i < len; i++) {
sim_debug(DEBUG_DATA, &dsk_dev, "%02x ", flp_buf[i]);
if ((i & 0xf) == 0xf)
sim_debug(DEBUG_DATA, &dsk_dev, "\n");
}
sim_debug(DEBUG_DATA, &dsk_dev, "\n");
sim_debug(DEBUG_DATA, &dsk_dev, "Disk Read: %d bytes\n", len);
for (i = 0; i < len; i++) {
sim_debug(DEBUG_DATA, &dsk_dev, "%02x ", flp_buf[i]);
if ((i & 0xf) == 0xf)
sim_debug(DEBUG_DATA, &dsk_dev, "\n");
}
sim_debug(DEBUG_DATA, &dsk_dev, "\n");
if (len > flp_dcb.count)
len = flp_dcb.count;
@@ -677,16 +682,16 @@ flp_svc (UNIT *uptr)
flp_dcb.count -= len;
flp_dcb.xcount += len;
flp_dcb.addr += len;
if (flp_dcb.stat[5] == flp_dcb.cmd[6]) {
flp_dcb.stat[5] = 1;
if(flp_dcb.stat[4]) {
flp_dcb.stat[3]++;
flp_dcb.stat[4] = 0;
if (flp_dcb.cmd[4] == flp_dcb.cmd[6]) {
flp_dcb.cmd[4] = 1;
if(flp_dcb.cmd[3]) {
flp_dcb.cmd[2]++;
flp_dcb.cmd[3] = 0;
} else {
flp_dcb.stat[4] = 1;
flp_dcb.cmd[3] = 1;
}
} else {
flp_dcb.stat[5]++;
flp_dcb.cmd[4]++;
}
if (flp_dcb.count == 0) {
// flp_dcb.stat[0] = 0x20 | (flp_dcb.cmd[1] & 0x7);
@@ -697,8 +702,10 @@ flp_svc (UNIT *uptr)
}
return SCPE_OK;
case CMD_WRDEL: /* Write delete */
case CMD_WRSEC: /* Write sector */
flags = 0;
flags = ((flp_dcb.cmd[0] & 0xf) == CMD_WRDEL) ?
IMD_DISK_IO_DELETED_ADDR_MARK : 0;
len = flp_dcb.cmd[5];
if (len == 0) {
len = flp_dcb.cmd[8];
@@ -708,15 +715,15 @@ flp_svc (UNIT *uptr)
if (len > flp_dcb.count)
len = flp_dcb.count;
io_read_blk(flp_dcb.addr, &flp_buf[0], len);
sim_debug(DEBUG_DATA, &dsk_dev, "Disk Write: %d bytes\n", len);
for (i = 0; i < len; i++) {
sim_debug(DEBUG_DATA, &dsk_dev, "%02x ", flp_buf[i]);
if ((i & 0xf) == 0xf)
sim_debug(DEBUG_DATA, &dsk_dev, "\n");
}
sim_debug(DEBUG_DATA, &dsk_dev, "\n");
if (sectWrite((DISK_INFO *)uptr->up7, flp_dcb.stat[3],
flp_dcb.stat[4], flp_dcb.stat[5],
sim_debug(DEBUG_DATA, &dsk_dev, "Disk Write: %d bytes\n", len);
for (i = 0; i < len; i++) {
sim_debug(DEBUG_DATA, &dsk_dev, "%02x ", flp_buf[i]);
if ((i & 0xf) == 0xf)
sim_debug(DEBUG_DATA, &dsk_dev, "\n");
}
sim_debug(DEBUG_DATA, &dsk_dev, "\n");
if (sectWrite((DISK_INFO *)uptr->up7, flp_dcb.cmd[2],
flp_dcb.cmd[3], flp_dcb.cmd[4],
&flp_buf[0], sizeof(flp_buf), &flags, &len) != SCPE_OK) {
uptr->PHASE = PHASE_RES;
sim_activate(uptr, 1000);
@@ -725,16 +732,16 @@ flp_svc (UNIT *uptr)
flp_dcb.count -= len;
flp_dcb.xcount += len;
flp_dcb.addr += len;
if (flp_dcb.stat[5] == flp_dcb.cmd[6]) {
flp_dcb.stat[5] = 1;
if(flp_dcb.stat[4]) {
flp_dcb.stat[3]++;
flp_dcb.stat[4] = 0;
if (flp_dcb.cmd[4] == flp_dcb.cmd[6]) {
flp_dcb.cmd[4] = 1;
if(flp_dcb.cmd[3]) {
flp_dcb.cmd[2]++;
flp_dcb.cmd[3] = 0;
} else {
flp_dcb.stat[4] = 1;
flp_dcb.cmd[3] = 1;
}
} else {
flp_dcb.stat[5]++;
flp_dcb.cmd[4]++;
}
if (flp_dcb.count == 0) {
uptr->PHASE = PHASE_RES;
@@ -746,8 +753,6 @@ flp_svc (UNIT *uptr)
return SCPE_OK;
case CMD_RDTRK: /* Read track */
case CMD_WRDEL: /* Write delete */
case CMD_RDDEL: /* Read delete */
/* Make sure cylinder is correct */
flp_dcb.stat[1] = 0;
flp_dcb.stat[2] = 0;
@@ -777,6 +782,26 @@ flp_svc (UNIT *uptr)
return SCPE_OK;
}
case PHASE_RES:
switch(flp_dcb.cmd[0] & 0xf) {
case CMD_RDSEC: /* Read sector */
case CMD_WRSEC: /* Write sector */
case CMD_RDTRK: /* Read track */
case CMD_WRDEL: /* Write delete */
case CMD_RDDEL: /* Read delete */
/* Make sure cylinder is correct */
flp_dcb.stat[3] = flp_dcb.cmd[2]; /* C */
flp_dcb.stat[4] = flp_dcb.cmd[3]; /* H */
flp_dcb.stat[5] = flp_dcb.cmd[4]; /* R */
flp_dcb.stat[6] = flp_dcb.cmd[5]; /* N */
flp_dcb.stat_len = 7;
break;
case CMD_FIXDR: /* Fix drive */
case CMD_RDSID: /* Read sector ID */
case CMD_FMTTK: /* Format track */
default: /* Invalid command */
break;
}
/* Save results back to memory */
io_dcbwrite_blk(uptr, 0xD9, &flp_dcb.stat[0], flp_dcb.stat_len);
io_dcbwrite_byte(uptr, 0xc2, flp_dcb.gstat);
@@ -785,12 +810,13 @@ flp_svc (UNIT *uptr)
if (uptr->CYL == 0)
flags |= 0x10;
io_dcbwrite_byte(uptr, 0xc3, flags);
io_dcbwrite_half(uptr, 0xca, flp_dcb.xcount);
io_dcbwrite_byte(uptr, 0xCE, flp_dcb.stat[3]);
io_dcbwrite_byte(uptr, 0xCD, (flp_dcb.stat[4] << 2) | 0);
io_dcbwrite_byte(uptr, 0xCF, flp_dcb.stat[5]);
io_dcbwrite_addr(uptr, 0xC5, flp_dcb.addr);
// io_dcbwrite_byte(uptr, 0xc4, 0);
io_dcbwrite_half(uptr, 0xC8, flp_dcb.count);
io_dcbwrite_half(uptr, 0xca, flp_dcb.xcount);
io_dcbwrite_byte(uptr, 0xCD, (flp_dcb.stat[4] << 2) | 0);
io_dcbwrite_byte(uptr, 0xCE, flp_dcb.stat[3]);
io_dcbwrite_byte(uptr, 0xCF, flp_dcb.stat[5]);
sim_debug(DEBUG_DETAIL, &flp_dev,"Stop floppy %2x %4x %2x\n\r",
flags, flp_dcb.xcount, flp_dcb.gstat);
uptr->PHASE = PHASE_IRQ;

1154
Ridge32/ridge32_flt.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -146,6 +146,9 @@ io_dcbwrite_byte(UNIT *uptr, int off, uint8 data)
offset = 8 * (3 - (addr & 0x3));
M[addr >> 2] &= ~(0xff << offset);
M[addr >> 2] |= ((uint32)(data)) << offset;
if ((addr & ~3) == 0x0e1200)
sim_debug(DEBUG_CMD, &cpu_dev, "Set %08x %08x\n", addr, M[addr>>2]);
return;
}
@@ -191,6 +194,8 @@ io_write_blk(int addr, uint8 *data, int sz)
isprint((word >> 8) & 0xff)?(word >> 8)& 0xff:'.',
isprint(word & 0xff)?word& 0xff:'.');
}
if ((addr & ~3) == 0x0e1200)
sim_debug(DEBUG_CMD, &cpu_dev, "Set %08x %08x\n", addr, M[addr>>2]);
}
}
@@ -202,7 +207,7 @@ io_read(uint32 dev_data, uint32 *data)
dev = (dev_data >> 24) & 0xff;
r = dev_table[dev]->io_read(dev_data, data);
sim_debug(DEBUG_CMD, &cpu_dev, "Read %02x, data=%08x\n", dev, *data);
sim_debug(DEBUG_CMD, &cpu_dev, "Read %02x, dev=%08x data=%08x\n", dev, dev_data, *data);
return r;
}
@@ -213,7 +218,7 @@ io_write(uint32 dev_data, uint32 data)
int r;
dev = (dev_data >> 24) & 0xff;
sim_debug(DEBUG_CMD, &cpu_dev, "Write %02x, data=%08x\n", dev, data);
sim_debug(DEBUG_CMD, &cpu_dev, "Write %02x, dev=%08x data=%08x\n", dev, dev_data, data);
r = dev_table[dev]->io_write(dev_data, data);
return r;
}

View File

@@ -85,7 +85,7 @@ t_stat sim_load (FILE *fileref, CONST char *cptr, CONST char *fnam, int flag)
int i, sect;
uint32 flags;
uint32 len;
uint32 addr = 0x3e000;
uint32 addr = 0x3a000;
uint32 data;
uint32 mask;
uint32 pa;
@@ -702,7 +702,7 @@ if (sw & SWMASK ('M')) {
if (*cptr == ',') {
cptr++;
while (sim_isspace (*cptr)) cptr++;
if (*cptr != 'L' || *cptr != 'l')
if (*cptr != 'L' && *cptr != 'l')
return SCPE_ARG;
val[0] |= 0x10;
l = 4;

View File

@@ -2076,10 +2076,10 @@ KL10 = ${KL10D}/kx10_cpu.c ${KL10D}/kx10_sys.c ${KL10D}/kx10_df.c \
KL10_OPT = -DKL=1 -DUSE_INT64 -I $(KL10D) -DUSE_SIM_CARD ${NETWORK_OPT}
RIDGE32D = ${SIMHD}/Ridge32
RIDGE32 = ${RIDGE32D}/ridge32_cpu.c ${RIDGE32D}/ridge32_sys.c \
${RIDGE32D}/ridge32_iobus.c ${RIDGE32D}/ridge32_flp.c \
${RIDGE32D}/ridge32_dsk.c ${RIDGE32D}/ridge32_ct.c \
${RIDGE32D}/ridge32_vid.c
RIDGE32 = ${RIDGE32D}/ridge32_cpu.c ${RIDGE32D}/ridge32_flt.c \
${RIDGE32D}/ridge32_sys.c ${RIDGE32D}/ridge32_iobus.c \
${RIDGE32D}/ridge32_flp.c ${RIDGE32D}/ridge32_dsk.c \
${RIDGE32D}/ridge32_ct.c ${RIDGE32D}/ridge32_vid.c
RIDGE32_OPT = -I $(RIDGE32D) -DRIDGE32 -DUSE_SIM_IMD ${VIDEO_CCDEFS} ${VIDEO_LDFLAGS}
ATT3B2D = ${SIMHD}/3B2