diff --git a/Ridge32/ridge32_cpu.c b/Ridge32/ridge32_cpu.c index db0cc9a..9659988 100644 --- a/Ridge32/ridge32_cpu.c +++ b/Ridge32/ridge32_cpu.c @@ -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; diff --git a/Ridge32/ridge32_defs.h b/Ridge32/ridge32_defs.h index 6ed4808..e523873 100644 --- a/Ridge32/ridge32_defs.h +++ b/Ridge32/ridge32_defs.h @@ -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); diff --git a/Ridge32/ridge32_dsk.c b/Ridge32/ridge32_dsk.c index d495c79..4f99c5f 100644 --- a/Ridge32/ridge32_dsk.c +++ b/Ridge32/ridge32_dsk.c @@ -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); diff --git a/Ridge32/ridge32_flp.c b/Ridge32/ridge32_flp.c index 46cbf53..7cc3348 100644 --- a/Ridge32/ridge32_flp.c +++ b/Ridge32/ridge32_flp.c @@ -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; diff --git a/Ridge32/ridge32_flt.c b/Ridge32/ridge32_flt.c new file mode 100644 index 0000000..91619e9 --- /dev/null +++ b/Ridge32/ridge32_flt.c @@ -0,0 +1,1154 @@ +/* Ridge32_flp.c: Ridge 32 floating point. + + Copyright (c) 2020, Richard Cornwell + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + RICHARD CORNWELL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ + +#include "ridge32_defs.h" /* simulator defns */ + +#define EMASK 0x7f800000 +#define MSIGN 0x80000000 +#define MMASK 0x007fffff +#define ONE 0x00800000 +#define NMASK 0x01000000 +#define XMASK 0x00ffffff +#define CMASK 0xff000000 +#define CMASK1 0xfe000000 +#define FMASK 0xffffffff +#define DEMSK 0x7ff00000 +#define DCMSK 0xfff00000 +#define DMMSK 0x000fffff +#define DONE 0x00100000 + +/* Convert integer to floating point */ +int +rfloat(uint32 *res, uint32 src1) +{ + int e1 = 150; /* Exponent */ + int s = 0; /* Sign */ + + /* Make number positive */ + if (src1 & MSIGN) { + s = 1; + src1 = (src1 ^ FMASK) + 1; + } + + /* Quick exit if zero */ + if (src1 == 0) { + *res = (s)? MSIGN: 0; + return 0; + } + + /* Denomalize the number first */ + while ((src1 & CMASK) != 0) { + src1 >>= 1; + e1 ++; + } + + /* Now normalize number */ + while ((src1 & ONE) == 0) { + src1 <<= 1; + e1 --; + } + + /* Put things together */ + *res = ((s) ? MSIGN: 0) | (e1 << 23) | (src1 & MMASK); + return 0; +} + +/* Convert floating point to integer */ +int +rfix(uint32 *res, uint32 src, int round) +{ + int e1; /* Exponent */ + int s = 0; /* Sign */ + + /* Extract sign and exponent */ + e1 = (src & EMASK) >> 23; + if (src & MSIGN) { + s = 1; + src &= ~MSIGN; + } + + /* Check if unormalized */ + if (e1 == 0) { + if (s) + src = (src ^ FMASK) + 1; + *res = src; + return 0; + } + + /* Check if zero result */ + if (e1 < 119) { + *res = 0; + return 0; + } + + /* Check if out of range */ + if (e1 > 157) { + *res = (s)? MSIGN : ~MSIGN; + return 18; /* Indicate overflow */ + } + + /* Convert to scaled integer */ + src &= MMASK; + src |= ONE; + src <<= 8; /* Add in guard bit */ + + while (e1 < 157) { + src >>= 1; + e1 ++; + } + + if (round) + src++; + src >>= 1; /* Remove guard bit */ + if (s) + src = (src ^ FMASK) + 1; + *res = src; + return 0; +} + +/* Make single precsion number a double precision number */ +void +makerd(uint32 *resl, uint32 *resh, uint32 src) +{ + int e; /* Hold the exponent */ + + e = (src & EMASK) >> 23; + + if (e == 0) { + *resh = 0; + *resl = 0; + return; + } + e -= 127; + e += 1023; + *resh = (src & 07) << 25; + *resl = (src & MSIGN) | ((e << 20) & DEMSK) | ((src & MMASK) >> 3); +} + + +/* Compare to floating point numbers */ +int +rcomp(uint32 src1, uint32 src2) +{ + int e1, e2; /* Hold the two exponents */ + int s; /* Hold resulting sign */ + int temp; /* Hold exponent difference */ + uint32 m1, m2; + + /* Extract numbers and adjust */ + e1 = (src1 & EMASK) >> 23; + m1 = src1 & MMASK; /* extract mantissa */ + if (e1 != 0) /* Add in hidden bit if needed */ + m1 |= ONE; + e2 = (src2 & EMASK) >> 23; + m2 = src2 & MMASK; /* extract mantissa */ + if (e2 != 0) /* Add in hidden bit if needed */ + m2 |= ONE; + temp = e1 - e2; + /* Align operands */ + if (temp > 0) { + if (temp > 24) { + m2 = 0; + } else { + /* Shift src2 right if src1 larger expo - expo */ + m2 >>= temp; + } + } else if (temp < 0) { + if (temp < -24) { + m1 = 0; + } else { + /* Shift src1 right if src2 larger expo - expo */ + m1 >>= temp; + } + } + + /* Exponents should be equal now. */ + if (src1 & MSIGN) + m1 = (m1 ^ FMASK) + 1; + + if ((src2 & MSIGN) == 0) + m2 = (m2 ^ FMASK) + 1; + + /* Add results */ + m1 = m1 + m2; + + /* Compute result */ + if (m1 & MSIGN) { + return FMASK; + } else if (m1 != 0) { + return 1; + } + return 0; +} + + +/* Add two single precision numbers */ +int +radd(uint32 *res, uint32 src1, uint32 src2) +{ + int e1, e2; /* Hold the two exponents */ + int s; /* Hold resulting sign */ + int temp; /* Hold exponent difference */ + + /* Extract numbers and adjust */ + e1 = (src1 & EMASK) >> 23; + e2 = (src2 & EMASK) >> 23; + s = 0; + if (src1 & MSIGN) + s |= 2; + if (src2 & MSIGN) + s |= 1; + src2 &= MMASK; /* extract mantissa */ + if (e2 != 0) /* Add in hidden bit if needed */ + src2 |= ONE; + src1 &= MMASK; /* extract mantissa */ + if (e1 != 0) /* Add in hidden bit if needed */ + src1 |= ONE; + temp = e1 - e2; + /* Create guard digit */ + src2 <<= 1; + src1 <<= 1; + if (temp > 0) { + if (temp > 24) { + src2 = 0; + } else { + /* Shift src2 right if src1 larger expo - expo */ + src2 >>= temp; + } + } else if (temp < 0) { + if (temp < -24) { + src1 = 0; + e1 = e2; + } else { + /* Shift src1 right if src2 larger expo - expo */ + src1 >>= temp; + e1 += temp; + } + } + + /* Exponents should be equal now. */ + if (s & 2) + src1 = (src1 ^ FMASK) + 1; + + if (s & 1) + src2 = (src2 ^ FMASK) + 1; + + /* Add results */ + src1 = src1 + src2; + + /* figure sign */ + if (src1 & MSIGN) { + src1 = (src1 ^ FMASK) + 1; + s = 1; + } else { + s = 0; + } + + /* Handle overflow */ + while ((src1 & CMASK1) != 0) { + src1 >>= 1; + e1++; + } + + /* Exit if zero result */ + if (src1 == 0) { + *res = ((s)?MSIGN:0); + return 0; + } + + /* Normalize result */ + while ((src1 & NMASK) == 0) { + src1 <<= 1; + e1--; + } + + /* Remove DP Guard bit */ + src1 >>= 1; + + *res = ((s)?MSIGN:0) | ((e1 << 23) & EMASK) | (src1 & MMASK); + + if (e1 > 254) + return 18; + else if (e1 < 0) + return 19; + return 0; +} + +/* Multiply two single precision numbers */ +int +rmult(uint32 *res, uint32 src1, uint32 src2) +{ + int e1, e2; /* Hold the two exponents */ + int s; /* Hold resulting sign */ + int temp; /* Hold exponent difference */ + uint32 dest, desth; + + /* Extract numbers and adjust */ + e1 = (src1 & EMASK) >> 23; + e2 = (src2 & EMASK) >> 23; + s = 0; + if ((src1 & MSIGN) != (src2 & MSIGN)) + s = 1; + src2 &= MMASK; /* extract mantissa */ + if (e2 != 0) /* Add in hidden bit if needed */ + src2 |= ONE; + src1 &= MMASK; /* extract mantissa */ + if (e1 != 0) /* Add in hidden bit if needed */ + src1 |= ONE; + + /* Compute exponent */ + e1 = e1 + e2 - 127; + + dest = desth = 0; + + /* Do multiply */ + for (temp = 0; temp < 24; temp++) { + /* Add if we need too */ + if (src1 & 1) { + dest += src2; + } + /* Shift right by one */ + src1 >>= 1; + desth >>= 1; + if (dest & 1) + desth |= MSIGN; + dest >>= 1; + } + + /* Fix result */ + dest <<= 1; + if (desth & MSIGN) + dest |= 1; + desth <<= 1; + + /* Handle overflow */ + while ((dest & CMASK) != 0) { + desth >>= 1; + if (dest & 1) + desth |= MSIGN; + dest >>= 1; + e1++; + } + + /* Exit if zero result */ + if (dest == 0 && desth == 0) { + *res = ((s)?MSIGN:0); + return 0; + } + + /* Normalize result */ + while ((dest & ONE) == 0) { + dest <<= 1; + if (desth & MSIGN) + dest |= 1; + desth <<= 1; + e1--; + } + + *res = ((s)?MSIGN:0) | ((e1 << 23) & EMASK) | (dest & MMASK); + + if (e1 > 254) + return 18; + else if (e1 < 0) + return 19; + return 0; +} + +/* Divide two single precision numbers */ +int +rdiv(uint32 *res, uint32 src1, uint32 src2) +{ + int e1, e2; /* Hold the two exponents */ + int s; /* Hold resulting sign */ + int temp; /* Hold exponent difference */ + uint32 dest, desth; + uint32 src1h; + + /* Extract numbers and adjust */ + e1 = (src1 & EMASK) >> 23; + e2 = (src2 & EMASK) >> 23; + s = 0; + if (e2 == 0) + return 20; + if ((src1 & MSIGN) != (src2 & MSIGN)) + s = 1; + src2 &= MMASK; /* extract mantissa */ + if (e2 != 0) /* Add in hidden bit if needed */ + src2 |= ONE; + src1 &= MMASK; /* extract mantissa */ + if (e1 != 0) /* Add in hidden bit if needed */ + src1 |= ONE; + + /* Compute exponent */ + e1 = e1 - e2 + 127; + + dest = desth = 0; + + src1h = src1; + src1 = 0; + + + /* Do divide */ + dest = 0; + for (temp = 0; temp < 32; temp++) { + /* Shift left by one */ + src1 <<= 1; + if (src1h & MSIGN) + src1 |= 1; + src1h <<= 1; + + /* Subtract remainder to dividend */ + desth = src1 - src2; + + /* Shift quotent left one bit */ + dest <<= 1; + + /* If remainder larger then divisor replace */ + if ((desth & MSIGN) == 0) { + src1 = desth; + dest |= 1; + } + } + + *res = ((s)?MSIGN:0) | ((e1 << 23) & EMASK) | (desth & MMASK); + + if (e1 > 254) + return 18; + else if (e1 < 0) + return 19; + return 0; +} + +/* Convert integer to floating point */ +int +dfloat(uint32 *resl, uint32 *resh, uint32 src1) +{ + int e1 = 1043; /* Exponent */ + int s = 0; /* Sign */ + uint32 src1h = 0; /* High order bits */ + + /* Make number positive */ + if (src1 & MSIGN) { + s = 1; + src1 = (src1 ^ FMASK) + 1; + } + + /* Quick exit if zero */ + if (src1 == 0) { + *resl = (s)? MSIGN: 0; + *resh = 0; + return 0; + } + + /* Denomalize the number first */ + while ((src1 & DCMSK) != 0) { + src1h >>= 1; + if (src1 & 1) + src1h |= MSIGN; + src1 >>= 1; + e1 ++; + } + + /* Now normalize number */ + while ((src1 & DONE) == 0) { + src1 <<= 1; + if (src1h & MSIGN) + src1 |= 1; + src1h <<= 1; + e1 --; + } + + /* Put things together */ + *resl = ((s) ? MSIGN : 0) | ((e1 << 20) & DEMSK) | (src1 & DMMSK); + *resh = src1h; + return 0; +} + +/* Convert floating point to integer */ +int +dfix(uint32 *res, uint32 src, uint32 srch, int round) +{ + int e1; /* Exponent */ + int s = 0; /* Sign */ + + /* Extract sign and exponent */ + e1 = (src & DEMSK) >> 20; + if (src & MSIGN) { + s = 1; + src &= ~MSIGN; + } + + /* Check if unormalized */ + if (e1 == 0) { + if (s) + src = (src ^ FMASK) + 1; + *res = src; + return 0; + } + + /* Check if zero result */ + if (e1 < 1023) { + *res = 0; + return 0; + } + + /* Check if out of range */ + if (e1 > 1053) { + *res = (s)? MSIGN : ~MSIGN; + return 18; /* Indicate overflow */ + } + + /* Convert to scaled integer */ + src &= DMMSK; + src |= DONE; + src <<= 10; + src |= srch >> 20; + srch <<= 10; + + while (e1 < 1053) { + srch >>= 1; + if (src & 1) + srch |= MSIGN; + src >>= 1; + e1 ++; + } + + if (round && (srch & MSIGN) != 0) + src++; + if (s) + src = (src ^ FMASK) + 1; + *res = src; + return 0; +} + +/* Make single precsion number a double precision number */ +int +makedr(uint32 *res, uint32 src, uint32 srch) +{ + int e; /* Hold the exponent */ + + e = (src & DEMSK) >> 20; + if (e == 0) { + *res = 0; + return 0; + } + /* Adjust bias */ + e -= 1023; + e += 127; + src <<= 3; + src |= srch >> 29; + /* Check if out of range */ + *res = (src & MSIGN) | ((e << 23) & EMASK) | (src & MMASK); + return 0; +} + + +/* Compare to floating point numbers */ +int +drcomp(uint32 src1, uint32 src1h, uint32 src2, uint32 src2h) +{ + int e1, e2; /* Hold the two exponents */ + int s; /* Hold resulting sign */ + int temp; /* Hold exponent difference */ + uint32 m1, m2, mh; + + /* Extract numbers and adjust */ + e1 = (src1 & DEMSK) >> 20; + m1 = src1 & DMMSK; /* extract mantissa */ + if (e1 != 0) /* Add in hidden bit if needed */ + m1 |= DONE; + e2 = (src2 & DEMSK) >> 20; + m2 = src2 & DMMSK; /* extract mantissa */ + if (e2 != 0) /* Add in hidden bit if needed */ + m2 |= DONE; + temp = e1 - e2; + /* Align operands */ + if (temp > 0) { + if (temp > 56) { + m2 = src2h = 0; + } else { + /* Shift src2 right if src1 larger expo - expo */ + m2 >>= temp; + while (temp-- != 0) { + src2h >>= 1; + if (m2 & 1) + src2h |= MSIGN; + m2 >>= 1; + } + } + } else if (temp < 0) { + if (temp < -56) { + m1 = src1h = 0; + } else { + /* Shift src1 right if src2 larger expo - expo */ + m1 >>= temp; + while (temp-- != 0) { + src1h >>= 1; + if (m1 & 1) + src1h |= MSIGN; + m1 >>= 1; + } + } + } + + /* Exponents should be equal now. */ + if (src1 & MSIGN) { + src1h = (src1h ^ FMASK) + 1; + m1 = m1 ^ FMASK; + if (src1h == 0) + m1++; + } + + if ((src2 & MSIGN) == 0) { + src2h = (src2h ^ FMASK) + 1; + m2 = m2 ^ FMASK; + if (src2h == 0) + m2++; + } + + /* Add results */ + mh = src1h + src2h; + m1 = m1 + m2; + if (mh < src2h || mh < src1h) + m1 ++; + + /* Compute result */ + if (m1 & MSIGN) { + return FMASK; + } else if (m1 != 0 && mh != 0) { + return 1; + } + return 0; +} + + +/* Add two double precision numbers */ +int +dradd(uint32 *resl, uint32 *resh, uint32 src1, uint32 src1h, uint32 src2, uint32 src2h) +{ + int e1, e2; /* Hold the two exponents */ + int s; /* Hold resulting sign */ + int temp; /* Hold exponent difference */ + uint32 m1, m2, mh; + + /* Extract numbers and adjust */ + e1 = (src1 & DEMSK) >> 20; + m1 = src1 & DMMSK; /* extract mantissa */ + if (e1 != 0) /* Add in hidden bit if needed */ + m1 |= DONE; + e2 = (src2 & DEMSK) >> 20; + m2 = src2 & DMMSK; /* extract mantissa */ + if (e2 != 0) /* Add in hidden bit if needed */ + m2 |= DONE; + temp = e1 - e2; +//printf(" %08x %08x %08x %08x %d %d %d\n", m1, src1h, m2, src2h, e1, e2, temp); + /* Align operands */ + if (temp > 0) { + if (temp > 56) { + m2 = src2h = 0; + } else { + /* Shift src2 right if src1 larger expo - expo */ + while (temp-- != 0) { + src2h >>= 1; + if (m2 & 1) + src2h |= MSIGN; + m2 >>= 1; + } + } + } else if (temp < 0) { + if (temp < -27) { + m1 = src1h = 0; + } else { + /* Shift src1 right if src2 larger expo - expo */ + while (temp-- != 0) { + src1h >>= 1; + if (m1 & 1) + src1h |= MSIGN; + m1 >>= 1; + } + } + } + + /* Exponents should be equal now. */ + if ((src1 & MSIGN) != 0) { + src1h = (src1h ^ FMASK) + 1; + m1 = m1 ^ FMASK; + if (src1h == 0) + m1++; + } + + if ((src2 & MSIGN) != 0) { + src2h = (src2h ^ FMASK) + 1; + m2 = m2 ^ FMASK; + if (src2h == 0) + m2++; + } + + /* Add results */ + mh = src1h + src2h; + m1 = m1 + m2; + if (mh < src1h || mh < src2h) + m1 ++; + +//printf("s %08x %08x \n", m1, mh); + /* figure sign */ + if (m1 & MSIGN) { + mh = (mh ^ FMASK) + 1; + m1 = m1 ^ FMASK; + if (mh == 0) + m1++; + s = 1; + } else { + s = 0; + } + + /* Handle overflow */ + while ((m1 & DCMSK) != 0) { + mh >>= 1; + if (m1 & 1) + mh |= MSIGN; + m1 >>= 1; + e1++; + } + +//printf("n %08x %08x %d \n", m1, mh, e1); + /* Exit if zero result */ + if (m1 == 0 && mh == 0) { + *resl = ((s)?MSIGN:0); + *resh = 0; + return 0; + } + + /* Normalize result */ + while ((m1 & DONE) == 0) { + m1 <<= 1; + if (mh & MSIGN) + m1 |= 1; + mh <<= 1; + e1--; + } +//printf("f %08x %08x %d \n", m1, mh, e1); + + *resl = ((s)?MSIGN:0) | ((e1 << 20) & DEMSK) | (m1 & DMMSK); + *resh = mh; + +//printf("r %08x %08x\n", *resl, *resh); + if (e1 > 1023) + return 18; + else if (e1 < 0) + return 19; + return 0; +} + +/* Multiply two double precision numbers */ +int +drmult(uint32 *resl, uint32 *resh, uint32 src1, uint32 src1h, uint32 src2, uint32 src2h) +{ + int e1, e2; /* Hold the two exponents */ + int s = 0; /* Hold resulting sign */ + int temp; /* Hold exponent difference */ + uint32 m1, m2, mh; + uint32 dest, desth; + + /* Extract numbers and adjust */ + e1 = (src1 & DEMSK) >> 20; + if ((src1 & MSIGN) != (src2 & MSIGN)) + s = 1; + m1 = src1 & DMMSK; /* extract mantissa */ + if (e1 != 0) /* Add in hidden bit if needed */ + m1 |= DONE; + e2 = (src2 & DEMSK) >> 20; + m2 = src2 & DMMSK; /* extract mantissa */ + if (e2 != 0) /* Add in hidden bit if needed */ + m2 |= DONE; + temp = e1 - e2; + + /* Compute exponent */ + e1 = e1 + e2 - 1022; +//printf(" %08x %08x %08x %08x %d %d %d\n", m1, src1h, m2, src2h, e1, e2, temp); + + dest = desth = 0; + + /* Do multiply */ + for (temp = 0; temp < 53; temp++) { + /* Add if we need too */ + if (src1h & 1) { + desth += src2h; + dest += m2; + if (desth < src2h) + dest ++; + } + /* Shift right by one */ + src1h >>= 1; + if (m1 & 1) + src1h |= MSIGN; + m1 >>= 1; + desth >>= 1; + if (dest & 1) + desth |= MSIGN; + dest >>= 1; +//printf("m %08x %08x : %08x %08x -> %08x %08x\n", m1, src1h, m2, src2h, dest, desth); + } + + /* Handle overflow */ + while ((dest & DCMSK) != 0) { + desth >>= 1; + if (dest & 1) + desth |= MSIGN; + dest >>= 1; + e1++; + } + +//printf("n %08x %08x %d \n", dest, desth, e1); + /* Exit if zero result */ + if (dest == 0 && desth == 0) { + *resl = ((s)?MSIGN:0); + *resh = 0; + return 0; + } + + /* Normalize result */ + while ((dest & DONE) == 0) { + dest <<= 1; + if (desth & MSIGN) + dest |= 1; + desth <<= 1; + e1--; + } + +//printf("f %08x %08x %d \n", dest, desth, e1); + *resl = ((s)?MSIGN:0) | ((e1 << 20) & DEMSK) | (dest & DMMSK); + *resh = desth; +//printf("r %08x %08x\n", *resl, *resh); + + if (e1 > 1023) + return 1; + else if (e1 < 0) + return 2; + return 0; +} + +/* Divide two double precision numbers */ +int +drdiv(uint32 *resl, uint32 *resh, uint32 src1, uint32 src1h, uint32 src2, uint32 src2h) +{ + int e1, e2; /* Hold the two exponents */ + int s = 0; /* Hold resulting sign */ + int temp; /* Hold exponent difference */ + uint32 m1, m2, mh; + uint32 dest, desth; + + /* Extract numbers and adjust */ + e1 = (src1 & DEMSK) >> 20; + if ((src1 & MSIGN) != (src2 & MSIGN)) + s = 1; + m1 = src1 & DMMSK; /* extract mantissa */ + if (e1 != 0) /* Add in hidden bit if needed */ + m1 |= DONE; + e2 = (src2 & DEMSK) >> 20; + m2 = src2 & DMMSK; /* extract mantissa */ + if (e2 != 0) /* Add in hidden bit if needed */ + m2 |= DONE; + temp = e1 - e2; + + /* Compute exponent */ + e1 = e1 - e2 + 1022; + /* Do divide */ + /* Change sign of src2 so we can add */ + src2h ^= FMASK; + m2 ^= XMASK; + if (src2h == FMASK) + m2 ++; + src2h ++; + dest = desth = 0; + /* Do divide */ + for (temp = 53; temp > 0; temp--) { + uint32 tlow, thigh; + + /* Shift left by one */ + m1 <<= 1; + if (src1h & MSIGN) + m1 |= 1; + src1h <<= 1; + /* Subtract dividend from remainder */ + thigh = src1h + src2h; + tlow = m1 + src2; + if (thigh < src2h) + tlow ++; + + /* Shift quotent left one bit */ + dest <<= 1; + if (desth & MSIGN) + dest |= 1; + desth <<= 1; + + /* If remainder larger then divisor replace */ + if ((tlow & CMASK) != 0) { + m1 = tlow; + src1h = thigh; + desth |= 1; + } + } + + /* Compute one final set to see if rounding needed */ + /* Shift left by one */ + m1 <<= 1; + if (src1h & MSIGN) + m1 |= 1; + src1h <<= 1; + /* Subtract remainder to dividend */ + src1h += src2h; + m1 += src2; + if (src1h < src2h) + m1++; + + /* If .5 off, round */ + if (m1 & MSIGN) { + if (desth == FMASK) + dest++; + desth++; + } + + /* Handle overflow */ + while ((dest & DCMSK) != 0) { + desth >>= 1; + if (dest & 1) + desth |= MSIGN; + dest >>= 1; + e1++; + } + +//printf("n %08x %08x %d \n", dest, desth, e1); + /* Exit if zero result */ + if (dest == 0 && desth == 0) { + *resl = ((s)?MSIGN:0); + *resh = 0; + return 0; + } + + /* Normalize result */ + while ((dest & DONE) == 0) { + dest <<= 1; + if (desth & MSIGN) + dest |= 1; + desth <<= 1; + e1--; + } + +//printf("f %08x %08x %d \n", dest, desth, e1); + *resl = ((s)?MSIGN:0) | ((e1 << 20) & DEMSK) | (dest & DMMSK); + *resh = desth; +//printf("r %08x %08x\n", *resl, *resh); + + if (e1 > 1023) + return 1; + else if (e1 < 0) + return 2; + return 0; +} +#ifdef TEST + +typedef union { + uint32 fr; + float f; +} FLOAT; + +typedef union { + struct { uint32 h; uint32 l; } r; + uint64_t dr; + double d; +} DFLOAT; + + +FLOAT Zero; +FLOAT Half; +FLOAT One; +FLOAT Two; +FLOAT Three; +FLOAT Four; +FLOAT Five; +FLOAT Eight; +FLOAT Nine; +FLOAT TwentySeven; +FLOAT ThirtyTwo; +FLOAT TwoForty; +FLOAT MinusOne; +FLOAT Half; +FLOAT OneAndHalf; + +DFLOAT DZero; +DFLOAT DHalf; +DFLOAT DOne; +DFLOAT DTwo; +DFLOAT DThree; +DFLOAT DFour; +DFLOAT DFive; +DFLOAT DEight; +DFLOAT DNine; +DFLOAT DTwentySeven; +DFLOAT DThirtyTwo; +DFLOAT DTwoForty; +DFLOAT DMinusOne; +DFLOAT DHalf; +DFLOAT DOneAndHalf; +#define PRINT(a, b) (void)makerd(&rl, &rh, b.fr); temp.r.h = rh; temp.r.l = rl; \ + printf("V= %f %f\n", a, temp.d); +#define DPRINT(a, b) printf("V= %f %f\n", a, b.d); + +int +main(int argc, char *argv) +{ + + uint32 v; + int i; + uint32 r; + uint32 r2; + uint32 rl, rh; + uint32 hlf = 0xBf400000; + uint32 one = 0x3f800000; + FLOAT stmp; + DFLOAT temp; + + Zero.fr = 0; + One.fr = 0x3f800000; + DZero.r.l = 0; + DZero.r.h = 0; + DOne.r.l = 0x3ff00000; + DOne.r.h = 0; + + (void)radd(&Two.fr, One.fr, One.fr); /* Two = One + One */ + (void)radd(&Three.fr, Two.fr, One.fr); /* Three = Two + One */ + (void)radd(&Four.fr, Three.fr, One.fr); /* Four = Three + One */ + (void)radd(&Five.fr, Four.fr, One.fr); /* Five = Four + One */ + (void)radd(&Eight.fr, Four.fr, Four.fr); /* Eight = Four + Four */ + (void)rmult(&Nine.fr, Three.fr, Three.fr); /* Nine = Three * Three */ + (void)rmult(&TwentySeven.fr, Nine.fr, Three.fr); /* TwentySeven = Nine * Three */ + (void)rmult(&ThirtyTwo.fr, Four.fr, Eight.fr); /* ThirtyTwo = Four * Eight */ + (void)rmult(&stmp.fr, Four.fr, Five.fr); /* TwoForty = Four * Five * Three * Four */ + (void)rmult(&stmp.fr, stmp.fr, Three.fr); + (void)rmult(&TwoForty.fr, stmp.fr, Four.fr); + MinusOne.fr = MSIGN ^ One.fr; /* MinusOne = -One */ + (void)rdiv(&Half.fr, One.fr, Two.fr); /* Half = One / Two */ + (void)radd(&OneAndHalf.fr, One.fr, Half.fr); /* OneAndHalf = One + Half */ + + PRINT(0.0f, Zero); + PRINT(1.0f, One); + PRINT(2.0f, Two); + PRINT(3.0f, Three); + PRINT(4.0f, Four); + PRINT(5.0f, Five); + PRINT(8.0f, Eight); + PRINT(9.0f, Nine); + PRINT(27.0f, TwentySeven); + PRINT(32.0f, ThirtyTwo); + PRINT(240.0, TwoForty); + PRINT(-1.0f, MinusOne); + PRINT(0.5f, Half); + PRINT(1.5f, OneAndHalf); + + (void)radd(&stmp.fr, Zero.fr, Zero.fr); + r = rcomp(stmp.fr, Zero.fr); + if (r != 0) + printf("0+0 != 0\n"); + (void)radd(&stmp.fr, One.fr, MSIGN ^ One.fr); + r = rcomp(stmp.fr, Zero.fr); + if (r != 0) + printf("1-1 != 0\n"); + r = rcomp(One.fr, Zero.fr); + if (r != 1) + printf("1 <= 0 %d\n", r); + (void)radd(&stmp.fr, One.fr, One.fr); + r = rcomp(stmp.fr, Two.fr); + if (r != 0) + printf("1+1 != 2\n"); + r = rcomp(Zero.fr, MSIGN ^ Zero.fr); + if (r != 0) + printf("0 != -0\n"); + + (void)radd(&stmp.fr, Two.fr, One.fr); + r = rcomp(stmp.fr, Three.fr); + if (r != 0) + printf("2+1 != 3\n"); + (void)radd(&stmp.fr, Three.fr, One.fr); + r = rcomp(stmp.fr, Four.fr); + if (r != 0) + printf("3+1 != 4\n"); + (void)rmult(&stmp.fr, Two.fr, MSIGN ^ Two.fr); + (void)radd(&stmp.fr, stmp.fr, Four.fr); + r = rcomp(stmp.fr, Zero.fr); + if (r != 0) + printf("4+2*(-2) != 0\n"); + (void)radd(&stmp.fr, Four.fr, MSIGN ^ Three.fr); + (void)radd(&stmp.fr, stmp.fr, MSIGN ^ One.fr); + r = rcomp(stmp.fr, Zero.fr); + if (r != 0) + printf("4-3-1 != 0\n"); + for(i = 0; i < 31; i++) { + v = 1 << i; + (void) dfloat( &temp.r.l, &temp.r.h, v); + (void) dradd(&temp.r.l, &temp.r.h, temp.r.l, temp.r.h, DOne.r.l, DOne.r.h); +// (void) rdiv( &r, r2, hlf); + // (void) makerd( &rl, &rh, r); + // x.dr = ((uint64_t)rl << 32) | (uint64_t)rh; + // printf("%d v=%15d %08x r=%08x %14f %016lx ", i, v, v, r, x.d, x.dr); + // (void) rfix( &r2, r, 0); + // temp.r.h |= MSIGN; + // temp.r.l |= 1; + (void) dfix ( &r2, temp.r.l, temp.r.h, 0); + printf("%d r=%15d %08x %08x %f -> %d\n", i, v, temp.r.l, temp.r.h, temp.d, r2); + } + +#define DADD(a, b, c) (void)dradd(&a.r.l, &a.r.h, b.r.l, b.r.h, c.r.l, c.r.h) +#define DMUL(a, b, c) (void)drmult(&a.r.l, &a.r.h, b.r.l, b.r.h, c.r.l, c.r.h) +#define DDIV(a, b, c) (void)drdiv(&a.r.l, &a.r.h, b.r.l, b.r.h, c.r.l, c.r.h) + DPRINT(0.0f, DZero); + DPRINT(1.0f, DOne); + DADD(DTwo, DOne, DOne); /* Two = One + One */ + DPRINT(2.0f, DTwo); + DADD(DThree, DTwo, DOne); /* Three = Two + One */ + DPRINT(3.0f, DThree); + DADD(DFour, DThree, DOne); /* Four = Three + One */ + DPRINT(4.0f, DFour); + DADD(DFive, DFour, DOne); /* Five = Four + One */ + DPRINT(5.0f, DFive); + DADD(DEight, DFour, DFour); /* Eight = Four + Four */ + DPRINT(8.0f, DEight); + DMUL(DNine, DThree, DThree); /* Nine = Three * Three */ + DPRINT(9.0f, DNine); + DMUL(DTwentySeven, DNine, DThree); /* TwentySeven = Nine * Three */ + DPRINT(27.0f, DTwentySeven); + DMUL(DThirtyTwo, DFour, DEight); /* ThirtyTwo = Four * Eight */ + DPRINT(32.0f, DThirtyTwo); + DMUL(temp, DFour, DFive); /* TwoForty = Four * Five * Three * Four */ + DMUL(temp, temp, DThree); + DMUL(DTwoForty, temp, DFour); + DPRINT(240.0, DTwoForty); + DMinusOne.r.l = MSIGN ^ DOne.r.l; /* MinusOne = -One */ + DMinusOne.r.h = DOne.r.h; + DPRINT(-1.0f, DMinusOne); + DDIV(DHalf, DOne, DTwo); /* Half = One / Two */ + DPRINT(0.5f, DHalf); + DADD(DOneAndHalf, DOne, DHalf); /* OneAndHalf = One + Half */ + DPRINT(1.5f, DOneAndHalf); +} +#endif diff --git a/Ridge32/ridge32_iobus.c b/Ridge32/ridge32_iobus.c index 40c213a..2952aab 100644 --- a/Ridge32/ridge32_iobus.c +++ b/Ridge32/ridge32_iobus.c @@ -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; } diff --git a/Ridge32/ridge32_sys.c b/Ridge32/ridge32_sys.c index 494b8b7..9fdd9e3 100644 --- a/Ridge32/ridge32_sys.c +++ b/Ridge32/ridge32_sys.c @@ -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; diff --git a/makefile b/makefile index fb5333c..db19552 100644 --- a/makefile +++ b/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