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:
@@ -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(®s[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(®s[reg1], src2, op & 1);
|
||||
goto fptrap;
|
||||
|
||||
case OP_RSUB: /* Real subtract */
|
||||
src2 ^= MSIGN;
|
||||
/* Fall through */
|
||||
|
||||
case OP_RADD: /* Real add */
|
||||
temp = radd(®s[reg1], src1, src2);
|
||||
goto fptrap;
|
||||
|
||||
case OP_RMPY: /* Real product */
|
||||
temp = rmult(®s[reg1], src1, src2);
|
||||
goto fptrap;
|
||||
|
||||
case OP_RDIV: /* Real divide */
|
||||
case OP_FLOAT: /* Make integer real */
|
||||
temp = rdiv(®s[reg1], src1, src2);
|
||||
goto fptrap;
|
||||
|
||||
case OP_MAKERD: /* Convert real to double */
|
||||
makerd(®s[reg1], ®s[(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(®s[reg1], ®s[(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(®s[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(®s[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(®s[reg1], ®s[(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(®s[reg1], ®s[(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(®s[reg1], ®s[(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, ®s[(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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
1154
Ridge32/ridge32_flt.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
8
makefile
8
makefile
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user