diff --git a/AltairZ80/altairz80_cpu.c b/AltairZ80/altairz80_cpu.c index e4eab31c..123c3ef8 100644 --- a/AltairZ80/altairz80_cpu.c +++ b/AltairZ80/altairz80_cpu.c @@ -1,6 +1,6 @@ /* altairz80_cpu.c: MITS Altair CPU (8080 and Z80) - Copyright (c) 2002-2011, Peter Schorn + Copyright (c) 2002-2013, Peter Schorn Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -75,57 +75,58 @@ /* CHECK_CPU_8080 must be invoked whenever a Z80 only instruction is executed In case a Z80 instruction is executed on an 8080 the following two cases exist: 1) Trapping is enabled: execution stops - 2) Trapping is not enabled: decoding continues with the next byte + 2) Trapping is not enabled: decoding continues with the next byte, i.e. interpret as NOP + Note: in some cases different instructions need to be chosen on 8080 */ -#define CHECK_CPU_8080 \ - if (chiptype == CHIP_TYPE_8080) { \ - if (cpu_unit.flags & UNIT_CPU_OPSTOP) { \ - reason = STOP_OPCODE; \ - goto end_decode; \ - } \ - else { \ - sim_brk_pend[0] = FALSE; \ - continue; \ - } \ +#define CHECK_CPU_8080 \ + if (chiptype == CHIP_TYPE_8080) { \ + if (cpu_unit.flags & UNIT_CPU_OPSTOP) { \ + reason = STOP_OPCODE; \ + goto end_decode; \ + } \ + else { \ + sim_brk_pend[0] = FALSE; \ + continue; \ + } \ } /* CHECK_CPU_Z80 must be invoked whenever a non Z80 instruction is executed */ -#define CHECK_CPU_Z80 \ - if (cpu_unit.flags & UNIT_CPU_OPSTOP) { \ - reason = STOP_OPCODE; \ - goto end_decode; \ +#define CHECK_CPU_Z80 \ + if (cpu_unit.flags & UNIT_CPU_OPSTOP) { \ + reason = STOP_OPCODE; \ + goto end_decode; \ } -#define POP(x) { \ - register uint32 y = RAM_PP(SP); \ - x = y + (RAM_PP(SP) << 8); \ +#define POP(x) { \ + register uint32 y = RAM_PP(SP); \ + x = y + (RAM_PP(SP) << 8); \ } -#define JPC(cond) { \ - tStates += 10; \ - if (cond) { \ - PCQ_ENTRY(PCX); \ - PC = GET_WORD(PC); \ - } \ - else { \ - PC += 2; \ - } \ +#define JPC(cond) { \ + tStates += 10; \ + if (cond) { \ + PCQ_ENTRY(PCX); \ + PC = GET_WORD(PC); \ + } \ + else { \ + PC += 2; \ + } \ } -#define CALLC(cond) { \ - if (cond) { \ - register uint32 adrr = GET_WORD(PC); \ - CHECK_BREAK_WORD(SP - 2); \ - PUSH(PC + 2); \ - PCQ_ENTRY(PCX); \ - PC = adrr; \ - tStates += 17; \ - } \ - else { \ - sim_brk_pend[0] = FALSE; \ - PC += 2; \ - tStates += 10; \ - } \ +#define CALLC(cond) { \ + if (cond) { \ + register uint32 adrr = GET_WORD(PC); \ + CHECK_BREAK_WORD(SP - 2); \ + PUSH(PC + 2); \ + PCQ_ENTRY(PCX); \ + PC = adrr; \ + tStates += 17; \ + } \ + else { \ + sim_brk_pend[0] = FALSE; \ + PC += 2; \ + tStates += (chiptype == CHIP_TYPE_8080 ? 11 : 10); \ + } \ } extern int32 sio0s (const int32 port, const int32 io, const int32 data); @@ -2017,31 +2018,31 @@ static t_stat sim_instr_mmu (void) { switch(RAM_PP(PC)) { case 0x00: /* NOP */ - tStates += 4; + tStates += 4; /* NOP 4 */ sim_brk_pend[0] = FALSE; break; case 0x01: /* LD BC,nnnn */ - tStates += 10; + tStates += 10; /* LXI B,nnnn 10 */ sim_brk_pend[0] = FALSE; BC = GET_WORD(PC); PC += 2; break; case 0x02: /* LD (BC),A */ - tStates += 7; + tStates += 7; /* STAX B 7 */ CHECK_BREAK_BYTE(BC) PutBYTE(BC, HIGH_REGISTER(AF)); break; case 0x03: /* INC BC */ - tStates += 6; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 6); /* INX B 5 */ sim_brk_pend[0] = FALSE; ++BC; break; case 0x04: /* INC B */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* INR B 5 */ sim_brk_pend[0] = FALSE; BC += 0x100; temp = HIGH_REGISTER(BC); @@ -2049,7 +2050,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x05: /* DEC B */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* DCR B 5 */ sim_brk_pend[0] = FALSE; BC -= 0x100; temp = HIGH_REGISTER(BC); @@ -2057,20 +2058,20 @@ static t_stat sim_instr_mmu (void) { break; case 0x06: /* LD B,nn */ - tStates += 7; + tStates += 7; /* MVI B,nn 7 */ sim_brk_pend[0] = FALSE; SET_HIGH_REGISTER(BC, RAM_PP(PC)); break; case 0x07: /* RLCA */ - tStates += 4; + tStates += 4; /* RLC 4 */ sim_brk_pend[0] = FALSE; AF = ((AF >> 7) & 0x0128) | ((AF << 1) & ~0x1ff) | (AF & 0xc4) | ((AF >> 15) & 1); break; case 0x08: /* EX AF,AF' */ - tStates += 4; + tStates += 4; /* NOP 4 */ sim_brk_pend[0] = FALSE; CHECK_CPU_8080; temp = AF; @@ -2079,7 +2080,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x09: /* ADD HL,BC */ - tStates += 11; + tStates += (chiptype == CHIP_TYPE_8080 ? 10 : 11); /* DAD B 10 */ sim_brk_pend[0] = FALSE; HL &= ADDRMASK; BC &= ADDRMASK; @@ -2089,19 +2090,19 @@ static t_stat sim_instr_mmu (void) { break; case 0x0a: /* LD A,(BC) */ - tStates += 7; + tStates += 7; /* LDAX B 7 */ CHECK_BREAK_BYTE(BC) SET_HIGH_REGISTER(AF, GetBYTE(BC)); break; case 0x0b: /* DEC BC */ - tStates += 6; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 6); /* DCX B 5 */ sim_brk_pend[0] = FALSE; --BC; break; case 0x0c: /* INC C */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* INR C 5 */ sim_brk_pend[0] = FALSE; temp = LOW_REGISTER(BC) + 1; SET_LOW_REGISTER(BC, temp); @@ -2109,7 +2110,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x0d: /* DEC C */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* DCR C 5 */ sim_brk_pend[0] = FALSE; temp = LOW_REGISTER(BC) - 1; SET_LOW_REGISTER(BC, temp); @@ -2117,19 +2118,21 @@ static t_stat sim_instr_mmu (void) { break; case 0x0e: /* LD C,nn */ - tStates += 7; + tStates += 7; /* MVI C,nn 7 */ sim_brk_pend[0] = FALSE; SET_LOW_REGISTER(BC, RAM_PP(PC)); break; case 0x0f: /* RRCA */ - tStates += 4; + tStates += 4; /* RRC 4 */ sim_brk_pend[0] = FALSE; AF = (AF & 0xc4) | rrcaTable[HIGH_REGISTER(AF)]; break; case 0x10: /* DJNZ dd */ sim_brk_pend[0] = FALSE; + if (chiptype == CHIP_TYPE_8080) + tStates += 4; /* NOP 4 */ CHECK_CPU_8080; if ((BC -= 0x100) & 0xff00) { PCQ_ENTRY(PCX); @@ -2143,26 +2146,26 @@ static t_stat sim_instr_mmu (void) { break; case 0x11: /* LD DE,nnnn */ - tStates += 10; + tStates += 10; /* LXI D,nnnn 10 */ sim_brk_pend[0] = FALSE; DE = GET_WORD(PC); PC += 2; break; case 0x12: /* LD (DE),A */ - tStates += 7; + tStates += 7; /* STAX D 7 */ CHECK_BREAK_BYTE(DE) PutBYTE(DE, HIGH_REGISTER(AF)); break; case 0x13: /* INC DE */ - tStates += 6; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 6); /* INX D 5 */ sim_brk_pend[0] = FALSE; ++DE; break; case 0x14: /* INC D */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* INR D 5 */ sim_brk_pend[0] = FALSE; DE += 0x100; temp = HIGH_REGISTER(DE); @@ -2170,7 +2173,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x15: /* DEC D */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* DCR D 5 */ sim_brk_pend[0] = FALSE; DE -= 0x100; temp = HIGH_REGISTER(DE); @@ -2178,20 +2181,20 @@ static t_stat sim_instr_mmu (void) { break; case 0x16: /* LD D,nn */ - tStates += 7; + tStates += 7; /* MVI D,nn 7 */ sim_brk_pend[0] = FALSE; SET_HIGH_REGISTER(DE, RAM_PP(PC)); break; case 0x17: /* RLA */ - tStates += 4; + tStates += 4; /* RAL 4 */ sim_brk_pend[0] = FALSE; AF = ((AF << 8) & 0x0100) | ((AF >> 7) & 0x28) | ((AF << 1) & ~0x01ff) | (AF & 0xc4) | ((AF >> 15) & 1); break; case 0x18: /* JR dd */ - tStates += 12; + tStates += (chiptype == CHIP_TYPE_8080 ? 4 : 12); /* NOP 4 */ sim_brk_pend[0] = FALSE; CHECK_CPU_8080; PCQ_ENTRY(PCX); @@ -2199,7 +2202,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x19: /* ADD HL,DE */ - tStates += 11; + tStates += (chiptype == CHIP_TYPE_8080 ? 10 : 11); /* DAD D 10 */ sim_brk_pend[0] = FALSE; HL &= ADDRMASK; DE &= ADDRMASK; @@ -2209,19 +2212,19 @@ static t_stat sim_instr_mmu (void) { break; case 0x1a: /* LD A,(DE) */ - tStates += 7; + tStates += 7; /* LDAX D 7 */ CHECK_BREAK_BYTE(DE) SET_HIGH_REGISTER(AF, GetBYTE(DE)); break; case 0x1b: /* DEC DE */ - tStates += 6; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 6); /* DCX D 5 */ sim_brk_pend[0] = FALSE; --DE; break; case 0x1c: /* INC E */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* INR E 5 */ sim_brk_pend[0] = FALSE; temp = LOW_REGISTER(DE) + 1; SET_LOW_REGISTER(DE, temp); @@ -2229,7 +2232,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x1d: /* DEC E */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* DCR E 5 */ sim_brk_pend[0] = FALSE; temp = LOW_REGISTER(DE) - 1; SET_LOW_REGISTER(DE, temp); @@ -2237,18 +2240,20 @@ static t_stat sim_instr_mmu (void) { break; case 0x1e: /* LD E,nn */ - tStates += 7; + tStates += 7; /* MVI E 7 */ sim_brk_pend[0] = FALSE; SET_LOW_REGISTER(DE, RAM_PP(PC)); break; case 0x1f: /* RRA */ - tStates += 4; + tStates += 4; /* RAR 4 */ sim_brk_pend[0] = FALSE; AF = ((AF & 1) << 15) | (AF & 0xc4) | rraTable[HIGH_REGISTER(AF)]; break; case 0x20: /* JR NZ,dd */ + if (chiptype == CHIP_TYPE_8080) + tStates += 4; /* NOP 4 */ sim_brk_pend[0] = FALSE; CHECK_CPU_8080; if (TSTFLAG(Z)) { @@ -2263,14 +2268,14 @@ static t_stat sim_instr_mmu (void) { break; case 0x21: /* LD HL,nnnn */ - tStates += 10; + tStates += 10; /* LXI H,nnnn 10 */ sim_brk_pend[0] = FALSE; HL = GET_WORD(PC); PC += 2; break; case 0x22: /* LD (nnnn),HL */ - tStates += 16; + tStates += 16; /* SHLD 16 */ temp = GET_WORD(PC); CHECK_BREAK_WORD(temp); PutWORD(temp, HL); @@ -2278,13 +2283,13 @@ static t_stat sim_instr_mmu (void) { break; case 0x23: /* INC HL */ - tStates += 6; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 6); /* INX H 5 */ sim_brk_pend[0] = FALSE; ++HL; break; case 0x24: /* INC H */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* INR H 5 */ sim_brk_pend[0] = FALSE; HL += 0x100; temp = HIGH_REGISTER(HL); @@ -2292,7 +2297,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x25: /* DEC H */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* DCR H 5 */ sim_brk_pend[0] = FALSE; HL -= 0x100; temp = HIGH_REGISTER(HL); @@ -2300,13 +2305,13 @@ static t_stat sim_instr_mmu (void) { break; case 0x26: /* LD H,nn */ - tStates += 7; + tStates += 7; /* MVI H,nn 7 */ sim_brk_pend[0] = FALSE; SET_HIGH_REGISTER(HL, RAM_PP(PC)); break; case 0x27: /* DAA */ - tStates += 4; + tStates += 4; /* DAA 4 */ sim_brk_pend[0] = FALSE; acu = HIGH_REGISTER(AF); temp = LOW_DIGIT(acu); @@ -2335,6 +2340,8 @@ static t_stat sim_instr_mmu (void) { break; case 0x28: /* JR Z,dd */ + if (chiptype == CHIP_TYPE_8080) + tStates += 4; /* NOP 4 */ sim_brk_pend[0] = FALSE; CHECK_CPU_8080; if (TSTFLAG(Z)) { @@ -2349,7 +2356,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x29: /* ADD HL,HL */ - tStates += 11; + tStates += (chiptype == CHIP_TYPE_8080 ? 10 : 11); /* DAD H 10 */ sim_brk_pend[0] = FALSE; HL &= ADDRMASK; sum = HL + HL; @@ -2358,7 +2365,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x2a: /* LD HL,(nnnn) */ - tStates += 16; + tStates += 16; /* LHLD nnnn 16 */ temp = GET_WORD(PC); CHECK_BREAK_WORD(temp); HL = GET_WORD(temp); @@ -2366,13 +2373,13 @@ static t_stat sim_instr_mmu (void) { break; case 0x2b: /* DEC HL */ - tStates += 6; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 6); /* DCX H 5 */ sim_brk_pend[0] = FALSE; --HL; break; case 0x2c: /* INC L */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* INR L 5 */ sim_brk_pend[0] = FALSE; temp = LOW_REGISTER(HL) + 1; SET_LOW_REGISTER(HL, temp); @@ -2380,7 +2387,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x2d: /* DEC L */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* DCR L 5 */ sim_brk_pend[0] = FALSE; temp = LOW_REGISTER(HL) - 1; SET_LOW_REGISTER(HL, temp); @@ -2388,18 +2395,20 @@ static t_stat sim_instr_mmu (void) { break; case 0x2e: /* LD L,nn */ - tStates += 7; + tStates += 7; /* MVI L,nn 7 */ sim_brk_pend[0] = FALSE; SET_LOW_REGISTER(HL, RAM_PP(PC)); break; case 0x2f: /* CPL */ - tStates += 4; + tStates += 4; /* CMA 4 */ sim_brk_pend[0] = FALSE; AF = (~AF & ~0xff) | (AF & 0xc5) | ((~AF >> 8) & 0x28) | 0x12; break; case 0x30: /* JR NC,dd */ + if (chiptype == CHIP_TYPE_8080) + tStates += 4; /* NOP 4 */ sim_brk_pend[0] = FALSE; CHECK_CPU_8080; if (TSTFLAG(C)) { @@ -2414,14 +2423,14 @@ static t_stat sim_instr_mmu (void) { break; case 0x31: /* LD SP,nnnn */ - tStates += 10; + tStates += 10; /* LXI SP,nnnn 10 */ sim_brk_pend[0] = FALSE; SP = GET_WORD(PC); PC += 2; break; case 0x32: /* LD (nnnn),A */ - tStates += 13; + tStates += 13; /* STA nnnn 13 */ temp = GET_WORD(PC); CHECK_BREAK_BYTE(temp); PutBYTE(temp, HIGH_REGISTER(AF)); @@ -2429,13 +2438,13 @@ static t_stat sim_instr_mmu (void) { break; case 0x33: /* INC SP */ - tStates += 6; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 6); /* INX SP 5 */ sim_brk_pend[0] = FALSE; ++SP; break; case 0x34: /* INC (HL) */ - tStates += 11; + tStates += (chiptype == CHIP_TYPE_8080 ? 10 : 11); /* INR M 10 */ CHECK_BREAK_BYTE(HL); temp = GetBYTE(HL) + 1; PutBYTE(HL, temp); @@ -2443,7 +2452,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x35: /* DEC (HL) */ - tStates += 11; + tStates += (chiptype == CHIP_TYPE_8080 ? 10 : 11); /* DCR M 10 */ CHECK_BREAK_BYTE(HL); temp = GetBYTE(HL) - 1; PutBYTE(HL, temp); @@ -2451,18 +2460,20 @@ static t_stat sim_instr_mmu (void) { break; case 0x36: /* LD (HL),nn */ - tStates += 10; + tStates += 10; /* MVI M 10 */ CHECK_BREAK_BYTE(HL); PutBYTE(HL, RAM_PP(PC)); break; case 0x37: /* SCF */ - tStates += 4; + tStates += 4; /* STC 4 */ sim_brk_pend[0] = FALSE; AF = (AF & ~0x3b) | ((AF >> 8) & 0x28) | 1; break; case 0x38: /* JR C,dd */ + if (chiptype == CHIP_TYPE_8080) + tStates += 4; /* NOP 4 */ sim_brk_pend[0] = FALSE; CHECK_CPU_8080; if (TSTFLAG(C)) { @@ -2477,7 +2488,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x39: /* ADD HL,SP */ - tStates += 11; + tStates += (chiptype == CHIP_TYPE_8080 ? 10 : 11); /* DAD SP 10 */ sim_brk_pend[0] = FALSE; HL &= ADDRMASK; SP &= ADDRMASK; @@ -2487,7 +2498,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x3a: /* LD A,(nnnn) */ - tStates += 13; + tStates += 13; /* LDA nnnn 13 */ temp = GET_WORD(PC); CHECK_BREAK_BYTE(temp); SET_HIGH_REGISTER(AF, GetBYTE(temp)); @@ -2495,13 +2506,13 @@ static t_stat sim_instr_mmu (void) { break; case 0x3b: /* DEC SP */ - tStates += 6; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 6); /* DCX SP 5 */ sim_brk_pend[0] = FALSE; --SP; break; case 0x3c: /* INC A */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* INR A 5 */ sim_brk_pend[0] = FALSE; AF += 0x100; temp = HIGH_REGISTER(AF); @@ -2509,7 +2520,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x3d: /* DEC A */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* DCR A 5 */ sim_brk_pend[0] = FALSE; AF -= 0x100; temp = HIGH_REGISTER(AF); @@ -2517,337 +2528,337 @@ static t_stat sim_instr_mmu (void) { break; case 0x3e: /* LD A,nn */ - tStates += 7; + tStates += 7; /* MVI A,nn 7 */ sim_brk_pend[0] = FALSE; SET_HIGH_REGISTER(AF, RAM_PP(PC)); break; case 0x3f: /* CCF */ - tStates += 4; + tStates += 4; /* CMC 4 */ sim_brk_pend[0] = FALSE; AF = (AF & ~0x3b) | ((AF >> 8) & 0x28) | ((AF & 1) << 4) | (~AF & 1); break; case 0x40: /* LD B,B */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV B,B 5 */ sim_brk_pend[0] = FALSE; /* nop */ break; case 0x41: /* LD B,C */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV B,C 5 */ sim_brk_pend[0] = FALSE; BC = (BC & 0xff) | ((BC & 0xff) << 8); break; case 0x42: /* LD B,D */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV B,D 5 */ sim_brk_pend[0] = FALSE; BC = (BC & 0xff) | (DE & ~0xff); break; case 0x43: /* LD B,E */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV B,E 5 */ sim_brk_pend[0] = FALSE; BC = (BC & 0xff) | ((DE & 0xff) << 8); break; case 0x44: /* LD B,H */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV B,H 5 */ sim_brk_pend[0] = FALSE; BC = (BC & 0xff) | (HL & ~0xff); break; case 0x45: /* LD B,L */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV B,L 5 */ sim_brk_pend[0] = FALSE; BC = (BC & 0xff) | ((HL & 0xff) << 8); break; case 0x46: /* LD B,(HL) */ - tStates += 7; + tStates += 7; /* MOV B,M 7 */ CHECK_BREAK_BYTE(HL); SET_HIGH_REGISTER(BC, GetBYTE(HL)); break; case 0x47: /* LD B,A */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV B,A 5 */ sim_brk_pend[0] = FALSE; BC = (BC & 0xff) | (AF & ~0xff); break; case 0x48: /* LD C,B */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV C,B 5 */ sim_brk_pend[0] = FALSE; BC = (BC & ~0xff) | ((BC >> 8) & 0xff); break; case 0x49: /* LD C,C */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV C,C 5 */ sim_brk_pend[0] = FALSE; /* nop */ break; case 0x4a: /* LD C,D */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV C,D 5 */ sim_brk_pend[0] = FALSE; BC = (BC & ~0xff) | ((DE >> 8) & 0xff); break; case 0x4b: /* LD C,E */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV C,E 5 */ sim_brk_pend[0] = FALSE; BC = (BC & ~0xff) | (DE & 0xff); break; case 0x4c: /* LD C,H */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV C,H 5 */ sim_brk_pend[0] = FALSE; BC = (BC & ~0xff) | ((HL >> 8) & 0xff); break; case 0x4d: /* LD C,L */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV C,L 5 */ sim_brk_pend[0] = FALSE; BC = (BC & ~0xff) | (HL & 0xff); break; case 0x4e: /* LD C,(HL) */ - tStates += 7; + tStates += 7; /* MOV C,M 7 */ CHECK_BREAK_BYTE(HL); SET_LOW_REGISTER(BC, GetBYTE(HL)); break; case 0x4f: /* LD C,A */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV C,A 5 */ sim_brk_pend[0] = FALSE; BC = (BC & ~0xff) | ((AF >> 8) & 0xff); break; case 0x50: /* LD D,B */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV D,B 5 */ sim_brk_pend[0] = FALSE; DE = (DE & 0xff) | (BC & ~0xff); break; case 0x51: /* LD D,C */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV D,C 5 */ sim_brk_pend[0] = FALSE; DE = (DE & 0xff) | ((BC & 0xff) << 8); break; case 0x52: /* LD D,D */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV D,D 5 */ sim_brk_pend[0] = FALSE; /* nop */ break; case 0x53: /* LD D,E */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV D,E 5 */ sim_brk_pend[0] = FALSE; DE = (DE & 0xff) | ((DE & 0xff) << 8); break; case 0x54: /* LD D,H */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV D,H 5 */ sim_brk_pend[0] = FALSE; DE = (DE & 0xff) | (HL & ~0xff); break; case 0x55: /* LD D,L */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV D,L 5 */ sim_brk_pend[0] = FALSE; DE = (DE & 0xff) | ((HL & 0xff) << 8); break; case 0x56: /* LD D,(HL) */ - tStates += 7; + tStates += 7; /* MOV D,M 7 */ CHECK_BREAK_BYTE(HL); SET_HIGH_REGISTER(DE, GetBYTE(HL)); break; case 0x57: /* LD D,A */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV D,A 5 */ sim_brk_pend[0] = FALSE; DE = (DE & 0xff) | (AF & ~0xff); break; case 0x58: /* LD E,B */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV E,B 5 */ sim_brk_pend[0] = FALSE; DE = (DE & ~0xff) | ((BC >> 8) & 0xff); break; case 0x59: /* LD E,C */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV E,C 5 */ sim_brk_pend[0] = FALSE; DE = (DE & ~0xff) | (BC & 0xff); break; case 0x5a: /* LD E,D */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV E,D 5 */ sim_brk_pend[0] = FALSE; DE = (DE & ~0xff) | ((DE >> 8) & 0xff); break; case 0x5b: /* LD E,E */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV E,E 5 */ sim_brk_pend[0] = FALSE; /* nop */ break; case 0x5c: /* LD E,H */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV E,H 5 */ sim_brk_pend[0] = FALSE; DE = (DE & ~0xff) | ((HL >> 8) & 0xff); break; case 0x5d: /* LD E,L */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV E,L 5 */ sim_brk_pend[0] = FALSE; DE = (DE & ~0xff) | (HL & 0xff); break; case 0x5e: /* LD E,(HL) */ - tStates += 7; + tStates += 7; /* MOV E,M 7 */ CHECK_BREAK_BYTE(HL); SET_LOW_REGISTER(DE, GetBYTE(HL)); break; case 0x5f: /* LD E,A */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV E,A 5 */ sim_brk_pend[0] = FALSE; DE = (DE & ~0xff) | ((AF >> 8) & 0xff); break; case 0x60: /* LD H,B */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV H,B 5 */ sim_brk_pend[0] = FALSE; HL = (HL & 0xff) | (BC & ~0xff); break; case 0x61: /* LD H,C */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV H,C 5 */ sim_brk_pend[0] = FALSE; HL = (HL & 0xff) | ((BC & 0xff) << 8); break; case 0x62: /* LD H,D */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV H,D 5 */ sim_brk_pend[0] = FALSE; HL = (HL & 0xff) | (DE & ~0xff); break; case 0x63: /* LD H,E */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV H,E 5 */ sim_brk_pend[0] = FALSE; HL = (HL & 0xff) | ((DE & 0xff) << 8); break; case 0x64: /* LD H,H */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV H,H 5 */ sim_brk_pend[0] = FALSE; /* nop */ break; case 0x65: /* LD H,L */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV H,L 5 */ sim_brk_pend[0] = FALSE; HL = (HL & 0xff) | ((HL & 0xff) << 8); break; case 0x66: /* LD H,(HL) */ - tStates += 7; + tStates += 7; /* MOV H,M 7 */ CHECK_BREAK_BYTE(HL); SET_HIGH_REGISTER(HL, GetBYTE(HL)); break; case 0x67: /* LD H,A */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV H,A 5 */ sim_brk_pend[0] = FALSE; HL = (HL & 0xff) | (AF & ~0xff); break; case 0x68: /* LD L,B */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV L,B 5 */ sim_brk_pend[0] = FALSE; HL = (HL & ~0xff) | ((BC >> 8) & 0xff); break; case 0x69: /* LD L,C */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV L,C 5 */ sim_brk_pend[0] = FALSE; HL = (HL & ~0xff) | (BC & 0xff); break; case 0x6a: /* LD L,D */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV L,D 5 */ sim_brk_pend[0] = FALSE; HL = (HL & ~0xff) | ((DE >> 8) & 0xff); break; case 0x6b: /* LD L,E */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV L,E 5 */ sim_brk_pend[0] = FALSE; HL = (HL & ~0xff) | (DE & 0xff); break; case 0x6c: /* LD L,H */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV L,H 5 */ sim_brk_pend[0] = FALSE; HL = (HL & ~0xff) | ((HL >> 8) & 0xff); break; case 0x6d: /* LD L,L */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV L,L 5 */ sim_brk_pend[0] = FALSE; /* nop */ break; case 0x6e: /* LD L,(HL) */ - tStates += 7; + tStates += 7; /* MOV L,M 7 */ CHECK_BREAK_BYTE(HL); SET_LOW_REGISTER(HL, GetBYTE(HL)); break; case 0x6f: /* LD L,A */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV L,A 5 */ sim_brk_pend[0] = FALSE; HL = (HL & ~0xff) | ((AF >> 8) & 0xff); break; case 0x70: /* LD (HL),B */ - tStates += 7; + tStates += 7; /* MOV M,B 7 */ CHECK_BREAK_BYTE(HL); PutBYTE(HL, HIGH_REGISTER(BC)); break; case 0x71: /* LD (HL),C */ - tStates += 7; + tStates += 7; /* MOV M,C 7 */ CHECK_BREAK_BYTE(HL); PutBYTE(HL, LOW_REGISTER(BC)); break; case 0x72: /* LD (HL),D */ - tStates += 7; + tStates += 7; /* MOV M,D 7 */ CHECK_BREAK_BYTE(HL); PutBYTE(HL, HIGH_REGISTER(DE)); break; case 0x73: /* LD (HL),E */ - tStates += 7; + tStates += 7; /* MOV M,E 7 */ CHECK_BREAK_BYTE(HL); PutBYTE(HL, LOW_REGISTER(DE)); break; case 0x74: /* LD (HL),H */ - tStates += 7; + tStates += 7; /* MOV M,H 7 */ CHECK_BREAK_BYTE(HL); PutBYTE(HL, HIGH_REGISTER(HL)); break; case 0x75: /* LD (HL),L */ - tStates += 7; + tStates += 7; /* MOV M,L 7 */ CHECK_BREAK_BYTE(HL); PutBYTE(HL, LOW_REGISTER(HL)); break; case HALTINSTRUCTION: /* HALT */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 7 : 4); /* HLT 7 */ sim_brk_pend[0] = FALSE; PC--; if (cpu_unit.flags & UNIT_CPU_STOPONHALT) { @@ -2859,60 +2870,60 @@ static t_stat sim_instr_mmu (void) { break; case 0x77: /* LD (HL),A */ - tStates += 7; + tStates += 7; /* MOV M,A 7 */ CHECK_BREAK_BYTE(HL); PutBYTE(HL, HIGH_REGISTER(AF)); break; case 0x78: /* LD A,B */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV A,B 5 */ sim_brk_pend[0] = FALSE; AF = (AF & 0xff) | (BC & ~0xff); break; case 0x79: /* LD A,C */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV A,C 5 */ sim_brk_pend[0] = FALSE; AF = (AF & 0xff) | ((BC & 0xff) << 8); break; case 0x7a: /* LD A,D */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV A,D 5 */ sim_brk_pend[0] = FALSE; AF = (AF & 0xff) | (DE & ~0xff); break; case 0x7b: /* LD A,E */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV A,E 5 */ sim_brk_pend[0] = FALSE; AF = (AF & 0xff) | ((DE & 0xff) << 8); break; case 0x7c: /* LD A,H */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV A,H 5 */ sim_brk_pend[0] = FALSE; AF = (AF & 0xff) | (HL & ~0xff); break; case 0x7d: /* LD A,L */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV A,L 5 */ sim_brk_pend[0] = FALSE; AF = (AF & 0xff) | ((HL & 0xff) << 8); break; case 0x7e: /* LD A,(HL) */ - tStates += 7; + tStates += 7; /* MOV A,M 7 */ CHECK_BREAK_BYTE(HL); SET_HIGH_REGISTER(AF, GetBYTE(HL)); break; case 0x7f: /* LD A,A */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* MOV A,A 5 */ sim_brk_pend[0] = FALSE; /* nop */ break; case 0x80: /* ADD A,B */ - tStates += 4; + tStates += 4; /* ADD B 4 */ sim_brk_pend[0] = FALSE; temp = HIGH_REGISTER(BC); acu = HIGH_REGISTER(AF); @@ -2922,7 +2933,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x81: /* ADD A,C */ - tStates += 4; + tStates += 4; /* ADD C 4 */ sim_brk_pend[0] = FALSE; temp = LOW_REGISTER(BC); acu = HIGH_REGISTER(AF); @@ -2932,7 +2943,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x82: /* ADD A,D */ - tStates += 4; + tStates += 4; /* ADD D 4 */ sim_brk_pend[0] = FALSE; temp = HIGH_REGISTER(DE); acu = HIGH_REGISTER(AF); @@ -2942,7 +2953,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x83: /* ADD A,E */ - tStates += 4; + tStates += 4; /* ADD E 4 */ sim_brk_pend[0] = FALSE; temp = LOW_REGISTER(DE); acu = HIGH_REGISTER(AF); @@ -2952,7 +2963,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x84: /* ADD A,H */ - tStates += 4; + tStates += 4; /* ADD H 4 */ sim_brk_pend[0] = FALSE; temp = HIGH_REGISTER(HL); acu = HIGH_REGISTER(AF); @@ -2962,7 +2973,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x85: /* ADD A,L */ - tStates += 4; + tStates += 4; /* ADD L 4 */ sim_brk_pend[0] = FALSE; temp = LOW_REGISTER(HL); acu = HIGH_REGISTER(AF); @@ -2972,7 +2983,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x86: /* ADD A,(HL) */ - tStates += 7; + tStates += 7; /* ADD M 7 */ CHECK_BREAK_BYTE(HL); temp = GetBYTE(HL); acu = HIGH_REGISTER(AF); @@ -2982,14 +2993,14 @@ static t_stat sim_instr_mmu (void) { break; case 0x87: /* ADD A,A */ - tStates += 4; + tStates += 4; /* ADD A 4 */ sim_brk_pend[0] = FALSE; cbits = 2 * HIGH_REGISTER(AF); AF = cbitsDup8Table[cbits] | (SET_PVS(cbits)); break; case 0x88: /* ADC A,B */ - tStates += 4; + tStates += 4; /* ADC B 4 */ sim_brk_pend[0] = FALSE; temp = HIGH_REGISTER(BC); acu = HIGH_REGISTER(AF); @@ -2999,7 +3010,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x89: /* ADC A,C */ - tStates += 4; + tStates += 4; /* ADC C 4 */ sim_brk_pend[0] = FALSE; temp = LOW_REGISTER(BC); acu = HIGH_REGISTER(AF); @@ -3009,7 +3020,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x8a: /* ADC A,D */ - tStates += 4; + tStates += 4; /* ADC D 4 */ sim_brk_pend[0] = FALSE; temp = HIGH_REGISTER(DE); acu = HIGH_REGISTER(AF); @@ -3019,7 +3030,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x8b: /* ADC A,E */ - tStates += 4; + tStates += 4; /* ADC E 4 */ sim_brk_pend[0] = FALSE; temp = LOW_REGISTER(DE); acu = HIGH_REGISTER(AF); @@ -3029,7 +3040,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x8c: /* ADC A,H */ - tStates += 4; + tStates += 4; /* ADC H 4 */ sim_brk_pend[0] = FALSE; temp = HIGH_REGISTER(HL); acu = HIGH_REGISTER(AF); @@ -3039,7 +3050,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x8d: /* ADC A,L */ - tStates += 4; + tStates += 4; /* ADC L 4 */ sim_brk_pend[0] = FALSE; temp = LOW_REGISTER(HL); acu = HIGH_REGISTER(AF); @@ -3049,7 +3060,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x8e: /* ADC A,(HL) */ - tStates += 7; + tStates += 7; /* ADC M 7 */ CHECK_BREAK_BYTE(HL); temp = GetBYTE(HL); acu = HIGH_REGISTER(AF); @@ -3059,14 +3070,14 @@ static t_stat sim_instr_mmu (void) { break; case 0x8f: /* ADC A,A */ - tStates += 4; + tStates += 4; /* ADC A 4 */ sim_brk_pend[0] = FALSE; cbits = 2 * HIGH_REGISTER(AF) + TSTFLAG(C); AF = cbitsDup8Table[cbits] | (SET_PVS(cbits)); break; case 0x90: /* SUB B */ - tStates += 4; + tStates += 4; /* SUB B 4 */ sim_brk_pend[0] = FALSE; temp = HIGH_REGISTER(BC); acu = HIGH_REGISTER(AF); @@ -3076,7 +3087,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x91: /* SUB C */ - tStates += 4; + tStates += 4; /* SUB C 4 */ sim_brk_pend[0] = FALSE; temp = LOW_REGISTER(BC); acu = HIGH_REGISTER(AF); @@ -3086,7 +3097,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x92: /* SUB D */ - tStates += 4; + tStates += 4; /* SUB D 4 */ sim_brk_pend[0] = FALSE; temp = HIGH_REGISTER(DE); acu = HIGH_REGISTER(AF); @@ -3096,7 +3107,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x93: /* SUB E */ - tStates += 4; + tStates += 4; /* SUB E 4 */ sim_brk_pend[0] = FALSE; temp = LOW_REGISTER(DE); acu = HIGH_REGISTER(AF); @@ -3106,7 +3117,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x94: /* SUB H */ - tStates += 4; + tStates += 4; /* SUB H 4 */ sim_brk_pend[0] = FALSE; temp = HIGH_REGISTER(HL); acu = HIGH_REGISTER(AF); @@ -3116,7 +3127,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x95: /* SUB L */ - tStates += 4; + tStates += 4; /* SUB L 4 */ sim_brk_pend[0] = FALSE; temp = LOW_REGISTER(HL); acu = HIGH_REGISTER(AF); @@ -3126,7 +3137,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x96: /* SUB (HL) */ - tStates += 7; + tStates += 7; /* SUB M 7 */ CHECK_BREAK_BYTE(HL); temp = GetBYTE(HL); acu = HIGH_REGISTER(AF); @@ -3136,13 +3147,13 @@ static t_stat sim_instr_mmu (void) { break; case 0x97: /* SUB A */ - tStates += 4; + tStates += 4; /* SUB A 4 */ sim_brk_pend[0] = FALSE; AF = (chiptype == CHIP_TYPE_Z80) ? 0x42 : 0x46; break; case 0x98: /* SBC A,B */ - tStates += 4; + tStates += 4; /* SBB B 4 */ sim_brk_pend[0] = FALSE; temp = HIGH_REGISTER(BC); acu = HIGH_REGISTER(AF); @@ -3152,7 +3163,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x99: /* SBC A,C */ - tStates += 4; + tStates += 4; /* SBB C 4 */ sim_brk_pend[0] = FALSE; temp = LOW_REGISTER(BC); acu = HIGH_REGISTER(AF); @@ -3162,7 +3173,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x9a: /* SBC A,D */ - tStates += 4; + tStates += 4; /* SBB D 4 */ sim_brk_pend[0] = FALSE; temp = HIGH_REGISTER(DE); acu = HIGH_REGISTER(AF); @@ -3172,7 +3183,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x9b: /* SBC A,E */ - tStates += 4; + tStates += 4; /* SBB E 4 */ sim_brk_pend[0] = FALSE; temp = LOW_REGISTER(DE); acu = HIGH_REGISTER(AF); @@ -3182,7 +3193,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x9c: /* SBC A,H */ - tStates += 4; + tStates += 4; /* SBB H 4 */ sim_brk_pend[0] = FALSE; temp = HIGH_REGISTER(HL); acu = HIGH_REGISTER(AF); @@ -3192,7 +3203,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x9d: /* SBC A,L */ - tStates += 4; + tStates += 4; /* SBB L 4 */ sim_brk_pend[0] = FALSE; temp = LOW_REGISTER(HL); acu = HIGH_REGISTER(AF); @@ -3202,7 +3213,7 @@ static t_stat sim_instr_mmu (void) { break; case 0x9e: /* SBC A,(HL) */ - tStates += 7; + tStates += 7; /* SBB M 7 */ CHECK_BREAK_BYTE(HL); temp = GetBYTE(HL); acu = HIGH_REGISTER(AF); @@ -3212,158 +3223,158 @@ static t_stat sim_instr_mmu (void) { break; case 0x9f: /* SBC A,A */ - tStates += 4; + tStates += 4; /* SBB A 4 */ sim_brk_pend[0] = FALSE; cbits = -TSTFLAG(C); AF = subTable[cbits & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PVS(cbits)); break; case 0xa0: /* AND B */ - tStates += 4; + tStates += 4; /* ANA B 4 */ sim_brk_pend[0] = FALSE; AF = andTable[((AF & BC) >> 8) & 0xff]; break; case 0xa1: /* AND C */ - tStates += 4; + tStates += 4; /* ANA C 4 */ sim_brk_pend[0] = FALSE; AF = andTable[((AF >> 8) & BC) & 0xff]; break; case 0xa2: /* AND D */ - tStates += 4; + tStates += 4; /* ANA D 4 */ sim_brk_pend[0] = FALSE; AF = andTable[((AF & DE) >> 8) & 0xff]; break; case 0xa3: /* AND E */ - tStates += 4; + tStates += 4; /* ANA E 4 */ sim_brk_pend[0] = FALSE; AF = andTable[((AF >> 8) & DE) & 0xff]; break; case 0xa4: /* AND H */ - tStates += 4; + tStates += 4; /* ANA H 4 */ sim_brk_pend[0] = FALSE; AF = andTable[((AF & HL) >> 8) & 0xff]; break; case 0xa5: /* AND L */ - tStates += 4; + tStates += 4; /* ANA L 4 */ sim_brk_pend[0] = FALSE; AF = andTable[((AF >> 8) & HL) & 0xff]; break; case 0xa6: /* AND (HL) */ - tStates += 7; + tStates += 7; /* ANA M 7 */ CHECK_BREAK_BYTE(HL); AF = andTable[((AF >> 8) & GetBYTE(HL)) & 0xff]; break; case 0xa7: /* AND A */ - tStates += 4; + tStates += 4; /* ANA A 4 */ sim_brk_pend[0] = FALSE; AF = andTable[(AF >> 8) & 0xff]; break; case 0xa8: /* XOR B */ - tStates += 4; + tStates += 4; /* XRA B 4 */ sim_brk_pend[0] = FALSE; AF = xororTable[((AF ^ BC) >> 8) & 0xff]; break; case 0xa9: /* XOR C */ - tStates += 4; + tStates += 4; /* XRA C 4 */ sim_brk_pend[0] = FALSE; AF = xororTable[((AF >> 8) ^ BC) & 0xff]; break; case 0xaa: /* XOR D */ - tStates += 4; + tStates += 4; /* XRA D 4 */ sim_brk_pend[0] = FALSE; AF = xororTable[((AF ^ DE) >> 8) & 0xff]; break; case 0xab: /* XOR E */ - tStates += 4; + tStates += 4; /* XRA E 4 */ sim_brk_pend[0] = FALSE; AF = xororTable[((AF >> 8) ^ DE) & 0xff]; break; case 0xac: /* XOR H */ - tStates += 4; + tStates += 4; /* XRA H 4 */ sim_brk_pend[0] = FALSE; AF = xororTable[((AF ^ HL) >> 8) & 0xff]; break; case 0xad: /* XOR L */ - tStates += 4; + tStates += 4; /* XRA L 4 */ sim_brk_pend[0] = FALSE; AF = xororTable[((AF >> 8) ^ HL) & 0xff]; break; case 0xae: /* XOR (HL) */ - tStates += 7; + tStates += 7; /* XRA M 7 */ CHECK_BREAK_BYTE(HL); AF = xororTable[((AF >> 8) ^ GetBYTE(HL)) & 0xff]; break; case 0xaf: /* XOR A */ - tStates += 4; + tStates += 4; /* XRA A 4 */ sim_brk_pend[0] = FALSE; AF = 0x44; break; case 0xb0: /* OR B */ - tStates += 4; + tStates += 4; /* ORA B 4 */ sim_brk_pend[0] = FALSE; AF = xororTable[((AF | BC) >> 8) & 0xff]; break; case 0xb1: /* OR C */ - tStates += 4; + tStates += 4; /* ORA C 4 */ sim_brk_pend[0] = FALSE; AF = xororTable[((AF >> 8) | BC) & 0xff]; break; case 0xb2: /* OR D */ - tStates += 4; + tStates += 4; /* ORA D 4 */ sim_brk_pend[0] = FALSE; AF = xororTable[((AF | DE) >> 8) & 0xff]; break; case 0xb3: /* OR E */ - tStates += 4; + tStates += 4; /* ORA E 4 */ sim_brk_pend[0] = FALSE; AF = xororTable[((AF >> 8) | DE) & 0xff]; break; case 0xb4: /* OR H */ - tStates += 4; + tStates += 4; /* ORA H 4 */ sim_brk_pend[0] = FALSE; AF = xororTable[((AF | HL) >> 8) & 0xff]; break; case 0xb5: /* OR L */ - tStates += 4; + tStates += 4; /* ORA L 4 */ sim_brk_pend[0] = FALSE; AF = xororTable[((AF >> 8) | HL) & 0xff]; break; case 0xb6: /* OR (HL) */ - tStates += 7; + tStates += 7; /* ORA M 7 */ CHECK_BREAK_BYTE(HL); AF = xororTable[((AF >> 8) | GetBYTE(HL)) & 0xff]; break; case 0xb7: /* OR A */ - tStates += 4; + tStates += 4; /* ORA A 4 */ sim_brk_pend[0] = FALSE; AF = xororTable[(AF >> 8) & 0xff]; break; case 0xb8: /* CP B */ - tStates += 4; + tStates += 4; /* CMP B 4 */ sim_brk_pend[0] = FALSE; temp = HIGH_REGISTER(BC); AF = (AF & ~0x28) | (temp & 0x28); @@ -3375,7 +3386,7 @@ static t_stat sim_instr_mmu (void) { break; case 0xb9: /* CP C */ - tStates += 4; + tStates += 4; /* CMP C 4 */ sim_brk_pend[0] = FALSE; temp = LOW_REGISTER(BC); AF = (AF & ~0x28) | (temp & 0x28); @@ -3387,7 +3398,7 @@ static t_stat sim_instr_mmu (void) { break; case 0xba: /* CP D */ - tStates += 4; + tStates += 4; /* CMP D 4 */ sim_brk_pend[0] = FALSE; temp = HIGH_REGISTER(DE); AF = (AF & ~0x28) | (temp & 0x28); @@ -3399,7 +3410,7 @@ static t_stat sim_instr_mmu (void) { break; case 0xbb: /* CP E */ - tStates += 4; + tStates += 4; /* CMP E 4 */ sim_brk_pend[0] = FALSE; temp = LOW_REGISTER(DE); AF = (AF & ~0x28) | (temp & 0x28); @@ -3411,7 +3422,7 @@ static t_stat sim_instr_mmu (void) { break; case 0xbc: /* CP H */ - tStates += 4; + tStates += 4; /* CMP H 4 */ sim_brk_pend[0] = FALSE; temp = HIGH_REGISTER(HL); AF = (AF & ~0x28) | (temp & 0x28); @@ -3423,7 +3434,7 @@ static t_stat sim_instr_mmu (void) { break; case 0xbd: /* CP L */ - tStates += 4; + tStates += 4; /* CMP L 4 */ sim_brk_pend[0] = FALSE; temp = LOW_REGISTER(HL); AF = (AF & ~0x28) | (temp & 0x28); @@ -3435,7 +3446,7 @@ static t_stat sim_instr_mmu (void) { break; case 0xbe: /* CP (HL) */ - tStates += 7; + tStates += 7; /* CMP M 7 */ CHECK_BREAK_BYTE(HL); temp = GetBYTE(HL); AF = (AF & ~0x28) | (temp & 0x28); @@ -3447,7 +3458,7 @@ static t_stat sim_instr_mmu (void) { break; case 0xbf: /* CP A */ - tStates += 4; + tStates += 4; /* CMP A 4 */ sim_brk_pend[0] = FALSE; SET_LOW_REGISTER(AF, (HIGH_REGISTER(AF) & 0x28) | (chiptype == CHIP_TYPE_Z80 ? 0x42 : 0x46)); break; @@ -3455,30 +3466,30 @@ static t_stat sim_instr_mmu (void) { case 0xc0: /* RET NZ */ if (TSTFLAG(Z)) { sim_brk_pend[0] = FALSE; - tStates += 5; + tStates += 5; /* RNZ 5 */ } else { CHECK_BREAK_WORD(SP); PCQ_ENTRY(PCX); POP(PC); - tStates += 11; + tStates += 11; /* RNZ 11 */ } break; case 0xc1: /* POP BC */ - tStates += 10; + tStates += 10; /* POP B 10 */ CHECK_BREAK_WORD(SP); POP(BC); break; case 0xc2: /* JP NZ,nnnn */ sim_brk_pend[0] = FALSE; - JPC(!TSTFLAG(Z)); /* also updates tStates */ + JPC(!TSTFLAG(Z)); /* also updates tStates, Z80 and 8080 are equal */ break; case 0xc3: /* JP nnnn */ sim_brk_pend[0] = FALSE; - JPC(1); /* also updates tStates */ + JPC(1); /* also updates tStates, Z80 and 8080 are equal */ break; case 0xc4: /* CALL NZ,nnnn */ @@ -3486,13 +3497,13 @@ static t_stat sim_instr_mmu (void) { break; case 0xc5: /* PUSH BC */ - tStates += 11; + tStates += 11; /* PUSH B 11 */ CHECK_BREAK_WORD(SP - 2); PUSH(BC); break; case 0xc6: /* ADD A,nn */ - tStates += 7; + tStates += 7; /* ADI nn 7 */ sim_brk_pend[0] = FALSE; temp = RAM_PP(PC); acu = HIGH_REGISTER(AF); @@ -3502,7 +3513,7 @@ static t_stat sim_instr_mmu (void) { break; case 0xc7: /* RST 0 */ - tStates += 11; + tStates += 11; /* RST 0 11 */ CHECK_BREAK_WORD(SP - 2); PUSH(PC); PCQ_ENTRY(PCX); @@ -3514,16 +3525,16 @@ static t_stat sim_instr_mmu (void) { CHECK_BREAK_WORD(SP); PCQ_ENTRY(PCX); POP(PC); - tStates += 11; + tStates += 11; /* RZ 11 */ } else { sim_brk_pend[0] = FALSE; - tStates += 5; + tStates += 5; /* RZ 5 */ } break; case 0xc9: /* RET */ - tStates += 10; + tStates += 10; /* RET 10 */ CHECK_BREAK_WORD(SP); PCQ_ENTRY(PCX); POP(PC); @@ -3535,7 +3546,17 @@ static t_stat sim_instr_mmu (void) { break; case 0xcb: /* CB prefix */ - CHECK_CPU_8080; + if (chiptype == CHIP_TYPE_8080) { + if (cpu_unit.flags & UNIT_CPU_OPSTOP) { + reason = STOP_OPCODE; + goto end_decode; + } + else { + sim_brk_pend[0] = FALSE; + JPC(1); + break; + } + } adr = HL; switch ((op = GetBYTE(PC)) & 7) { @@ -3711,7 +3732,7 @@ static t_stat sim_instr_mmu (void) { break; case 0xce: /* ADC A,nn */ - tStates += 7; + tStates += 7; /* ACI nn 7 */ sim_brk_pend[0] = FALSE; temp = RAM_PP(PC); acu = HIGH_REGISTER(AF); @@ -3721,7 +3742,7 @@ static t_stat sim_instr_mmu (void) { break; case 0xcf: /* RST 8 */ - tStates += 11; + tStates += 11; /* RST 1 */ CHECK_BREAK_WORD(SP - 2); PUSH(PC); PCQ_ENTRY(PCX); @@ -3731,18 +3752,18 @@ static t_stat sim_instr_mmu (void) { case 0xd0: /* RET NC */ if (TSTFLAG(C)) { sim_brk_pend[0] = FALSE; - tStates += 5; + tStates += 5; /* RNC 5 */ } else { CHECK_BREAK_WORD(SP); PCQ_ENTRY(PCX); POP(PC); - tStates += 11; + tStates += 11; /* RNC 11 */ } break; case 0xd1: /* POP DE */ - tStates += 10; + tStates += 10; /* POP D 10 */ CHECK_BREAK_WORD(SP); POP(DE); break; @@ -3753,7 +3774,7 @@ static t_stat sim_instr_mmu (void) { break; case 0xd3: /* OUT (nn),A */ - tStates += 11; + tStates += (chiptype == CHIP_TYPE_8080 ? 10 :11); /* OUT nn 10 */ sim_brk_pend[0] = FALSE; out(RAM_PP(PC), HIGH_REGISTER(AF)); break; @@ -3763,13 +3784,13 @@ static t_stat sim_instr_mmu (void) { break; case 0xd5: /* PUSH DE */ - tStates += 11; + tStates += 11; /* PUSH D 11 */ CHECK_BREAK_WORD(SP - 2); PUSH(DE); break; case 0xd6: /* SUB nn */ - tStates += 7; + tStates += 7; /* SUI nn 7 */ sim_brk_pend[0] = FALSE; temp = RAM_PP(PC); acu = HIGH_REGISTER(AF); @@ -3779,7 +3800,7 @@ static t_stat sim_instr_mmu (void) { break; case 0xd7: /* RST 10H */ - tStates += 11; + tStates += 11; /* RST 2 11 */ CHECK_BREAK_WORD(SP - 2); PUSH(PC); PCQ_ENTRY(PCX); @@ -3791,18 +3812,30 @@ static t_stat sim_instr_mmu (void) { CHECK_BREAK_WORD(SP); PCQ_ENTRY(PCX); POP(PC); - tStates += 11; + tStates += 11; /* RC 11 */ } else { sim_brk_pend[0] = FALSE; - tStates += 5; + tStates += 5; /* RC 5 */ } break; case 0xd9: /* EXX */ + if (chiptype == CHIP_TYPE_8080) { + if (cpu_unit.flags & UNIT_CPU_OPSTOP) { + reason = STOP_OPCODE; + goto end_decode; + } + else { + tStates += 10; /* RET 10 */ + CHECK_BREAK_WORD(SP); + PCQ_ENTRY(PCX); + POP(PC); + break; + } + } tStates += 4; sim_brk_pend[0] = FALSE; - CHECK_CPU_8080; temp = BC; BC = BC1_S; BC1_S = temp; @@ -3820,7 +3853,7 @@ static t_stat sim_instr_mmu (void) { break; case 0xdb: /* IN A,(nn) */ - tStates += 11; + tStates += (chiptype == CHIP_TYPE_8080 ? 10 : 11); /* IN nn 10 */ sim_brk_pend[0] = FALSE; SET_HIGH_REGISTER(AF, in(RAM_PP(PC))); break; @@ -3830,7 +3863,16 @@ static t_stat sim_instr_mmu (void) { break; case 0xdd: /* DD prefix */ - CHECK_CPU_8080; + if (chiptype == CHIP_TYPE_8080) { + if (cpu_unit.flags & UNIT_CPU_OPSTOP) { + reason = STOP_OPCODE; + goto end_decode; + } + else { + CALLC(1); /* also updates tStates */ + break; + } + } switch (RAM_PP(PC)) { case 0x09: /* ADD IX,BC */ @@ -4605,7 +4647,7 @@ static t_stat sim_instr_mmu (void) { break; case 0xde: /* SBC A,nn */ - tStates += 7; + tStates += 7; /* SBI nn 7 */ sim_brk_pend[0] = FALSE; temp = RAM_PP(PC); acu = HIGH_REGISTER(AF); @@ -4615,7 +4657,7 @@ static t_stat sim_instr_mmu (void) { break; case 0xdf: /* RST 18H */ - tStates += 11; + tStates += 11; /* RST 3 11 */ CHECK_BREAK_WORD(SP - 2); PUSH(PC); PCQ_ENTRY(PCX); @@ -4625,18 +4667,18 @@ static t_stat sim_instr_mmu (void) { case 0xe0: /* RET PO */ if (TSTFLAG(P)) { sim_brk_pend[0] = FALSE; - tStates += 5; + tStates += 5; /* RPO 5 */ } else { CHECK_BREAK_WORD(SP); PCQ_ENTRY(PCX); POP(PC); - tStates += 11; + tStates += 11; /* RPO 11 */ } break; case 0xe1: /* POP HL */ - tStates += 10; + tStates += 10; /* POP H 10 */ CHECK_BREAK_WORD(SP); POP(HL); break; @@ -4647,7 +4689,7 @@ static t_stat sim_instr_mmu (void) { break; case 0xe3: /* EX (SP),HL */ - tStates += 19; + tStates += (chiptype == CHIP_TYPE_8080 ? 18 : 19); /* XTHL 18 */ CHECK_BREAK_WORD(SP); temp = HL; POP(HL); @@ -4659,19 +4701,19 @@ static t_stat sim_instr_mmu (void) { break; case 0xe5: /* PUSH HL */ - tStates += 11; + tStates += 11; /* PUSH H 11 */ CHECK_BREAK_WORD(SP - 2); PUSH(HL); break; case 0xe6: /* AND nn */ - tStates += 7; + tStates += 7; /* ANI nn 7 */ sim_brk_pend[0] = FALSE; AF = andTable[((AF >> 8) & RAM_PP(PC)) & 0xff]; break; case 0xe7: /* RST 20H */ - tStates += 11; + tStates += 11; /* RST 4 11 */ CHECK_BREAK_WORD(SP - 2); PUSH(PC); PCQ_ENTRY(PCX); @@ -4683,16 +4725,16 @@ static t_stat sim_instr_mmu (void) { CHECK_BREAK_WORD(SP); PCQ_ENTRY(PCX); POP(PC); - tStates += 11; + tStates += 11; /* RPE 11 */ } else { sim_brk_pend[0] = FALSE; - tStates += 5; + tStates += 5; /* RPE 5 */ } break; case 0xe9: /* JP (HL) */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* PCHL 5 */ sim_brk_pend[0] = FALSE; PCQ_ENTRY(PCX); PC = HL; @@ -4704,7 +4746,7 @@ static t_stat sim_instr_mmu (void) { break; case 0xeb: /* EX DE,HL */ - tStates += 4; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 4); /* XCHG 5 */ sim_brk_pend[0] = FALSE; temp = HL; HL = DE; @@ -4716,7 +4758,16 @@ static t_stat sim_instr_mmu (void) { break; case 0xed: /* ED prefix */ - CHECK_CPU_8080; + if (chiptype == CHIP_TYPE_8080) { + if (cpu_unit.flags & UNIT_CPU_OPSTOP) { + reason = STOP_OPCODE; + goto end_decode; + } + else { + CALLC(1); /* also updates tStates */ + break; + } + } switch (RAM_PP(PC)) { case 0x40: /* IN B,(C) */ @@ -5357,13 +5408,13 @@ static t_stat sim_instr_mmu (void) { break; case 0xee: /* XOR nn */ - tStates += 7; + tStates += 7; /* XRI nn 7 */ sim_brk_pend[0] = FALSE; AF = xororTable[((AF >> 8) ^ RAM_PP(PC)) & 0xff]; break; case 0xef: /* RST 28H */ - tStates += 11; + tStates += 11; /* RST 5 11 */ CHECK_BREAK_WORD(SP - 2); PUSH(PC); PCQ_ENTRY(PCX); @@ -5373,18 +5424,18 @@ static t_stat sim_instr_mmu (void) { case 0xf0: /* RET P */ if (TSTFLAG(S)) { sim_brk_pend[0] = FALSE; - tStates += 5; + tStates += 5; /* RP 5 */ } else { CHECK_BREAK_WORD(SP); PCQ_ENTRY(PCX); POP(PC); - tStates += 11; + tStates += 11; /* RP 11 */ } break; case 0xf1: /* POP AF */ - tStates += 10; + tStates += 10; /* POP PSW 10 */ CHECK_BREAK_WORD(SP); POP(AF); break; @@ -5395,7 +5446,7 @@ static t_stat sim_instr_mmu (void) { break; case 0xf3: /* DI */ - tStates += 4; + tStates += 4; /* DI 4 */ sim_brk_pend[0] = FALSE; IFF_S = 0; break; @@ -5405,19 +5456,19 @@ static t_stat sim_instr_mmu (void) { break; case 0xf5: /* PUSH AF */ - tStates += 11; + tStates += 11; /* PUSH PSW 11 */ CHECK_BREAK_WORD(SP - 2); PUSH(AF); break; case 0xf6: /* OR nn */ - tStates += 7; + tStates += 7; /* ORI nn 7 */ sim_brk_pend[0] = FALSE; AF = xororTable[((AF >> 8) | RAM_PP(PC)) & 0xff]; break; case 0xf7: /* RST 30H */ - tStates += 11; + tStates += 11; /* RST 6 11 */ CHECK_BREAK_WORD(SP - 2); PUSH(PC); PCQ_ENTRY(PCX); @@ -5429,16 +5480,16 @@ static t_stat sim_instr_mmu (void) { CHECK_BREAK_WORD(SP); PCQ_ENTRY(PCX); POP(PC); - tStates += 11; + tStates += 11; /* RM 11 */ } else { sim_brk_pend[0] = FALSE; - tStates += 5; + tStates += 5; /* RM 5 */ } break; case 0xf9: /* LD SP,HL */ - tStates += 6; + tStates += (chiptype == CHIP_TYPE_8080 ? 5 : 6); /* SPHL 5 */ sim_brk_pend[0] = FALSE; SP = HL; break; @@ -5449,7 +5500,7 @@ static t_stat sim_instr_mmu (void) { break; case 0xfb: /* EI */ - tStates += 4; + tStates += 4; /* EI 4 */ sim_brk_pend[0] = FALSE; IFF_S = 3; break; @@ -5459,7 +5510,16 @@ static t_stat sim_instr_mmu (void) { break; case 0xfd: /* FD prefix */ - CHECK_CPU_8080; + if (chiptype == CHIP_TYPE_8080) { + if (cpu_unit.flags & UNIT_CPU_OPSTOP) { + reason = STOP_OPCODE; + goto end_decode; + } + else { + CALLC(1); /* also updates tStates */ + break; + } + } switch (RAM_PP(PC)) { case 0x09: /* ADD IY,BC */ @@ -6234,7 +6294,7 @@ static t_stat sim_instr_mmu (void) { break; case 0xfe: /* CP nn */ - tStates += 7; + tStates += 7; /* CPI nn 7 */ sim_brk_pend[0] = FALSE; temp = RAM_PP(PC); AF = (AF & ~0x28) | (temp & 0x28); @@ -6246,7 +6306,7 @@ static t_stat sim_instr_mmu (void) { break; case 0xff: /* RST 38H */ - tStates += 11; + tStates += 11; /* RST 7 11 */ CHECK_BREAK_WORD(SP - 2); PUSH(PC); PCQ_ENTRY(PCX); diff --git a/AltairZ80/altairz80_cpu_nommu.c b/AltairZ80/altairz80_cpu_nommu.c index 552ac1d9..460b5166 100644 --- a/AltairZ80/altairz80_cpu_nommu.c +++ b/AltairZ80/altairz80_cpu_nommu.c @@ -1,6 +1,6 @@ /* altairz80_cpu_opt.c: MITS Altair CPU (8080 and Z80) - Copyright (c) 2002-2011, Peter Schorn + Copyright (c) 2002-2013, Peter Schorn Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/AltairZ80/altairz80_defs.h b/AltairZ80/altairz80_defs.h index 39385c74..3d92b492 100644 --- a/AltairZ80/altairz80_defs.h +++ b/AltairZ80/altairz80_defs.h @@ -1,6 +1,6 @@ /* altairz80_defs.h: MITS Altair simulator definitions - Copyright (c) 2002-2011, Peter Schorn + Copyright (c) 2002-2013, Peter Schorn Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/AltairZ80/altairz80_doc.pdf b/AltairZ80/altairz80_doc.pdf index a09c74bd..3497e9b3 100644 Binary files a/AltairZ80/altairz80_doc.pdf and b/AltairZ80/altairz80_doc.pdf differ diff --git a/AltairZ80/altairz80_dsk.c b/AltairZ80/altairz80_dsk.c index 368f9743..74a4dfe4 100644 --- a/AltairZ80/altairz80_dsk.c +++ b/AltairZ80/altairz80_dsk.c @@ -1,6 +1,6 @@ /* altairz80_dsk.c: MITS Altair 88-DISK Simulator - Copyright (c) 2002-2011, Peter Schorn + Copyright (c) 2002-2013, Peter Schorn Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -483,6 +483,7 @@ int32 dsk11(const int32 port, const int32 io, const int32 data) { current_disk, PCX); } current_track[current_disk]++; + current_flag[current_disk] &= 0xbf; /* mwd 1/29/13: track zero now false */ if (current_track[current_disk] > (tracks[current_disk] - 1)) current_track[current_disk] = (tracks[current_disk] - 1); if (dirty) /* implies that current_disk < NUM_OF_DSK */ diff --git a/AltairZ80/altairz80_hdsk.c b/AltairZ80/altairz80_hdsk.c index 1565c010..0f4761c5 100644 --- a/AltairZ80/altairz80_hdsk.c +++ b/AltairZ80/altairz80_hdsk.c @@ -1,6 +1,6 @@ /* altairz80_hdsk.c: simulated hard disk device to increase capacity - Copyright (c) 2002-2011, Peter Schorn + Copyright (c) 2002-2013, Peter Schorn Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -28,6 +28,7 @@ #include "altairz80_defs.h" #include +#include "sim_imd.h" /* Debug flags */ #define READ_MSG (1 << 0) @@ -43,6 +44,9 @@ static t_stat show_format(FILE *st, UNIT *uptr, int32 val, void *desc); static t_stat hdsk_reset(DEVICE *dptr); static t_stat hdsk_attach(UNIT *uptr, char *cptr); static t_stat hdsk_detach(UNIT *uptr); +static uint32 is_imd(const UNIT *uptr); +static void assignFormat(UNIT *uptr); +static void verifyDiskInfo(const DISK_INFO info, const char unitChar); #define UNIT_V_HDSK_WLK (UNIT_V_UF + 0) /* write locked */ #define UNIT_HDSK_WLK (1 << UNIT_V_HDSK_WLK) @@ -118,6 +122,7 @@ typedef struct { #define SPT16 16 #define SPT32 32 #define SPT26 26 +#define SPT52 52 static HDSK_INFO hdsk_info_data = { { 0x0000, 0, 0xFD, 1 } }; @@ -126,18 +131,18 @@ static int32 standard8[SPT26] = { 0, 6, 12, 18, 24, 4, 10, 16, 19, 25, 5, 11, 17, 23, 3, 9, 15, 21 }; -static int32 appple_ii_DOS[SPT16] = { 0, 6, 12, 3, 9, 15, 14, 5, +static int32 apple_ii_DOS[SPT16] = { 0, 6, 12, 3, 9, 15, 14, 5, 11, 2, 8, 7, 13, 4, 10, 1 }; -static int32 appple_ii_DOS2[SPT32] = { 0, 1, 12, 13, 24, 25, 6, 7, +static int32 apple_ii_DOS2[SPT32] = { 0, 1, 12, 13, 24, 25, 6, 7, 18, 19, 30, 31, 28, 29, 10, 11, 22, 23, 4, 5, 16, 17, 14, 15, 26, 27, 8, 9, 20, 21, 2, 3 }; -static int32 appple_ii_PRODOS[SPT16] = { 0, 9, 3, 12, 6, 15, 1, 10, +static int32 apple_ii_PRODOS[SPT16] = { 0, 9, 3, 12, 6, 15, 1, 10, 4, 13, 7, 8, 2, 11, 5, 14 }; -static int32 appple_ii_PRODOS2[SPT32] = { 0, 1, 18, 19, 6, 7, 24, 25, +static int32 apple_ii_PRODOS2[SPT32] = { 0, 1, 18, 19, 6, 7, 24, 25, 12, 13, 30, 31, 2, 3, 20, 21, 8, 9, 26, 27, 14, 15, 16, 17, 4, 5, 22, 23, 10, 11, 28, 29 }; @@ -197,17 +202,44 @@ static DPB dpb[] = { { "SSSD8S", 256256, SPT26, 0x03, 0x07, 0x00, 242, 0x003F, 0xC0, 0x00, 0x0000, 0x0002, 0x00, 0x00, 0, 0, standard8 }, /* Standard 8" SS SD with skew */ + { "SSDD8", 512512, SPT52, 0x04, 0x0F, 0x01, 242, 0x007F, + 0xC0, 0x00, 0x0000, 0x0002, 0x01, 0x01, 0, 0, NULL }, /* Standard 8" SS DD */ + + { "SSDD8S", 512512, SPT52, 0x04, 0x0F, 0x01, 242, 0x007F, + 0xC0, 0x00, 0x0000, 0x0002, 0x01, 0x01, 0, 0, standard8 }, /* Standard 8" SS DD with skew */ + + { "DSDD8", 1025024, SPT52, 0x04, 0x0F, 0x00, 493, 0x007F, + 0xC0, 0x00, 0x0000, 0x0002, 0x01, 0x01, 0, 0, NULL }, /* Standard 8" DS DD */ + + { "DSDD8S", 1025024, SPT52, 0x04, 0x0F, 0x00, 493, 0x007F, + 0xC0, 0x00, 0x0000, 0x0002, 0x01, 0x01, 0, 0, NULL }, /* Standard 8" DS DD with skew */ + + {"512SSDD8",591360, 60, 0x04, 0x0F, 0x00, 280, 0x007F, + 0xC0, 0x00, 0x0000, 0x0002, 0x02, 0x03, 0, 0, NULL }, /* Standard 8" SS DD with 512 byte sectors */ + + {"512DSDD8",1182720, 60, 0x04, 0x0F, 0x00, 569, 0x007F, + 0xC0, 0x00, 0x0000, 0x0002, 0x02, 0x03, 0, 0, NULL }, /* Standard 8" DS DD with 512 byte sectors */ + +#if 0 + /* CP/M 3 BIOS currently does not support physical sector size 1024 */ + {"1024SSDD8",630784, 64, 0x04, 0x0F, 0x00, 299, 0x007F, + 0xC0, 0x00, 0x0000, 0x0002, 0x03, 0x07, 0, 0, NULL }, /* Standard 8" SS DD with 1024 byte sectors */ + + {"1024DSDD8",1261568, 64, 0x04, 0x0F, 0x00, 607, 0x007F, + 0xC0, 0x00, 0x0000, 0x0002, 0x03, 0x07, 0, 0, NULL }, /* Standard 8" DS DD with 1024 byte sectors */ +#endif + { "APPLE-DO",143360, SPT32, 0x03, 0x07, 0x00, 127, 0x003F, - 0xC0, 0x00, 0x0000, 0x0003, 0x01, 0x01, 0, 0, appple_ii_DOS }, /* Apple II DOS 3.3 */ + 0xC0, 0x00, 0x0000, 0x0003, 0x01, 0x01, 0, 0, apple_ii_DOS }, /* Apple II DOS 3.3 */ { "APPLE-PO",143360, SPT32, 0x03, 0x07, 0x00, 127, 0x003F, - 0xC0, 0x00, 0x0000, 0x0003, 0x01, 0x01, 0, 0, appple_ii_PRODOS }, /* Apple II PRODOS */ + 0xC0, 0x00, 0x0000, 0x0003, 0x01, 0x01, 0, 0, apple_ii_PRODOS }, /* Apple II PRODOS */ { "APPLE-D2",143360, SPT32, 0x03, 0x07, 0x00, 127, 0x003F, - 0xC0, 0x00, 0x0000, 0x0003, 0x00, 0x00, 0, 0, appple_ii_DOS2 }, /* Apple II DOS 3.3, deblocked */ + 0xC0, 0x00, 0x0000, 0x0003, 0x00, 0x00, 0, 0, apple_ii_DOS2 }, /* Apple II DOS 3.3, deblocked */ { "APPLE-P2",143360, SPT32, 0x03, 0x07, 0x00, 127, 0x003F, - 0xC0, 0x00, 0x0000, 0x0003, 0x00, 0x00, 0, 0, appple_ii_PRODOS2 }, /* Apple II PRODOS, deblocked */ + 0xC0, 0x00, 0x0000, 0x0003, 0x00, 0x00, 0, 0, apple_ii_PRODOS2 }, /* Apple II PRODOS, deblocked */ { "MITS", 337568, SPT32, 0x03, 0x07, 0x00, 254, 0x00FF, 0xFF, 0x00, 0x0000, 0x0006, 0x00, 0x00, 137, 3, mits }, /* MITS Altair original */ @@ -215,6 +247,20 @@ static DPB dpb[] = { { "MITS2", 1113536, SPT32, 0x04, 0x0F, 0x00, 0x1EF, 0x00FF, 0xF0, 0x00, 0x0000, 0x0006, 0x00, 0x00, 137, 3, mits }, /* MITS Altair original, extra */ + /* + dw 40 ;#128 byte records/track + db 4,0fh ;block shift mask (2K) + db 1 ;extent mask + dw 194 ;maximun block number + dw 127 ;max number of dir entry - 1 + db 0C0H,00h ;alloc vector for directory + dw 0020h ;checksum size + dw 2 ;offset for sys tracks + db 2,3 ;physical sector shift (512 sector) + */ + { "V1050", 409600, 40, 0x04, 0x0F, 0x01, 194, 0x007F, + 0xC0, 0x00, 0x0000, 0x0002, 0x02, 0x03, 0, 0, NULL }, /* Visual Technology Visual 1050, http://www.metabarn.com/v1050/index.html */ + { "", 0 } }; @@ -228,6 +274,7 @@ static UNIT hdsk_unit[] = { { UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, HDSK_CAPACITY) }, { UDATA (NULL, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, HDSK_CAPACITY) } }; +static DISK_INFO* hdsk_imd[HDSK_NUMBER]; static REG hdsk_reg[] = { { DRDATA (HDCMD, hdskLastCommand, 32), REG_RO }, @@ -267,63 +314,128 @@ DEVICE hdsk_dev = { /* Reset routine */ static t_stat hdsk_reset(DEVICE *dptr) { - PNP_INFO *pnp = (PNP_INFO *)dptr->ctxt; - if (dptr->flags & DEV_DIS) { - sim_map_resource(pnp->io_base, pnp->io_size, RESOURCE_TYPE_IO, &hdsk_io, TRUE); + PNP_INFO *pnp = (PNP_INFO *)dptr -> ctxt; + if (dptr -> flags & DEV_DIS) { + sim_map_resource(pnp -> io_base, pnp -> io_size, RESOURCE_TYPE_IO, &hdsk_io, TRUE); } else { /* Connect HDSK at base address */ - if (sim_map_resource(pnp->io_base, pnp->io_size, RESOURCE_TYPE_IO, &hdsk_io, FALSE) != 0) { - printf("%s: error mapping I/O resource at 0x%04x\n", __FUNCTION__, pnp->mem_base); - dptr->flags |= DEV_DIS; + if (sim_map_resource(pnp -> io_base, pnp -> io_size, RESOURCE_TYPE_IO, &hdsk_io, FALSE) != 0) { + printf("%s: error mapping I/O resource at 0x%04x\n", __FUNCTION__, pnp -> mem_base); + dptr -> flags |= DEV_DIS; return SCPE_ARG; } } return SCPE_OK; } -/* Attach routine */ -static t_stat hdsk_attach(UNIT *uptr, char *cptr) { - t_stat r; +#ifdef _WIN32 +#define strcasecmp _stricmp +#endif +static uint32 is_imd(const UNIT *uptr) { + return ((uptr != NULL) && (uptr -> filename != NULL) && (strlen(uptr -> filename) > 3) && + (strcasecmp(".IMD", uptr -> filename + strlen(uptr -> filename) - 4) == 0)); +} + +static void assignFormat(UNIT *uptr) { uint32 i; - char unitChar; - - r = attach_unit(uptr, cptr); /* attach unit */ - if ( r != SCPE_OK) /* error? */ - return r; - - /* Step 1: Determine capacity of this disk */ - uptr -> capac = sim_fsize(uptr -> fileref); /* the file length is a good indication */ - if (uptr -> capac == 0) { /* file does not exist or has length 0 */ - uptr -> capac = uptr -> HDSK_NUMBER_OF_TRACKS * - uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE; - if (uptr -> capac == 0) - uptr -> capac = HDSK_CAPACITY; - } /* post condition: uptr -> capac > 0 */ - assert(uptr -> capac); - - /* Step 2: Determine format based on disk capacity */ - uptr -> HDSK_FORMAT_TYPE = -1; /* default to unknown format type */ - for (i = 0; dpb[i].capac != 0; i++) { /* find disk parameter block */ - if (dpb[i].capac == uptr -> capac) { /* found if correct capacity */ + uptr -> HDSK_FORMAT_TYPE = -1; /* default to unknown format type */ + for (i = 0; dpb[i].capac != 0; i++) { /* find disk parameter block */ + if (dpb[i].capac == uptr -> capac) { /* found if correct capacity */ uptr -> HDSK_FORMAT_TYPE = i; break; } } +} - /* Step 3: Set number of sectors per track and sector size */ - if (uptr -> HDSK_FORMAT_TYPE == -1) { /* Case 1: no disk parameter block found*/ - for (i = 0; i < hdsk_dev.numunits; i++) /* find affected unit number */ - if (&hdsk_unit[i] == uptr) - break; /* found */ - unitChar = '0' + i; +static void verifyDiskInfo(const DISK_INFO info, const char unitChar) { + uint32 track, head; + if (info.ntracks < 1) + printf("HDSK%c (IMD): WARNING: Number of tracks is 0.\n", unitChar); + if (info.nsides < 1) { + printf("HDSK%c (IMD): WARNING: Number of sides is 0.\n", unitChar); + return; + } + for (track = 0; track < info.ntracks / info.nsides; track++) + for (head = 0; head < info.nsides; head++) { + if (info.track[track][head].nsects != info.track[1][0].nsects) + printf("HDSK%c (IMD): WARNING: For track %i and head %i expected number of sectors " + "%i but got %i.\n", unitChar, track, head, + info.track[1][0].nsects, info.track[track][head].nsects); + if (info.track[track][head].sectsize != info.track[1][0].sectsize) + printf("HDSK%c (IMD): WARNING: For track %i and head %i expected sector size " + "%i but got %i.\n", unitChar, track, head, + info.track[1][0].sectsize, info.track[track][head].sectsize); + if (info.track[track][head].start_sector != info.track[1][0].start_sector) + printf("HDSK%c (IMD): WARNING: For track %i and head %i expected start sector " + "%i but got %i.\n", unitChar, track, head, + info.track[1][0].start_sector, info.track[track][head].start_sector); + } +} + +/* Attach routine */ +static t_stat hdsk_attach(UNIT *uptr, char *cptr) { + int32 thisUnitIndex; + char unitChar; + const t_stat r = attach_unit(uptr, cptr); /* attach unit */ + if (r != SCPE_OK) /* error? */ + return r; + + assert(uptr != NULL); + thisUnitIndex = find_unit_index(uptr); + unitChar = '0' + thisUnitIndex; + assert((0 <= thisUnitIndex) && (thisUnitIndex < HDSK_NUMBER)); + + if (is_imd(uptr)) { + if ((sim_fsize(uptr -> fileref) == 0) && + (diskCreate(uptr -> fileref, "$Id: SIMH hdsk.c $") != SCPE_OK)) { + printf("HDSK%c (IMD): Failed to create IMD disk.\n", unitChar); + detach_unit(uptr); + return SCPE_OPENERR; + } + hdsk_imd[thisUnitIndex] = diskOpen(uptr -> fileref, sim_deb && (hdsk_dev.dctrl & VERBOSE_MSG)); + if (hdsk_imd[thisUnitIndex] == NULL) + return SCPE_IOERR; + verifyDiskInfo(*hdsk_imd[thisUnitIndex], '0' + thisUnitIndex); + uptr -> HDSK_NUMBER_OF_TRACKS = hdsk_imd[thisUnitIndex] -> ntracks; + uptr -> HDSK_SECTORS_PER_TRACK = hdsk_imd[thisUnitIndex] -> track[1][0].nsects; + uptr -> HDSK_SECTOR_SIZE = hdsk_imd[thisUnitIndex] -> track[1][0].sectsize; + uptr -> capac = ((uptr -> HDSK_NUMBER_OF_TRACKS) * + (uptr -> HDSK_SECTORS_PER_TRACK) * + (uptr -> HDSK_SECTOR_SIZE)); + assignFormat(uptr); + if (uptr -> HDSK_FORMAT_TYPE == -1) { /* Case 1: no disk parameter block found*/ + uptr -> HDSK_FORMAT_TYPE = 0; + printf("HDSK%c (IMD): WARNING: Unsupported disk capacity, assuming HDSK type " + "with capacity %iKB.\n", unitChar, uptr -> capac / 1000); + uptr -> flags |= UNIT_HDSK_WLK; + printf("HDSK%c (IMD): WARNING: Forcing WRTLCK.\n", unitChar); + } + return SCPE_OK; + } + + /* Step 1: Determine capacity of this disk */ + uptr -> capac = sim_fsize(uptr -> fileref); /* the file length is a good indication */ + if (uptr -> capac == 0) { /* file does not exist or has length 0 */ + uptr -> capac = (uptr -> HDSK_NUMBER_OF_TRACKS * + uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE); + if (uptr -> capac == 0) + uptr -> capac = HDSK_CAPACITY; + } /* post condition: uptr -> capac > 0 */ + assert(uptr -> capac); + + /* Step 2: Determine format based on disk capacity */ + assignFormat(uptr); + + /* Step 3: Set number of sectors per track and sector size */ + if (uptr -> HDSK_FORMAT_TYPE == -1) { /* Case 1: no disk parameter block found */ uptr -> HDSK_FORMAT_TYPE = 0; printf("HDSK%c: WARNING: Unsupported disk capacity, assuming HDSK type with capacity %iKB.\n", - unitChar, uptr -> capac / 1000); + unitChar, uptr -> capac / 1000); uptr -> flags |= UNIT_HDSK_WLK; printf("HDSK%c: WARNING: Forcing WRTLCK.\n", unitChar); - /* check whether capacity corresponds to setting of tracks, sectors per track and sector size */ + /* check whether capacity corresponds to setting of tracks, sectors per track and sector size */ if (uptr -> capac != (uint32)(uptr -> HDSK_NUMBER_OF_TRACKS * - uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE)) { + uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE)) { printf("HDSK%c: WARNING: Fixing geometry.\n", unitChar); if (uptr -> HDSK_SECTORS_PER_TRACK == 0) uptr -> HDSK_SECTORS_PER_TRACK = 32; @@ -331,27 +443,35 @@ static t_stat hdsk_attach(UNIT *uptr, char *cptr) { uptr -> HDSK_SECTOR_SIZE = 128; } } - else { /* Case 2: disk parameter block found */ + else { /* Case 2: disk parameter block found */ uptr -> HDSK_SECTORS_PER_TRACK = dpb[uptr -> HDSK_FORMAT_TYPE].spt >> dpb[uptr -> HDSK_FORMAT_TYPE].psh; uptr -> HDSK_SECTOR_SIZE = (128 << dpb[uptr -> HDSK_FORMAT_TYPE].psh); } assert((uptr -> HDSK_SECTORS_PER_TRACK) && (uptr -> HDSK_SECTOR_SIZE) && (uptr -> HDSK_FORMAT_TYPE >= 0)); - - /* Step 4: Number of tracks is smallest number to accomodate capacity */ + + /* Step 4: Number of tracks is smallest number to accomodate capacity */ uptr -> HDSK_NUMBER_OF_TRACKS = (uptr -> capac + uptr -> HDSK_SECTORS_PER_TRACK * - uptr -> HDSK_SECTOR_SIZE - 1) / (uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE); + uptr -> HDSK_SECTOR_SIZE - 1) / (uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE); assert( ( (t_addr) ((uptr -> HDSK_NUMBER_OF_TRACKS - 1) * uptr -> HDSK_SECTORS_PER_TRACK * - uptr -> HDSK_SECTOR_SIZE) < uptr -> capac) && - (uptr -> capac <= (t_addr) (uptr -> HDSK_NUMBER_OF_TRACKS * - uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE) ) ); - + uptr -> HDSK_SECTOR_SIZE) < uptr -> capac) && + (uptr -> capac <= (t_addr) (uptr -> HDSK_NUMBER_OF_TRACKS * + uptr -> HDSK_SECTORS_PER_TRACK * uptr -> HDSK_SECTOR_SIZE) ) ); + return SCPE_OK; } static t_stat hdsk_detach(UNIT *uptr) { t_stat result; + int32 unitIndex; if (uptr == NULL) return SCPE_IERR; + if (is_imd(uptr)) { + unitIndex = find_unit_index(uptr); + if (unitIndex == -1) + return SCPE_IERR; + assert((0 <= unitIndex) && (unitIndex < HDSK_NUMBER)); + diskClose(&hdsk_imd[unitIndex]); + } result = detach_unit(uptr); uptr -> capac = HDSK_CAPACITY; uptr -> HDSK_FORMAT_TYPE = 0; @@ -490,7 +610,7 @@ static t_stat hdsk_boot(int32 unitno, DEVICE *dptr) { install_ALTAIRbootROM(); /* install modified ROM */ } assert(install_bootrom(bootrom_hdsk, BOOTROM_SIZE_HDSK, HDSK_BOOT_ADDRESS, FALSE) == SCPE_OK); - *((int32 *) sim_PC->loc) = HDSK_BOOT_ADDRESS; + *((int32 *) sim_PC -> loc) = HDSK_BOOT_ADDRESS; return SCPE_OK; } @@ -603,22 +723,57 @@ static int32 doSeek(void) { return CPM_OK; } -uint8 hdskbuf[HDSK_MAX_SECTOR_SIZE] = { 0 }; /* data buffer */ +static uint8 hdskbuf[HDSK_MAX_SECTOR_SIZE] = { 0 }; /* data buffer */ /* pre-condition: checkParameters has been executed to repair any faulty parameters */ static int32 doRead(void) { int32 i; + t_stat result; + DISK_INFO *thisDisk; + int32 hostSector; + int32 sectorSize; + uint32 flags; + uint32 readlen; + uint32 cylinder; + uint32 head; UNIT *uptr = &hdsk_dev.units[selectedDisk]; - if (doSeek()) - return CPM_ERROR; - - if (sim_fread(hdskbuf, 1, uptr -> HDSK_SECTOR_SIZE, uptr -> fileref) != (size_t)(uptr -> HDSK_SECTOR_SIZE)) { - for (i = 0; i < uptr -> HDSK_SECTOR_SIZE; i++) - hdskbuf[i] = CPM_EMPTY; - sim_debug(VERBOSE_MSG, &hdsk_dev, "HDSK%d: " ADDRESS_FORMAT - " Could not read Sector=%02d Track=%04d.\n", - selectedDisk, PCX, selectedSector, selectedTrack); - return CPM_OK; /* allows the creation of empty hard disks */ + if (is_imd(uptr)) { + thisDisk = hdsk_imd[selectedDisk]; + hostSector = ((dpb[uptr -> HDSK_FORMAT_TYPE].skew == NULL) ? + selectedSector : dpb[uptr -> HDSK_FORMAT_TYPE].skew[selectedSector]) + thisDisk -> track[1][0].start_sector; + sectorSize = ((dpb[uptr -> HDSK_FORMAT_TYPE].physicalSectorSize == 0) ? + uptr -> HDSK_SECTOR_SIZE : + dpb[uptr -> HDSK_FORMAT_TYPE].physicalSectorSize); + flags = 0; + readlen = 0; + cylinder = selectedTrack; + head = 0; + if (cylinder >= thisDisk -> ntracks / thisDisk -> nsides) { + head = 1; + cylinder -= thisDisk -> ntracks / thisDisk -> nsides; + } + result = sectRead(thisDisk, cylinder, head, hostSector, hdskbuf, sectorSize, + &flags, &readlen); + if (result != SCPE_OK) { + for (i = 0; i < uptr -> HDSK_SECTOR_SIZE; i++) + hdskbuf[i] = CPM_EMPTY; + sim_debug(VERBOSE_MSG, &hdsk_dev, "HDSK%d (IMD): " ADDRESS_FORMAT + " . Could not read Sector=%02d Track=%04d.\n", + selectedDisk, PCX, selectedSector, selectedTrack); + return CPM_ERROR; + } + } else { + if (doSeek()) + return CPM_ERROR; + + if (sim_fread(hdskbuf, 1, uptr -> HDSK_SECTOR_SIZE, uptr -> fileref) != (size_t)(uptr -> HDSK_SECTOR_SIZE)) { + for (i = 0; i < uptr -> HDSK_SECTOR_SIZE; i++) + hdskbuf[i] = CPM_EMPTY; + sim_debug(VERBOSE_MSG, &hdsk_dev, "HDSK%d: " ADDRESS_FORMAT + " Could not read Sector=%02d Track=%04d.\n", + selectedDisk, PCX, selectedSector, selectedTrack); + return CPM_OK; /* allows the creation of empty hard disks */ + } } for (i = 0; i < uptr -> HDSK_SECTOR_SIZE; i++) PutBYTEWrapper(selectedDMA + i, hdskbuf[i]); @@ -628,19 +783,54 @@ static int32 doRead(void) { /* pre-condition: checkParameters has been executed to repair any faulty parameters */ static int32 doWrite(void) { int32 i; + t_stat result; + DISK_INFO *thisDisk; + int32 hostSector; + int32 sectorSize; + uint32 flags; + uint32 writelen; + uint32 cylinder; + uint32 head; size_t rtn; UNIT *uptr = &hdsk_dev.units[selectedDisk]; if (((uptr -> flags) & UNIT_HDSK_WLK) == 0) { /* write enabled */ - if (doSeek()) - return CPM_ERROR; - for (i = 0; i < uptr -> HDSK_SECTOR_SIZE; i++) - hdskbuf[i] = GetBYTEWrapper(selectedDMA + i); - rtn = sim_fwrite(hdskbuf, 1, uptr -> HDSK_SECTOR_SIZE, uptr -> fileref); - if (rtn != (size_t)(uptr -> HDSK_SECTOR_SIZE)) { - sim_debug(VERBOSE_MSG, &hdsk_dev, "HDSK%d: " ADDRESS_FORMAT - " Could not write Sector=%02d Track=%04d Result=%zd.\n", - selectedDisk, PCX, selectedSector, selectedTrack, rtn); - return CPM_ERROR; + if (is_imd(uptr)) { + for (i = 0; i < uptr -> HDSK_SECTOR_SIZE; i++) + hdskbuf[i] = GetBYTEWrapper(selectedDMA + i); + thisDisk = hdsk_imd[selectedDisk]; + hostSector = ((dpb[uptr -> HDSK_FORMAT_TYPE].skew == NULL) ? + selectedSector : dpb[uptr -> HDSK_FORMAT_TYPE].skew[selectedSector]) + thisDisk -> track[1][0].start_sector; + sectorSize = ((dpb[uptr -> HDSK_FORMAT_TYPE].physicalSectorSize == 0) ? + uptr -> HDSK_SECTOR_SIZE : + dpb[uptr -> HDSK_FORMAT_TYPE].physicalSectorSize); + flags = 0; + writelen = 0; + cylinder = selectedTrack; + head = 0; + if (cylinder >= thisDisk -> ntracks / thisDisk -> nsides) { + head = 1; + cylinder -= thisDisk -> ntracks / thisDisk -> nsides; + } + result = sectWrite(thisDisk, cylinder, head, hostSector, hdskbuf, + sectorSize, &flags, &writelen); + if (result != SCPE_OK) { + sim_debug(VERBOSE_MSG, &hdsk_dev, "HDSK%d (IMD): " ADDRESS_FORMAT + " . Could not write Sector=%02d Track=%04d.\n", + selectedDisk, PCX, selectedSector, selectedTrack); + return CPM_ERROR; + } + } else { + if (doSeek()) + return CPM_ERROR; + for (i = 0; i < uptr -> HDSK_SECTOR_SIZE; i++) + hdskbuf[i] = GetBYTEWrapper(selectedDMA + i); + rtn = sim_fwrite(hdskbuf, 1, uptr -> HDSK_SECTOR_SIZE, uptr -> fileref); + if (rtn != (size_t)(uptr -> HDSK_SECTOR_SIZE)) { + sim_debug(VERBOSE_MSG, &hdsk_dev, "HDSK%d: " ADDRESS_FORMAT + " Could not write Sector=%02d Track=%04d Result=%zd.\n", + selectedDisk, PCX, selectedSector, selectedTrack, rtn); + return CPM_ERROR; + } } } else { diff --git a/AltairZ80/altairz80_net.c b/AltairZ80/altairz80_net.c index f6d71ffe..9c1c4edd 100644 --- a/AltairZ80/altairz80_net.c +++ b/AltairZ80/altairz80_net.c @@ -1,6 +1,6 @@ /* altairz80_net.c: networking capability - Copyright (c) 2002-2011, Peter Schorn + Copyright (c) 2002-2013, Peter Schorn Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -77,16 +77,14 @@ static struct { static UNIT net_unit = { UDATA (&net_svc, UNIT_ATTABLE, 0), 0, /* wait, set in attach */ - 0, /* u3 = Port */ - 0, /* u4 = IP of host */ + 0, /* u3, unused */ + 0, /* u4, unused */ 0, /* u5, unused */ 0, /* u6, unused */ }; static REG net_reg[] = { { DRDATA (POLL, net_unit.wait, 32) }, - { HRDATA (IPHOST, net_unit.u4, 32), REG_RO }, - { DRDATA (PORT, net_unit.u3, 32), REG_RO }, { NULL } }; diff --git a/AltairZ80/altairz80_sio.c b/AltairZ80/altairz80_sio.c index 726b029d..f66d69bb 100644 --- a/AltairZ80/altairz80_sio.c +++ b/AltairZ80/altairz80_sio.c @@ -1,6 +1,6 @@ /* altairz80_sio.c: MITS Altair serial I/O card - Copyright (c) 2002-2011, Peter Schorn + Copyright (c) 2002-2013, Peter Schorn Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -64,27 +64,27 @@ uint8 *URLContents(const char *URL, uint32 *length); #ifndef URL_READER_SUPPORT -#define RESULT_BUFFER_LENGTH 1024 +#define RESULT_BUFFER_LENGTH 1024 #define RESULT_LEAD_IN "URL is not supported on this platform. START URL \"" #define RESULT_LEAD_OUT "\" URL END." uint8 *URLContents(const char *URL, uint32 *length) { - char str[RESULT_BUFFER_LENGTH] = RESULT_LEAD_IN; + char str[RESULT_BUFFER_LENGTH] = RESULT_LEAD_IN; char *result; - strncat(str, URL, RESULT_BUFFER_LENGTH - strlen(RESULT_LEAD_IN) - strlen(RESULT_LEAD_OUT) - 1); - strcat(str, RESULT_LEAD_OUT); - result = malloc(strlen(str)); - strcpy(result, str); - *length = strlen(str); - return (uint8*)result; + strncat(str, URL, RESULT_BUFFER_LENGTH - strlen(RESULT_LEAD_IN) - strlen(RESULT_LEAD_OUT) - 1); + strcat(str, RESULT_LEAD_OUT); + result = (char*)malloc(strlen(str)); + strcpy(result, str); + *length = strlen(str); + return (uint8*)result; } #endif /* Debug flags */ -#define IN_MSG (1 << 0) -#define OUT_MSG (1 << 1) -#define CMD_MSG (1 << 2) -#define VERBOSE_MSG (1 << 3) -#define BUFFER_EMPTY_MSG (1 << 4) +#define IN_MSG (1 << 0) +#define OUT_MSG (1 << 1) +#define CMD_MSG (1 << 2) +#define VERBOSE_MSG (1 << 3) +#define BUFFER_EMPTY_MSG (1 << 4) #define UNIT_V_SIO_ANSI (UNIT_V_UF + 0) /* ANSI mode, strip bit 8 on output */ #define UNIT_SIO_ANSI (1 << UNIT_V_SIO_ANSI) @@ -172,12 +172,12 @@ extern volatile int32 stop_cpu; /* Debug Flags */ static DEBTAB generic_dt[] = { - { "IN", IN_MSG }, - { "OUT", OUT_MSG }, - { "CMD", CMD_MSG }, - { "VERBOSE", VERBOSE_MSG }, - { "BUFFEREMPTY", BUFFER_EMPTY_MSG }, - { NULL, 0 } + { "IN", IN_MSG }, + { "OUT", OUT_MSG }, + { "CMD", CMD_MSG }, + { "VERBOSE", VERBOSE_MSG }, + { "BUFFEREMPTY", BUFFER_EMPTY_MSG }, + { NULL, 0 } }; /* SIMH pseudo device status registers */ @@ -225,10 +225,10 @@ static int32 lastCPMStatus = 0; /* result of last attachCPM comm static int32 lastCommand = 0; /* most recent command processed on port 0xfeh */ static int32 getCommonPos = 0; /* determines state for sending the 'common' register */ -/* CPU Clock Frequency related */ +/* CPU Clock Frequency related */ static uint32 newClockFrequency; -static int32 setClockFrequencyPos = 0; /* determines state for sending the clock frequency */ -static int32 getClockFrequencyPos = 0; /* determines state for receiving the clock frequency */ +static int32 setClockFrequencyPos = 0; /* determines state for sending the clock frequency */ +static int32 getClockFrequencyPos = 0; /* determines state for receiving the clock frequency */ /* support for wild card expansion */ #if UNIX_PLATFORM @@ -274,7 +274,7 @@ static UNIT sio_unit = { 100000, /* wait */ FALSE, /* u3 = FALSE, no character available in buffer */ FALSE, /* u4 = FALSE, terminal input is not attached to a file */ - 0, /* u5 = 0, not used */ + 0, /* u5 = 0, not used */ 0 /* u6 = 0, not used */ }; @@ -456,7 +456,7 @@ static t_stat sio_reset(DEVICE *dptr) { int32 i; sim_debug(VERBOSE_MSG, &sio_dev, "SIO: " ADDRESS_FORMAT " Reset\n", PCX); sio_unit.u3 = FALSE; /* no character in terminal input buffer */ - sio_unit.buf = 0; + sio_unit.buf = 0; resetSIOWarningFlags(); if (sio_unit.u4) /* is terminal input attached to a file? */ rewind(sio_unit.fileref); /* yes, rewind input */ @@ -472,7 +472,7 @@ static t_stat ptr_reset(DEVICE *dptr) { sim_debug(VERBOSE_MSG, &ptr_dev, "PTR: " ADDRESS_FORMAT " Reset\n", PCX); resetSIOWarningFlags(); ptr_unit.u3 = FALSE; /* End Of File not yet reached */ - ptr_unit.buf = 0; + ptr_unit.buf = 0; if (ptr_unit.flags & UNIT_ATT) /* attached? */ rewind(ptr_unit.fileref); sim_map_resource(0x12, 1, RESOURCE_TYPE_IO, &sio1s, dptr->flags & DEV_DIS); @@ -650,18 +650,18 @@ static int32 sio0sCore(const int32 port, const int32 io, const int32 data) { pollConnection(); if (io == 0) { /* IN */ if (sio_unit.u4) { /* attached to a file? */ - if (sio_unit.u3) /* character available? */ - return spi.sio_can_read | spi.sio_can_write; - ch = getc(sio_unit.fileref); - if (ch == EOF) { + if (sio_unit.u3) /* character available? */ + return spi.sio_can_read | spi.sio_can_write; + ch = getc(sio_unit.fileref); + if (ch == EOF) { sio_detach(&sio_unit); /* detach file and switch to keyboard input */ - return spi.sio_cannot_read | spi.sio_can_write; - } - else { - sio_unit.u3 = TRUE; /* indicate character available */ - sio_unit.buf = ch; /* store character in buffer */ - return spi.sio_can_read | spi.sio_can_write; - } + return spi.sio_cannot_read | spi.sio_can_write; + } + else { + sio_unit.u3 = TRUE; /* indicate character available */ + sio_unit.buf = ch; /* store character in buffer */ + return spi.sio_can_read | spi.sio_can_write; + } } if (sio_unit.flags & UNIT_ATT) { /* attached to a port? */ if (tmxr_rqln(&TerminalLines[spi.terminalLine])) @@ -692,8 +692,8 @@ static int32 sio0sCore(const int32 port, const int32 io, const int32 data) { return spi.sio_cannot_read | spi.sio_can_write; } /* OUT follows, no fall-through from IN */ if (spi.hasReset && (data == spi.sio_reset)) { /* reset command */ - if (!sio_unit.u4) /* only reset for regular console I/O */ - sio_unit.u3 = FALSE; /* indicate that no character is available */ + if (!sio_unit.u4) /* only reset for regular console I/O */ + sio_unit.u3 = FALSE; /* indicate that no character is available */ sim_debug(CMD_MSG, &sio_dev, "\tSIO_S: " ADDRESS_FORMAT " Command OUT(0x%03x) = 0x%02x\n", PCX, port, data); } @@ -723,7 +723,7 @@ static int32 sio0dCore(const int32 port, const int32 io, const int32 data) { if ((sio_unit.flags & UNIT_ATT) && (!sio_unit.u4)) return mapCharacter(tmxr_getc_ln(&TerminalLines[spi.terminalLine])); if (!sio_unit.u3) { - sim_debug(BUFFER_EMPTY_MSG, &sio_dev, "\tSIO_D: " ADDRESS_FORMAT + sim_debug(BUFFER_EMPTY_MSG, &sio_dev, "\tSIO_D: " ADDRESS_FORMAT " IN(0x%03x) for empty character buffer\n", PCX, port); } sio_unit.u3 = FALSE; /* no character is available any more */ @@ -733,8 +733,10 @@ static int32 sio0dCore(const int32 port, const int32 io, const int32 data) { ch = sio_unit.flags & UNIT_SIO_ANSI ? data & 0x7f : data; /* clear highest bit in ANSI mode */ if ((ch != CONTROLG_CHAR) || !(sio_unit.flags & UNIT_SIO_BELL)) { voidSleep(); - if ((sio_unit.flags & UNIT_ATT) && (!sio_unit.u4)) /* attached to a port and not to a file */ + if ((sio_unit.flags & UNIT_ATT) && (!sio_unit.u4)) { /* attached to a port and not to a file */ tmxr_putc_ln(&TerminalLines[spi.terminalLine], ch); /* status ignored */ + tmxr_poll_tx(&altairTMXR); /* poll xmt */ + } else sim_putchar(ch); } @@ -743,15 +745,15 @@ static int32 sio0dCore(const int32 port, const int32 io, const int32 data) { } static char* printable(char* result, int32 data, const int32 isIn) { - result[0] = 0; - data &= 0x7f; - if ((0x20 <= data) && (data < 0x7f)) - sprintf(result, isIn ? " <-\"%c\"" : " ->\"%c\"", data); - return result; + result[0] = 0; + data &= 0x7f; + if ((0x20 <= data) && (data < 0x7f)) + sprintf(result, isIn ? " <-\"%c\"" : " ->\"%c\"", data); + return result; } int32 sio0d(const int32 port, const int32 io, const int32 data) { - char buffer[8]; + char buffer[8]; const int32 result = sio0dCore(port, io, data); if (io == 0) { sim_debug(IN_MSG, &sio_dev, "\tSIO_D: " ADDRESS_FORMAT @@ -797,7 +799,7 @@ int32 sio1s(const int32 port, const int32 io, const int32 data) { " IN(0x%02x) = 0x%02x\n", PCX, port, result); sim_debug(IN_MSG, &ptp_dev, "PTP_S: " ADDRESS_FORMAT " IN(0x%02x) = 0x%02x\n", PCX, port, result); - } + } else if (io) { sim_debug(OUT_MSG, &ptr_dev, "PTR_S: " ADDRESS_FORMAT " OUT(0x%02x) = 0x%02x\n", PCX, port, data); @@ -1068,11 +1070,11 @@ static int32 fromBCD(const int32 x) { out (0feh),a ld a, out (0feh),a - ... ; send all parameters + ... ; send all parameters in a,(0feh) ; contains first byte of result in a,(0feh) ; contains second byte of result ... - + */ enum simhPseudoDeviceCommands { /* do not change order or remove commands, add only at the end */ @@ -1106,10 +1108,10 @@ enum simhPseudoDeviceCommands { /* do not change order or remove commands, add o SIMHSleepCmd, /* 27 let SIMH sleep for SIMHSleep microseconds */ getHostOSPathSeparatorCmd, /* 28 obtain the file path separator of the OS under which SIMH runs */ getHostFilenamesCmd, /* 29 perform wildcard expansion and obtain list of file names */ - readURLCmd, /* 30 read the contents of an URL */ - getCPUClockFrequency, /* 31 get the clock frequency of the CPU */ - setCPUClockFrequency, /* 32 set the clock frequency of the CPU */ - kSimhPseudoDeviceCommands + readURLCmd, /* 30 read the contents of an URL */ + getCPUClockFrequency, /* 31 get the clock frequency of the CPU */ + setCPUClockFrequency, /* 32 set the clock frequency of the CPU */ + kSimhPseudoDeviceCommands }; static char *cmdNames[kSimhPseudoDeviceCommands] = { @@ -1143,9 +1145,9 @@ static char *cmdNames[kSimhPseudoDeviceCommands] = { "SIMHSleep", "getHostOSPathSeparator", "getHostFilenames", - "readURL", - "getCPUClockFrequency", - "setCPUClockFrequency", + "readURL", + "getCPUClockFrequency", + "setCPUClockFrequency", }; #define CPM_COMMAND_LINE_LENGTH 128 @@ -1155,7 +1157,7 @@ static struct tm currentTime; static int32 currentTimeValid = FALSE; static char version[] = "SIMH004"; -#define URL_MAX_LENGTH 1024 +#define URL_MAX_LENGTH 1024 static uint32 urlPointer; static char urlStore[URL_MAX_LENGTH]; static uint8 *urlResult = NULL; @@ -1182,13 +1184,13 @@ static t_stat simh_dev_reset(DEVICE *dptr) { lastCommand = 0; lastCPMStatus = SCPE_OK; timerInterrupt = FALSE; - urlPointer = 0; - getClockFrequencyPos = 0; - setClockFrequencyPos = 0; - if (urlResult != NULL) { - free(urlResult); - urlResult = NULL; - } + urlPointer = 0; + getClockFrequencyPos = 0; + setClockFrequencyPos = 0; + if (urlResult != NULL) { + free(urlResult); + urlResult = NULL; + } if (simh_unit.flags & UNIT_SIMH_TIMERON) simh_dev_set_timeron(NULL, 0, NULL, NULL); return SCPE_OK; @@ -1319,26 +1321,26 @@ static void setClockCPM3(void) { static int32 simh_in(const int32 port) { int32 result = 0; switch(lastCommand) { - case readURLCmd: + case readURLCmd: if (isInReadPhase) { - if (showAvailability) { - if (resultPointer < resultLength) - result = 1; - else { - if (urlResult != NULL) - free(urlResult); - urlResult = NULL; - lastCommand = 0; - } - } - else if (resultPointer < resultLength) - result = urlResult[resultPointer++]; - showAvailability = 1 - showAvailability; + if (showAvailability) { + if (resultPointer < resultLength) + result = 1; + else { + if (urlResult != NULL) + free(urlResult); + urlResult = NULL; + lastCommand = 0; + } + } + else if (resultPointer < resultLength) + result = urlResult[resultPointer++]; + showAvailability = 1 - showAvailability; } else lastCommand = 0; - break; - + break; + case getHostFilenamesCmd: #if UNIX_PLATFORM if (globValid) { @@ -1479,7 +1481,7 @@ static int32 simh_in(const int32 port) { } break; - case getCPUClockFrequency: + case getCPUClockFrequency: if (getClockFrequencyPos == 0) { result = getClockFrequency() & 0xff; getClockFrequencyPos = 1; @@ -1489,7 +1491,7 @@ static int32 simh_in(const int32 port) { getClockFrequencyPos = lastCommand = 0; } break; - + case hasBankedMemoryCmd: result = cpu_unit.flags & UNIT_CPU_BANKED ? MAXBANKS : 0; lastCommand = 0; @@ -1542,7 +1544,7 @@ void do_SIMH_sleep(void) { static int32 simh_out(const int32 port, const int32 data) { time_t now; switch(lastCommand) { - case readURLCmd: + case readURLCmd: if (isInReadPhase) lastCommand = 0; else { @@ -1559,8 +1561,8 @@ static int32 simh_out(const int32 port, const int32 data) { showAvailability = 1; isInReadPhase = TRUE; } - } - break; + } + break; case setClockZSDOSCmd: if (setClockZSDOSPos == 0) { @@ -1586,16 +1588,16 @@ static int32 simh_out(const int32 port, const int32 data) { } break; - case setCPUClockFrequency: - if (setClockFrequencyPos == 0) { - newClockFrequency = data; - setClockFrequencyPos = 1; - } - else { - setClockFrequency((data << 8) | newClockFrequency); + case setCPUClockFrequency: + if (setClockFrequencyPos == 0) { + newClockFrequency = data; + setClockFrequencyPos = 1; + } + else { + setClockFrequency((data << 8) | newClockFrequency); setClockFrequencyPos = lastCommand = 0; - } - break; + } + break; case setBankSelectCmd: if (cpu_unit.flags & UNIT_CPU_BANKED) @@ -1644,10 +1646,10 @@ static int32 simh_out(const int32 port, const int32 data) { lastCommand = data; switch(data) { - case readURLCmd: - urlPointer = 0; + case readURLCmd: + urlPointer = 0; isInReadPhase = FALSE; - break; + break; case getHostFilenamesCmd: #if UNIX_PLATFORM @@ -1758,18 +1760,18 @@ static int32 simh_out(const int32 port, const int32 data) { setClockCPM3Pos = 0; break; - case getCommonCmd: - getCommonPos = 0; - break; - - case getCPUClockFrequency: - getClockFrequencyPos = 0; - break; - - case setCPUClockFrequency: - setClockFrequencyPos = 0; - break; - + case getCommonCmd: + getCommonPos = 0; + break; + + case getCPUClockFrequency: + getClockFrequencyPos = 0; + break; + + case setCPUClockFrequency: + setClockFrequencyPos = 0; + break; + case getBankSelectCmd: case setBankSelectCmd: case hasBankedMemoryCmd: diff --git a/AltairZ80/altairz80_sys.c b/AltairZ80/altairz80_sys.c index 6a4f8985..ced454b6 100644 --- a/AltairZ80/altairz80_sys.c +++ b/AltairZ80/altairz80_sys.c @@ -1,6 +1,6 @@ /* altairz80_sys.c: MITS Altair system interface - Copyright (c) 2002-2011, Peter Schorn + Copyright (c) 2002-2013, Peter Schorn Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -138,13 +138,13 @@ const char *sim_stop_messages[] = { static char *const Mnemonics8080[] = { /* 0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */ "NOP", "LXI B,#h", "STAX B", "INX B", "INR B", "DCR B", "MVI B,*h", "RLC", /* 00-07 */ - "DB 09h", "DAD B", "LDAX B", "DCX B", "INR C", "DCR C", "MVI C,*h", "RRC", /* 08-0f */ - "DB 10h", "LXI D,#h", "STAX D", "INX D", "INR D", "DCR D", "MVI D,*h", "RAL", /* 10-17 */ - "DB 18h", "DAD D", "LDAX D", "DCX D", "INR E", "DCR E", "MVI E,*h", "RAR", /* 18-1f */ - "DB 20h", "LXI H,#h", "SHLD #h", "INX H", "INR H", "DCR H", "MVI H,*h", "DAA", /* 20-27 */ - "DB 28h", "DAD H", "LHLD #h", "DCX H", "INR L", "DCR L", "MVI L,*h", "CMA", /* 28-2f */ - "DB 30h", "LXI SP,#h", "STA #h", "INX SP", "INR M", "DCR M", "MVI M,*h", "STC", /* 30-37 */ - "DB 38h", "DAD SP", "LDA #h", "DCX SP", "INR A", "DCR A", "MVI A,*h", "CMC", /* 38-3f */ + "_NOP", "DAD B", "LDAX B", "DCX B", "INR C", "DCR C", "MVI C,*h", "RRC", /* 08-0f */ + "_NOP", "LXI D,#h", "STAX D", "INX D", "INR D", "DCR D", "MVI D,*h", "RAL", /* 10-17 */ + "_NOP", "DAD D", "LDAX D", "DCX D", "INR E", "DCR E", "MVI E,*h", "RAR", /* 18-1f */ + "_NOP", "LXI H,#h", "SHLD #h", "INX H", "INR H", "DCR H", "MVI H,*h", "DAA", /* 20-27 */ + "_NOP", "DAD H", "LHLD #h", "DCX H", "INR L", "DCR L", "MVI L,*h", "CMA", /* 28-2f */ + "_NOP", "LXI SP,#h", "STA #h", "INX SP", "INR M", "DCR M", "MVI M,*h", "STC", /* 30-37 */ + "_NOP", "DAD SP", "LDA #h", "DCX SP", "INR A", "DCR A", "MVI A,*h", "CMC", /* 38-3f */ "MOV B,B", "MOV B,C", "MOV B,D", "MOV B,E", "MOV B,H", "MOV B,L", "MOV B,M", "MOV B,A", /* 40-47 */ "MOV C,B", "MOV C,C", "MOV C,D", "MOV C,E", "MOV C,H", "MOV C,L", "MOV C,M", "MOV C,A", /* 48-4f */ "MOV D,B", "MOV D,C", "MOV D,D", "MOV D,E", "MOV D,H", "MOV D,L", "MOV D,M", "MOV D,A", /* 50-57 */ @@ -162,13 +162,13 @@ static char *const Mnemonics8080[] = { "ORA B", "ORA C", "ORA D", "ORA E", "ORA H", "ORA L", "ORA M", "ORA A", /* b0-b7 */ "CMP B", "CMP C", "CMP D", "CMP E", "CMP H", "CMP L", "CMP M", "CMP A", /* b8-bf */ "RNZ", "POP B", "JNZ #h", "JMP #h", "CNZ #h", "PUSH B", "ADI *h", "RST 0", /* c0-c7 */ - "RZ", "RET", "JZ #h", "DB CBh", "CZ #h", "CALL #h", "ACI *h", "RST 1", /* c8-cf */ + "RZ", "RET", "JZ #h", "_JMP #h", "CZ #h", "CALL #h", "ACI *h", "RST 1", /* c8-cf */ "RNC", "POP D", "JNC #h", "OUT *h", "CNC #h", "PUSH D", "SUI *h", "RST 2", /* d0-d7 */ - "RC", "DB D9h", "JC #h", "IN *h", "CC #h", "DB DDh", "SBI *h", "RST 3", /* d8-df */ + "RC", "_RET", "JC #h", "IN *h", "CC #h", "_CALL #h", "SBI *h", "RST 3", /* d8-df */ "RPO", "POP H", "JPO #h", "XTHL", "CPO #h", "PUSH H", "ANI *h", "RST 4", /* e0-e7 */ - "RPE", "PCHL", "JPE #h", "XCHG", "CPE #h", "DB EDh", "XRI *h", "RST 5", /* e8-ef */ + "RPE", "PCHL", "JPE #h", "XCHG", "CPE #h", "_CALL #h", "XRI *h", "RST 5", /* e8-ef */ "RP", "POP PSW", "JP #h", "DI", "CP #h", "PUSH PSW", "ORI *h", "RST 6", /* f0-f7 */ - "RM", "SPHL", "JM #h", "EI", "CM #h", "DB FDh", "CPI *h", "RST 7" /* f8-ff */ + "RM", "SPHL", "JM #h", "EI", "CM #h", "_CALL #h", "CPI *h", "RST 7" /* f8-ff */ }; static char *const MnemonicsZ80[256] = { diff --git a/AltairZ80/s100_fif.c b/AltairZ80/s100_fif.c index ca5481c4..9795e160 100644 --- a/AltairZ80/s100_fif.c +++ b/AltairZ80/s100_fif.c @@ -2,7 +2,7 @@ IMSAI FIF Disk Controller by Ernie Price - Based on altairz80_dsk.c, Copyright (c) 2002-2011, Peter Schorn + Based on altairz80_dsk.c, Copyright (c) 2002-2013, Peter Schorn Plug-n-Play added by Howard M. Harte diff --git a/AltairZ80/sim_imd.c b/AltairZ80/sim_imd.c index 0a367549..a157bd4a 100644 --- a/AltairZ80/sim_imd.c +++ b/AltairZ80/sim_imd.c @@ -759,7 +759,7 @@ t_stat trackWrite(DISK_INFO *myDisk, * sector record type as the first byte, and fill the sector * data with the fillbyte. */ - dataLen = (128 << sectorLen)+1; + dataLen = sectorLen + 1; sectorData = malloc(dataLen); memset(sectorData, fillbyte, dataLen); sectorData[0] = SECT_RECORD_NORM;