From ceacac4741a88f236407760f048c2f4d42a37907 Mon Sep 17 00:00:00 2001 From: Adrian Conlon Date: Mon, 6 Oct 2025 13:44:31 +0100 Subject: [PATCH] Fix up some oddities in the EightBit library --- EightBit/BigEndianProcessor.cs | 21 +- EightBit/IntelProcessor.cs | 41 +- EightBit/LittleEndianProcessor.cs | 21 +- EightBit/Processor.cs | 51 +- Intel8080/Intel8080.Test/Configuration.cs | 8 +- Intel8080/Intel8080.Test/roms/8080EXER.COM | Bin 4608 -> 4608 bytes Intel8080/Intel8080.Test/roms/8080EXER.MAC | 1283 +++++++++++ Intel8080/Intel8080.Test/roms/8080EXER.PNG | Bin 0 -> 56703 bytes Intel8080/Intel8080.Test/roms/8080EXER.PRN | 2239 ++++++++++++++++++ Intel8080/Intel8080.Test/roms/8080EXM.COM | Bin 0 -> 4608 bytes Intel8080/Intel8080.Test/roms/8080EXM.MAC | 1296 +++++++++++ Intel8080/Intel8080.Test/roms/8080EXM.PRN | 2254 +++++++++++++++++++ Intel8080/Intel8080.Test/roms/8080PRE.PRN | 535 +++++ Intel8080/Intel8080.Test/roms/README.TXT | 31 + Intel8080/Intel8080.Test/roms/TST8080.ASM | 819 +++++++ Intel8080/Intel8080.Test/roms/TST8080.COM | Bin 0 -> 1536 bytes Intel8080/Intel8080.Test/roms/TST8080.PRN | 821 +++++++ Intel8080/Intel8080.cs | 284 +-- LR35902/LR35902.BlarggTest/Board.cs | 2 +- LR35902/LR35902.BlarggTest/Computer.cs | 2 +- LR35902/LR35902.BlarggTest/Configuration.cs | 2 +- LR35902/LR35902.FuseTest/TestSuite.cs | 12 +- LR35902/LR35902.cs | 41 +- M6502/Core.cs | 162 +- M6502/MOS6502.cs | 4 +- M6502/WDC65C02.cs | 16 +- MC6809/MC6809.Test/Board.cs | 184 +- MC6809/MC6809.Test/TestHarness.cs | 1 + MC6809/MC6809.cs | 65 +- Z80/Z80.cs | 66 +- 30 files changed, 9775 insertions(+), 486 deletions(-) create mode 100644 Intel8080/Intel8080.Test/roms/8080EXER.MAC create mode 100644 Intel8080/Intel8080.Test/roms/8080EXER.PNG create mode 100644 Intel8080/Intel8080.Test/roms/8080EXER.PRN create mode 100644 Intel8080/Intel8080.Test/roms/8080EXM.COM create mode 100644 Intel8080/Intel8080.Test/roms/8080EXM.MAC create mode 100644 Intel8080/Intel8080.Test/roms/8080EXM.PRN create mode 100644 Intel8080/Intel8080.Test/roms/8080PRE.PRN create mode 100644 Intel8080/Intel8080.Test/roms/README.TXT create mode 100644 Intel8080/Intel8080.Test/roms/TST8080.ASM create mode 100644 Intel8080/Intel8080.Test/roms/TST8080.COM create mode 100644 Intel8080/Intel8080.Test/roms/TST8080.PRN diff --git a/EightBit/BigEndianProcessor.cs b/EightBit/BigEndianProcessor.cs index c7f5a53..525ae16 100644 --- a/EightBit/BigEndianProcessor.cs +++ b/EightBit/BigEndianProcessor.cs @@ -18,19 +18,17 @@ namespace EightBit this.Bus.Poke(++address, value.Low); } - protected override Register16 FetchWord() + protected override void FetchInto(Register16 into) { - this.Intermediate.High = this.FetchByte(); - this.Intermediate.Low = this.FetchByte(); - return this.Intermediate; + into.High = this.FetchByte(); + into.Low = this.FetchByte(); } - protected override Register16 GetWord() + protected override void GetInto(Register16 into) { - this.Intermediate.High = this.MemoryRead(); + into.High = this.MemoryRead(); _ = this.Bus.Address.Increment(); - this.Intermediate.Low = this.MemoryRead(); - return this.Intermediate; + into.Low = this.MemoryRead(); } protected override Register16 GetWordPaged() @@ -41,11 +39,10 @@ namespace EightBit return this.Intermediate; } - protected override Register16 PopWord() + protected override void PopInto(Register16 into) { - this.Intermediate.High = this.Pop(); - this.Intermediate.Low = this.Pop(); - return this.Intermediate; + into.High = this.Pop(); + into.Low = this.Pop(); } protected override void PushWord(Register16 value) diff --git a/EightBit/IntelProcessor.cs b/EightBit/IntelProcessor.cs index e38e719..9120dd6 100644 --- a/EightBit/IntelProcessor.cs +++ b/EightBit/IntelProcessor.cs @@ -99,8 +99,8 @@ namespace EightBit protected override byte FetchInstruction() { - var read = this.FetchByte(); - return this.HALT.Lowered() ? (byte)0 : read; + _ = this.FetchByte(); + return this.HALT.Lowered() ? (byte)0 : this.Bus.Data; } protected static int BuildHalfCarryIndex(byte before, byte value, int calculation) => ((before & 0x88) >> 1) | ((value & 0x88) >> 2) | ((calculation & 0x88) >> 3); @@ -176,57 +176,44 @@ namespace EightBit this.Call(); } - protected bool CallConditional(bool condition) + protected void CallConditional(bool condition) { - this.FetchWordMEMPTR(); + this.FetchInto(this.MEMPTR); if (condition) { this.Call(); } - - return condition; } - protected virtual bool JumpConditional(bool condition) + protected virtual void JumpConditional(bool condition) { - this.FetchWordMEMPTR(); + this.FetchInto(this.MEMPTR); if (condition) { this.Jump(); } - - return condition; } - protected virtual bool JumpRelativeConditional(bool condition) + protected virtual void JumpRelativeConditional(bool condition) { var offset = this.FetchByte(); if (condition) { this.JumpRelative(offset); } - return condition; } - protected virtual bool ReturnConditional(bool condition) + protected virtual void ReturnConditional(bool condition) { if (condition) { this.Return(); } - - return condition; - } - - protected void FetchWordMEMPTR() - { - _ = this.FetchWord(); - this.MEMPTR.Assign(this.Intermediate); } protected virtual void JumpIndirect() { - this.FetchWordMEMPTR(); + this.FetchInto(this.MEMPTR); this.Jump(); } @@ -237,7 +224,7 @@ namespace EightBit protected void CallIndirect() { - this.FetchWordMEMPTR(); + this.FetchInto(this.MEMPTR); this.Call(); } @@ -262,12 +249,12 @@ namespace EightBit protected abstract bool ConvertCondition(int flag); - protected virtual bool JumpConditionalFlag(int flag) => this.JumpConditional(this.ConvertCondition(flag)); + protected virtual void JumpConditionalFlag(int flag) => this.JumpConditional(this.ConvertCondition(flag)); - protected virtual bool JumpRelativeConditionalFlag(int flag) => this.JumpRelativeConditional(this.ConvertCondition(flag)); + protected virtual void JumpRelativeConditionalFlag(int flag) => this.JumpRelativeConditional(this.ConvertCondition(flag)); - protected virtual bool ReturnConditionalFlag(int flag) => this.ReturnConditional(this.ConvertCondition(flag)); + protected virtual void ReturnConditionalFlag(int flag) => this.ReturnConditional(this.ConvertCondition(flag)); - protected virtual bool CallConditionalFlag(int flag) => this.CallConditional(this.ConvertCondition(flag)); + protected virtual void CallConditionalFlag(int flag) => this.CallConditional(this.ConvertCondition(flag)); } } diff --git a/EightBit/LittleEndianProcessor.cs b/EightBit/LittleEndianProcessor.cs index ad7dd61..ab06d69 100644 --- a/EightBit/LittleEndianProcessor.cs +++ b/EightBit/LittleEndianProcessor.cs @@ -19,19 +19,17 @@ namespace EightBit this.Bus.Poke(++address, value.High); } - protected override Register16 FetchWord() + protected override void FetchInto(Register16 into) { - this.Intermediate.Low = this.FetchByte(); - this.Intermediate.High = this.FetchByte(); - return this.Intermediate; + into.Low = this.FetchByte(); + into.High = this.FetchByte(); } - protected override Register16 GetWord() + protected override void GetInto(Register16 into) { - this.Intermediate.Low = this.MemoryRead(); + into.Low = this.MemoryRead(); _ = this.Bus.Address.Increment(); - this.Intermediate.High = this.MemoryRead(); - return this.Intermediate; + into.High = this.MemoryRead(); } protected override Register16 GetWordPaged() @@ -42,11 +40,10 @@ namespace EightBit return this.Intermediate; } - protected override Register16 PopWord() + protected override void PopInto(Register16 into) { - this.Intermediate.Low = this.Pop(); - this.Intermediate.High = this.Pop(); - return this.Intermediate; + into.Low = this.Pop(); + into.High = this.Pop(); } protected override void PushWord(Register16 value) diff --git a/EightBit/Processor.cs b/EightBit/Processor.cs index 1e53347..b27cbac 100644 --- a/EightBit/Processor.cs +++ b/EightBit/Processor.cs @@ -224,10 +224,7 @@ namespace EightBit return this.MemoryRead(); } - protected virtual byte MemoryRead() - { - return this.BusRead(); - } + protected virtual byte MemoryRead() => this.BusRead(); protected virtual byte BusRead() => this.Bus.Read(); // N.B. Should be the only real call into the "Bus.Read" code. @@ -247,18 +244,18 @@ namespace EightBit return this.MemoryRead(); } - protected abstract Register16 GetWord(); + protected abstract void GetInto(Register16 into); + + protected virtual Register16 GetWord() + { + this.GetInto(this.Intermediate); + return this.Intermediate; + } protected abstract void SetWord(Register16 value); protected abstract Register16 GetWordPaged(); - protected Register16 GetWordPaged(Register16 address) - { - this.Bus.Address.Assign(address); - return this.GetWordPaged(); - } - protected Register16 GetWordPaged(byte page, byte offset) { this.Bus.Address.Assign(offset, page); @@ -279,27 +276,23 @@ namespace EightBit this.SetWordPaged(value); } - protected abstract Register16 FetchWord(); + protected abstract void FetchInto(Register16 into); - protected void FetchWordAddress() + protected Register16 FetchWord() { - _ = this.FetchWord(); - this.Bus.Address.Assign(this.Intermediate); + this.FetchInto(this.Intermediate); + return this.Intermediate; } + protected void FetchWordAddress() => this.Bus.Address.Assign(this.FetchWord()); + protected abstract void Push(byte value); protected abstract byte Pop(); protected abstract void PushWord(Register16 value); - protected abstract Register16 PopWord(); - - protected Register16 GetWord(ushort address) - { - this.Bus.Address.Word = address; - return this.GetWord(); - } + protected abstract void PopInto(Register16 into); protected Register16 GetWord(Register16 address) { @@ -307,12 +300,6 @@ namespace EightBit return this.GetWord(); } - protected void SetWord(ushort address, Register16 value) - { - this.Bus.Address.Word = address; - this.SetWord(value); - } - protected void SetWord(Register16 address, Register16 value) { this.Bus.Address.Assign(address); @@ -323,12 +310,6 @@ namespace EightBit protected void Jump(Register16 destination) => this.PC.Assign(destination); - protected void Call(ushort destination) - { - this.Intermediate.Word = destination; - this.Call(this.Intermediate); - } - [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1716:Identifiers should not match keywords", Justification = "Not using VB.NET")] protected virtual void Call(Register16 destination) { @@ -337,6 +318,6 @@ namespace EightBit } [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1716:Identifiers should not match keywords", Justification = "Not using VB.NET")] - protected virtual void Return() => this.Jump(this.PopWord()); + protected virtual void Return() => this.PopInto(this.PC); } } diff --git a/Intel8080/Intel8080.Test/Configuration.cs b/Intel8080/Intel8080.Test/Configuration.cs index 1f64ac7..4dee931 100644 --- a/Intel8080/Intel8080.Test/Configuration.cs +++ b/Intel8080/Intel8080.Test/Configuration.cs @@ -20,6 +20,12 @@ namespace Intel8080.Test public string RomDirectory { get; } = "roms"; - public string Program { get; } = "8080EX1.COM"; + //public string Program { get; } = "8080EX1.COM"; + public string Program { get; } = "8080EXER.COM"; + //public string Program { get; } = "8080EXM.COM"; + //public string Program { get; } = "8080PRE.COM"; + //public string Program { get; } = "CPUTEST.COM"; + //public string Program { get; } = "TEST.COM"; + //public string Program { get; } = "TST8080.COM"; } } \ No newline at end of file diff --git a/Intel8080/Intel8080.Test/roms/8080EXER.COM b/Intel8080/Intel8080.Test/roms/8080EXER.COM index a6cb22defe9444878f48ba3737b49d8c46067804..73e037b5915f44fb3f02723deb6efbd4bf2ad61a 100644 GIT binary patch delta 231 zcmZorX;7K4nnlFjd)dVGF)Z^Y>Cc-A*8>^#eyWU<`B{MGXl V#w63p{+vL?EQK#OujdTp0056gSoZ(` delta 228 zcmZorX;7K4nuP%fCa#YG)06obp^SXSn8^#6Stg%{3FtFHW%^-^_b`S(GgN9ljKR+W zGX};u4`b-F!pwm&-oqIFY%!A^fOf8DgDT-?hd3gi9V&1h#?a@0nF3?HhcWy)AyS*y Ia|Ut%09Ilur~m)} diff --git a/Intel8080/Intel8080.Test/roms/8080EXER.MAC b/Intel8080/Intel8080.Test/roms/8080EXER.MAC new file mode 100644 index 0000000..c40e79a --- /dev/null +++ b/Intel8080/Intel8080.Test/roms/8080EXER.MAC @@ -0,0 +1,1283 @@ + title 'Z80 instruction set exerciser' + +; zexlax.z80 - Z80 instruction set exerciser +; Copyright (C) 1994 Frank D. Cringle +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation; either version 2 +; of the License, or (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +; +;****************************************************************************** +; +; Modified to exercise an 8080 by Ian Bartholomew, February 2009 +; +; I have made the following changes - +; +; Converted all mnemonics to 8080 and rewritten any Z80 code used +; in the original exerciser. Changes are tagged with a #idb in the +; source code listing. +; +; Removed any test descriptors that are not used. +; +; Changed the macro definitions to work in M80 +; +; The machine state snapshot has been changed to remove the IX/IY registers. +; They have been replaced by two more copies of HL to obviate the need +; for major changes in the exerciser code. +; +; Changed flag mask in all tests to 0ffh to reflect that the 8080, unlike the 8085 +; and Z80, does define the unused bits in the flag register - [S Z 0 AC 0 P 1 C] +; +;****************************************************************************** + + .8080 + aseg + org 100h + +begin: jmp start + +; machine state before test (needs to be at predictably constant address) +msbt: ds 14 +spbt: ds 2 + +; For the purposes of this test program, the machine state consists of: +; a 2 byte memory operand, followed by +; the registers iy,ix,hl,de,bc,af,sp +; for a total of 16 bytes. + +; The program tests instructions (or groups of similar instructions) +; by cycling through a sequence of machine states, executing the test +; instruction for each one and running a 32-bit crc over the resulting +; machine states. At the end of the sequence the crc is compared to +; an expected value that was found empirically on a real Z80. + +; A test case is defined by a descriptor which consists of: +; a flag mask byte, +; the base case, +; the incement vector, +; the shift vector, +; the expected crc, +; a short descriptive message. +; +; The flag mask byte is used to prevent undefined flag bits from +; influencing the results. Documented flags are as per Mostek Z80 +; Technical Manual. +; +; The next three parts of the descriptor are 20 byte vectors +; corresponding to a 4 byte instruction and a 16 byte machine state. +; The first part is the base case, which is the first test case of +; the sequence. This base is then modified according to the next 2 +; vectors. Each 1 bit in the increment vector specifies a bit to be +; cycled in the form of a binary counter. For instance, if the byte +; corresponding to the accumulator is set to 0ffh in the increment +; vector, the test will be repeated for all 256 values of the +; accumulator. Note that 1 bits don't have to be contiguous. The +; number of test cases 'caused' by the increment vector is equal to +; 2^(number of 1 bits). The shift vector is similar, but specifies a +; set of bits in the test case that are to be successively inverted. +; Thus the shift vector 'causes' a number of test cases equal to the +; number of 1 bits in it. + +; The total number of test cases is the product of those caused by the +; counter and shift vectors and can easily become unweildy. Each +; individual test case can take a few milliseconds to execute, due to +; the overhead of test setup and crc calculation, so test design is a +; compromise between coverage and execution time. + +; This program is designed to detect differences between +; implementations and is not ideal for diagnosing the causes of any +; discrepancies. However, provided a reference implementation (or +; real system) is available, a failing test case can be isolated by +; hand using a binary search of the test space. + + +start: lhld 6 + sphl + lxi d,msg1 + mvi c,9 + call bdos + + lxi h,tests ; first test case +loop: mov a,m ; end of list ? + inx h + ora m + jz done + dcx h + call stt + jmp loop + +done: lxi d,msg2 + mvi c,9 + call bdos + jmp 0 ; warm boot + +tests: + dw add16 + dw alu8i + dw alu8r + dw daa + dw inca + dw incb + dw incbc + dw incc + dw incd + dw incde + dw ince + dw inch + dw inchl + dw incl + dw incm + dw incsp + dw ld162 + dw ld166 + dw ld16im + dw ld8bd + dw ld8im + dw ld8rr + dw lda + dw rot8080 + dw stabd + dw 0 + +tstr macro insn,memop,hliy,hlix,hl,de,bc,flags,acc,sp + local lab +lab: db insn + ds lab+4-$,0 + dw memop,hliy,hlix,hl,de,bc + db flags + db acc + dw sp + if $-lab ne 20 + error 'missing parameter' + endif + endm + +tmsg macro m + local lab +lab: db m + if $ ge lab+30 + error 'message too long' + else + ds lab+30-$,'.' + endif + db '$' + endm + +; add hl, (19,456 cycles) +add16: db 0ffh ; flag mask + tstr 9,0c4a5h,0c4c7h,0d226h,0a050h,058eah,08566h,0c6h,0deh,09bc9h + tstr 030h,0,0,0,0f821h,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,-1,-1,-1,0d7h,0,-1 ; (38 cycles) + db 014h, 047h, 04Bh, 0A6h ; expected crc + tmsg 'dad ' + +; aluop a,nn (28,672 cycles) +alu8i: db 0ffh ; flag mask + tstr 0c6h,09140h,07e3ch,07a67h,0df6dh,05b61h,00b29h,010h,066h,085b2h + tstr 038h,0,0,0,0,0,0,0,-1,0 ; (2048 cycles) + tstr <0,-1>,0,0,0,0,0,0,0d7h,0,0 ; (14 cycles) + db 09Eh, 092h, 02Fh, 09Eh ; expected crc + tmsg 'aluop nn' + +; aluop a, (753,664 cycles) +alu8r: db 0ffh ; flag mask + tstr 080h,0c53eh,0573ah,04c4dh,msbt,0e309h,0a666h,0d0h,03bh,0adbbh + tstr 03fh,0,0,0,0,0,0,0,-1,0 ; (16,384 cycles) + tstr 0,0ffh,0,0,0,-1,-1,0d7h,0,0 ; (46 cycles) + db 0CFh, 076h, 02Ch, 086h ; expected crc + tmsg 'aluop ' + +; +daa: db 0ffh ; flag mask + tstr 027h,02141h,009fah,01d60h,0a559h,08d5bh,09079h,004h,08eh,0299dh + tstr 018h,0,0,0,0,0,0,0d7h,-1,0 ; (65,536 cycles) + tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) + db 0BBh, 03Fh, 003h, 00Ch ; expected crc + tmsg '' + +; a (3072 cycles) +inca: db 0ffh ; flag mask + tstr 03ch,04adfh,0d5d8h,0e598h,08a2bh,0a7b0h,0431bh,044h,05ah,0d030h + tstr 001h,0,0,0,0,0,0,0,-1,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 0ADh, 0B6h, 046h, 00Eh ; expected crc + tmsg ' a' + +; b (3072 cycles) +incb: db 0ffh ; flag mask + tstr 004h,0d623h,0432dh,07a61h,08180h,05a86h,01e85h,086h,058h,09bbbh + tstr 001h,0,0,0,0,0,0ff00h,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 083h, 0EDh, 013h, 045h ; expected crc + tmsg ' b' + +; bc (1536 cycles) +incbc: db 0ffh ; flag mask + tstr 003h,0cd97h,044abh,08dc9h,0e3e3h,011cch,0e8a4h,002h,049h,02a4dh + tstr 008h,0,0,0,0,0,0f821h,0,0,0 ; (256 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 0F7h, 092h, 087h, 0CDh ; expected crc + tmsg ' b' + +; c (3072 cycles) +incc: db 0ffh ; flag mask + tstr 00ch,0d789h,00935h,0055bh,09f85h,08b27h,0d208h,095h,005h,00660h + tstr 001h,0,0,0,0,0,0ffh,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 0E5h, 0F6h, 072h, 01Bh ; expected crc + tmsg ' c' + +; d (3072 cycles) +incd: db 0ffh ; flag mask + tstr 014h,0a0eah,05fbah,065fbh,0981ch,038cch,0debch,043h,05ch,003bdh + tstr 001h,0,0,0,0,0ff00h,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 015h, 0B5h, 057h, 09Ah ; expected crc + tmsg ' d' + +; de (1536 cycles) +incde: db 0ffh ; flag mask + tstr 013h,0342eh,0131dh,028c9h,00acah,09967h,03a2eh,092h,0f6h,09d54h + tstr 008h,0,0,0,0,0f821h,0,0,0,0 ; (256 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 07Fh, 04Eh, 025h, 001h ; expected crc + tmsg ' d' + +; e (3072 cycles) +ince: db 0ffh ; flag mask + tstr 01ch,0602fh,04c0dh,02402h,0e2f5h,0a0f4h,0a10ah,013h,032h,05925h + tstr 001h,0,0,0,0,0ffh,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 0CFh, 02Ah, 0B3h, 096h ; expected crc + tmsg ' e' + +; h (3072 cycles) +inch: db 0ffh ; flag mask + tstr 024h,01506h,0f2ebh,0e8ddh,0262bh,011a6h,0bc1ah,017h,006h,02818h + tstr 001h,0,0,0,0ff00h,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 012h, 0B2h, 095h, 02Ch ; expected crc + tmsg ' h' + +; hl (1536 cycles) +inchl: db 0ffh ; flag mask + tstr 023h,0c3f4h,007a5h,01b6dh,04f04h,0e2c2h,0822ah,057h,0e0h,0c3e1h + tstr 008h,0,0,0,0f821h,0,0,0,0,0 ; (256 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 09Fh, 02Bh, 023h, 0C0h ; expected crc + tmsg ' h' + +; l (3072 cycles) +incl: db 0ffh ; flag mask + tstr 02ch,08031h,0a520h,04356h,0b409h,0f4c1h,0dfa2h,0d1h,03ch,03ea2h + tstr 001h,0,0,0,0ffh,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 0FFh, 057h, 0D3h, 056h ; expected crc + tmsg ' l' + +; (hl) (3072 cycles) +incm: db 0ffh ; flag mask + tstr 034h,0b856h,00c7ch,0e53eh,msbt,0877eh,0da58h,015h,05ch,01f37h + tstr 001h,0ffh,0,0,0,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 092h, 0E9h, 063h, 0BDh ; expected crc + tmsg ' m' + +; sp (1536 cycles) +incsp: db 0ffh ; flag mask + tstr 033h,0346fh,0d482h,0d169h,0deb6h,0a494h,0f476h,053h,002h,0855bh + tstr 008h,0,0,0,0,0,0,0,0,0f821h ; (256 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 0D5h, 070h, 02Fh, 0ABh ; expected crc + tmsg ' sp' + +; ld hl,(nnnn) (16 cycles) +ld162: db 0ffh ; flag mask + tstr <02ah,low msbt,high msbt>,09863h,07830h,02077h,0b1feh,0b9fah,0abb8h,004h,006h,06015h + tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) + tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) + db 0A9h, 0C3h, 0D5h, 0CBh ; expected crc + tmsg 'lhld nnnn' + +; ld (nnnn),hl (16 cycles) +ld166: db 0ffh ; flag mask + tstr <022h,low msbt,high msbt>,0d003h,07772h,07f53h,03f72h,064eah,0e180h,010h,02dh,035e9h + tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) + tstr 0,0,0,0,-1,0,0,0,0,0 ; (16 cycles) + db 0E8h, 086h, 04Fh, 026h ; expected crc + tmsg 'shld nnnn' + +; ld ,nnnn (64 cycles) +ld16im: db 0ffh ; flag mask + tstr 1,05c1ch,02d46h,08eb9h,06078h,074b1h,0b30eh,046h,0d1h,030cch + tstr 030h,0,0,0,0,0,0,0,0,0 ; (4 cycles) + tstr <0,0ffh,0ffh>,0,0,0,0,0,0,0,0,0 ; (16 cycles) + db 0FCh, 0F4h, 06Eh, 012h ; expected crc + tmsg 'lxi ,nnnn' + +; ld a,<(bc),(de)> (44 cycles) +ld8bd: db 0ffh ; flag mask + tstr 00ah,0b3a8h,01d2ah,07f8eh,042ach,msbt,msbt,0c6h,0b1h,0ef8eh + tstr 010h,0,0,0,0,0,0,0,0,0 ; (2 cycles) + tstr 0,0ffh,0,0,0,0,0,0d7h,-1,0 ; (22 cycles) + db 02Bh, 082h, 01Dh, 05Fh ; expected crc + tmsg 'ldax ' + +; ld ,nn (64 cycles) +ld8im: db 0ffh ; flag mask + tstr 6,0c407h,0f49dh,0d13dh,00339h,0de89h,07455h,053h,0c0h,05509h + tstr 038h,0,0,0,0,0,0,0,0,0 ; (8 cycles) + tstr 0,0,0,0,0,0,0,0,-1,0 ; (8 cycles) + db 0EAh, 0A7h, 020h, 044h ; expected crc + tmsg 'mvi ,nn' + +; ld , (3456 cycles) +ld8rr: db 0ffh ; flag mask + tstr 040h,072a4h,0a024h,061ach,msbt,082c7h,0718fh,097h,08fh,0ef8eh + tstr 03fh,0,0,0,0,0,0,0,0,0 ; (64 cycles) + tstr 0,0ffh,0,0,0,-1,-1,0d7h,-1,0 ; (54 cycles) + db 010h, 0B5h, 08Ch, 0EEh ; expected crc + tmsg 'mov ,' + +; ld a,(nnnn) / ld (nnnn),a (44 cycles) +lda: db 0ffh ; flag mask + tstr <032h,low msbt,high msbt>,0fd68h,0f4ech,044a0h,0b543h,00653h,0cdbah,0d2h,04fh,01fd8h + tstr 008h,0,0,0,0,0,0,0,0,0 ; (2 cycle) + tstr 0,0ffh,0,0,0,0,0,0d7h,-1,0 ; (22 cycles) + db 0EDh, 057h, 0AFh, 072h ; expected crc + tmsg 'sta nnnn / lda nnnn' + +; (6144 cycles) +rot8080: db 0ffh ; flag mask + tstr 7,0cb92h,06d43h,00a90h,0c284h,00c53h,0f50eh,091h,0ebh,040fch + tstr 018h,0,0,0,0,0,0,0,-1,0 ; (1024 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 0E0h, 0D8h, 092h, 035h ; expected crc + tmsg '' + +; ld (),a (96 cycles) +stabd: db 0ffh ; flag mask + tstr 2,00c3bh,0b592h,06cffh,0959eh,msbt,msbt+1,0c1h,021h,0bde7h + tstr 018h,0,0,0,0,0,0,0,0,0 ; (4 cycles) + tstr 0,-1,0,0,0,0,0,0,-1,0 ; (24 cycles) + db 02Bh, 004h, 071h, 0E9h ; expected crc + tmsg 'stax ' + +; start test pointed to by (hl) +stt: push h + mov a,m ; get pointer to test + inx h + mov h,m + mov l,a + mov a,m ; flag mask + sta flgmsk+1 + inx h + push h + lxi d,20 + dad d ; point to incmask + lxi d,counter + call initmask + pop h + push h + lxi d,20+20 + dad d ; point to scanmask + lxi d,shifter + call initmask + lxi h,shifter + mvi m,1 ; first bit + pop h + push h + lxi d,iut ; copy initial instruction under test + lxi b,4 + +;#idb ldir replaced with following code +ldir1: mov a,m + stax d + inx h + inx d + dcx b + mov a,b + ora c + jnz ldir1 +;#idb + + lxi d,msbt ; copy initial machine state + lxi b,16 + +;#idb ldir replaced with following code +ldir2: mov a,m + stax d + inx h + inx d + dcx b + mov a,b + ora c + jnz ldir2 +;#idb + + lxi d,20+20+4 ; skip incmask, scanmask and expcrc + dad d + xchg + mvi c,9 + call bdos ; show test name + call initcrc ; initialise crc +; test loop +tlp: lda iut + cpi 076h ; pragmatically avoid halt intructions + jz tlp2 + ani 0dfh + cpi 0ddh + jnz tlp1 + lda iut+1 + cpi 076h +tlp1: cnz test ; execute the test instruction +tlp2: call count ; increment the counter + cnz shift ; shift the scan bit + pop h ; pointer to test case + jz tlp3 ; done if shift returned NZ + lxi d,20+20+20 + dad d ; point to expected crc + call cmpcrc + lxi d,okmsg + jz tlpok + lxi d,ermsg1 + mvi c,9 + call bdos + call phex8 + lxi d,ermsg2 + mvi c,9 + call bdos + lxi h,crcval + call phex8 + lxi d,crlf +tlpok: mvi c,9 + call bdos + pop h + inx h + inx h + ret + +tlp3: push h + mvi a,1 ; initialise count and shift scanners + sta cntbit + sta shfbit + lxi h,counter + shld cntbyt + lxi h,shifter + shld shfbyt + + mvi b,4 ; bytes in iut field + pop h ; pointer to test case + push h + lxi d,iut + call setup ; setup iut + mvi b,16 ; bytes in machine state + lxi d,msbt + call setup ; setup machine state + jmp tlp + +; setup a field of the test case +; b = number of bytes +; hl = pointer to base case +; de = destination +setup: call subyte + inx h + dcr b + jnz setup + ret + +subyte: push b + push d + push h + mov c,m ; get base byte + lxi d,20 + dad d ; point to incmask + mov a,m + cpi 0 + jz subshf + mvi b,8 ; 8 bits +subclp: rrc + push psw + mvi a,0 + cc nxtcbit ; get next counter bit if mask bit was set + xra c ; flip bit if counter bit was set + rrc + mov c,a + pop psw + dcr b + jnz subclp + mvi b,8 +subshf: lxi d,20 + dad d ; point to shift mask + mov a,m + cpi 0 + jz substr + mvi b,8 ; 8 bits +sbshf1: rrc + push psw + mvi a,0 + cc nxtsbit ; get next shifter bit if mask bit was set + xra c ; flip bit if shifter bit was set + rrc + mov c,a + pop psw + dcr b + jnz sbshf1 +substr: pop h + pop d + mov a,c + stax d ; mangled byte to destination + inx d + pop b + ret + +; get next counter bit in low bit of a +cntbit: ds 1 +cntbyt: ds 2 + +nxtcbit: push b + push h + lhld cntbyt + mov b,m + lxi h,cntbit + mov a,m + mov c,a + rlc + mov m,a + cpi 1 + jnz ncb1 + lhld cntbyt + inx h + shld cntbyt +ncb1: mov a,b + ana c + pop h + pop b + rz + mvi a,1 + ret + +; get next shifter bit in low bit of a +shfbit: ds 1 +shfbyt: ds 2 + +nxtsbit: push b + push h + lhld shfbyt + mov b,m + lxi h,shfbit + mov a,m + mov c,a + rlc + mov m,a + cpi 1 + jnz nsb1 + lhld shfbyt + inx h + shld shfbyt +nsb1: mov a,b + ana c + pop h + pop b + rz + mvi a,1 + ret + + +; clear memory at hl, bc bytes +clrmem: push psw + push b + push d + push h + mvi m,0 + mov d,h + mov e,l + inx d + dcx b + +;#idb ldir replaced with following code +ldir3: mov a,m + stax d + inx h + inx d + dcx b + mov a,b + ora c + jnz ldir3 +;#idb + + pop h + pop d + pop b + pop psw + ret + +; initialise counter or shifter +; de = pointer to work area for counter or shifter +; hl = pointer to mask +initmask: + push d + xchg + lxi b,20+20 + call clrmem ; clear work area + xchg + mvi b,20 ; byte counter + mvi c,1 ; first bit + mvi d,0 ; bit counter +imlp: mov e,m +imlp1: mov a,e + ana c + jz imlp2 + inr d +imlp2: mov a,c + rlc + mov c,a + cpi 1 + jnz imlp1 + inx h + dcr b + jnz imlp +; got number of 1-bits in mask in reg d + mov a,d + ani 0f8h + rrc + rrc + rrc ; divide by 8 (get byte offset) + mov l,a + mvi h,0 + mov a,d + ani 7 ; bit offset + inr a + mov b,a + mvi a,080h +imlp3: rlc + dcr b + jnz imlp3 + pop d + dad d + lxi d,20 + dad d + mov m,a + ret + +; multi-byte counter +count: push b + push d + push h + lxi h,counter ; 20 byte counter starts here + lxi d,20 ; somewhere in here is the stop bit + xchg + dad d + xchg +cntlp: inr m + mov a,m + cpi 0 + jz cntlp1 ; overflow to next byte + mov b,a + ldax d + ana b ; test for terminal value + jz cntend + mvi m,0 ; reset to zero +cntend: pop b + pop d + pop h + ret + +cntlp1: inx h + inx d + jmp cntlp + + +; multi-byte shifter +shift: push b + push d + push h + lxi h,shifter ; 20 byte shift register starts here + lxi d,20 ; somewhere in here is the stop bit + xchg + dad d + xchg +shflp: mov a,m + ora a + jz shflp1 + mov b,a + ldax d + ana b + jnz shlpe + mov a,b + rlc + cpi 1 + jnz shflp2 + mvi m,0 + inx h + inx d +shflp2: mov m,a + xra a ; set Z +shlpe: pop h + pop d + pop b + ret +shflp1: inx h + inx d + jmp shflp + +counter: ds 2*20 +shifter: ds 2*20 + +; test harness +test: push psw + push b + push d + push h + if 0 + lxi d,crlf + mvi c,9 + call bdos + lxi h,iut + mvi b,4 + call hexstr + mvi e,' ' + mvi c,2 + call bdos + mvi b,16 + lxi h,msbt + call hexstr + endif + di ; disable interrupts + +;#idb ld (spsav),sp replaced by following code +;#idb All registers and flages are immediately overwritten so +;#idb no need to preserve any state. + lxi h,0 ; save stack pointer + dad sp + shld spsav +;#idb + + lxi sp,msbt+2 ; point to test-case machine state + +;#idb pop iy +;#idb pop ix both replaced by following code +;#idb Just dummy out ix/iy with copies of hl + pop h ; and load all regs + pop h +;#idb + + pop h + pop d + pop b + pop psw + +;#idb ld sp,(spbt) replaced with the following code +;#idb HL is copied/restored before/after load so no state changed + shld temp + lhld spbt + sphl + lhld temp +;#idb + +iut: ds 4 ; max 4 byte instruction under test + +;#idb ld (spat),sp replaced with the following code +;#idb Must be very careful to preserve registers and flag +;#idb state resulting from the test. The temptation is to use the +;#idb stack - but that doesn't work because of the way the app +;#idb uses SP as a quick way of pointing to memory. +;#idb Bit of a code smell, but I can't think of an easier way. + shld temp + lxi h,0 + jc temp1 ;jump on the state of the C flag set in the test + + dad sp ;this code will clear the C flag (0 + nnnn = nc) + jmp temp2 ;C flag is same state as before + +temp1: dad sp ;this code will clear the C flag (0 + nnnn = nc) + stc ;C flage needs re-setting to preserve state + +temp2: shld spat + lhld temp +;#idb + + lxi sp,spat + push psw ; save other registers + push b + push d + push h + +;#idb push ix +;#idb push iy both replaced by following code +;#idb Must match change made to pops made before test + push h + push h +;#idb + +;#idb ld sp,(spsav) replaced with following code +;#idb No need to preserve state + lhld spsav ; restore stack pointer + sphl +;#idb + + ei ; enable interrupts + lhld msbt ; copy memory operand + shld msat + lxi h,flgsat ; flags after test + mov a,m +flgmsk: ani 0ffh ; mask-out irrelevant bits (self-modified code!) + mov m,a + mvi b,16 ; total of 16 bytes of state + lxi d,msat + lxi h,crcval +tcrc: ldax d + inx d + call updcrc ; accumulate crc of this test case + dcr b + jnz tcrc + if 0 + mvi e,' ' + mvi c,2 + call bdos + lxi h,crcval + call phex8 + lxi d,crlf + mvi c,9 + call bdos + lxi h,msat + mvi b,16 + call hexstr + lxi d,crlf + mvi c,9 + call bdos + endif + pop h + pop d + pop b + pop psw + ret + +;#idb Added to store HL state +temp: ds 2 +;#idb + +; machine state after test +msat: ds 14 ; memop,iy,ix,hl,de,bc,af +spat: ds 2 ; stack pointer after test +flgsat equ spat-2 ; flags + +spsav: ds 2 ; saved stack pointer + +; display hex string (pointer in hl, byte count in b) +hexstr: mov a,m + call phex2 + inx h + dcr b + jnz hexstr + ret + +; display hex +; display the big-endian 32-bit value pointed to by hl +phex8: push psw + push b + push h + mvi b,4 +ph8lp: mov a,m + call phex2 + inx h + dcr b + jnz ph8lp + pop h + pop b + pop psw + ret + +; display byte in a +phex2: push psw + rrc + rrc + rrc + rrc + call phex1 + pop psw +; fall through + +; display low nibble in a +phex1: push psw + push b + push d + push h + ani 0fh + cpi 10 + jc ph11 + adi 'a'-'9'-1 +ph11: adi '0' + mov e,a + mvi c,2 + call bdos + pop h + pop d + pop b + pop psw + ret + +bdos: push psw + push b + push d + push h + call 5 + pop h + pop d + pop b + pop psw + ret + +msg1: db '8080 instruction exerciser',10,13,'$' +msg2: db 'Tests complete$' +okmsg: db ' OK',10,13,'$' +ermsg1: db ' ERROR **** crc expected:$' +ermsg2: db ' found:$' +crlf: db 10,13,'$' + +; compare crc +; hl points to value to compare to crcval +cmpcrc: push b + push d + push h + lxi d,crcval + mvi b,4 +cclp: ldax d + cmp m + jnz cce + inx h + inx d + dcr b + jnz cclp +cce: pop h + pop d + pop b + ret + +; 32-bit crc routine +; entry: a contains next byte, hl points to crc +; exit: crc updated +updcrc: push psw + push b + push d + push h + push h + lxi d,3 + dad d ; point to low byte of old crc + xra m ; xor with new byte + mov l,a + mvi h,0 + dad h ; use result as index into table of 4 byte entries + dad h + xchg + lxi h,crctab + dad d ; point to selected entry in crctab + xchg + pop h + lxi b,4 ; c = byte count, b = accumulator +crclp: ldax d + xra b + mov b,m + mov m,a + inx d + inx h + dcr c + jnz crclp + if 0 + lxi h,crcval + call phex8 + lxi d,crlf + mvi c,9 + call bdos + endif + pop h + pop d + pop b + pop psw + ret + +initcrc:push psw + push b + push h + lxi h,crcval + mvi a,0ffh + mvi b,4 +icrclp: mov m,a + inx h + dcr b + jnz icrclp + pop h + pop b + pop psw + ret + +crcval: ds 4 + +crctab: db 000h,000h,000h,000h + db 077h,007h,030h,096h + db 0eeh,00eh,061h,02ch + db 099h,009h,051h,0bah + db 007h,06dh,0c4h,019h + db 070h,06ah,0f4h,08fh + db 0e9h,063h,0a5h,035h + db 09eh,064h,095h,0a3h + db 00eh,0dbh,088h,032h + db 079h,0dch,0b8h,0a4h + db 0e0h,0d5h,0e9h,01eh + db 097h,0d2h,0d9h,088h + db 009h,0b6h,04ch,02bh + db 07eh,0b1h,07ch,0bdh + db 0e7h,0b8h,02dh,007h + db 090h,0bfh,01dh,091h + db 01dh,0b7h,010h,064h + db 06ah,0b0h,020h,0f2h + db 0f3h,0b9h,071h,048h + db 084h,0beh,041h,0deh + db 01ah,0dah,0d4h,07dh + db 06dh,0ddh,0e4h,0ebh + db 0f4h,0d4h,0b5h,051h + db 083h,0d3h,085h,0c7h + db 013h,06ch,098h,056h + db 064h,06bh,0a8h,0c0h + db 0fdh,062h,0f9h,07ah + db 08ah,065h,0c9h,0ech + db 014h,001h,05ch,04fh + db 063h,006h,06ch,0d9h + db 0fah,00fh,03dh,063h + db 08dh,008h,00dh,0f5h + db 03bh,06eh,020h,0c8h + db 04ch,069h,010h,05eh + db 0d5h,060h,041h,0e4h + db 0a2h,067h,071h,072h + db 03ch,003h,0e4h,0d1h + db 04bh,004h,0d4h,047h + db 0d2h,00dh,085h,0fdh + db 0a5h,00ah,0b5h,06bh + db 035h,0b5h,0a8h,0fah + db 042h,0b2h,098h,06ch + db 0dbh,0bbh,0c9h,0d6h + db 0ach,0bch,0f9h,040h + db 032h,0d8h,06ch,0e3h + db 045h,0dfh,05ch,075h + db 0dch,0d6h,00dh,0cfh + db 0abh,0d1h,03dh,059h + db 026h,0d9h,030h,0ach + db 051h,0deh,000h,03ah + db 0c8h,0d7h,051h,080h + db 0bfh,0d0h,061h,016h + db 021h,0b4h,0f4h,0b5h + db 056h,0b3h,0c4h,023h + db 0cfh,0bah,095h,099h + db 0b8h,0bdh,0a5h,00fh + db 028h,002h,0b8h,09eh + db 05fh,005h,088h,008h + db 0c6h,00ch,0d9h,0b2h + db 0b1h,00bh,0e9h,024h + db 02fh,06fh,07ch,087h + db 058h,068h,04ch,011h + db 0c1h,061h,01dh,0abh + db 0b6h,066h,02dh,03dh + db 076h,0dch,041h,090h + db 001h,0dbh,071h,006h + db 098h,0d2h,020h,0bch + db 0efh,0d5h,010h,02ah + db 071h,0b1h,085h,089h + db 006h,0b6h,0b5h,01fh + db 09fh,0bfh,0e4h,0a5h + db 0e8h,0b8h,0d4h,033h + db 078h,007h,0c9h,0a2h + db 00fh,000h,0f9h,034h + db 096h,009h,0a8h,08eh + db 0e1h,00eh,098h,018h + db 07fh,06ah,00dh,0bbh + db 008h,06dh,03dh,02dh + db 091h,064h,06ch,097h + db 0e6h,063h,05ch,001h + db 06bh,06bh,051h,0f4h + db 01ch,06ch,061h,062h + db 085h,065h,030h,0d8h + db 0f2h,062h,000h,04eh + db 06ch,006h,095h,0edh + db 01bh,001h,0a5h,07bh + db 082h,008h,0f4h,0c1h + db 0f5h,00fh,0c4h,057h + db 065h,0b0h,0d9h,0c6h + db 012h,0b7h,0e9h,050h + db 08bh,0beh,0b8h,0eah + db 0fch,0b9h,088h,07ch + db 062h,0ddh,01dh,0dfh + db 015h,0dah,02dh,049h + db 08ch,0d3h,07ch,0f3h + db 0fbh,0d4h,04ch,065h + db 04dh,0b2h,061h,058h + db 03ah,0b5h,051h,0ceh + db 0a3h,0bch,000h,074h + db 0d4h,0bbh,030h,0e2h + db 04ah,0dfh,0a5h,041h + db 03dh,0d8h,095h,0d7h + db 0a4h,0d1h,0c4h,06dh + db 0d3h,0d6h,0f4h,0fbh + db 043h,069h,0e9h,06ah + db 034h,06eh,0d9h,0fch + db 0adh,067h,088h,046h + db 0dah,060h,0b8h,0d0h + db 044h,004h,02dh,073h + db 033h,003h,01dh,0e5h + db 0aah,00ah,04ch,05fh + db 0ddh,00dh,07ch,0c9h + db 050h,005h,071h,03ch + db 027h,002h,041h,0aah + db 0beh,00bh,010h,010h + db 0c9h,00ch,020h,086h + db 057h,068h,0b5h,025h + db 020h,06fh,085h,0b3h + db 0b9h,066h,0d4h,009h + db 0ceh,061h,0e4h,09fh + db 05eh,0deh,0f9h,00eh + db 029h,0d9h,0c9h,098h + db 0b0h,0d0h,098h,022h + db 0c7h,0d7h,0a8h,0b4h + db 059h,0b3h,03dh,017h + db 02eh,0b4h,00dh,081h + db 0b7h,0bdh,05ch,03bh + db 0c0h,0bah,06ch,0adh + db 0edh,0b8h,083h,020h + db 09ah,0bfh,0b3h,0b6h + db 003h,0b6h,0e2h,00ch + db 074h,0b1h,0d2h,09ah + db 0eah,0d5h,047h,039h + db 09dh,0d2h,077h,0afh + db 004h,0dbh,026h,015h + db 073h,0dch,016h,083h + db 0e3h,063h,00bh,012h + db 094h,064h,03bh,084h + db 00dh,06dh,06ah,03eh + db 07ah,06ah,05ah,0a8h + db 0e4h,00eh,0cfh,00bh + db 093h,009h,0ffh,09dh + db 00ah,000h,0aeh,027h + db 07dh,007h,09eh,0b1h + db 0f0h,00fh,093h,044h + db 087h,008h,0a3h,0d2h + db 01eh,001h,0f2h,068h + db 069h,006h,0c2h,0feh + db 0f7h,062h,057h,05dh + db 080h,065h,067h,0cbh + db 019h,06ch,036h,071h + db 06eh,06bh,006h,0e7h + db 0feh,0d4h,01bh,076h + db 089h,0d3h,02bh,0e0h + db 010h,0dah,07ah,05ah + db 067h,0ddh,04ah,0cch + db 0f9h,0b9h,0dfh,06fh + db 08eh,0beh,0efh,0f9h + db 017h,0b7h,0beh,043h + db 060h,0b0h,08eh,0d5h + db 0d6h,0d6h,0a3h,0e8h + db 0a1h,0d1h,093h,07eh + db 038h,0d8h,0c2h,0c4h + db 04fh,0dfh,0f2h,052h + db 0d1h,0bbh,067h,0f1h + db 0a6h,0bch,057h,067h + db 03fh,0b5h,006h,0ddh + db 048h,0b2h,036h,04bh + db 0d8h,00dh,02bh,0dah + db 0afh,00ah,01bh,04ch + db 036h,003h,04ah,0f6h + db 041h,004h,07ah,060h + db 0dfh,060h,0efh,0c3h + db 0a8h,067h,0dfh,055h + db 031h,06eh,08eh,0efh + db 046h,069h,0beh,079h + db 0cbh,061h,0b3h,08ch + db 0bch,066h,083h,01ah + db 025h,06fh,0d2h,0a0h + db 052h,068h,0e2h,036h + db 0cch,00ch,077h,095h + db 0bbh,00bh,047h,003h + db 022h,002h,016h,0b9h + db 055h,005h,026h,02fh + db 0c5h,0bah,03bh,0beh + db 0b2h,0bdh,00bh,028h + db 02bh,0b4h,05ah,092h + db 05ch,0b3h,06ah,004h + db 0c2h,0d7h,0ffh,0a7h + db 0b5h,0d0h,0cfh,031h + db 02ch,0d9h,09eh,08bh + db 05bh,0deh,0aeh,01dh + db 09bh,064h,0c2h,0b0h + db 0ech,063h,0f2h,026h + db 075h,06ah,0a3h,09ch + db 002h,06dh,093h,00ah + db 09ch,009h,006h,0a9h + db 0ebh,00eh,036h,03fh + db 072h,007h,067h,085h + db 005h,000h,057h,013h + db 095h,0bfh,04ah,082h + db 0e2h,0b8h,07ah,014h + db 07bh,0b1h,02bh,0aeh + db 00ch,0b6h,01bh,038h + db 092h,0d2h,08eh,09bh + db 0e5h,0d5h,0beh,00dh + db 07ch,0dch,0efh,0b7h + db 00bh,0dbh,0dfh,021h + db 086h,0d3h,0d2h,0d4h + db 0f1h,0d4h,0e2h,042h + db 068h,0ddh,0b3h,0f8h + db 01fh,0dah,083h,06eh + db 081h,0beh,016h,0cdh + db 0f6h,0b9h,026h,05bh + db 06fh,0b0h,077h,0e1h + db 018h,0b7h,047h,077h + db 088h,008h,05ah,0e6h + db 0ffh,00fh,06ah,070h + db 066h,006h,03bh,0cah + db 011h,001h,00bh,05ch + db 08fh,065h,09eh,0ffh + db 0f8h,062h,0aeh,069h + db 061h,06bh,0ffh,0d3h + db 016h,06ch,0cfh,045h + db 0a0h,00ah,0e2h,078h + db 0d7h,00dh,0d2h,0eeh + db 04eh,004h,083h,054h + db 039h,003h,0b3h,0c2h + db 0a7h,067h,026h,061h + db 0d0h,060h,016h,0f7h + db 049h,069h,047h,04dh + db 03eh,06eh,077h,0dbh + db 0aeh,0d1h,06ah,04ah + db 0d9h,0d6h,05ah,0dch + db 040h,0dfh,00bh,066h + db 037h,0d8h,03bh,0f0h + db 0a9h,0bch,0aeh,053h + db 0deh,0bbh,09eh,0c5h + db 047h,0b2h,0cfh,07fh + db 030h,0b5h,0ffh,0e9h + db 0bdh,0bdh,0f2h,01ch + db 0cah,0bah,0c2h,08ah + db 053h,0b3h,093h,030h + db 024h,0b4h,0a3h,0a6h + db 0bah,0d0h,036h,005h + db 0cdh,0d7h,006h,093h + db 054h,0deh,057h,029h + db 023h,0d9h,067h,0bfh + db 0b3h,066h,07ah,02eh + db 0c4h,061h,04ah,0b8h + db 05dh,068h,01bh,002h + db 02ah,06fh,02bh,094h + db 0b4h,00bh,0beh,037h + db 0c3h,00ch,08eh,0a1h + db 05ah,005h,0dfh,01bh + db 02dh,002h,0efh,08dh + + end diff --git a/Intel8080/Intel8080.Test/roms/8080EXER.PNG b/Intel8080/Intel8080.Test/roms/8080EXER.PNG new file mode 100644 index 0000000000000000000000000000000000000000..e47bcd3cb5c815e0e30e4b4106624492e43796d1 GIT binary patch literal 56703 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 literal 0 HcmV?d00001 diff --git a/Intel8080/Intel8080.Test/roms/8080EXER.PRN b/Intel8080/Intel8080.Test/roms/8080EXER.PRN new file mode 100644 index 0000000..e8d223f --- /dev/null +++ b/Intel8080/Intel8080.Test/roms/8080EXER.PRN @@ -0,0 +1,2239 @@ + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1 + + + title 'Z80 instruction set exerciser' + + ; zexlax.z80 - Z80 instruction set exerciser + ; Copyright (C) 1994 Frank D. Cringle + ; + ; This program is free software; you can redistribute it and/or + ; modify it under the terms of the GNU General Public License + ; as published by the Free Software Foundation; either version 2 + ; of the License, or (at your option) any later version. + ; + ; This program is distributed in the hope that it will be useful, + ; but WITHOUT ANY WARRANTY; without even the implied warranty of + ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ; GNU General Public License for more details. + ; + ; You should have received a copy of the GNU General Public License + ; along with this program; if not, write to the Free Software + ; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ; + ;****************************************************************************** + ; + ; Modified to exercise an 8080 by Ian Bartholomew, February 2009 + ; + ; I have made the following changes - + ; + ; Converted all mnemonics to 8080 and rewritten any Z80 code used + ; in the original exerciser. Changes are tagged with a #idb in the + ; source code listing. + ; + ; Removed any test descriptors that are not used. + ; + ; Changed the macro definitions to work in M80 + ; + ; The machine state snapshot has been changed to remove the IX/IY registers. + ; They have been replaced by two more copies of HL to obviate the need + ; for major changes in the exerciser code. + ; + ; Changed flag mask in all tests to 0ffh to reflect that the 8080, unlike the 8085 + ; and Z80, does define the unused bits in the flag register - [S Z 0 AC 0 P 1 C] + ; + ;****************************************************************************** + + .8080 + 0000' aseg + org 100h + + 0100 C3 0113 begin: jmp start + + ; machine state before test (needs to be at predictably constant address) + 0103 msbt: ds 14 + 0111 spbt: ds 2 + + ; For the purposes of this test program, the machine state consists of: + ; a 2 byte memory operand, followed by + ; the registers iy,ix,hl,de,bc,af,sp + ; for a total of 16 bytes. + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-1 + + + + ; The program tests instructions (or groups of similar instructions) + ; by cycling through a sequence of machine states, executing the test + ; instruction for each one and running a 32-bit crc over the resulting + ; machine states. At the end of the sequence the crc is compared to + ; an expected value that was found empirically on a real Z80. + + ; A test case is defined by a descriptor which consists of: + ; a flag mask byte, + ; the base case, + ; the incement vector, + ; the shift vector, + ; the expected crc, + ; a short descriptive message. + ; + ; The flag mask byte is used to prevent undefined flag bits from + ; influencing the results. Documented flags are as per Mostek Z80 + ; Technical Manual. + ; + ; The next three parts of the descriptor are 20 byte vectors + ; corresponding to a 4 byte instruction and a 16 byte machine state. + ; The first part is the base case, which is the first test case of + ; the sequence. This base is then modified according to the next 2 + ; vectors. Each 1 bit in the increment vector specifies a bit to be + ; cycled in the form of a binary counter. For instance, if the byte + ; corresponding to the accumulator is set to 0ffh in the increment + ; vector, the test will be repeated for all 256 values of the + ; accumulator. Note that 1 bits don't have to be contiguous. The + ; number of test cases 'caused' by the increment vector is equal to + ; 2^(number of 1 bits). The shift vector is similar, but specifies a + ; set of bits in the test case that are to be successively inverted. + ; Thus the shift vector 'causes' a number of test cases equal to the + ; number of 1 bits in it. + + ; The total number of test cases is the product of those caused by the + ; counter and shift vectors and can easily become unweildy. Each + ; individual test case can take a few milliseconds to execute, due to + ; the overhead of test setup and crc calculation, so test design is a + ; compromise between coverage and execution time. + + ; This program is designed to detect differences between + ; implementations and is not ideal for diagnosing the causes of any + ; discrepancies. However, provided a reference implementation (or + ; real system) is available, a failing test case can be isolated by + ; hand using a binary search of the test space. + + + 0113 2A 0006 start: lhld 6 + 0116 F9 sphl + 0117 11 0DF6 lxi d,msg1 + 011A 0E 09 mvi c,9 + 011C CD 0DEA call bdos + + 011F 21 013A lxi h,tests ; first test case + 0122 7E loop: mov a,m ; end of list ? + 0123 23 inx h + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-2 + + + 0124 B6 ora m + 0125 CA 012F jz done + 0128 2B dcx h + 0129 CD 0ACE call stt + 012C C3 0122 jmp loop + + 012F 11 0E13 done: lxi d,msg2 + 0132 0E 09 mvi c,9 + 0134 CD 0DEA call bdos + 0137 C3 0000 jmp 0 ; warm boot + + 013A tests: + 013A 016E dw add16 + 013C 01CE dw alu8i + 013E 022E dw alu8r + 0140 028E dw daa + 0142 02EE dw inca + 0144 034E dw incb + 0146 03AE dw incbc + 0148 040E dw incc + 014A 046E dw incd + 014C 04CE dw incde + 014E 052E dw ince + 0150 058E dw inch + 0152 05EE dw inchl + 0154 064E dw incl + 0156 06AE dw incm + 0158 070E dw incsp + 015A 076E dw ld162 + 015C 07CE dw ld166 + 015E 082E dw ld16im + 0160 088E dw ld8bd + 0162 08EE dw ld8im + 0164 094E dw ld8rr + 0166 09AE dw lda + 0168 0A0E dw rot8080 + 016A 0A6E dw stabd + 016C 0000 dw 0 + + tstr macro insn,memop,hliy,hlix,hl,de,bc,flags,acc,sp + local lab + lab: db insn + ds lab+4-$,0 + dw memop,hliy,hlix,hl,de,bc + db flags + db acc + dw sp + if $-lab ne 20 + error 'missing parameter' + endif + endm + + tmsg macro m + local lab + lab: db m + if $ ge lab+30 + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-3 + + + error 'message too long' + else + ds lab+30-$,'.' + endif + db '$' + endm + + ; add hl, (19,456 cycles) + 016E FF add16: db 0ffh ; flag mask + tstr 9,0c4a5h,0c4c7h,0d226h,0a050h,058eah,08566h,0c6h,0deh,09bc9h + 016F 09 + ..0000: db 9 + 0170 + ds ..0000+4-$,0 + 0173 C4A5 C4C7 + dw 0c4a5h,0c4c7h,0d226h,0a050h,058eah,08566h + 0177 D226 A050 + + 017B 58EA 8566 + + 017F C6 + db 0c6h + 0180 DE + db 0deh + 0181 9BC9 + dw 09bc9h + tstr 030h,0,0,0,0f821h,0,0,0,0,0 ; (512 cycles) + 0183 30 + ..0001: db 030h + 0184 + ds ..0001+4-$,0 + 0187 0000 0000 + dw 0,0,0,0f821h,0,0 + 018B 0000 F821 + + 018F 0000 0000 + + 0193 00 + db 0 + 0194 00 + db 0 + 0195 0000 + dw 0 + tstr 0,0,0,0,-1,-1,-1,0d7h,0,-1 ; (38 cycles) + 0197 00 + ..0002: db 0 + 0198 + ds ..0002+4-$,0 + 019B 0000 0000 + dw 0,0,0,-1,-1,-1 + 019F 0000 FFFF + + 01A3 FFFF FFFF + + 01A7 D7 + db 0d7h + 01A8 00 + db 0 + 01A9 FFFF + dw -1 + 01AB 14 47 4B A6 db 014h, 047h, 04Bh, 0A6h ; expected crc + tmsg 'dad ' + 01AF 64 61 64 20 + ..0003: db 'dad ' + 01B3 3C 62 2C 64 + + 01B7 2C 68 2C 73 + + 01BB 70 3E + + 01BD + ds ..0003+30-$,'.' + 01CD 24 + db '$' + + ; aluop a,nn (28,672 cycles) + 01CE FF alu8i: db 0ffh ; flag mask + tstr 0c6h,09140h,07e3ch,07a67h,0df6dh,05b61h,00b29h,010h,066h,085b2h + 01CF C6 + ..0004: db 0c6h + 01D0 + ds ..0004+4-$,0 + 01D3 9140 7E3C + dw 09140h,07e3ch,07a67h,0df6dh,05b61h,00b29h + 01D7 7A67 DF6D + + 01DB 5B61 0B29 + + 01DF 10 + db 010h + 01E0 66 + db 066h + 01E1 85B2 + dw 085b2h + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-4 + + + tstr 038h,0,0,0,0,0,0,0,-1,0 ; (2048 cycles) + 01E3 38 + ..0005: db 038h + 01E4 + ds ..0005+4-$,0 + 01E7 0000 0000 + dw 0,0,0,0,0,0 + 01EB 0000 0000 + + 01EF 0000 0000 + + 01F3 00 + db 0 + 01F4 FF + db -1 + 01F5 0000 + dw 0 + tstr <0,-1>,0,0,0,0,0,0,0d7h,0,0 ; (14 cycles) + 01F7 00 FF + ..0006: db 0,-1 + 01F9 + ds ..0006+4-$,0 + 01FB 0000 0000 + dw 0,0,0,0,0,0 + 01FF 0000 0000 + + 0203 0000 0000 + + 0207 D7 + db 0d7h + 0208 00 + db 0 + 0209 0000 + dw 0 + 020B 9E 92 2F 9E db 09Eh, 092h, 02Fh, 09Eh ; expected crc + tmsg 'aluop nn' + 020F 61 6C 75 6F + ..0007: db 'aluop nn' + 0213 70 20 6E 6E + + 0217 + ds ..0007+30-$,'.' + 022D 24 + db '$' + + ; aluop a, (753,664 cycles) + 022E FF alu8r: db 0ffh ; flag mask + tstr 080h,0c53eh,0573ah,04c4dh,msbt,0e309h,0a666h,0d0h,03bh,0adbbh + 022F 80 + ..0008: db 080h + 0230 + ds ..0008+4-$,0 + 0233 C53E 573A + dw 0c53eh,0573ah,04c4dh,msbt,0e309h,0a666h + 0237 4C4D 0103 + + 023B E309 A666 + + 023F D0 + db 0d0h + 0240 3B + db 03bh + 0241 ADBB + dw 0adbbh + tstr 03fh,0,0,0,0,0,0,0,-1,0 ; (16,384 cycles) + 0243 3F + ..0009: db 03fh + 0244 + ds ..0009+4-$,0 + 0247 0000 0000 + dw 0,0,0,0,0,0 + 024B 0000 0000 + + 024F 0000 0000 + + 0253 00 + db 0 + 0254 FF + db -1 + 0255 0000 + dw 0 + tstr 0,0ffh,0,0,0,-1,-1,0d7h,0,0 ; (46 cycles) + 0257 00 + ..000A: db 0 + 0258 + ds ..000A+4-$,0 + 025B 00FF 0000 + dw 0ffh,0,0,0,-1,-1 + 025F 0000 0000 + + 0263 FFFF FFFF + + 0267 D7 + db 0d7h + 0268 00 + db 0 + 0269 0000 + dw 0 + 026B CF 76 2C 86 db 0CFh, 076h, 02Ch, 086h ; expected crc + tmsg 'aluop ' + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-5 + + + 026F 61 6C 75 6F + ..000B: db 'aluop ' + 0273 70 20 3C 62 + + 0277 2C 63 2C 64 + + 027B 2C 65 2C 68 + + 027F 2C 6C 2C 6D + + 0283 2C 61 3E + + 0286 + ds ..000B+30-$,'.' + 028D 24 + db '$' + + ; + 028E FF daa: db 0ffh ; flag mask + tstr 027h,02141h,009fah,01d60h,0a559h,08d5bh,09079h,004h,08eh,0299dh + 028F 27 + ..000C: db 027h + 0290 + ds ..000C+4-$,0 + 0293 2141 09FA + dw 02141h,009fah,01d60h,0a559h,08d5bh,09079h + 0297 1D60 A559 + + 029B 8D5B 9079 + + 029F 04 + db 004h + 02A0 8E + db 08eh + 02A1 299D + dw 0299dh + tstr 018h,0,0,0,0,0,0,0d7h,-1,0 ; (65,536 cycles) + 02A3 18 + ..000D: db 018h + 02A4 + ds ..000D+4-$,0 + 02A7 0000 0000 + dw 0,0,0,0,0,0 + 02AB 0000 0000 + + 02AF 0000 0000 + + 02B3 D7 + db 0d7h + 02B4 FF + db -1 + 02B5 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) + 02B7 00 + ..000E: db 0 + 02B8 + ds ..000E+4-$,0 + 02BB 0000 0000 + dw 0,0,0,0,0,0 + 02BF 0000 0000 + + 02C3 0000 0000 + + 02C7 00 + db 0 + 02C8 00 + db 0 + 02C9 0000 + dw 0 + 02CB BB 3F 03 0C db 0BBh, 03Fh, 003h, 00Ch ; expected crc + tmsg '' + 02CF 3C 64 61 61 + ..000F: db '' + 02D3 2C 63 6D 61 + + 02D7 2C 73 74 63 + + 02DB 2C 63 6D 63 + + 02DF 3E + + 02E0 + ds ..000F+30-$,'.' + 02ED 24 + db '$' + + ; a (3072 cycles) + 02EE FF inca: db 0ffh ; flag mask + tstr 03ch,04adfh,0d5d8h,0e598h,08a2bh,0a7b0h,0431bh,044h,05ah,0d030h + 02EF 3C + ..0010: db 03ch + 02F0 + ds ..0010+4-$,0 + 02F3 4ADF D5D8 + dw 04adfh,0d5d8h,0e598h,08a2bh,0a7b0h,0431bh + 02F7 E598 8A2B + + 02FB A7B0 431B + + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-6 + + + 02FF 44 + db 044h + 0300 5A + db 05ah + 0301 D030 + dw 0d030h + tstr 001h,0,0,0,0,0,0,0,-1,0 ; (512 cycles) + 0303 01 + ..0011: db 001h + 0304 + ds ..0011+4-$,0 + 0307 0000 0000 + dw 0,0,0,0,0,0 + 030B 0000 0000 + + 030F 0000 0000 + + 0313 00 + db 0 + 0314 FF + db -1 + 0315 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + 0317 00 + ..0012: db 0 + 0318 + ds ..0012+4-$,0 + 031B 0000 0000 + dw 0,0,0,0,0,0 + 031F 0000 0000 + + 0323 0000 0000 + + 0327 D7 + db 0d7h + 0328 00 + db 0 + 0329 0000 + dw 0 + 032B AD B6 46 0E db 0ADh, 0B6h, 046h, 00Eh ; expected crc + tmsg ' a' + 032F 3C 69 6E 72 + ..0013: db ' a' + 0333 2C 64 63 72 + + 0337 3E 20 61 + + 033A + ds ..0013+30-$,'.' + 034D 24 + db '$' + + ; b (3072 cycles) + 034E FF incb: db 0ffh ; flag mask + tstr 004h,0d623h,0432dh,07a61h,08180h,05a86h,01e85h,086h,058h,09bbbh + 034F 04 + ..0014: db 004h + 0350 + ds ..0014+4-$,0 + 0353 D623 432D + dw 0d623h,0432dh,07a61h,08180h,05a86h,01e85h + 0357 7A61 8180 + + 035B 5A86 1E85 + + 035F 86 + db 086h + 0360 58 + db 058h + 0361 9BBB + dw 09bbbh + tstr 001h,0,0,0,0,0,0ff00h,0,0,0 ; (512 cycles) + 0363 01 + ..0015: db 001h + 0364 + ds ..0015+4-$,0 + 0367 0000 0000 + dw 0,0,0,0,0,0ff00h + 036B 0000 0000 + + 036F 0000 FF00 + + 0373 00 + db 0 + 0374 00 + db 0 + 0375 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + 0377 00 + ..0016: db 0 + 0378 + ds ..0016+4-$,0 + 037B 0000 0000 + dw 0,0,0,0,0,0 + 037F 0000 0000 + + 0383 0000 0000 + + 0387 D7 + db 0d7h + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-7 + + + 0388 00 + db 0 + 0389 0000 + dw 0 + 038B 83 ED 13 45 db 083h, 0EDh, 013h, 045h ; expected crc + tmsg ' b' + 038F 3C 69 6E 72 + ..0017: db ' b' + 0393 2C 64 63 72 + + 0397 3E 20 62 + + 039A + ds ..0017+30-$,'.' + 03AD 24 + db '$' + + ; bc (1536 cycles) + 03AE FF incbc: db 0ffh ; flag mask + tstr 003h,0cd97h,044abh,08dc9h,0e3e3h,011cch,0e8a4h,002h,049h,02a4dh + 03AF 03 + ..0018: db 003h + 03B0 + ds ..0018+4-$,0 + 03B3 CD97 44AB + dw 0cd97h,044abh,08dc9h,0e3e3h,011cch,0e8a4h + 03B7 8DC9 E3E3 + + 03BB 11CC E8A4 + + 03BF 02 + db 002h + 03C0 49 + db 049h + 03C1 2A4D + dw 02a4dh + tstr 008h,0,0,0,0,0,0f821h,0,0,0 ; (256 cycles) + 03C3 08 + ..0019: db 008h + 03C4 + ds ..0019+4-$,0 + 03C7 0000 0000 + dw 0,0,0,0,0,0f821h + 03CB 0000 0000 + + 03CF 0000 F821 + + 03D3 00 + db 0 + 03D4 00 + db 0 + 03D5 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + 03D7 00 + ..001A: db 0 + 03D8 + ds ..001A+4-$,0 + 03DB 0000 0000 + dw 0,0,0,0,0,0 + 03DF 0000 0000 + + 03E3 0000 0000 + + 03E7 D7 + db 0d7h + 03E8 00 + db 0 + 03E9 0000 + dw 0 + 03EB F7 92 87 CD db 0F7h, 092h, 087h, 0CDh ; expected crc + tmsg ' b' + 03EF 3C 69 6E 78 + ..001B: db ' b' + 03F3 2C 64 63 78 + + 03F7 3E 20 62 + + 03FA + ds ..001B+30-$,'.' + 040D 24 + db '$' + + ; c (3072 cycles) + 040E FF incc: db 0ffh ; flag mask + tstr 00ch,0d789h,00935h,0055bh,09f85h,08b27h,0d208h,095h,005h,00660h + 040F 0C + ..001C: db 00ch + 0410 + ds ..001C+4-$,0 + 0413 D789 0935 + dw 0d789h,00935h,0055bh,09f85h,08b27h,0d208h + 0417 055B 9F85 + + 041B 8B27 D208 + + 041F 95 + db 095h + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-8 + + + 0420 05 + db 005h + 0421 0660 + dw 00660h + tstr 001h,0,0,0,0,0,0ffh,0,0,0 ; (512 cycles) + 0423 01 + ..001D: db 001h + 0424 + ds ..001D+4-$,0 + 0427 0000 0000 + dw 0,0,0,0,0,0ffh + 042B 0000 0000 + + 042F 0000 00FF + + 0433 00 + db 0 + 0434 00 + db 0 + 0435 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + 0437 00 + ..001E: db 0 + 0438 + ds ..001E+4-$,0 + 043B 0000 0000 + dw 0,0,0,0,0,0 + 043F 0000 0000 + + 0443 0000 0000 + + 0447 D7 + db 0d7h + 0448 00 + db 0 + 0449 0000 + dw 0 + 044B E5 F6 72 1B db 0E5h, 0F6h, 072h, 01Bh ; expected crc + tmsg ' c' + 044F 3C 69 6E 72 + ..001F: db ' c' + 0453 2C 64 63 72 + + 0457 3E 20 63 + + 045A + ds ..001F+30-$,'.' + 046D 24 + db '$' + + ; d (3072 cycles) + 046E FF incd: db 0ffh ; flag mask + tstr 014h,0a0eah,05fbah,065fbh,0981ch,038cch,0debch,043h,05ch,003bdh + 046F 14 + ..0020: db 014h + 0470 + ds ..0020+4-$,0 + 0473 A0EA 5FBA + dw 0a0eah,05fbah,065fbh,0981ch,038cch,0debch + 0477 65FB 981C + + 047B 38CC DEBC + + 047F 43 + db 043h + 0480 5C + db 05ch + 0481 03BD + dw 003bdh + tstr 001h,0,0,0,0,0ff00h,0,0,0,0 ; (512 cycles) + 0483 01 + ..0021: db 001h + 0484 + ds ..0021+4-$,0 + 0487 0000 0000 + dw 0,0,0,0,0ff00h,0 + 048B 0000 0000 + + 048F FF00 0000 + + 0493 00 + db 0 + 0494 00 + db 0 + 0495 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + 0497 00 + ..0022: db 0 + 0498 + ds ..0022+4-$,0 + 049B 0000 0000 + dw 0,0,0,0,0,0 + 049F 0000 0000 + + 04A3 0000 0000 + + 04A7 D7 + db 0d7h + 04A8 00 + db 0 + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-9 + + + 04A9 0000 + dw 0 + 04AB 15 B5 57 9A db 015h, 0B5h, 057h, 09Ah ; expected crc + tmsg ' d' + 04AF 3C 69 6E 72 + ..0023: db ' d' + 04B3 2C 64 63 72 + + 04B7 3E 20 64 + + 04BA + ds ..0023+30-$,'.' + 04CD 24 + db '$' + + ; de (1536 cycles) + 04CE FF incde: db 0ffh ; flag mask + tstr 013h,0342eh,0131dh,028c9h,00acah,09967h,03a2eh,092h,0f6h,09d54h + 04CF 13 + ..0024: db 013h + 04D0 + ds ..0024+4-$,0 + 04D3 342E 131D + dw 0342eh,0131dh,028c9h,00acah,09967h,03a2eh + 04D7 28C9 0ACA + + 04DB 9967 3A2E + + 04DF 92 + db 092h + 04E0 F6 + db 0f6h + 04E1 9D54 + dw 09d54h + tstr 008h,0,0,0,0,0f821h,0,0,0,0 ; (256 cycles) + 04E3 08 + ..0025: db 008h + 04E4 + ds ..0025+4-$,0 + 04E7 0000 0000 + dw 0,0,0,0,0f821h,0 + 04EB 0000 0000 + + 04EF F821 0000 + + 04F3 00 + db 0 + 04F4 00 + db 0 + 04F5 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + 04F7 00 + ..0026: db 0 + 04F8 + ds ..0026+4-$,0 + 04FB 0000 0000 + dw 0,0,0,0,0,0 + 04FF 0000 0000 + + 0503 0000 0000 + + 0507 D7 + db 0d7h + 0508 00 + db 0 + 0509 0000 + dw 0 + 050B 7F 4E 25 01 db 07Fh, 04Eh, 025h, 001h ; expected crc + tmsg ' d' + 050F 3C 69 6E 78 + ..0027: db ' d' + 0513 2C 64 63 78 + + 0517 3E 20 64 + + 051A + ds ..0027+30-$,'.' + 052D 24 + db '$' + + ; e (3072 cycles) + 052E FF ince: db 0ffh ; flag mask + tstr 01ch,0602fh,04c0dh,02402h,0e2f5h,0a0f4h,0a10ah,013h,032h,05925h + 052F 1C + ..0028: db 01ch + 0530 + ds ..0028+4-$,0 + 0533 602F 4C0D + dw 0602fh,04c0dh,02402h,0e2f5h,0a0f4h,0a10ah + 0537 2402 E2F5 + + 053B A0F4 A10A + + 053F 13 + db 013h + 0540 32 + db 032h + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-10 + + + 0541 5925 + dw 05925h + tstr 001h,0,0,0,0,0ffh,0,0,0,0 ; (512 cycles) + 0543 01 + ..0029: db 001h + 0544 + ds ..0029+4-$,0 + 0547 0000 0000 + dw 0,0,0,0,0ffh,0 + 054B 0000 0000 + + 054F 00FF 0000 + + 0553 00 + db 0 + 0554 00 + db 0 + 0555 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + 0557 00 + ..002A: db 0 + 0558 + ds ..002A+4-$,0 + 055B 0000 0000 + dw 0,0,0,0,0,0 + 055F 0000 0000 + + 0563 0000 0000 + + 0567 D7 + db 0d7h + 0568 00 + db 0 + 0569 0000 + dw 0 + 056B CF 2A B3 96 db 0CFh, 02Ah, 0B3h, 096h ; expected crc + tmsg ' e' + 056F 3C 69 6E 72 + ..002B: db ' e' + 0573 2C 64 63 72 + + 0577 3E 20 65 + + 057A + ds ..002B+30-$,'.' + 058D 24 + db '$' + + ; h (3072 cycles) + 058E FF inch: db 0ffh ; flag mask + tstr 024h,01506h,0f2ebh,0e8ddh,0262bh,011a6h,0bc1ah,017h,006h,02818h + 058F 24 + ..002C: db 024h + 0590 + ds ..002C+4-$,0 + 0593 1506 F2EB + dw 01506h,0f2ebh,0e8ddh,0262bh,011a6h,0bc1ah + 0597 E8DD 262B + + 059B 11A6 BC1A + + 059F 17 + db 017h + 05A0 06 + db 006h + 05A1 2818 + dw 02818h + tstr 001h,0,0,0,0ff00h,0,0,0,0,0 ; (512 cycles) + 05A3 01 + ..002D: db 001h + 05A4 + ds ..002D+4-$,0 + 05A7 0000 0000 + dw 0,0,0,0ff00h,0,0 + 05AB 0000 FF00 + + 05AF 0000 0000 + + 05B3 00 + db 0 + 05B4 00 + db 0 + 05B5 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + 05B7 00 + ..002E: db 0 + 05B8 + ds ..002E+4-$,0 + 05BB 0000 0000 + dw 0,0,0,0,0,0 + 05BF 0000 0000 + + 05C3 0000 0000 + + 05C7 D7 + db 0d7h + 05C8 00 + db 0 + 05C9 0000 + dw 0 + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-11 + + + 05CB 12 B2 95 2C db 012h, 0B2h, 095h, 02Ch ; expected crc + tmsg ' h' + 05CF 3C 69 6E 72 + ..002F: db ' h' + 05D3 2C 64 63 72 + + 05D7 3E 20 68 + + 05DA + ds ..002F+30-$,'.' + 05ED 24 + db '$' + + ; hl (1536 cycles) + 05EE FF inchl: db 0ffh ; flag mask + tstr 023h,0c3f4h,007a5h,01b6dh,04f04h,0e2c2h,0822ah,057h,0e0h,0c3e1h + 05EF 23 + ..0030: db 023h + 05F0 + ds ..0030+4-$,0 + 05F3 C3F4 07A5 + dw 0c3f4h,007a5h,01b6dh,04f04h,0e2c2h,0822ah + 05F7 1B6D 4F04 + + 05FB E2C2 822A + + 05FF 57 + db 057h + 0600 E0 + db 0e0h + 0601 C3E1 + dw 0c3e1h + tstr 008h,0,0,0,0f821h,0,0,0,0,0 ; (256 cycles) + 0603 08 + ..0031: db 008h + 0604 + ds ..0031+4-$,0 + 0607 0000 0000 + dw 0,0,0,0f821h,0,0 + 060B 0000 F821 + + 060F 0000 0000 + + 0613 00 + db 0 + 0614 00 + db 0 + 0615 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + 0617 00 + ..0032: db 0 + 0618 + ds ..0032+4-$,0 + 061B 0000 0000 + dw 0,0,0,0,0,0 + 061F 0000 0000 + + 0623 0000 0000 + + 0627 D7 + db 0d7h + 0628 00 + db 0 + 0629 0000 + dw 0 + 062B 9F 2B 23 C0 db 09Fh, 02Bh, 023h, 0C0h ; expected crc + tmsg ' h' + 062F 3C 69 6E 78 + ..0033: db ' h' + 0633 2C 64 63 78 + + 0637 3E 20 68 + + 063A + ds ..0033+30-$,'.' + 064D 24 + db '$' + + ; l (3072 cycles) + 064E FF incl: db 0ffh ; flag mask + tstr 02ch,08031h,0a520h,04356h,0b409h,0f4c1h,0dfa2h,0d1h,03ch,03ea2h + 064F 2C + ..0034: db 02ch + 0650 + ds ..0034+4-$,0 + 0653 8031 A520 + dw 08031h,0a520h,04356h,0b409h,0f4c1h,0dfa2h + 0657 4356 B409 + + 065B F4C1 DFA2 + + 065F D1 + db 0d1h + 0660 3C + db 03ch + 0661 3EA2 + dw 03ea2h + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-12 + + + tstr 001h,0,0,0,0ffh,0,0,0,0,0 ; (512 cycles) + 0663 01 + ..0035: db 001h + 0664 + ds ..0035+4-$,0 + 0667 0000 0000 + dw 0,0,0,0ffh,0,0 + 066B 0000 00FF + + 066F 0000 0000 + + 0673 00 + db 0 + 0674 00 + db 0 + 0675 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + 0677 00 + ..0036: db 0 + 0678 + ds ..0036+4-$,0 + 067B 0000 0000 + dw 0,0,0,0,0,0 + 067F 0000 0000 + + 0683 0000 0000 + + 0687 D7 + db 0d7h + 0688 00 + db 0 + 0689 0000 + dw 0 + 068B FF 57 D3 56 db 0FFh, 057h, 0D3h, 056h ; expected crc + tmsg ' l' + 068F 3C 69 6E 72 + ..0037: db ' l' + 0693 2C 64 63 72 + + 0697 3E 20 6C + + 069A + ds ..0037+30-$,'.' + 06AD 24 + db '$' + + ; (hl) (3072 cycles) + 06AE FF incm: db 0ffh ; flag mask + tstr 034h,0b856h,00c7ch,0e53eh,msbt,0877eh,0da58h,015h,05ch,01f37h + 06AF 34 + ..0038: db 034h + 06B0 + ds ..0038+4-$,0 + 06B3 B856 0C7C + dw 0b856h,00c7ch,0e53eh,msbt,0877eh,0da58h + 06B7 E53E 0103 + + 06BB 877E DA58 + + 06BF 15 + db 015h + 06C0 5C + db 05ch + 06C1 1F37 + dw 01f37h + tstr 001h,0ffh,0,0,0,0,0,0,0,0 ; (512 cycles) + 06C3 01 + ..0039: db 001h + 06C4 + ds ..0039+4-$,0 + 06C7 00FF 0000 + dw 0ffh,0,0,0,0,0 + 06CB 0000 0000 + + 06CF 0000 0000 + + 06D3 00 + db 0 + 06D4 00 + db 0 + 06D5 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + 06D7 00 + ..003A: db 0 + 06D8 + ds ..003A+4-$,0 + 06DB 0000 0000 + dw 0,0,0,0,0,0 + 06DF 0000 0000 + + 06E3 0000 0000 + + 06E7 D7 + db 0d7h + 06E8 00 + db 0 + 06E9 0000 + dw 0 + 06EB 92 E9 63 BD db 092h, 0E9h, 063h, 0BDh ; expected crc + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-13 + + + tmsg ' m' + 06EF 3C 69 6E 72 + ..003B: db ' m' + 06F3 2C 64 63 72 + + 06F7 3E 20 6D + + 06FA + ds ..003B+30-$,'.' + 070D 24 + db '$' + + ; sp (1536 cycles) + 070E FF incsp: db 0ffh ; flag mask + tstr 033h,0346fh,0d482h,0d169h,0deb6h,0a494h,0f476h,053h,002h,0855bh + 070F 33 + ..003C: db 033h + 0710 + ds ..003C+4-$,0 + 0713 346F D482 + dw 0346fh,0d482h,0d169h,0deb6h,0a494h,0f476h + 0717 D169 DEB6 + + 071B A494 F476 + + 071F 53 + db 053h + 0720 02 + db 002h + 0721 855B + dw 0855bh + tstr 008h,0,0,0,0,0,0,0,0,0f821h ; (256 cycles) + 0723 08 + ..003D: db 008h + 0724 + ds ..003D+4-$,0 + 0727 0000 0000 + dw 0,0,0,0,0,0 + 072B 0000 0000 + + 072F 0000 0000 + + 0733 00 + db 0 + 0734 00 + db 0 + 0735 F821 + dw 0f821h + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + 0737 00 + ..003E: db 0 + 0738 + ds ..003E+4-$,0 + 073B 0000 0000 + dw 0,0,0,0,0,0 + 073F 0000 0000 + + 0743 0000 0000 + + 0747 D7 + db 0d7h + 0748 00 + db 0 + 0749 0000 + dw 0 + 074B D5 70 2F AB db 0D5h, 070h, 02Fh, 0ABh ; expected crc + tmsg ' sp' + 074F 3C 69 6E 78 + ..003F: db ' sp' + 0753 2C 64 63 78 + + 0757 3E 20 73 70 + + 075B + ds ..003F+30-$,'.' + 076D 24 + db '$' + + ; ld hl,(nnnn) (16 cycles) + 076E FF ld162: db 0ffh ; flag mask + tstr <02ah,low msbt,high msbt>,09863h,07830h,02077h,0b1feh,0b9fah,0abb8h,004h,006h,06015h + 076F 2A 03 01 + ..0040: db 02ah,low msbt,high msbt + 0772 + ds ..0040+4-$,0 + 0773 9863 7830 + dw 09863h,07830h,02077h,0b1feh,0b9fah,0abb8h + 0777 2077 B1FE + + 077B B9FA ABB8 + + 077F 04 + db 004h + 0780 06 + db 006h + 0781 6015 + dw 06015h + tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-14 + + + 0783 00 + ..0041: db 0 + 0784 + ds ..0041+4-$,0 + 0787 0000 0000 + dw 0,0,0,0,0,0 + 078B 0000 0000 + + 078F 0000 0000 + + 0793 00 + db 0 + 0794 00 + db 0 + 0795 0000 + dw 0 + tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) + 0797 00 + ..0042: db 0 + 0798 + ds ..0042+4-$,0 + 079B FFFF 0000 + dw -1,0,0,0,0,0 + 079F 0000 0000 + + 07A3 0000 0000 + + 07A7 00 + db 0 + 07A8 00 + db 0 + 07A9 0000 + dw 0 + 07AB A9 C3 D5 CB db 0A9h, 0C3h, 0D5h, 0CBh ; expected crc + tmsg 'lhld nnnn' + 07AF 6C 68 6C 64 + ..0043: db 'lhld nnnn' + 07B3 20 6E 6E 6E + + 07B7 6E + + 07B8 + ds ..0043+30-$,'.' + 07CD 24 + db '$' + + ; ld (nnnn),hl (16 cycles) + 07CE FF ld166: db 0ffh ; flag mask + tstr <022h,low msbt,high msbt>,0d003h,07772h,07f53h,03f72h,064eah,0e180h,010h,02dh,035e9h + 07CF 22 03 01 + ..0044: db 022h,low msbt,high msbt + 07D2 + ds ..0044+4-$,0 + 07D3 D003 7772 + dw 0d003h,07772h,07f53h,03f72h,064eah,0e180h + 07D7 7F53 3F72 + + 07DB 64EA E180 + + 07DF 10 + db 010h + 07E0 2D + db 02dh + 07E1 35E9 + dw 035e9h + tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) + 07E3 00 + ..0045: db 0 + 07E4 + ds ..0045+4-$,0 + 07E7 0000 0000 + dw 0,0,0,0,0,0 + 07EB 0000 0000 + + 07EF 0000 0000 + + 07F3 00 + db 0 + 07F4 00 + db 0 + 07F5 0000 + dw 0 + tstr 0,0,0,0,-1,0,0,0,0,0 ; (16 cycles) + 07F7 00 + ..0046: db 0 + 07F8 + ds ..0046+4-$,0 + 07FB 0000 0000 + dw 0,0,0,-1,0,0 + 07FF 0000 FFFF + + 0803 0000 0000 + + 0807 00 + db 0 + 0808 00 + db 0 + 0809 0000 + dw 0 + 080B E8 86 4F 26 db 0E8h, 086h, 04Fh, 026h ; expected crc + tmsg 'shld nnnn' + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-15 + + + 080F 73 68 6C 64 + ..0047: db 'shld nnnn' + 0813 20 6E 6E 6E + + 0817 6E + + 0818 + ds ..0047+30-$,'.' + 082D 24 + db '$' + + ; ld ,nnnn (64 cycles) + 082E FF ld16im: db 0ffh ; flag mask + tstr 1,05c1ch,02d46h,08eb9h,06078h,074b1h,0b30eh,046h,0d1h,030cch + 082F 01 + ..0048: db 1 + 0830 + ds ..0048+4-$,0 + 0833 5C1C 2D46 + dw 05c1ch,02d46h,08eb9h,06078h,074b1h,0b30eh + 0837 8EB9 6078 + + 083B 74B1 B30E + + 083F 46 + db 046h + 0840 D1 + db 0d1h + 0841 30CC + dw 030cch + tstr 030h,0,0,0,0,0,0,0,0,0 ; (4 cycles) + 0843 30 + ..0049: db 030h + 0844 + ds ..0049+4-$,0 + 0847 0000 0000 + dw 0,0,0,0,0,0 + 084B 0000 0000 + + 084F 0000 0000 + + 0853 00 + db 0 + 0854 00 + db 0 + 0855 0000 + dw 0 + tstr <0,0ffh,0ffh>,0,0,0,0,0,0,0,0,0 ; (16 cycles) + 0857 00 FF FF + ..004A: db 0,0ffh,0ffh + 085A + ds ..004A+4-$,0 + 085B 0000 0000 + dw 0,0,0,0,0,0 + 085F 0000 0000 + + 0863 0000 0000 + + 0867 00 + db 0 + 0868 00 + db 0 + 0869 0000 + dw 0 + 086B FC F4 6E 12 db 0FCh, 0F4h, 06Eh, 012h ; expected crc + tmsg 'lxi ,nnnn' + 086F 6C 78 69 20 + ..004B: db 'lxi ,nnnn' + 0873 3C 62 2C 64 + + 0877 2C 68 2C 73 + + 087B 70 3E 2C 6E + + 087F 6E 6E 6E + + 0882 + ds ..004B+30-$,'.' + 088D 24 + db '$' + + ; ld a,<(bc),(de)> (44 cycles) + 088E FF ld8bd: db 0ffh ; flag mask + tstr 00ah,0b3a8h,01d2ah,07f8eh,042ach,msbt,msbt,0c6h,0b1h,0ef8eh + 088F 0A + ..004C: db 00ah + 0890 + ds ..004C+4-$,0 + 0893 B3A8 1D2A + dw 0b3a8h,01d2ah,07f8eh,042ach,msbt,msbt + 0897 7F8E 42AC + + 089B 0103 0103 + + 089F C6 + db 0c6h + 08A0 B1 + db 0b1h + 08A1 EF8E + dw 0ef8eh + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-16 + + + tstr 010h,0,0,0,0,0,0,0,0,0 ; (2 cycles) + 08A3 10 + ..004D: db 010h + 08A4 + ds ..004D+4-$,0 + 08A7 0000 0000 + dw 0,0,0,0,0,0 + 08AB 0000 0000 + + 08AF 0000 0000 + + 08B3 00 + db 0 + 08B4 00 + db 0 + 08B5 0000 + dw 0 + tstr 0,0ffh,0,0,0,0,0,0d7h,-1,0 ; (22 cycles) + 08B7 00 + ..004E: db 0 + 08B8 + ds ..004E+4-$,0 + 08BB 00FF 0000 + dw 0ffh,0,0,0,0,0 + 08BF 0000 0000 + + 08C3 0000 0000 + + 08C7 D7 + db 0d7h + 08C8 FF + db -1 + 08C9 0000 + dw 0 + 08CB 2B 82 1D 5F db 02Bh, 082h, 01Dh, 05Fh ; expected crc + tmsg 'ldax ' + 08CF 6C 64 61 78 + ..004F: db 'ldax ' + 08D3 20 3C 62 2C + + 08D7 64 3E + + 08D9 + ds ..004F+30-$,'.' + 08ED 24 + db '$' + + ; ld ,nn (64 cycles) + 08EE FF ld8im: db 0ffh ; flag mask + tstr 6,0c407h,0f49dh,0d13dh,00339h,0de89h,07455h,053h,0c0h,05509h + 08EF 06 + ..0050: db 6 + 08F0 + ds ..0050+4-$,0 + 08F3 C407 F49D + dw 0c407h,0f49dh,0d13dh,00339h,0de89h,07455h + 08F7 D13D 0339 + + 08FB DE89 7455 + + 08FF 53 + db 053h + 0900 C0 + db 0c0h + 0901 5509 + dw 05509h + tstr 038h,0,0,0,0,0,0,0,0,0 ; (8 cycles) + 0903 38 + ..0051: db 038h + 0904 + ds ..0051+4-$,0 + 0907 0000 0000 + dw 0,0,0,0,0,0 + 090B 0000 0000 + + 090F 0000 0000 + + 0913 00 + db 0 + 0914 00 + db 0 + 0915 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0,-1,0 ; (8 cycles) + 0917 00 + ..0052: db 0 + 0918 + ds ..0052+4-$,0 + 091B 0000 0000 + dw 0,0,0,0,0,0 + 091F 0000 0000 + + 0923 0000 0000 + + 0927 00 + db 0 + 0928 FF + db -1 + 0929 0000 + dw 0 + 092B EA A7 20 44 db 0EAh, 0A7h, 020h, 044h ; expected crc + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-17 + + + tmsg 'mvi ,nn' + 092F 6D 76 69 20 + ..0053: db 'mvi ,nn' + 0933 3C 62 2C 63 + + 0937 2C 64 2C 65 + + 093B 2C 68 2C 6C + + 093F 2C 6D 2C 61 + + 0943 3E 2C 6E 6E + + 0947 + ds ..0053+30-$,'.' + 094D 24 + db '$' + + ; ld , (3456 cycles) + 094E FF ld8rr: db 0ffh ; flag mask + tstr 040h,072a4h,0a024h,061ach,msbt,082c7h,0718fh,097h,08fh,0ef8eh + 094F 40 + ..0054: db 040h + 0950 + ds ..0054+4-$,0 + 0953 72A4 A024 + dw 072a4h,0a024h,061ach,msbt,082c7h,0718fh + 0957 61AC 0103 + + 095B 82C7 718F + + 095F 97 + db 097h + 0960 8F + db 08fh + 0961 EF8E + dw 0ef8eh + tstr 03fh,0,0,0,0,0,0,0,0,0 ; (64 cycles) + 0963 3F + ..0055: db 03fh + 0964 + ds ..0055+4-$,0 + 0967 0000 0000 + dw 0,0,0,0,0,0 + 096B 0000 0000 + + 096F 0000 0000 + + 0973 00 + db 0 + 0974 00 + db 0 + 0975 0000 + dw 0 + tstr 0,0ffh,0,0,0,-1,-1,0d7h,-1,0 ; (54 cycles) + 0977 00 + ..0056: db 0 + 0978 + ds ..0056+4-$,0 + 097B 00FF 0000 + dw 0ffh,0,0,0,-1,-1 + 097F 0000 0000 + + 0983 FFFF FFFF + + 0987 D7 + db 0d7h + 0988 FF + db -1 + 0989 0000 + dw 0 + 098B 10 B5 8C EE db 010h, 0B5h, 08Ch, 0EEh ; expected crc + tmsg 'mov ,' + 098F 6D 6F 76 20 + ..0057: db 'mov ,' + 0993 3C 62 63 64 + + 0997 65 68 6C 61 + + 099B 3E 2C 3C 62 + + 099F 63 64 65 68 + + 09A3 6C 61 3E + + 09A6 + ds ..0057+30-$,'.' + 09AD 24 + db '$' + + ; ld a,(nnnn) / ld (nnnn),a (44 cycles) + 09AE FF lda: db 0ffh ; flag mask + tstr <032h,low msbt,high msbt>,0fd68h,0f4ech,044a0h,0b543h,00653h,0cdbah,0d2h,04fh,01fd8h + 09AF 32 03 01 + ..0058: db 032h,low msbt,high msbt + 09B2 + ds ..0058+4-$,0 + 09B3 FD68 F4EC + dw 0fd68h,0f4ech,044a0h,0b543h,00653h,0cdbah + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-18 + + + 09B7 44A0 B543 + + 09BB 0653 CDBA + + 09BF D2 + db 0d2h + 09C0 4F + db 04fh + 09C1 1FD8 + dw 01fd8h + tstr 008h,0,0,0,0,0,0,0,0,0 ; (2 cycle) + 09C3 08 + ..0059: db 008h + 09C4 + ds ..0059+4-$,0 + 09C7 0000 0000 + dw 0,0,0,0,0,0 + 09CB 0000 0000 + + 09CF 0000 0000 + + 09D3 00 + db 0 + 09D4 00 + db 0 + 09D5 0000 + dw 0 + tstr 0,0ffh,0,0,0,0,0,0d7h,-1,0 ; (22 cycles) + 09D7 00 + ..005A: db 0 + 09D8 + ds ..005A+4-$,0 + 09DB 00FF 0000 + dw 0ffh,0,0,0,0,0 + 09DF 0000 0000 + + 09E3 0000 0000 + + 09E7 D7 + db 0d7h + 09E8 FF + db -1 + 09E9 0000 + dw 0 + 09EB ED 57 AF 72 db 0EDh, 057h, 0AFh, 072h ; expected crc + tmsg 'sta nnnn / lda nnnn' + 09EF 73 74 61 20 + ..005B: db 'sta nnnn / lda nnnn' + 09F3 6E 6E 6E 6E + + 09F7 20 2F 20 6C + + 09FB 64 61 20 6E + + 09FF 6E 6E 6E + + 0A02 + ds ..005B+30-$,'.' + 0A0D 24 + db '$' + + ; (6144 cycles) + 0A0E FF rot8080: db 0ffh ; flag mask + tstr 7,0cb92h,06d43h,00a90h,0c284h,00c53h,0f50eh,091h,0ebh,040fch + 0A0F 07 + ..005C: db 7 + 0A10 + ds ..005C+4-$,0 + 0A13 CB92 6D43 + dw 0cb92h,06d43h,00a90h,0c284h,00c53h,0f50eh + 0A17 0A90 C284 + + 0A1B 0C53 F50E + + 0A1F 91 + db 091h + 0A20 EB + db 0ebh + 0A21 40FC + dw 040fch + tstr 018h,0,0,0,0,0,0,0,-1,0 ; (1024 cycles) + 0A23 18 + ..005D: db 018h + 0A24 + ds ..005D+4-$,0 + 0A27 0000 0000 + dw 0,0,0,0,0,0 + 0A2B 0000 0000 + + 0A2F 0000 0000 + + 0A33 00 + db 0 + 0A34 FF + db -1 + 0A35 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + 0A37 00 + ..005E: db 0 + 0A38 + ds ..005E+4-$,0 + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-19 + + + 0A3B 0000 0000 + dw 0,0,0,0,0,0 + 0A3F 0000 0000 + + 0A43 0000 0000 + + 0A47 D7 + db 0d7h + 0A48 00 + db 0 + 0A49 0000 + dw 0 + 0A4B E0 D8 92 35 db 0E0h, 0D8h, 092h, 035h ; expected crc + tmsg '' + 0A4F 3C 72 6C 63 + ..005F: db '' + 0A53 2C 72 72 63 + + 0A57 2C 72 61 6C + + 0A5B 2C 72 61 72 + + 0A5F 3E + + 0A60 + ds ..005F+30-$,'.' + 0A6D 24 + db '$' + + ; ld (),a (96 cycles) + 0A6E FF stabd: db 0ffh ; flag mask + tstr 2,00c3bh,0b592h,06cffh,0959eh,msbt,msbt+1,0c1h,021h,0bde7h + 0A6F 02 + ..0060: db 2 + 0A70 + ds ..0060+4-$,0 + 0A73 0C3B B592 + dw 00c3bh,0b592h,06cffh,0959eh,msbt,msbt+1 + 0A77 6CFF 959E + + 0A7B 0103 0104 + + 0A7F C1 + db 0c1h + 0A80 21 + db 021h + 0A81 BDE7 + dw 0bde7h + tstr 018h,0,0,0,0,0,0,0,0,0 ; (4 cycles) + 0A83 18 + ..0061: db 018h + 0A84 + ds ..0061+4-$,0 + 0A87 0000 0000 + dw 0,0,0,0,0,0 + 0A8B 0000 0000 + + 0A8F 0000 0000 + + 0A93 00 + db 0 + 0A94 00 + db 0 + 0A95 0000 + dw 0 + tstr 0,-1,0,0,0,0,0,0,-1,0 ; (24 cycles) + 0A97 00 + ..0062: db 0 + 0A98 + ds ..0062+4-$,0 + 0A9B FFFF 0000 + dw -1,0,0,0,0,0 + 0A9F 0000 0000 + + 0AA3 0000 0000 + + 0AA7 00 + db 0 + 0AA8 FF + db -1 + 0AA9 0000 + dw 0 + 0AAB 2B 04 71 E9 db 02Bh, 004h, 071h, 0E9h ; expected crc + tmsg 'stax ' + 0AAF 73 74 61 78 + ..0063: db 'stax ' + 0AB3 20 3C 62 2C + + 0AB7 64 3E + + 0AB9 + ds ..0063+30-$,'.' + 0ACD 24 + db '$' + + ; start test pointed to by (hl) + 0ACE E5 stt: push h + 0ACF 7E mov a,m ; get pointer to test + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-20 + + + 0AD0 23 inx h + 0AD1 66 mov h,m + 0AD2 6F mov l,a + 0AD3 7E mov a,m ; flag mask + 0AD4 32 0D7F sta flgmsk+1 + 0AD7 23 inx h + 0AD8 E5 push h + 0AD9 11 0014 lxi d,20 + 0ADC 19 dad d ; point to incmask + 0ADD 11 0CDE lxi d,counter + 0AE0 CD 0C4D call initmask + 0AE3 E1 pop h + 0AE4 E5 push h + 0AE5 11 0028 lxi d,20+20 + 0AE8 19 dad d ; point to scanmask + 0AE9 11 0D06 lxi d,shifter + 0AEC CD 0C4D call initmask + 0AEF 21 0D06 lxi h,shifter + 0AF2 36 01 mvi m,1 ; first bit + 0AF4 E1 pop h + 0AF5 E5 push h + 0AF6 11 0D4D lxi d,iut ; copy initial instruction under test + 0AF9 01 0004 lxi b,4 + + ;#idb ldir replaced with following code + 0AFC 7E ldir1: mov a,m + 0AFD 12 stax d + 0AFE 23 inx h + 0AFF 13 inx d + 0B00 0B dcx b + 0B01 78 mov a,b + 0B02 B1 ora c + 0B03 C2 0AFC jnz ldir1 + ;#idb + + 0B06 11 0103 lxi d,msbt ; copy initial machine state + 0B09 01 0010 lxi b,16 + + ;#idb ldir replaced with following code + 0B0C 7E ldir2: mov a,m + 0B0D 12 stax d + 0B0E 23 inx h + 0B0F 13 inx d + 0B10 0B dcx b + 0B11 78 mov a,b + 0B12 B1 ora c + 0B13 C2 0B0C jnz ldir2 + ;#idb + + 0B16 11 002C lxi d,20+20+4 ; skip incmask, scanmask and expcrc + 0B19 19 dad d + 0B1A EB xchg + 0B1B 0E 09 mvi c,9 + 0B1D CD 0DEA call bdos ; show test name + 0B20 CD 0E8E call initcrc ; initialise crc + ; test loop + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-21 + + + 0B23 3A 0D4D tlp: lda iut + 0B26 FE 76 cpi 076h ; pragmatically avoid halt intructions + 0B28 CA 0B3A jz tlp2 + 0B2B E6 DF ani 0dfh + 0B2D FE DD cpi 0ddh + 0B2F C2 0B37 jnz tlp1 + 0B32 3A 0D4E lda iut+1 + 0B35 FE 76 cpi 076h + 0B37 C4 0D2E tlp1: cnz test ; execute the test instruction + 0B3A CD 0C8D tlp2: call count ; increment the counter + 0B3D C4 0CB1 cnz shift ; shift the scan bit + 0B40 E1 pop h ; pointer to test case + 0B41 CA 0B76 jz tlp3 ; done if shift returned NZ + 0B44 11 003C lxi d,20+20+20 + 0B47 19 dad d ; point to expected crc + 0B48 CD 0E4F call cmpcrc + 0B4B 11 0E22 lxi d,okmsg + 0B4E CA 0B6D jz tlpok + 0B51 11 0E29 lxi d,ermsg1 + 0B54 0E 09 mvi c,9 + 0B56 CD 0DEA call bdos + 0B59 CD 0DB5 call phex8 + 0B5C 11 0E44 lxi d,ermsg2 + 0B5F 0E 09 mvi c,9 + 0B61 CD 0DEA call bdos + 0B64 21 0EA2 lxi h,crcval + 0B67 CD 0DB5 call phex8 + 0B6A 11 0E4C lxi d,crlf + 0B6D 0E 09 tlpok: mvi c,9 + 0B6F CD 0DEA call bdos + 0B72 E1 pop h + 0B73 23 inx h + 0B74 23 inx h + 0B75 C9 ret + + 0B76 E5 tlp3: push h + 0B77 3E 01 mvi a,1 ; initialise count and shift scanners + 0B79 32 0BEC sta cntbit + 0B7C 32 0C10 sta shfbit + 0B7F 21 0CDE lxi h,counter + 0B82 22 0BED shld cntbyt + 0B85 21 0D06 lxi h,shifter + 0B88 22 0C11 shld shfbyt + + 0B8B 06 04 mvi b,4 ; bytes in iut field + 0B8D E1 pop h ; pointer to test case + 0B8E E5 push h + 0B8F 11 0D4D lxi d,iut + 0B92 CD 0BA0 call setup ; setup iut + 0B95 06 10 mvi b,16 ; bytes in machine state + 0B97 11 0103 lxi d,msbt + 0B9A CD 0BA0 call setup ; setup machine state + 0B9D C3 0B23 jmp tlp + + ; setup a field of the test case + ; b = number of bytes + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-22 + + + ; hl = pointer to base case + ; de = destination + 0BA0 CD 0BA9 setup: call subyte + 0BA3 23 inx h + 0BA4 05 dcr b + 0BA5 C2 0BA0 jnz setup + 0BA8 C9 ret + + 0BA9 C5 subyte: push b + 0BAA D5 push d + 0BAB E5 push h + 0BAC 4E mov c,m ; get base byte + 0BAD 11 0014 lxi d,20 + 0BB0 19 dad d ; point to incmask + 0BB1 7E mov a,m + 0BB2 FE 00 cpi 0 + 0BB4 CA 0BCA jz subshf + 0BB7 06 08 mvi b,8 ; 8 bits + 0BB9 0F subclp: rrc + 0BBA F5 push psw + 0BBB 3E 00 mvi a,0 + 0BBD DC 0BEF cc nxtcbit ; get next counter bit if mask bit was set + 0BC0 A9 xra c ; flip bit if counter bit was set + 0BC1 0F rrc + 0BC2 4F mov c,a + 0BC3 F1 pop psw + 0BC4 05 dcr b + 0BC5 C2 0BB9 jnz subclp + 0BC8 06 08 mvi b,8 + 0BCA 11 0014 subshf: lxi d,20 + 0BCD 19 dad d ; point to shift mask + 0BCE 7E mov a,m + 0BCF FE 00 cpi 0 + 0BD1 CA 0BE5 jz substr + 0BD4 06 08 mvi b,8 ; 8 bits + 0BD6 0F sbshf1: rrc + 0BD7 F5 push psw + 0BD8 3E 00 mvi a,0 + 0BDA DC 0C13 cc nxtsbit ; get next shifter bit if mask bit was set + 0BDD A9 xra c ; flip bit if shifter bit was set + 0BDE 0F rrc + 0BDF 4F mov c,a + 0BE0 F1 pop psw + 0BE1 05 dcr b + 0BE2 C2 0BD6 jnz sbshf1 + 0BE5 E1 substr: pop h + 0BE6 D1 pop d + 0BE7 79 mov a,c + 0BE8 12 stax d ; mangled byte to destination + 0BE9 13 inx d + 0BEA C1 pop b + 0BEB C9 ret + + ; get next counter bit in low bit of a + 0BEC cntbit: ds 1 + 0BED cntbyt: ds 2 + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-23 + + + + 0BEF C5 nxtcbit: push b + 0BF0 E5 push h + 0BF1 2A 0BED lhld cntbyt + 0BF4 46 mov b,m + 0BF5 21 0BEC lxi h,cntbit + 0BF8 7E mov a,m + 0BF9 4F mov c,a + 0BFA 07 rlc + 0BFB 77 mov m,a + 0BFC FE 01 cpi 1 + 0BFE C2 0C08 jnz ncb1 + 0C01 2A 0BED lhld cntbyt + 0C04 23 inx h + 0C05 22 0BED shld cntbyt + 0C08 78 ncb1: mov a,b + 0C09 A1 ana c + 0C0A E1 pop h + 0C0B C1 pop b + 0C0C C8 rz + 0C0D 3E 01 mvi a,1 + 0C0F C9 ret + + ; get next shifter bit in low bit of a + 0C10 shfbit: ds 1 + 0C11 shfbyt: ds 2 + + 0C13 C5 nxtsbit: push b + 0C14 E5 push h + 0C15 2A 0C11 lhld shfbyt + 0C18 46 mov b,m + 0C19 21 0C10 lxi h,shfbit + 0C1C 7E mov a,m + 0C1D 4F mov c,a + 0C1E 07 rlc + 0C1F 77 mov m,a + 0C20 FE 01 cpi 1 + 0C22 C2 0C2C jnz nsb1 + 0C25 2A 0C11 lhld shfbyt + 0C28 23 inx h + 0C29 22 0C11 shld shfbyt + 0C2C 78 nsb1: mov a,b + 0C2D A1 ana c + 0C2E E1 pop h + 0C2F C1 pop b + 0C30 C8 rz + 0C31 3E 01 mvi a,1 + 0C33 C9 ret + + + ; clear memory at hl, bc bytes + 0C34 F5 clrmem: push psw + 0C35 C5 push b + 0C36 D5 push d + 0C37 E5 push h + 0C38 36 00 mvi m,0 + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-24 + + + 0C3A 54 mov d,h + 0C3B 5D mov e,l + 0C3C 13 inx d + 0C3D 0B dcx b + + ;#idb ldir replaced with following code + 0C3E 7E ldir3: mov a,m + 0C3F 12 stax d + 0C40 23 inx h + 0C41 13 inx d + 0C42 0B dcx b + 0C43 78 mov a,b + 0C44 B1 ora c + 0C45 C2 0C3E jnz ldir3 + ;#idb + + 0C48 E1 pop h + 0C49 D1 pop d + 0C4A C1 pop b + 0C4B F1 pop psw + 0C4C C9 ret + + ; initialise counter or shifter + ; de = pointer to work area for counter or shifter + ; hl = pointer to mask + 0C4D initmask: + 0C4D D5 push d + 0C4E EB xchg + 0C4F 01 0028 lxi b,20+20 + 0C52 CD 0C34 call clrmem ; clear work area + 0C55 EB xchg + 0C56 06 14 mvi b,20 ; byte counter + 0C58 0E 01 mvi c,1 ; first bit + 0C5A 16 00 mvi d,0 ; bit counter + 0C5C 5E imlp: mov e,m + 0C5D 7B imlp1: mov a,e + 0C5E A1 ana c + 0C5F CA 0C63 jz imlp2 + 0C62 14 inr d + 0C63 79 imlp2: mov a,c + 0C64 07 rlc + 0C65 4F mov c,a + 0C66 FE 01 cpi 1 + 0C68 C2 0C5D jnz imlp1 + 0C6B 23 inx h + 0C6C 05 dcr b + 0C6D C2 0C5C jnz imlp + ; got number of 1-bits in mask in reg d + 0C70 7A mov a,d + 0C71 E6 F8 ani 0f8h + 0C73 0F rrc + 0C74 0F rrc + 0C75 0F rrc ; divide by 8 (get byte offset) + 0C76 6F mov l,a + 0C77 26 00 mvi h,0 + 0C79 7A mov a,d + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-25 + + + 0C7A E6 07 ani 7 ; bit offset + 0C7C 3C inr a + 0C7D 47 mov b,a + 0C7E 3E 80 mvi a,080h + 0C80 07 imlp3: rlc + 0C81 05 dcr b + 0C82 C2 0C80 jnz imlp3 + 0C85 D1 pop d + 0C86 19 dad d + 0C87 11 0014 lxi d,20 + 0C8A 19 dad d + 0C8B 77 mov m,a + 0C8C C9 ret + + ; multi-byte counter + 0C8D C5 count: push b + 0C8E D5 push d + 0C8F E5 push h + 0C90 21 0CDE lxi h,counter ; 20 byte counter starts here + 0C93 11 0014 lxi d,20 ; somewhere in here is the stop bit + 0C96 EB xchg + 0C97 19 dad d + 0C98 EB xchg + 0C99 34 cntlp: inr m + 0C9A 7E mov a,m + 0C9B FE 00 cpi 0 + 0C9D CA 0CAC jz cntlp1 ; overflow to next byte + 0CA0 47 mov b,a + 0CA1 1A ldax d + 0CA2 A0 ana b ; test for terminal value + 0CA3 CA 0CA8 jz cntend + 0CA6 36 00 mvi m,0 ; reset to zero + 0CA8 C1 cntend: pop b + 0CA9 D1 pop d + 0CAA E1 pop h + 0CAB C9 ret + + 0CAC 23 cntlp1: inx h + 0CAD 13 inx d + 0CAE C3 0C99 jmp cntlp + + + ; multi-byte shifter + 0CB1 C5 shift: push b + 0CB2 D5 push d + 0CB3 E5 push h + 0CB4 21 0D06 lxi h,shifter ; 20 byte shift register starts here + 0CB7 11 0014 lxi d,20 ; somewhere in here is the stop bit + 0CBA EB xchg + 0CBB 19 dad d + 0CBC EB xchg + 0CBD 7E shflp: mov a,m + 0CBE B7 ora a + 0CBF CA 0CD9 jz shflp1 + 0CC2 47 mov b,a + 0CC3 1A ldax d + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-26 + + + 0CC4 A0 ana b + 0CC5 C2 0CD5 jnz shlpe + 0CC8 78 mov a,b + 0CC9 07 rlc + 0CCA FE 01 cpi 1 + 0CCC C2 0CD3 jnz shflp2 + 0CCF 36 00 mvi m,0 + 0CD1 23 inx h + 0CD2 13 inx d + 0CD3 77 shflp2: mov m,a + 0CD4 AF xra a ; set Z + 0CD5 E1 shlpe: pop h + 0CD6 D1 pop d + 0CD7 C1 pop b + 0CD8 C9 ret + 0CD9 23 shflp1: inx h + 0CDA 13 inx d + 0CDB C3 0CBD jmp shflp + + 0CDE counter: ds 2*20 + 0D06 shifter: ds 2*20 + + ; test harness + 0D2E F5 test: push psw + 0D2F C5 push b + 0D30 D5 push d + 0D31 E5 push h + if 0 + lxi d,crlf + mvi c,9 + call bdos + lxi h,iut + mvi b,4 + call hexstr + mvi e,' ' + mvi c,2 + call bdos + mvi b,16 + lxi h,msbt + call hexstr + endif + 0D32 F3 di ; disable interrupts + + ;#idb ld (spsav),sp replaced by following code + ;#idb All registers and flages are immediately overwritten so + ;#idb no need to preserve any state. + 0D33 21 0000 lxi h,0 ; save stack pointer + 0D36 39 dad sp + 0D37 22 0DA9 shld spsav + ;#idb + + 0D3A 31 0105 lxi sp,msbt+2 ; point to test-case machine state + + ;#idb pop iy + ;#idb pop ix both replaced by following code + ;#idb Just dummy out ix/iy with copies of hl + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-27 + + + 0D3D E1 pop h ; and load all regs + 0D3E E1 pop h + ;#idb + + 0D3F E1 pop h + 0D40 D1 pop d + 0D41 C1 pop b + 0D42 F1 pop psw + + ;#idb ld sp,(spbt) replaced with the following code + ;#idb HL is copied/restored before/after load so no state changed + 0D43 22 0D97 shld temp + 0D46 2A 0111 lhld spbt + 0D49 F9 sphl + 0D4A 2A 0D97 lhld temp + ;#idb + + 0D4D iut: ds 4 ; max 4 byte instruction under test + + ;#idb ld (spat),sp replaced with the following code + ;#idb Must be very careful to preserve registers and flag + ;#idb state resulting from the test. The temptation is to use the + ;#idb stack - but that doesn't work because of the way the app + ;#idb uses SP as a quick way of pointing to memory. + ;#idb Bit of a code smell, but I can't think of an easier way. + 0D51 22 0D97 shld temp + 0D54 21 0000 lxi h,0 + 0D57 DA 0D5E jc temp1 ;jump on the state of the C flag set in the test + + 0D5A 39 dad sp ;this code will clear the C flag (0 + nnnn = nc) + 0D5B C3 0D60 jmp temp2 ;C flag is same state as before + + 0D5E 39 temp1: dad sp ;this code will clear the C flag (0 + nnnn = nc) + 0D5F 37 stc ;C flage needs re-setting to preserve state + + 0D60 22 0DA7 temp2: shld spat + 0D63 2A 0D97 lhld temp + ;#idb + + 0D66 31 0DA7 lxi sp,spat + 0D69 F5 push psw ; save other registers + 0D6A C5 push b + 0D6B D5 push d + 0D6C E5 push h + + ;#idb push ix + ;#idb push iy both replaced by following code + ;#idb Must match change made to pops made before test + 0D6D E5 push h + 0D6E E5 push h + ;#idb + + ;#idb ld sp,(spsav) replaced with following code + ;#idb No need to preserve state + 0D6F 2A 0DA9 lhld spsav ; restore stack pointer + 0D72 F9 sphl + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-28 + + + ;#idb + + 0D73 FB ei ; enable interrupts + 0D74 2A 0103 lhld msbt ; copy memory operand + 0D77 22 0D99 shld msat + 0D7A 21 0DA5 lxi h,flgsat ; flags after test + 0D7D 7E mov a,m + 0D7E E6 FF flgmsk: ani 0ffh ; mask-out irrelevant bits (self-modified code!) + 0D80 77 mov m,a + 0D81 06 10 mvi b,16 ; total of 16 bytes of state + 0D83 11 0D99 lxi d,msat + 0D86 21 0EA2 lxi h,crcval + 0D89 1A tcrc: ldax d + 0D8A 13 inx d + 0D8B CD 0E66 call updcrc ; accumulate crc of this test case + 0D8E 05 dcr b + 0D8F C2 0D89 jnz tcrc + if 0 + mvi e,' ' + mvi c,2 + call bdos + lxi h,crcval + call phex8 + lxi d,crlf + mvi c,9 + call bdos + lxi h,msat + mvi b,16 + call hexstr + lxi d,crlf + mvi c,9 + call bdos + endif + 0D92 E1 pop h + 0D93 D1 pop d + 0D94 C1 pop b + 0D95 F1 pop psw + 0D96 C9 ret + + ;#idb Added to store HL state + 0D97 temp: ds 2 + ;#idb + + ; machine state after test + 0D99 msat: ds 14 ; memop,iy,ix,hl,de,bc,af + 0DA7 spat: ds 2 ; stack pointer after test + 0DA5 flgsat equ spat-2 ; flags + + 0DA9 spsav: ds 2 ; saved stack pointer + + ; display hex string (pointer in hl, byte count in b) + 0DAB 7E hexstr: mov a,m + 0DAC CD 0DC7 call phex2 + 0DAF 23 inx h + 0DB0 05 dcr b + 0DB1 C2 0DAB jnz hexstr + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-29 + + + 0DB4 C9 ret + + ; display hex + ; display the big-endian 32-bit value pointed to by hl + 0DB5 F5 phex8: push psw + 0DB6 C5 push b + 0DB7 E5 push h + 0DB8 06 04 mvi b,4 + 0DBA 7E ph8lp: mov a,m + 0DBB CD 0DC7 call phex2 + 0DBE 23 inx h + 0DBF 05 dcr b + 0DC0 C2 0DBA jnz ph8lp + 0DC3 E1 pop h + 0DC4 C1 pop b + 0DC5 F1 pop psw + 0DC6 C9 ret + + ; display byte in a + 0DC7 F5 phex2: push psw + 0DC8 0F rrc + 0DC9 0F rrc + 0DCA 0F rrc + 0DCB 0F rrc + 0DCC CD 0DD0 call phex1 + 0DCF F1 pop psw + ; fall through + + ; display low nibble in a + 0DD0 F5 phex1: push psw + 0DD1 C5 push b + 0DD2 D5 push d + 0DD3 E5 push h + 0DD4 E6 0F ani 0fh + 0DD6 FE 0A cpi 10 + 0DD8 DA 0DDD jc ph11 + 0DDB C6 27 adi 'a'-'9'-1 + 0DDD C6 30 ph11: adi '0' + 0DDF 5F mov e,a + 0DE0 0E 02 mvi c,2 + 0DE2 CD 0DEA call bdos + 0DE5 E1 pop h + 0DE6 D1 pop d + 0DE7 C1 pop b + 0DE8 F1 pop psw + 0DE9 C9 ret + + 0DEA F5 bdos: push psw + 0DEB C5 push b + 0DEC D5 push d + 0DED E5 push h + 0DEE CD 0005 call 5 + 0DF1 E1 pop h + 0DF2 D1 pop d + 0DF3 C1 pop b + 0DF4 F1 pop psw + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-30 + + + 0DF5 C9 ret + + 0DF6 38 30 38 30 msg1: db '8080 instruction exerciser',10,13,'$' + 0DFA 20 69 6E 73 + 0DFE 74 72 75 63 + 0E02 74 69 6F 6E + 0E06 20 65 78 65 + 0E0A 72 63 69 73 + 0E0E 65 72 0A 0D + 0E12 24 + 0E13 54 65 73 74 msg2: db 'Tests complete$' + 0E17 73 20 63 6F + 0E1B 6D 70 6C 65 + 0E1F 74 65 24 + 0E22 20 20 4F 4B okmsg: db ' OK',10,13,'$' + 0E26 0A 0D 24 + 0E29 20 20 45 52 ermsg1: db ' ERROR **** crc expected:$' + 0E2D 52 4F 52 20 + 0E31 2A 2A 2A 2A + 0E35 20 63 72 63 + 0E39 20 65 78 70 + 0E3D 65 63 74 65 + 0E41 64 3A 24 + 0E44 20 66 6F 75 ermsg2: db ' found:$' + 0E48 6E 64 3A 24 + 0E4C 0A 0D 24 crlf: db 10,13,'$' + + ; compare crc + ; hl points to value to compare to crcval + 0E4F C5 cmpcrc: push b + 0E50 D5 push d + 0E51 E5 push h + 0E52 11 0EA2 lxi d,crcval + 0E55 06 04 mvi b,4 + 0E57 1A cclp: ldax d + 0E58 BE cmp m + 0E59 C2 0E62 jnz cce + 0E5C 23 inx h + 0E5D 13 inx d + 0E5E 05 dcr b + 0E5F C2 0E57 jnz cclp + 0E62 E1 cce: pop h + 0E63 D1 pop d + 0E64 C1 pop b + 0E65 C9 ret + + ; 32-bit crc routine + ; entry: a contains next byte, hl points to crc + ; exit: crc updated + 0E66 F5 updcrc: push psw + 0E67 C5 push b + 0E68 D5 push d + 0E69 E5 push h + 0E6A E5 push h + 0E6B 11 0003 lxi d,3 + 0E6E 19 dad d ; point to low byte of old crc + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-31 + + + 0E6F AE xra m ; xor with new byte + 0E70 6F mov l,a + 0E71 26 00 mvi h,0 + 0E73 29 dad h ; use result as index into table of 4 byte entries + 0E74 29 dad h + 0E75 EB xchg + 0E76 21 0EA6 lxi h,crctab + 0E79 19 dad d ; point to selected entry in crctab + 0E7A EB xchg + 0E7B E1 pop h + 0E7C 01 0004 lxi b,4 ; c = byte count, b = accumulator + 0E7F 1A crclp: ldax d + 0E80 A8 xra b + 0E81 46 mov b,m + 0E82 77 mov m,a + 0E83 13 inx d + 0E84 23 inx h + 0E85 0D dcr c + 0E86 C2 0E7F jnz crclp + if 0 + lxi h,crcval + call phex8 + lxi d,crlf + mvi c,9 + call bdos + endif + 0E89 E1 pop h + 0E8A D1 pop d + 0E8B C1 pop b + 0E8C F1 pop psw + 0E8D C9 ret + + 0E8E F5 initcrc:push psw + 0E8F C5 push b + 0E90 E5 push h + 0E91 21 0EA2 lxi h,crcval + 0E94 3E FF mvi a,0ffh + 0E96 06 04 mvi b,4 + 0E98 77 icrclp: mov m,a + 0E99 23 inx h + 0E9A 05 dcr b + 0E9B C2 0E98 jnz icrclp + 0E9E E1 pop h + 0E9F C1 pop b + 0EA0 F1 pop psw + 0EA1 C9 ret + + 0EA2 crcval: ds 4 + + 0EA6 00 00 00 00 crctab: db 000h,000h,000h,000h + 0EAA 77 07 30 96 db 077h,007h,030h,096h + 0EAE EE 0E 61 2C db 0eeh,00eh,061h,02ch + 0EB2 99 09 51 BA db 099h,009h,051h,0bah + 0EB6 07 6D C4 19 db 007h,06dh,0c4h,019h + 0EBA 70 6A F4 8F db 070h,06ah,0f4h,08fh + 0EBE E9 63 A5 35 db 0e9h,063h,0a5h,035h + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-32 + + + 0EC2 9E 64 95 A3 db 09eh,064h,095h,0a3h + 0EC6 0E DB 88 32 db 00eh,0dbh,088h,032h + 0ECA 79 DC B8 A4 db 079h,0dch,0b8h,0a4h + 0ECE E0 D5 E9 1E db 0e0h,0d5h,0e9h,01eh + 0ED2 97 D2 D9 88 db 097h,0d2h,0d9h,088h + 0ED6 09 B6 4C 2B db 009h,0b6h,04ch,02bh + 0EDA 7E B1 7C BD db 07eh,0b1h,07ch,0bdh + 0EDE E7 B8 2D 07 db 0e7h,0b8h,02dh,007h + 0EE2 90 BF 1D 91 db 090h,0bfh,01dh,091h + 0EE6 1D B7 10 64 db 01dh,0b7h,010h,064h + 0EEA 6A B0 20 F2 db 06ah,0b0h,020h,0f2h + 0EEE F3 B9 71 48 db 0f3h,0b9h,071h,048h + 0EF2 84 BE 41 DE db 084h,0beh,041h,0deh + 0EF6 1A DA D4 7D db 01ah,0dah,0d4h,07dh + 0EFA 6D DD E4 EB db 06dh,0ddh,0e4h,0ebh + 0EFE F4 D4 B5 51 db 0f4h,0d4h,0b5h,051h + 0F02 83 D3 85 C7 db 083h,0d3h,085h,0c7h + 0F06 13 6C 98 56 db 013h,06ch,098h,056h + 0F0A 64 6B A8 C0 db 064h,06bh,0a8h,0c0h + 0F0E FD 62 F9 7A db 0fdh,062h,0f9h,07ah + 0F12 8A 65 C9 EC db 08ah,065h,0c9h,0ech + 0F16 14 01 5C 4F db 014h,001h,05ch,04fh + 0F1A 63 06 6C D9 db 063h,006h,06ch,0d9h + 0F1E FA 0F 3D 63 db 0fah,00fh,03dh,063h + 0F22 8D 08 0D F5 db 08dh,008h,00dh,0f5h + 0F26 3B 6E 20 C8 db 03bh,06eh,020h,0c8h + 0F2A 4C 69 10 5E db 04ch,069h,010h,05eh + 0F2E D5 60 41 E4 db 0d5h,060h,041h,0e4h + 0F32 A2 67 71 72 db 0a2h,067h,071h,072h + 0F36 3C 03 E4 D1 db 03ch,003h,0e4h,0d1h + 0F3A 4B 04 D4 47 db 04bh,004h,0d4h,047h + 0F3E D2 0D 85 FD db 0d2h,00dh,085h,0fdh + 0F42 A5 0A B5 6B db 0a5h,00ah,0b5h,06bh + 0F46 35 B5 A8 FA db 035h,0b5h,0a8h,0fah + 0F4A 42 B2 98 6C db 042h,0b2h,098h,06ch + 0F4E DB BB C9 D6 db 0dbh,0bbh,0c9h,0d6h + 0F52 AC BC F9 40 db 0ach,0bch,0f9h,040h + 0F56 32 D8 6C E3 db 032h,0d8h,06ch,0e3h + 0F5A 45 DF 5C 75 db 045h,0dfh,05ch,075h + 0F5E DC D6 0D CF db 0dch,0d6h,00dh,0cfh + 0F62 AB D1 3D 59 db 0abh,0d1h,03dh,059h + 0F66 26 D9 30 AC db 026h,0d9h,030h,0ach + 0F6A 51 DE 00 3A db 051h,0deh,000h,03ah + 0F6E C8 D7 51 80 db 0c8h,0d7h,051h,080h + 0F72 BF D0 61 16 db 0bfh,0d0h,061h,016h + 0F76 21 B4 F4 B5 db 021h,0b4h,0f4h,0b5h + 0F7A 56 B3 C4 23 db 056h,0b3h,0c4h,023h + 0F7E CF BA 95 99 db 0cfh,0bah,095h,099h + 0F82 B8 BD A5 0F db 0b8h,0bdh,0a5h,00fh + 0F86 28 02 B8 9E db 028h,002h,0b8h,09eh + 0F8A 5F 05 88 08 db 05fh,005h,088h,008h + 0F8E C6 0C D9 B2 db 0c6h,00ch,0d9h,0b2h + 0F92 B1 0B E9 24 db 0b1h,00bh,0e9h,024h + 0F96 2F 6F 7C 87 db 02fh,06fh,07ch,087h + 0F9A 58 68 4C 11 db 058h,068h,04ch,011h + 0F9E C1 61 1D AB db 0c1h,061h,01dh,0abh + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-33 + + + 0FA2 B6 66 2D 3D db 0b6h,066h,02dh,03dh + 0FA6 76 DC 41 90 db 076h,0dch,041h,090h + 0FAA 01 DB 71 06 db 001h,0dbh,071h,006h + 0FAE 98 D2 20 BC db 098h,0d2h,020h,0bch + 0FB2 EF D5 10 2A db 0efh,0d5h,010h,02ah + 0FB6 71 B1 85 89 db 071h,0b1h,085h,089h + 0FBA 06 B6 B5 1F db 006h,0b6h,0b5h,01fh + 0FBE 9F BF E4 A5 db 09fh,0bfh,0e4h,0a5h + 0FC2 E8 B8 D4 33 db 0e8h,0b8h,0d4h,033h + 0FC6 78 07 C9 A2 db 078h,007h,0c9h,0a2h + 0FCA 0F 00 F9 34 db 00fh,000h,0f9h,034h + 0FCE 96 09 A8 8E db 096h,009h,0a8h,08eh + 0FD2 E1 0E 98 18 db 0e1h,00eh,098h,018h + 0FD6 7F 6A 0D BB db 07fh,06ah,00dh,0bbh + 0FDA 08 6D 3D 2D db 008h,06dh,03dh,02dh + 0FDE 91 64 6C 97 db 091h,064h,06ch,097h + 0FE2 E6 63 5C 01 db 0e6h,063h,05ch,001h + 0FE6 6B 6B 51 F4 db 06bh,06bh,051h,0f4h + 0FEA 1C 6C 61 62 db 01ch,06ch,061h,062h + 0FEE 85 65 30 D8 db 085h,065h,030h,0d8h + 0FF2 F2 62 00 4E db 0f2h,062h,000h,04eh + 0FF6 6C 06 95 ED db 06ch,006h,095h,0edh + 0FFA 1B 01 A5 7B db 01bh,001h,0a5h,07bh + 0FFE 82 08 F4 C1 db 082h,008h,0f4h,0c1h + 1002 F5 0F C4 57 db 0f5h,00fh,0c4h,057h + 1006 65 B0 D9 C6 db 065h,0b0h,0d9h,0c6h + 100A 12 B7 E9 50 db 012h,0b7h,0e9h,050h + 100E 8B BE B8 EA db 08bh,0beh,0b8h,0eah + 1012 FC B9 88 7C db 0fch,0b9h,088h,07ch + 1016 62 DD 1D DF db 062h,0ddh,01dh,0dfh + 101A 15 DA 2D 49 db 015h,0dah,02dh,049h + 101E 8C D3 7C F3 db 08ch,0d3h,07ch,0f3h + 1022 FB D4 4C 65 db 0fbh,0d4h,04ch,065h + 1026 4D B2 61 58 db 04dh,0b2h,061h,058h + 102A 3A B5 51 CE db 03ah,0b5h,051h,0ceh + 102E A3 BC 00 74 db 0a3h,0bch,000h,074h + 1032 D4 BB 30 E2 db 0d4h,0bbh,030h,0e2h + 1036 4A DF A5 41 db 04ah,0dfh,0a5h,041h + 103A 3D D8 95 D7 db 03dh,0d8h,095h,0d7h + 103E A4 D1 C4 6D db 0a4h,0d1h,0c4h,06dh + 1042 D3 D6 F4 FB db 0d3h,0d6h,0f4h,0fbh + 1046 43 69 E9 6A db 043h,069h,0e9h,06ah + 104A 34 6E D9 FC db 034h,06eh,0d9h,0fch + 104E AD 67 88 46 db 0adh,067h,088h,046h + 1052 DA 60 B8 D0 db 0dah,060h,0b8h,0d0h + 1056 44 04 2D 73 db 044h,004h,02dh,073h + 105A 33 03 1D E5 db 033h,003h,01dh,0e5h + 105E AA 0A 4C 5F db 0aah,00ah,04ch,05fh + 1062 DD 0D 7C C9 db 0ddh,00dh,07ch,0c9h + 1066 50 05 71 3C db 050h,005h,071h,03ch + 106A 27 02 41 AA db 027h,002h,041h,0aah + 106E BE 0B 10 10 db 0beh,00bh,010h,010h + 1072 C9 0C 20 86 db 0c9h,00ch,020h,086h + 1076 57 68 B5 25 db 057h,068h,0b5h,025h + 107A 20 6F 85 B3 db 020h,06fh,085h,0b3h + 107E B9 66 D4 09 db 0b9h,066h,0d4h,009h + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-34 + + + 1082 CE 61 E4 9F db 0ceh,061h,0e4h,09fh + 1086 5E DE F9 0E db 05eh,0deh,0f9h,00eh + 108A 29 D9 C9 98 db 029h,0d9h,0c9h,098h + 108E B0 D0 98 22 db 0b0h,0d0h,098h,022h + 1092 C7 D7 A8 B4 db 0c7h,0d7h,0a8h,0b4h + 1096 59 B3 3D 17 db 059h,0b3h,03dh,017h + 109A 2E B4 0D 81 db 02eh,0b4h,00dh,081h + 109E B7 BD 5C 3B db 0b7h,0bdh,05ch,03bh + 10A2 C0 BA 6C AD db 0c0h,0bah,06ch,0adh + 10A6 ED B8 83 20 db 0edh,0b8h,083h,020h + 10AA 9A BF B3 B6 db 09ah,0bfh,0b3h,0b6h + 10AE 03 B6 E2 0C db 003h,0b6h,0e2h,00ch + 10B2 74 B1 D2 9A db 074h,0b1h,0d2h,09ah + 10B6 EA D5 47 39 db 0eah,0d5h,047h,039h + 10BA 9D D2 77 AF db 09dh,0d2h,077h,0afh + 10BE 04 DB 26 15 db 004h,0dbh,026h,015h + 10C2 73 DC 16 83 db 073h,0dch,016h,083h + 10C6 E3 63 0B 12 db 0e3h,063h,00bh,012h + 10CA 94 64 3B 84 db 094h,064h,03bh,084h + 10CE 0D 6D 6A 3E db 00dh,06dh,06ah,03eh + 10D2 7A 6A 5A A8 db 07ah,06ah,05ah,0a8h + 10D6 E4 0E CF 0B db 0e4h,00eh,0cfh,00bh + 10DA 93 09 FF 9D db 093h,009h,0ffh,09dh + 10DE 0A 00 AE 27 db 00ah,000h,0aeh,027h + 10E2 7D 07 9E B1 db 07dh,007h,09eh,0b1h + 10E6 F0 0F 93 44 db 0f0h,00fh,093h,044h + 10EA 87 08 A3 D2 db 087h,008h,0a3h,0d2h + 10EE 1E 01 F2 68 db 01eh,001h,0f2h,068h + 10F2 69 06 C2 FE db 069h,006h,0c2h,0feh + 10F6 F7 62 57 5D db 0f7h,062h,057h,05dh + 10FA 80 65 67 CB db 080h,065h,067h,0cbh + 10FE 19 6C 36 71 db 019h,06ch,036h,071h + 1102 6E 6B 06 E7 db 06eh,06bh,006h,0e7h + 1106 FE D4 1B 76 db 0feh,0d4h,01bh,076h + 110A 89 D3 2B E0 db 089h,0d3h,02bh,0e0h + 110E 10 DA 7A 5A db 010h,0dah,07ah,05ah + 1112 67 DD 4A CC db 067h,0ddh,04ah,0cch + 1116 F9 B9 DF 6F db 0f9h,0b9h,0dfh,06fh + 111A 8E BE EF F9 db 08eh,0beh,0efh,0f9h + 111E 17 B7 BE 43 db 017h,0b7h,0beh,043h + 1122 60 B0 8E D5 db 060h,0b0h,08eh,0d5h + 1126 D6 D6 A3 E8 db 0d6h,0d6h,0a3h,0e8h + 112A A1 D1 93 7E db 0a1h,0d1h,093h,07eh + 112E 38 D8 C2 C4 db 038h,0d8h,0c2h,0c4h + 1132 4F DF F2 52 db 04fh,0dfh,0f2h,052h + 1136 D1 BB 67 F1 db 0d1h,0bbh,067h,0f1h + 113A A6 BC 57 67 db 0a6h,0bch,057h,067h + 113E 3F B5 06 DD db 03fh,0b5h,006h,0ddh + 1142 48 B2 36 4B db 048h,0b2h,036h,04bh + 1146 D8 0D 2B DA db 0d8h,00dh,02bh,0dah + 114A AF 0A 1B 4C db 0afh,00ah,01bh,04ch + 114E 36 03 4A F6 db 036h,003h,04ah,0f6h + 1152 41 04 7A 60 db 041h,004h,07ah,060h + 1156 DF 60 EF C3 db 0dfh,060h,0efh,0c3h + 115A A8 67 DF 55 db 0a8h,067h,0dfh,055h + 115E 31 6E 8E EF db 031h,06eh,08eh,0efh + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-35 + + + 1162 46 69 BE 79 db 046h,069h,0beh,079h + 1166 CB 61 B3 8C db 0cbh,061h,0b3h,08ch + 116A BC 66 83 1A db 0bch,066h,083h,01ah + 116E 25 6F D2 A0 db 025h,06fh,0d2h,0a0h + 1172 52 68 E2 36 db 052h,068h,0e2h,036h + 1176 CC 0C 77 95 db 0cch,00ch,077h,095h + 117A BB 0B 47 03 db 0bbh,00bh,047h,003h + 117E 22 02 16 B9 db 022h,002h,016h,0b9h + 1182 55 05 26 2F db 055h,005h,026h,02fh + 1186 C5 BA 3B BE db 0c5h,0bah,03bh,0beh + 118A B2 BD 0B 28 db 0b2h,0bdh,00bh,028h + 118E 2B B4 5A 92 db 02bh,0b4h,05ah,092h + 1192 5C B3 6A 04 db 05ch,0b3h,06ah,004h + 1196 C2 D7 FF A7 db 0c2h,0d7h,0ffh,0a7h + 119A B5 D0 CF 31 db 0b5h,0d0h,0cfh,031h + 119E 2C D9 9E 8B db 02ch,0d9h,09eh,08bh + 11A2 5B DE AE 1D db 05bh,0deh,0aeh,01dh + 11A6 9B 64 C2 B0 db 09bh,064h,0c2h,0b0h + 11AA EC 63 F2 26 db 0ech,063h,0f2h,026h + 11AE 75 6A A3 9C db 075h,06ah,0a3h,09ch + 11B2 02 6D 93 0A db 002h,06dh,093h,00ah + 11B6 9C 09 06 A9 db 09ch,009h,006h,0a9h + 11BA EB 0E 36 3F db 0ebh,00eh,036h,03fh + 11BE 72 07 67 85 db 072h,007h,067h,085h + 11C2 05 00 57 13 db 005h,000h,057h,013h + 11C6 95 BF 4A 82 db 095h,0bfh,04ah,082h + 11CA E2 B8 7A 14 db 0e2h,0b8h,07ah,014h + 11CE 7B B1 2B AE db 07bh,0b1h,02bh,0aeh + 11D2 0C B6 1B 38 db 00ch,0b6h,01bh,038h + 11D6 92 D2 8E 9B db 092h,0d2h,08eh,09bh + 11DA E5 D5 BE 0D db 0e5h,0d5h,0beh,00dh + 11DE 7C DC EF B7 db 07ch,0dch,0efh,0b7h + 11E2 0B DB DF 21 db 00bh,0dbh,0dfh,021h + 11E6 86 D3 D2 D4 db 086h,0d3h,0d2h,0d4h + 11EA F1 D4 E2 42 db 0f1h,0d4h,0e2h,042h + 11EE 68 DD B3 F8 db 068h,0ddh,0b3h,0f8h + 11F2 1F DA 83 6E db 01fh,0dah,083h,06eh + 11F6 81 BE 16 CD db 081h,0beh,016h,0cdh + 11FA F6 B9 26 5B db 0f6h,0b9h,026h,05bh + 11FE 6F B0 77 E1 db 06fh,0b0h,077h,0e1h + 1202 18 B7 47 77 db 018h,0b7h,047h,077h + 1206 88 08 5A E6 db 088h,008h,05ah,0e6h + 120A FF 0F 6A 70 db 0ffh,00fh,06ah,070h + 120E 66 06 3B CA db 066h,006h,03bh,0cah + 1212 11 01 0B 5C db 011h,001h,00bh,05ch + 1216 8F 65 9E FF db 08fh,065h,09eh,0ffh + 121A F8 62 AE 69 db 0f8h,062h,0aeh,069h + 121E 61 6B FF D3 db 061h,06bh,0ffh,0d3h + 1222 16 6C CF 45 db 016h,06ch,0cfh,045h + 1226 A0 0A E2 78 db 0a0h,00ah,0e2h,078h + 122A D7 0D D2 EE db 0d7h,00dh,0d2h,0eeh + 122E 4E 04 83 54 db 04eh,004h,083h,054h + 1232 39 03 B3 C2 db 039h,003h,0b3h,0c2h + 1236 A7 67 26 61 db 0a7h,067h,026h,061h + 123A D0 60 16 F7 db 0d0h,060h,016h,0f7h + 123E 49 69 47 4D db 049h,069h,047h,04dh + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-36 + + + 1242 3E 6E 77 DB db 03eh,06eh,077h,0dbh + 1246 AE D1 6A 4A db 0aeh,0d1h,06ah,04ah + 124A D9 D6 5A DC db 0d9h,0d6h,05ah,0dch + 124E 40 DF 0B 66 db 040h,0dfh,00bh,066h + 1252 37 D8 3B F0 db 037h,0d8h,03bh,0f0h + 1256 A9 BC AE 53 db 0a9h,0bch,0aeh,053h + 125A DE BB 9E C5 db 0deh,0bbh,09eh,0c5h + 125E 47 B2 CF 7F db 047h,0b2h,0cfh,07fh + 1262 30 B5 FF E9 db 030h,0b5h,0ffh,0e9h + 1266 BD BD F2 1C db 0bdh,0bdh,0f2h,01ch + 126A CA BA C2 8A db 0cah,0bah,0c2h,08ah + 126E 53 B3 93 30 db 053h,0b3h,093h,030h + 1272 24 B4 A3 A6 db 024h,0b4h,0a3h,0a6h + 1276 BA D0 36 05 db 0bah,0d0h,036h,005h + 127A CD D7 06 93 db 0cdh,0d7h,006h,093h + 127E 54 DE 57 29 db 054h,0deh,057h,029h + 1282 23 D9 67 BF db 023h,0d9h,067h,0bfh + 1286 B3 66 7A 2E db 0b3h,066h,07ah,02eh + 128A C4 61 4A B8 db 0c4h,061h,04ah,0b8h + 128E 5D 68 1B 02 db 05dh,068h,01bh,002h + 1292 2A 6F 2B 94 db 02ah,06fh,02bh,094h + 1296 B4 0B BE 37 db 0b4h,00bh,0beh,037h + 129A C3 0C 8E A1 db 0c3h,00ch,08eh,0a1h + 129E 5A 05 DF 1B db 05ah,005h,0dfh,01bh + 12A2 2D 02 EF 8D db 02dh,002h,0efh,08dh + + end + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE S + + +Macros: +TMSG TSTR + +Symbols: +016F ..0000 0183 ..0001 0197 ..0002 +01AF ..0003 01CF ..0004 01E3 ..0005 +01F7 ..0006 020F ..0007 022F ..0008 +0243 ..0009 0257 ..000A 026F ..000B +028F ..000C 02A3 ..000D 02B7 ..000E +02CF ..000F 02EF ..0010 0303 ..0011 +0317 ..0012 032F ..0013 034F ..0014 +0363 ..0015 0377 ..0016 038F ..0017 +03AF ..0018 03C3 ..0019 03D7 ..001A +03EF ..001B 040F ..001C 0423 ..001D +0437 ..001E 044F ..001F 046F ..0020 +0483 ..0021 0497 ..0022 04AF ..0023 +04CF ..0024 04E3 ..0025 04F7 ..0026 +050F ..0027 052F ..0028 0543 ..0029 +0557 ..002A 056F ..002B 058F ..002C +05A3 ..002D 05B7 ..002E 05CF ..002F +05EF ..0030 0603 ..0031 0617 ..0032 +062F ..0033 064F ..0034 0663 ..0035 +0677 ..0036 068F ..0037 06AF ..0038 +06C3 ..0039 06D7 ..003A 06EF ..003B +070F ..003C 0723 ..003D 0737 ..003E +074F ..003F 076F ..0040 0783 ..0041 +0797 ..0042 07AF ..0043 07CF ..0044 +07E3 ..0045 07F7 ..0046 080F ..0047 +082F ..0048 0843 ..0049 0857 ..004A +086F ..004B 088F ..004C 08A3 ..004D +08B7 ..004E 08CF ..004F 08EF ..0050 +0903 ..0051 0917 ..0052 092F ..0053 +094F ..0054 0963 ..0055 0977 ..0056 +098F ..0057 09AF ..0058 09C3 ..0059 +09D7 ..005A 09EF ..005B 0A0F ..005C +0A23 ..005D 0A37 ..005E 0A4F ..005F +0A6F ..0060 0A83 ..0061 0A97 ..0062 +0AAF ..0063 016E ADD16 01CE ALU8I +022E ALU8R 0DEA BDOS 0100 BEGIN +0E62 CCE 0E57 CCLP 0C34 CLRMEM +0E4F CMPCRC 0BEC CNTBIT 0BED CNTBYT +0CA8 CNTEND 0C99 CNTLP 0CAC CNTLP1 +0C8D COUNT 0CDE COUNTER 0E7F CRCLP +0EA6 CRCTAB 0EA2 CRCVAL 0E4C CRLF +028E DAA 012F DONE 0E29 ERMSG1 +0E44 ERMSG2 0D7E FLGMSK 0DA5 FLGSAT +0DAB HEXSTR 0E98 ICRCLP 0C5C IMLP +0C5D IMLP1 0C63 IMLP2 0C80 IMLP3 +02EE INCA 034E INCB 03AE INCBC +040E INCC 046E INCD 04CE INCDE +052E INCE 058E INCH 05EE INCHL +064E INCL 06AE INCM 070E INCSP +0E8E INITCRC 0C4D INITMASK 0D4D IUT +076E LD162 07CE LD166 082E LD16IM +088E LD8BD 08EE LD8IM 094E LD8RR +09AE LDA 0AFC LDIR1 0B0C LDIR2 + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE S-1 + + +0C3E LDIR3 0122 LOOP 0D99 MSAT +0103 MSBT 0DF6 MSG1 0E13 MSG2 +0C08 NCB1 0C2C NSB1 0BEF NXTCBIT +0C13 NXTSBIT 0E22 OKMSG 0DDD PH11 +0DBA PH8LP 0DD0 PHEX1 0DC7 PHEX2 +0DB5 PHEX8 0A0E ROT8080 0BD6 SBSHF1 +0BA0 SETUP 0C10 SHFBIT 0C11 SHFBYT +0CBD SHFLP 0CD9 SHFLP1 0CD3 SHFLP2 +0CB1 SHIFT 0D06 SHIFTER 0CD5 SHLPE +0DA7 SPAT 0111 SPBT 0DA9 SPSAV +0A6E STABD 0113 START 0ACE STT +0BB9 SUBCLP 0BCA SUBSHF 0BE5 SUBSTR +0BA9 SUBYTE 0D89 TCRC 0D97 TEMP +0D5E TEMP1 0D60 TEMP2 0D2E TEST +013A TESTS 0B23 TLP 0B37 TLP1 +0B3A TLP2 0B76 TLP3 0B6D TLPOK +0E66 UPDCRC + + + +No Fatal error(s) + + diff --git a/Intel8080/Intel8080.Test/roms/8080EXM.COM b/Intel8080/Intel8080.Test/roms/8080EXM.COM new file mode 100644 index 0000000000000000000000000000000000000000..76c1a3470bbb443aba17850a41179187d5bf02a5 GIT binary patch literal 4608 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 (19,456 cycles) +add16: db 0ffh ; flag mask + tstr 9,0c4a5h,0c4c7h,0d226h,0a050h,058eah,08566h,0c6h,0deh,09bc9h + tstr 030h,0,0,0,0f821h,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,-1,-1,-1,0d7h,0,-1 ; (38 cycles) + db 014h, 047h, 04Bh, 0A6h ; expected crc + tmsg 'dad ' + +; aluop a,nn (28,672 cycles) +alu8i: db 0ffh ; flag mask + tstr 0c6h,09140h,07e3ch,07a67h,0df6dh,05b61h,00b29h,010h,066h,085b2h + tstr 038h,0,0,0,0,0,0,0,-1,0 ; (2048 cycles) + tstr <0,-1>,0,0,0,0,0,0,0d7h,0,0 ; (14 cycles) + db 09Eh, 092h, 02Fh, 09Eh ; expected crc + tmsg 'aluop nn' + +; aluop a, (753,664 cycles) +alu8r: db 0ffh ; flag mask + tstr 080h,0c53eh,0573ah,04c4dh,msbt,0e309h,0a666h,0d0h,03bh,0adbbh + tstr 03fh,0,0,0,0,0,0,0,-1,0 ; (16,384 cycles) + tstr 0,0ffh,0,0,0,-1,-1,0d7h,0,0 ; (46 cycles) + db 0CFh, 076h, 02Ch, 086h ; expected crc + tmsg 'aluop ' + +; +daa: db 0ffh ; flag mask + tstr 027h,02141h,009fah,01d60h,0a559h,08d5bh,09079h,004h,08eh,0299dh + tstr 018h,0,0,0,0,0,0,0d7h,-1,0 ; (65,536 cycles) + tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) + db 0BBh, 03Fh, 003h, 00Ch ; expected crc + tmsg '' + +; a (3072 cycles) +inca: db 0ffh ; flag mask + tstr 03ch,04adfh,0d5d8h,0e598h,08a2bh,0a7b0h,0431bh,044h,05ah,0d030h + tstr 001h,0,0,0,0,0,0,0,-1,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 0ADh, 0B6h, 046h, 00Eh ; expected crc + tmsg ' a' + +; b (3072 cycles) +incb: db 0ffh ; flag mask + tstr 004h,0d623h,0432dh,07a61h,08180h,05a86h,01e85h,086h,058h,09bbbh + tstr 001h,0,0,0,0,0,0ff00h,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 083h, 0EDh, 013h, 045h ; expected crc + tmsg ' b' + +; bc (1536 cycles) +incbc: db 0ffh ; flag mask + tstr 003h,0cd97h,044abh,08dc9h,0e3e3h,011cch,0e8a4h,002h,049h,02a4dh + tstr 008h,0,0,0,0,0,0f821h,0,0,0 ; (256 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 0F7h, 092h, 087h, 0CDh ; expected crc + tmsg ' b' + +; c (3072 cycles) +incc: db 0ffh ; flag mask + tstr 00ch,0d789h,00935h,0055bh,09f85h,08b27h,0d208h,095h,005h,00660h + tstr 001h,0,0,0,0,0,0ffh,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 0E5h, 0F6h, 072h, 01Bh ; expected crc + tmsg ' c' + +; d (3072 cycles) +incd: db 0ffh ; flag mask + tstr 014h,0a0eah,05fbah,065fbh,0981ch,038cch,0debch,043h,05ch,003bdh + tstr 001h,0,0,0,0,0ff00h,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 015h, 0B5h, 057h, 09Ah ; expected crc + tmsg ' d' + +; de (1536 cycles) +incde: db 0ffh ; flag mask + tstr 013h,0342eh,0131dh,028c9h,00acah,09967h,03a2eh,092h,0f6h,09d54h + tstr 008h,0,0,0,0,0f821h,0,0,0,0 ; (256 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 07Fh, 04Eh, 025h, 001h ; expected crc + tmsg ' d' + +; e (3072 cycles) +ince: db 0ffh ; flag mask + tstr 01ch,0602fh,04c0dh,02402h,0e2f5h,0a0f4h,0a10ah,013h,032h,05925h + tstr 001h,0,0,0,0,0ffh,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 0CFh, 02Ah, 0B3h, 096h ; expected crc + tmsg ' e' + +; h (3072 cycles) +inch: db 0ffh ; flag mask + tstr 024h,01506h,0f2ebh,0e8ddh,0262bh,011a6h,0bc1ah,017h,006h,02818h + tstr 001h,0,0,0,0ff00h,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 012h, 0B2h, 095h, 02Ch ; expected crc + tmsg ' h' + +; hl (1536 cycles) +inchl: db 0ffh ; flag mask + tstr 023h,0c3f4h,007a5h,01b6dh,04f04h,0e2c2h,0822ah,057h,0e0h,0c3e1h + tstr 008h,0,0,0,0f821h,0,0,0,0,0 ; (256 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 09Fh, 02Bh, 023h, 0C0h ; expected crc + tmsg ' h' + +; l (3072 cycles) +incl: db 0ffh ; flag mask + tstr 02ch,08031h,0a520h,04356h,0b409h,0f4c1h,0dfa2h,0d1h,03ch,03ea2h + tstr 001h,0,0,0,0ffh,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 0FFh, 057h, 0D3h, 056h ; expected crc + tmsg ' l' + +; (hl) (3072 cycles) +incm: db 0ffh ; flag mask + tstr 034h,0b856h,00c7ch,0e53eh,msbt,0877eh,0da58h,015h,05ch,01f37h + tstr 001h,0ffh,0,0,0,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 092h, 0E9h, 063h, 0BDh ; expected crc + tmsg ' m' + +; sp (1536 cycles) +incsp: db 0ffh ; flag mask + tstr 033h,0346fh,0d482h,0d169h,0deb6h,0a494h,0f476h,053h,002h,0855bh + tstr 008h,0,0,0,0,0,0,0,0,0f821h ; (256 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 0D5h, 070h, 02Fh, 0ABh ; expected crc + tmsg ' sp' + +; ld hl,(nnnn) (16 cycles) +ld162: db 0ffh ; flag mask + tstr <02ah,low msbt,high msbt>,09863h,07830h,02077h,0b1feh,0b9fah,0abb8h,004h,006h,06015h + tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) + tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) + db 0A9h, 0C3h, 0D5h, 0CBh ; expected crc + tmsg 'lhld nnnn' + +; ld (nnnn),hl (16 cycles) +ld166: db 0ffh ; flag mask + tstr <022h,low msbt,high msbt>,0d003h,07772h,07f53h,03f72h,064eah,0e180h,010h,02dh,035e9h + tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) + tstr 0,0,0,0,-1,0,0,0,0,0 ; (16 cycles) + db 0E8h, 086h, 04Fh, 026h ; expected crc + tmsg 'shld nnnn' + +; ld ,nnnn (64 cycles) +ld16im: db 0ffh ; flag mask + tstr 1,05c1ch,02d46h,08eb9h,06078h,074b1h,0b30eh,046h,0d1h,030cch + tstr 030h,0,0,0,0,0,0,0,0,0 ; (4 cycles) + tstr <0,0ffh,0ffh>,0,0,0,0,0,0,0,0,0 ; (16 cycles) + db 0FCh, 0F4h, 06Eh, 012h ; expected crc + tmsg 'lxi ,nnnn' + +; ld a,<(bc),(de)> (44 cycles) +ld8bd: db 0ffh ; flag mask + tstr 00ah,0b3a8h,01d2ah,07f8eh,042ach,msbt,msbt,0c6h,0b1h,0ef8eh + tstr 010h,0,0,0,0,0,0,0,0,0 ; (2 cycles) + tstr 0,0ffh,0,0,0,0,0,0d7h,-1,0 ; (22 cycles) + db 02Bh, 082h, 01Dh, 05Fh ; expected crc + tmsg 'ldax ' + +; ld ,nn (64 cycles) +ld8im: db 0ffh ; flag mask + tstr 6,0c407h,0f49dh,0d13dh,00339h,0de89h,07455h,053h,0c0h,05509h + tstr 038h,0,0,0,0,0,0,0,0,0 ; (8 cycles) + tstr 0,0,0,0,0,0,0,0,-1,0 ; (8 cycles) + db 0EAh, 0A7h, 020h, 044h ; expected crc + tmsg 'mvi ,nn' + +; ld , (3456 cycles) +ld8rr: db 0ffh ; flag mask + tstr 040h,072a4h,0a024h,061ach,msbt,082c7h,0718fh,097h,08fh,0ef8eh + tstr 03fh,0,0,0,0,0,0,0,0,0 ; (64 cycles) + tstr 0,0ffh,0,0,0,-1,-1,0d7h,-1,0 ; (54 cycles) + db 010h, 0B5h, 08Ch, 0EEh ; expected crc + tmsg 'mov ,' + +; ld a,(nnnn) / ld (nnnn),a (44 cycles) +lda: db 0ffh ; flag mask + tstr <032h,low msbt,high msbt>,0fd68h,0f4ech,044a0h,0b543h,00653h,0cdbah,0d2h,04fh,01fd8h + tstr 008h,0,0,0,0,0,0,0,0,0 ; (2 cycle) + tstr 0,0ffh,0,0,0,0,0,0d7h,-1,0 ; (22 cycles) + db 0EDh, 057h, 0AFh, 072h ; expected crc + tmsg 'sta nnnn / lda nnnn' + +; (6144 cycles) +rot8080: db 0ffh ; flag mask + tstr 7,0cb92h,06d43h,00a90h,0c284h,00c53h,0f50eh,091h,0ebh,040fch + tstr 018h,0,0,0,0,0,0,0,-1,0 ; (1024 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 0E0h, 0D8h, 092h, 035h ; expected crc + tmsg '' + +; ld (),a (96 cycles) +stabd: db 0ffh ; flag mask + tstr 2,00c3bh,0b592h,06cffh,0959eh,msbt,msbt+1,0c1h,021h,0bde7h + tstr 018h,0,0,0,0,0,0,0,0,0 ; (4 cycles) + tstr 0,-1,0,0,0,0,0,0,-1,0 ; (24 cycles) + db 02Bh, 004h, 071h, 0E9h ; expected crc + tmsg 'stax ' + +; start test pointed to by (hl) +stt: push h + mov a,m ; get pointer to test + inx h + mov h,m + mov l,a + mov a,m ; flag mask + sta flgmsk+1 + inx h + push h + lxi d,20 + dad d ; point to incmask + lxi d,counter + call initmask + pop h + push h + lxi d,20+20 + dad d ; point to scanmask + lxi d,shifter + call initmask + lxi h,shifter + mvi m,1 ; first bit + pop h + push h + lxi d,iut ; copy initial instruction under test + lxi b,4 + +;#idb ldir replaced with following code +ldir1: mov a,m + stax d + inx h + inx d + dcx b + mov a,b + ora c + jnz ldir1 +;#idb + + lxi d,msbt ; copy initial machine state + lxi b,16 + +;#idb ldir replaced with following code +ldir2: mov a,m + stax d + inx h + inx d + dcx b + mov a,b + ora c + jnz ldir2 +;#idb + + lxi d,20+20+4 ; skip incmask, scanmask and expcrc + dad d + xchg + mvi c,9 + call bdos ; show test name + call initcrc ; initialise crc +; test loop +tlp: lda iut + cpi 076h ; pragmatically avoid halt intructions + jz tlp2 + ani 0dfh + cpi 0ddh + jnz tlp1 + lda iut+1 + cpi 076h +tlp1: cnz test ; execute the test instruction +tlp2: call count ; increment the counter + cnz shift ; shift the scan bit + pop h ; pointer to test case + jz tlp3 ; done if shift returned NZ + lxi d,20+20+20 + dad d ; point to expected crc + call cmpcrc + jz crcGood + lxi d,ermsg1 + mvi c,9 + call bdos + call phex8 + lxi d,ermsg2 + mvi c,9 + call bdos + lxi h,crcval + call phex8 +doCrLf: lxi d,crlf +tlpok: mvi c,9 + call bdos + pop h + inx h + inx h + ret + +crcGood: lxi d,okMsg + mvi c,9 + call bdos + call phex8 + jmp doCrLf + +tlp3: push h + mvi a,1 ; initialise count and shift scanners + sta cntbit + sta shfbit + lxi h,counter + shld cntbyt + lxi h,shifter + shld shfbyt + + mvi b,4 ; bytes in iut field + pop h ; pointer to test case + push h + lxi d,iut + call setup ; setup iut + mvi b,16 ; bytes in machine state + lxi d,msbt + call setup ; setup machine state + jmp tlp + +; setup a field of the test case +; b = number of bytes +; hl = pointer to base case +; de = destination +setup: call subyte + inx h + dcr b + jnz setup + ret + +subyte: push b + push d + push h + mov c,m ; get base byte + lxi d,20 + dad d ; point to incmask + mov a,m + cpi 0 + jz subshf + mvi b,8 ; 8 bits +subclp: rrc + push psw + mvi a,0 + cc nxtcbit ; get next counter bit if mask bit was set + xra c ; flip bit if counter bit was set + rrc + mov c,a + pop psw + dcr b + jnz subclp + mvi b,8 +subshf: lxi d,20 + dad d ; point to shift mask + mov a,m + cpi 0 + jz substr + mvi b,8 ; 8 bits +sbshf1: rrc + push psw + mvi a,0 + cc nxtsbit ; get next shifter bit if mask bit was set + xra c ; flip bit if shifter bit was set + rrc + mov c,a + pop psw + dcr b + jnz sbshf1 +substr: pop h + pop d + mov a,c + stax d ; mangled byte to destination + inx d + pop b + ret + +; get next counter bit in low bit of a +cntbit: ds 1 +cntbyt: ds 2 + +nxtcbit: push b + push h + lhld cntbyt + mov b,m + lxi h,cntbit + mov a,m + mov c,a + rlc + mov m,a + cpi 1 + jnz ncb1 + lhld cntbyt + inx h + shld cntbyt +ncb1: mov a,b + ana c + pop h + pop b + rz + mvi a,1 + ret + +; get next shifter bit in low bit of a +shfbit: ds 1 +shfbyt: ds 2 + +nxtsbit: push b + push h + lhld shfbyt + mov b,m + lxi h,shfbit + mov a,m + mov c,a + rlc + mov m,a + cpi 1 + jnz nsb1 + lhld shfbyt + inx h + shld shfbyt +nsb1: mov a,b + ana c + pop h + pop b + rz + mvi a,1 + ret + + +; clear memory at hl, bc bytes +clrmem: push psw + push b + push d + push h + mvi m,0 + mov d,h + mov e,l + inx d + dcx b + +;#idb ldir replaced with following code +ldir3: mov a,m + stax d + inx h + inx d + dcx b + mov a,b + ora c + jnz ldir3 +;#idb + + pop h + pop d + pop b + pop psw + ret + +; initialise counter or shifter +; de = pointer to work area for counter or shifter +; hl = pointer to mask +initmask: + push d + xchg + lxi b,20+20 + call clrmem ; clear work area + xchg + mvi b,20 ; byte counter + mvi c,1 ; first bit + mvi d,0 ; bit counter +imlp: mov e,m +imlp1: mov a,e + ana c + jz imlp2 + inr d +imlp2: mov a,c + rlc + mov c,a + cpi 1 + jnz imlp1 + inx h + dcr b + jnz imlp +; got number of 1-bits in mask in reg d + mov a,d + ani 0f8h + rrc + rrc + rrc ; divide by 8 (get byte offset) + mov l,a + mvi h,0 + mov a,d + ani 7 ; bit offset + inr a + mov b,a + mvi a,080h +imlp3: rlc + dcr b + jnz imlp3 + pop d + dad d + lxi d,20 + dad d + mov m,a + ret + +; multi-byte counter +count: push b + push d + push h + lxi h,counter ; 20 byte counter starts here + lxi d,20 ; somewhere in here is the stop bit + xchg + dad d + xchg +cntlp: inr m + mov a,m + cpi 0 + jz cntlp1 ; overflow to next byte + mov b,a + ldax d + ana b ; test for terminal value + jz cntend + mvi m,0 ; reset to zero +cntend: pop b + pop d + pop h + ret + +cntlp1: inx h + inx d + jmp cntlp + + +; multi-byte shifter +shift: push b + push d + push h + lxi h,shifter ; 20 byte shift register starts here + lxi d,20 ; somewhere in here is the stop bit + xchg + dad d + xchg +shflp: mov a,m + ora a + jz shflp1 + mov b,a + ldax d + ana b + jnz shlpe + mov a,b + rlc + cpi 1 + jnz shflp2 + mvi m,0 + inx h + inx d +shflp2: mov m,a + xra a ; set Z +shlpe: pop h + pop d + pop b + ret +shflp1: inx h + inx d + jmp shflp + +counter: ds 2*20 +shifter: ds 2*20 + +; test harness +test: push psw + push b + push d + push h + if 0 + lxi d,crlf + mvi c,9 + call bdos + lxi h,iut + mvi b,4 + call hexstr + mvi e,' ' + mvi c,2 + call bdos + mvi b,16 + lxi h,msbt + call hexstr + endif + di ; disable interrupts + +;#idb ld (spsav),sp replaced by following code +;#idb All registers and flages are immediately overwritten so +;#idb no need to preserve any state. + lxi h,0 ; save stack pointer + dad sp + shld spsav +;#idb + + lxi sp,msbt+2 ; point to test-case machine state + +;#idb pop iy +;#idb pop ix both replaced by following code +;#idb Just dummy out ix/iy with copies of hl + pop h ; and load all regs + pop h +;#idb + + pop h + pop d + pop b + pop psw + +;#idb ld sp,(spbt) replaced with the following code +;#idb HL is copied/restored before/after load so no state changed + shld temp + lhld spbt + sphl + lhld temp +;#idb + +iut: ds 4 ; max 4 byte instruction under test + +;#idb ld (spat),sp replaced with the following code +;#idb Must be very careful to preserve registers and flag +;#idb state resulting from the test. The temptation is to use the +;#idb stack - but that doesn't work because of the way the app +;#idb uses SP as a quick way of pointing to memory. +;#idb Bit of a code smell, but I can't think of an easier way. + shld temp + lxi h,0 + jc temp1 ;jump on the state of the C flag set in the test + + dad sp ;this code will clear the C flag (0 + nnnn = nc) + jmp temp2 ;C flag is same state as before + +temp1: dad sp ;this code will clear the C flag (0 + nnnn = nc) + stc ;C flage needs re-setting to preserve state + +temp2: shld spat + lhld temp +;#idb + + lxi sp,spat + push psw ; save other registers + push b + push d + push h + +;#idb push ix +;#idb push iy both replaced by following code +;#idb Must match change made to pops made before test + push h + push h +;#idb + +;#idb ld sp,(spsav) replaced with following code +;#idb No need to preserve state + lhld spsav ; restore stack pointer + sphl +;#idb + + ei ; enable interrupts + lhld msbt ; copy memory operand + shld msat + lxi h,flgsat ; flags after test + mov a,m +flgmsk: ani 0ffh ; mask-out irrelevant bits (self-modified code!) + mov m,a + mvi b,16 ; total of 16 bytes of state + lxi d,msat + lxi h,crcval +tcrc: ldax d + inx d + call updcrc ; accumulate crc of this test case + dcr b + jnz tcrc + if 0 + mvi e,' ' + mvi c,2 + call bdos + lxi h,crcval + call phex8 + lxi d,crlf + mvi c,9 + call bdos + lxi h,msat + mvi b,16 + call hexstr + lxi d,crlf + mvi c,9 + call bdos + endif + pop h + pop d + pop b + pop psw + ret + +;#idb Added to store HL state +temp: ds 2 +;#idb + +; machine state after test +msat: ds 14 ; memop,iy,ix,hl,de,bc,af +spat: ds 2 ; stack pointer after test +flgsat equ spat-2 ; flags + +spsav: ds 2 ; saved stack pointer + +; display hex string (pointer in hl, byte count in b) +hexstr: mov a,m + call phex2 + inx h + dcr b + jnz hexstr + ret + +; display hex +; display the big-endian 32-bit value pointed to by hl +phex8: push psw + push b + push h + mvi b,4 +ph8lp: mov a,m + call phex2 + inx h + dcr b + jnz ph8lp + pop h + pop b + pop psw + ret + +; display byte in a +phex2: push psw + rrc + rrc + rrc + rrc + call phex1 + pop psw +; fall through + +; display low nibble in a +phex1: push psw + push b + push d + push h + ani 0fh + cpi 10 + jc ph11 + adi 'a'-'9'-1 +ph11: adi '0' + mov e,a + mvi c,2 + call bdos + pop h + pop d + pop b + pop psw + ret + +bdos: push psw + push b + push d + push h + call 5 + pop h + pop d + pop b + pop psw + ret + +msg1: db '8080 instruction exerciser',10,13,'$' +msg2: db 'Tests complete$' +okmsg: db ' PASS! crc is:$' +ermsg1: db ' ERROR **** crc expected:$' +ermsg2: db ' found:$' +crlf: db 10,13,'$' + +; compare crc +; hl points to value to compare to crcval +cmpcrc: push b + push d + push h + lxi d,crcval + mvi b,4 +cclp: ldax d + cmp m + jnz cce + inx h + inx d + dcr b + jnz cclp +cce: pop h + pop d + pop b + ret + +; 32-bit crc routine +; entry: a contains next byte, hl points to crc +; exit: crc updated +updcrc: push psw + push b + push d + push h + push h + lxi d,3 + dad d ; point to low byte of old crc + xra m ; xor with new byte + mov l,a + mvi h,0 + dad h ; use result as index into table of 4 byte entries + dad h + xchg + lxi h,crctab + dad d ; point to selected entry in crctab + xchg + pop h + lxi b,4 ; c = byte count, b = accumulator +crclp: ldax d + xra b + mov b,m + mov m,a + inx d + inx h + dcr c + jnz crclp + if 0 + lxi h,crcval + call phex8 + lxi d,crlf + mvi c,9 + call bdos + endif + pop h + pop d + pop b + pop psw + ret + +initcrc:push psw + push b + push h + lxi h,crcval + mvi a,0ffh + mvi b,4 +icrclp: mov m,a + inx h + dcr b + jnz icrclp + pop h + pop b + pop psw + ret + +crcval: ds 4 + +crctab: db 000h,000h,000h,000h + db 077h,007h,030h,096h + db 0eeh,00eh,061h,02ch + db 099h,009h,051h,0bah + db 007h,06dh,0c4h,019h + db 070h,06ah,0f4h,08fh + db 0e9h,063h,0a5h,035h + db 09eh,064h,095h,0a3h + db 00eh,0dbh,088h,032h + db 079h,0dch,0b8h,0a4h + db 0e0h,0d5h,0e9h,01eh + db 097h,0d2h,0d9h,088h + db 009h,0b6h,04ch,02bh + db 07eh,0b1h,07ch,0bdh + db 0e7h,0b8h,02dh,007h + db 090h,0bfh,01dh,091h + db 01dh,0b7h,010h,064h + db 06ah,0b0h,020h,0f2h + db 0f3h,0b9h,071h,048h + db 084h,0beh,041h,0deh + db 01ah,0dah,0d4h,07dh + db 06dh,0ddh,0e4h,0ebh + db 0f4h,0d4h,0b5h,051h + db 083h,0d3h,085h,0c7h + db 013h,06ch,098h,056h + db 064h,06bh,0a8h,0c0h + db 0fdh,062h,0f9h,07ah + db 08ah,065h,0c9h,0ech + db 014h,001h,05ch,04fh + db 063h,006h,06ch,0d9h + db 0fah,00fh,03dh,063h + db 08dh,008h,00dh,0f5h + db 03bh,06eh,020h,0c8h + db 04ch,069h,010h,05eh + db 0d5h,060h,041h,0e4h + db 0a2h,067h,071h,072h + db 03ch,003h,0e4h,0d1h + db 04bh,004h,0d4h,047h + db 0d2h,00dh,085h,0fdh + db 0a5h,00ah,0b5h,06bh + db 035h,0b5h,0a8h,0fah + db 042h,0b2h,098h,06ch + db 0dbh,0bbh,0c9h,0d6h + db 0ach,0bch,0f9h,040h + db 032h,0d8h,06ch,0e3h + db 045h,0dfh,05ch,075h + db 0dch,0d6h,00dh,0cfh + db 0abh,0d1h,03dh,059h + db 026h,0d9h,030h,0ach + db 051h,0deh,000h,03ah + db 0c8h,0d7h,051h,080h + db 0bfh,0d0h,061h,016h + db 021h,0b4h,0f4h,0b5h + db 056h,0b3h,0c4h,023h + db 0cfh,0bah,095h,099h + db 0b8h,0bdh,0a5h,00fh + db 028h,002h,0b8h,09eh + db 05fh,005h,088h,008h + db 0c6h,00ch,0d9h,0b2h + db 0b1h,00bh,0e9h,024h + db 02fh,06fh,07ch,087h + db 058h,068h,04ch,011h + db 0c1h,061h,01dh,0abh + db 0b6h,066h,02dh,03dh + db 076h,0dch,041h,090h + db 001h,0dbh,071h,006h + db 098h,0d2h,020h,0bch + db 0efh,0d5h,010h,02ah + db 071h,0b1h,085h,089h + db 006h,0b6h,0b5h,01fh + db 09fh,0bfh,0e4h,0a5h + db 0e8h,0b8h,0d4h,033h + db 078h,007h,0c9h,0a2h + db 00fh,000h,0f9h,034h + db 096h,009h,0a8h,08eh + db 0e1h,00eh,098h,018h + db 07fh,06ah,00dh,0bbh + db 008h,06dh,03dh,02dh + db 091h,064h,06ch,097h + db 0e6h,063h,05ch,001h + db 06bh,06bh,051h,0f4h + db 01ch,06ch,061h,062h + db 085h,065h,030h,0d8h + db 0f2h,062h,000h,04eh + db 06ch,006h,095h,0edh + db 01bh,001h,0a5h,07bh + db 082h,008h,0f4h,0c1h + db 0f5h,00fh,0c4h,057h + db 065h,0b0h,0d9h,0c6h + db 012h,0b7h,0e9h,050h + db 08bh,0beh,0b8h,0eah + db 0fch,0b9h,088h,07ch + db 062h,0ddh,01dh,0dfh + db 015h,0dah,02dh,049h + db 08ch,0d3h,07ch,0f3h + db 0fbh,0d4h,04ch,065h + db 04dh,0b2h,061h,058h + db 03ah,0b5h,051h,0ceh + db 0a3h,0bch,000h,074h + db 0d4h,0bbh,030h,0e2h + db 04ah,0dfh,0a5h,041h + db 03dh,0d8h,095h,0d7h + db 0a4h,0d1h,0c4h,06dh + db 0d3h,0d6h,0f4h,0fbh + db 043h,069h,0e9h,06ah + db 034h,06eh,0d9h,0fch + db 0adh,067h,088h,046h + db 0dah,060h,0b8h,0d0h + db 044h,004h,02dh,073h + db 033h,003h,01dh,0e5h + db 0aah,00ah,04ch,05fh + db 0ddh,00dh,07ch,0c9h + db 050h,005h,071h,03ch + db 027h,002h,041h,0aah + db 0beh,00bh,010h,010h + db 0c9h,00ch,020h,086h + db 057h,068h,0b5h,025h + db 020h,06fh,085h,0b3h + db 0b9h,066h,0d4h,009h + db 0ceh,061h,0e4h,09fh + db 05eh,0deh,0f9h,00eh + db 029h,0d9h,0c9h,098h + db 0b0h,0d0h,098h,022h + db 0c7h,0d7h,0a8h,0b4h + db 059h,0b3h,03dh,017h + db 02eh,0b4h,00dh,081h + db 0b7h,0bdh,05ch,03bh + db 0c0h,0bah,06ch,0adh + db 0edh,0b8h,083h,020h + db 09ah,0bfh,0b3h,0b6h + db 003h,0b6h,0e2h,00ch + db 074h,0b1h,0d2h,09ah + db 0eah,0d5h,047h,039h + db 09dh,0d2h,077h,0afh + db 004h,0dbh,026h,015h + db 073h,0dch,016h,083h + db 0e3h,063h,00bh,012h + db 094h,064h,03bh,084h + db 00dh,06dh,06ah,03eh + db 07ah,06ah,05ah,0a8h + db 0e4h,00eh,0cfh,00bh + db 093h,009h,0ffh,09dh + db 00ah,000h,0aeh,027h + db 07dh,007h,09eh,0b1h + db 0f0h,00fh,093h,044h + db 087h,008h,0a3h,0d2h + db 01eh,001h,0f2h,068h + db 069h,006h,0c2h,0feh + db 0f7h,062h,057h,05dh + db 080h,065h,067h,0cbh + db 019h,06ch,036h,071h + db 06eh,06bh,006h,0e7h + db 0feh,0d4h,01bh,076h + db 089h,0d3h,02bh,0e0h + db 010h,0dah,07ah,05ah + db 067h,0ddh,04ah,0cch + db 0f9h,0b9h,0dfh,06fh + db 08eh,0beh,0efh,0f9h + db 017h,0b7h,0beh,043h + db 060h,0b0h,08eh,0d5h + db 0d6h,0d6h,0a3h,0e8h + db 0a1h,0d1h,093h,07eh + db 038h,0d8h,0c2h,0c4h + db 04fh,0dfh,0f2h,052h + db 0d1h,0bbh,067h,0f1h + db 0a6h,0bch,057h,067h + db 03fh,0b5h,006h,0ddh + db 048h,0b2h,036h,04bh + db 0d8h,00dh,02bh,0dah + db 0afh,00ah,01bh,04ch + db 036h,003h,04ah,0f6h + db 041h,004h,07ah,060h + db 0dfh,060h,0efh,0c3h + db 0a8h,067h,0dfh,055h + db 031h,06eh,08eh,0efh + db 046h,069h,0beh,079h + db 0cbh,061h,0b3h,08ch + db 0bch,066h,083h,01ah + db 025h,06fh,0d2h,0a0h + db 052h,068h,0e2h,036h + db 0cch,00ch,077h,095h + db 0bbh,00bh,047h,003h + db 022h,002h,016h,0b9h + db 055h,005h,026h,02fh + db 0c5h,0bah,03bh,0beh + db 0b2h,0bdh,00bh,028h + db 02bh,0b4h,05ah,092h + db 05ch,0b3h,06ah,004h + db 0c2h,0d7h,0ffh,0a7h + db 0b5h,0d0h,0cfh,031h + db 02ch,0d9h,09eh,08bh + db 05bh,0deh,0aeh,01dh + db 09bh,064h,0c2h,0b0h + db 0ech,063h,0f2h,026h + db 075h,06ah,0a3h,09ch + db 002h,06dh,093h,00ah + db 09ch,009h,006h,0a9h + db 0ebh,00eh,036h,03fh + db 072h,007h,067h,085h + db 005h,000h,057h,013h + db 095h,0bfh,04ah,082h + db 0e2h,0b8h,07ah,014h + db 07bh,0b1h,02bh,0aeh + db 00ch,0b6h,01bh,038h + db 092h,0d2h,08eh,09bh + db 0e5h,0d5h,0beh,00dh + db 07ch,0dch,0efh,0b7h + db 00bh,0dbh,0dfh,021h + db 086h,0d3h,0d2h,0d4h + db 0f1h,0d4h,0e2h,042h + db 068h,0ddh,0b3h,0f8h + db 01fh,0dah,083h,06eh + db 081h,0beh,016h,0cdh + db 0f6h,0b9h,026h,05bh + db 06fh,0b0h,077h,0e1h + db 018h,0b7h,047h,077h + db 088h,008h,05ah,0e6h + db 0ffh,00fh,06ah,070h + db 066h,006h,03bh,0cah + db 011h,001h,00bh,05ch + db 08fh,065h,09eh,0ffh + db 0f8h,062h,0aeh,069h + db 061h,06bh,0ffh,0d3h + db 016h,06ch,0cfh,045h + db 0a0h,00ah,0e2h,078h + db 0d7h,00dh,0d2h,0eeh + db 04eh,004h,083h,054h + db 039h,003h,0b3h,0c2h + db 0a7h,067h,026h,061h + db 0d0h,060h,016h,0f7h + db 049h,069h,047h,04dh + db 03eh,06eh,077h,0dbh + db 0aeh,0d1h,06ah,04ah + db 0d9h,0d6h,05ah,0dch + db 040h,0dfh,00bh,066h + db 037h,0d8h,03bh,0f0h + db 0a9h,0bch,0aeh,053h + db 0deh,0bbh,09eh,0c5h + db 047h,0b2h,0cfh,07fh + db 030h,0b5h,0ffh,0e9h + db 0bdh,0bdh,0f2h,01ch + db 0cah,0bah,0c2h,08ah + db 053h,0b3h,093h,030h + db 024h,0b4h,0a3h,0a6h + db 0bah,0d0h,036h,005h + db 0cdh,0d7h,006h,093h + db 054h,0deh,057h,029h + db 023h,0d9h,067h,0bfh + db 0b3h,066h,07ah,02eh + db 0c4h,061h,04ah,0b8h + db 05dh,068h,01bh,002h + db 02ah,06fh,02bh,094h + db 0b4h,00bh,0beh,037h + db 0c3h,00ch,08eh,0a1h + db 05ah,005h,0dfh,01bh + db 02dh,002h,0efh,08dh + + end diff --git a/Intel8080/Intel8080.Test/roms/8080EXM.PRN b/Intel8080/Intel8080.Test/roms/8080EXM.PRN new file mode 100644 index 0000000..301e914 --- /dev/null +++ b/Intel8080/Intel8080.Test/roms/8080EXM.PRN @@ -0,0 +1,2254 @@ + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1 + + + title 'Z80 instruction set exerciser' + + ; zexlax.z80 - Z80 instruction set exerciser + ; Copyright (C) 1994 Frank D. Cringle + ; + ; This program is free software; you can redistribute it and/or + ; modify it under the terms of the GNU General Public License + ; as published by the Free Software Foundation; either version 2 + ; of the License, or (at your option) any later version. + ; + ; This program is distributed in the hope that it will be useful, + ; but WITHOUT ANY WARRANTY; without even the implied warranty of + ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ; GNU General Public License for more details. + ; + ; You should have received a copy of the GNU General Public License + ; along with this program; if not, write to the Free Software + ; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ; + ;****************************************************************************** + ; + ; Modified to exercise an 8080 by Ian Bartholomew, February 2009 + ; + ; I have made the following changes - + ; + ; Converted all mnemonics to 8080 and rewritten any Z80 code used + ; in the original exerciser. Changes are tagged with a #idb in the + ; source code listing. + ; + ; Removed any test descriptors that are not used. + ; + ; Changed the macro definitions to work in M80 + ; + ; The machine state snapshot has been changed to remove the IX/IY registers. + ; They have been replaced by two more copies of HL to obviate the need + ; for major changes in the exerciser code. + ; + ; Changed flag mask in all tests to 0ffh to reflect that the 8080, unlike the 8085 + ; and Z80, does define the unused bits in the flag register - [S Z 0 AC 0 P 1 C] + ; + ;****************************************************************************** + ; + ; Modified to include success CRCs as shown on the 8080/8085 CPU Exerciser + ; website http://www.idb.me.uk/sunhillow/8080.html + ; + ; Also updated to display the CRC when the test is passed instead of just + ; displaying "OK" + ; + ; Mike Douglas, May 2013 + ; + .8080 + 0000' aseg + org 100h + + 0100 C3 0113 begin: jmp start + + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-1 + + + ; machine state before test (needs to be at predictably constant address) + 0103 msbt: ds 14 + 0111 spbt: ds 2 + + ; For the purposes of this test program, the machine state consists of: + ; a 2 byte memory operand, followed by + ; the registers iy,ix,hl,de,bc,af,sp + ; for a total of 16 bytes. + + ; The program tests instructions (or groups of similar instructions) + ; by cycling through a sequence of machine states, executing the test + ; instruction for each one and running a 32-bit crc over the resulting + ; machine states. At the end of the sequence the crc is compared to + ; an expected value that was found empirically on a real Z80. + + ; A test case is defined by a descriptor which consists of: + ; a flag mask byte, + ; the base case, + ; the incement vector, + ; the shift vector, + ; the expected crc, + ; a short descriptive message. + ; + ; The flag mask byte is used to prevent undefined flag bits from + ; influencing the results. Documented flags are as per Mostek Z80 + ; Technical Manual. + ; + ; The next three parts of the descriptor are 20 byte vectors + ; corresponding to a 4 byte instruction and a 16 byte machine state. + ; The first part is the base case, which is the first test case of + ; the sequence. This base is then modified according to the next 2 + ; vectors. Each 1 bit in the increment vector specifies a bit to be + ; cycled in the form of a binary counter. For instance, if the byte + ; corresponding to the accumulator is set to 0ffh in the increment + ; vector, the test will be repeated for all 256 values of the + ; accumulator. Note that 1 bits don't have to be contiguous. The + ; number of test cases 'caused' by the increment vector is equal to + ; 2^(number of 1 bits). The shift vector is similar, but specifies a + ; set of bits in the test case that are to be successively inverted. + ; Thus the shift vector 'causes' a number of test cases equal to the + ; number of 1 bits in it. + + ; The total number of test cases is the product of those caused by the + ; counter and shift vectors and can easily become unweildy. Each + ; individual test case can take a few milliseconds to execute, due to + ; the overhead of test setup and crc calculation, so test design is a + ; compromise between coverage and execution time. + + ; This program is designed to detect differences between + ; implementations and is not ideal for diagnosing the causes of any + ; discrepancies. However, provided a reference implementation (or + ; real system) is available, a failing test case can be isolated by + ; hand using a binary search of the test space. + + + 0113 2A 0006 start: lhld 6 + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-2 + + + 0116 F9 sphl + 0117 11 0E01 lxi d,msg1 + 011A 0E 09 mvi c,9 + 011C CD 0DF5 call bdos + + 011F 21 013A lxi h,tests ; first test case + 0122 7E loop: mov a,m ; end of list ? + 0123 23 inx h + 0124 B6 ora m + 0125 CA 012F jz done + 0128 2B dcx h + 0129 CD 0ACE call stt + 012C C3 0122 jmp loop + + 012F 11 0E1E done: lxi d,msg2 + 0132 0E 09 mvi c,9 + 0134 CD 0DF5 call bdos + 0137 C3 0000 jmp 0 ; warm boot + + 013A tests: + 013A 016E dw add16 + 013C 01CE dw alu8i + 013E 022E dw alu8r + 0140 028E dw daa + 0142 02EE dw inca + 0144 034E dw incb + 0146 03AE dw incbc + 0148 040E dw incc + 014A 046E dw incd + 014C 04CE dw incde + 014E 052E dw ince + 0150 058E dw inch + 0152 05EE dw inchl + 0154 064E dw incl + 0156 06AE dw incm + 0158 070E dw incsp + 015A 076E dw ld162 + 015C 07CE dw ld166 + 015E 082E dw ld16im + 0160 088E dw ld8bd + 0162 08EE dw ld8im + 0164 094E dw ld8rr + 0166 09AE dw lda + 0168 0A0E dw rot8080 + 016A 0A6E dw stabd + 016C 0000 dw 0 + + tstr macro insn,memop,hliy,hlix,hl,de,bc,flags,acc,sp + local lab + lab: db insn + ds lab+4-$,0 + dw memop,hliy,hlix,hl,de,bc + db flags + db acc + dw sp + if $-lab ne 20 + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-3 + + + error 'missing parameter' + endif + endm + + tmsg macro m + local lab + lab: db m + if $ ge lab+30 + error 'message too long' + else + ds lab+30-$,'.' + endif + db '$' + endm + + ; add hl, (19,456 cycles) + 016E FF add16: db 0ffh ; flag mask + tstr 9,0c4a5h,0c4c7h,0d226h,0a050h,058eah,08566h,0c6h,0deh,09bc9h + 016F 09 + ..0000: db 9 + 0170 + ds ..0000+4-$,0 + 0173 C4A5 C4C7 + dw 0c4a5h,0c4c7h,0d226h,0a050h,058eah,08566h + 0177 D226 A050 + + 017B 58EA 8566 + + 017F C6 + db 0c6h + 0180 DE + db 0deh + 0181 9BC9 + dw 09bc9h + tstr 030h,0,0,0,0f821h,0,0,0,0,0 ; (512 cycles) + 0183 30 + ..0001: db 030h + 0184 + ds ..0001+4-$,0 + 0187 0000 0000 + dw 0,0,0,0f821h,0,0 + 018B 0000 F821 + + 018F 0000 0000 + + 0193 00 + db 0 + 0194 00 + db 0 + 0195 0000 + dw 0 + tstr 0,0,0,0,-1,-1,-1,0d7h,0,-1 ; (38 cycles) + 0197 00 + ..0002: db 0 + 0198 + ds ..0002+4-$,0 + 019B 0000 0000 + dw 0,0,0,-1,-1,-1 + 019F 0000 FFFF + + 01A3 FFFF FFFF + + 01A7 D7 + db 0d7h + 01A8 00 + db 0 + 01A9 FFFF + dw -1 + 01AB 14 47 4B A6 db 014h, 047h, 04Bh, 0A6h ; expected crc + tmsg 'dad ' + 01AF 64 61 64 20 + ..0003: db 'dad ' + 01B3 3C 62 2C 64 + + 01B7 2C 68 2C 73 + + 01BB 70 3E + + 01BD + ds ..0003+30-$,'.' + 01CD 24 + db '$' + + ; aluop a,nn (28,672 cycles) + 01CE FF alu8i: db 0ffh ; flag mask + tstr 0c6h,09140h,07e3ch,07a67h,0df6dh,05b61h,00b29h,010h,066h,085b2h + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-4 + + + 01CF C6 + ..0004: db 0c6h + 01D0 + ds ..0004+4-$,0 + 01D3 9140 7E3C + dw 09140h,07e3ch,07a67h,0df6dh,05b61h,00b29h + 01D7 7A67 DF6D + + 01DB 5B61 0B29 + + 01DF 10 + db 010h + 01E0 66 + db 066h + 01E1 85B2 + dw 085b2h + tstr 038h,0,0,0,0,0,0,0,-1,0 ; (2048 cycles) + 01E3 38 + ..0005: db 038h + 01E4 + ds ..0005+4-$,0 + 01E7 0000 0000 + dw 0,0,0,0,0,0 + 01EB 0000 0000 + + 01EF 0000 0000 + + 01F3 00 + db 0 + 01F4 FF + db -1 + 01F5 0000 + dw 0 + tstr <0,-1>,0,0,0,0,0,0,0d7h,0,0 ; (14 cycles) + 01F7 00 FF + ..0006: db 0,-1 + 01F9 + ds ..0006+4-$,0 + 01FB 0000 0000 + dw 0,0,0,0,0,0 + 01FF 0000 0000 + + 0203 0000 0000 + + 0207 D7 + db 0d7h + 0208 00 + db 0 + 0209 0000 + dw 0 + 020B 9E 92 2F 9E db 09Eh, 092h, 02Fh, 09Eh ; expected crc + tmsg 'aluop nn' + 020F 61 6C 75 6F + ..0007: db 'aluop nn' + 0213 70 20 6E 6E + + 0217 + ds ..0007+30-$,'.' + 022D 24 + db '$' + + ; aluop a, (753,664 cycles) + 022E FF alu8r: db 0ffh ; flag mask + tstr 080h,0c53eh,0573ah,04c4dh,msbt,0e309h,0a666h,0d0h,03bh,0adbbh + 022F 80 + ..0008: db 080h + 0230 + ds ..0008+4-$,0 + 0233 C53E 573A + dw 0c53eh,0573ah,04c4dh,msbt,0e309h,0a666h + 0237 4C4D 0103 + + 023B E309 A666 + + 023F D0 + db 0d0h + 0240 3B + db 03bh + 0241 ADBB + dw 0adbbh + tstr 03fh,0,0,0,0,0,0,0,-1,0 ; (16,384 cycles) + 0243 3F + ..0009: db 03fh + 0244 + ds ..0009+4-$,0 + 0247 0000 0000 + dw 0,0,0,0,0,0 + 024B 0000 0000 + + 024F 0000 0000 + + 0253 00 + db 0 + 0254 FF + db -1 + 0255 0000 + dw 0 + tstr 0,0ffh,0,0,0,-1,-1,0d7h,0,0 ; (46 cycles) + 0257 00 + ..000A: db 0 + 0258 + ds ..000A+4-$,0 + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-5 + + + 025B 00FF 0000 + dw 0ffh,0,0,0,-1,-1 + 025F 0000 0000 + + 0263 FFFF FFFF + + 0267 D7 + db 0d7h + 0268 00 + db 0 + 0269 0000 + dw 0 + 026B CF 76 2C 86 db 0CFh, 076h, 02Ch, 086h ; expected crc + tmsg 'aluop ' + 026F 61 6C 75 6F + ..000B: db 'aluop ' + 0273 70 20 3C 62 + + 0277 2C 63 2C 64 + + 027B 2C 65 2C 68 + + 027F 2C 6C 2C 6D + + 0283 2C 61 3E + + 0286 + ds ..000B+30-$,'.' + 028D 24 + db '$' + + ; + 028E FF daa: db 0ffh ; flag mask + tstr 027h,02141h,009fah,01d60h,0a559h,08d5bh,09079h,004h,08eh,0299dh + 028F 27 + ..000C: db 027h + 0290 + ds ..000C+4-$,0 + 0293 2141 09FA + dw 02141h,009fah,01d60h,0a559h,08d5bh,09079h + 0297 1D60 A559 + + 029B 8D5B 9079 + + 029F 04 + db 004h + 02A0 8E + db 08eh + 02A1 299D + dw 0299dh + tstr 018h,0,0,0,0,0,0,0d7h,-1,0 ; (65,536 cycles) + 02A3 18 + ..000D: db 018h + 02A4 + ds ..000D+4-$,0 + 02A7 0000 0000 + dw 0,0,0,0,0,0 + 02AB 0000 0000 + + 02AF 0000 0000 + + 02B3 D7 + db 0d7h + 02B4 FF + db -1 + 02B5 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) + 02B7 00 + ..000E: db 0 + 02B8 + ds ..000E+4-$,0 + 02BB 0000 0000 + dw 0,0,0,0,0,0 + 02BF 0000 0000 + + 02C3 0000 0000 + + 02C7 00 + db 0 + 02C8 00 + db 0 + 02C9 0000 + dw 0 + 02CB BB 3F 03 0C db 0BBh, 03Fh, 003h, 00Ch ; expected crc + tmsg '' + 02CF 3C 64 61 61 + ..000F: db '' + 02D3 2C 63 6D 61 + + 02D7 2C 73 74 63 + + 02DB 2C 63 6D 63 + + 02DF 3E + + 02E0 + ds ..000F+30-$,'.' + 02ED 24 + db '$' + + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-6 + + + ; a (3072 cycles) + 02EE FF inca: db 0ffh ; flag mask + tstr 03ch,04adfh,0d5d8h,0e598h,08a2bh,0a7b0h,0431bh,044h,05ah,0d030h + 02EF 3C + ..0010: db 03ch + 02F0 + ds ..0010+4-$,0 + 02F3 4ADF D5D8 + dw 04adfh,0d5d8h,0e598h,08a2bh,0a7b0h,0431bh + 02F7 E598 8A2B + + 02FB A7B0 431B + + 02FF 44 + db 044h + 0300 5A + db 05ah + 0301 D030 + dw 0d030h + tstr 001h,0,0,0,0,0,0,0,-1,0 ; (512 cycles) + 0303 01 + ..0011: db 001h + 0304 + ds ..0011+4-$,0 + 0307 0000 0000 + dw 0,0,0,0,0,0 + 030B 0000 0000 + + 030F 0000 0000 + + 0313 00 + db 0 + 0314 FF + db -1 + 0315 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + 0317 00 + ..0012: db 0 + 0318 + ds ..0012+4-$,0 + 031B 0000 0000 + dw 0,0,0,0,0,0 + 031F 0000 0000 + + 0323 0000 0000 + + 0327 D7 + db 0d7h + 0328 00 + db 0 + 0329 0000 + dw 0 + 032B AD B6 46 0E db 0ADh, 0B6h, 046h, 00Eh ; expected crc + tmsg ' a' + 032F 3C 69 6E 72 + ..0013: db ' a' + 0333 2C 64 63 72 + + 0337 3E 20 61 + + 033A + ds ..0013+30-$,'.' + 034D 24 + db '$' + + ; b (3072 cycles) + 034E FF incb: db 0ffh ; flag mask + tstr 004h,0d623h,0432dh,07a61h,08180h,05a86h,01e85h,086h,058h,09bbbh + 034F 04 + ..0014: db 004h + 0350 + ds ..0014+4-$,0 + 0353 D623 432D + dw 0d623h,0432dh,07a61h,08180h,05a86h,01e85h + 0357 7A61 8180 + + 035B 5A86 1E85 + + 035F 86 + db 086h + 0360 58 + db 058h + 0361 9BBB + dw 09bbbh + tstr 001h,0,0,0,0,0,0ff00h,0,0,0 ; (512 cycles) + 0363 01 + ..0015: db 001h + 0364 + ds ..0015+4-$,0 + 0367 0000 0000 + dw 0,0,0,0,0,0ff00h + 036B 0000 0000 + + 036F 0000 FF00 + + 0373 00 + db 0 + 0374 00 + db 0 + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-7 + + + 0375 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + 0377 00 + ..0016: db 0 + 0378 + ds ..0016+4-$,0 + 037B 0000 0000 + dw 0,0,0,0,0,0 + 037F 0000 0000 + + 0383 0000 0000 + + 0387 D7 + db 0d7h + 0388 00 + db 0 + 0389 0000 + dw 0 + 038B 83 ED 13 45 db 083h, 0EDh, 013h, 045h ; expected crc + tmsg ' b' + 038F 3C 69 6E 72 + ..0017: db ' b' + 0393 2C 64 63 72 + + 0397 3E 20 62 + + 039A + ds ..0017+30-$,'.' + 03AD 24 + db '$' + + ; bc (1536 cycles) + 03AE FF incbc: db 0ffh ; flag mask + tstr 003h,0cd97h,044abh,08dc9h,0e3e3h,011cch,0e8a4h,002h,049h,02a4dh + 03AF 03 + ..0018: db 003h + 03B0 + ds ..0018+4-$,0 + 03B3 CD97 44AB + dw 0cd97h,044abh,08dc9h,0e3e3h,011cch,0e8a4h + 03B7 8DC9 E3E3 + + 03BB 11CC E8A4 + + 03BF 02 + db 002h + 03C0 49 + db 049h + 03C1 2A4D + dw 02a4dh + tstr 008h,0,0,0,0,0,0f821h,0,0,0 ; (256 cycles) + 03C3 08 + ..0019: db 008h + 03C4 + ds ..0019+4-$,0 + 03C7 0000 0000 + dw 0,0,0,0,0,0f821h + 03CB 0000 0000 + + 03CF 0000 F821 + + 03D3 00 + db 0 + 03D4 00 + db 0 + 03D5 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + 03D7 00 + ..001A: db 0 + 03D8 + ds ..001A+4-$,0 + 03DB 0000 0000 + dw 0,0,0,0,0,0 + 03DF 0000 0000 + + 03E3 0000 0000 + + 03E7 D7 + db 0d7h + 03E8 00 + db 0 + 03E9 0000 + dw 0 + 03EB F7 92 87 CD db 0F7h, 092h, 087h, 0CDh ; expected crc + tmsg ' b' + 03EF 3C 69 6E 78 + ..001B: db ' b' + 03F3 2C 64 63 78 + + 03F7 3E 20 62 + + 03FA + ds ..001B+30-$,'.' + 040D 24 + db '$' + + ; c (3072 cycles) + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-8 + + + 040E FF incc: db 0ffh ; flag mask + tstr 00ch,0d789h,00935h,0055bh,09f85h,08b27h,0d208h,095h,005h,00660h + 040F 0C + ..001C: db 00ch + 0410 + ds ..001C+4-$,0 + 0413 D789 0935 + dw 0d789h,00935h,0055bh,09f85h,08b27h,0d208h + 0417 055B 9F85 + + 041B 8B27 D208 + + 041F 95 + db 095h + 0420 05 + db 005h + 0421 0660 + dw 00660h + tstr 001h,0,0,0,0,0,0ffh,0,0,0 ; (512 cycles) + 0423 01 + ..001D: db 001h + 0424 + ds ..001D+4-$,0 + 0427 0000 0000 + dw 0,0,0,0,0,0ffh + 042B 0000 0000 + + 042F 0000 00FF + + 0433 00 + db 0 + 0434 00 + db 0 + 0435 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + 0437 00 + ..001E: db 0 + 0438 + ds ..001E+4-$,0 + 043B 0000 0000 + dw 0,0,0,0,0,0 + 043F 0000 0000 + + 0443 0000 0000 + + 0447 D7 + db 0d7h + 0448 00 + db 0 + 0449 0000 + dw 0 + 044B E5 F6 72 1B db 0E5h, 0F6h, 072h, 01Bh ; expected crc + tmsg ' c' + 044F 3C 69 6E 72 + ..001F: db ' c' + 0453 2C 64 63 72 + + 0457 3E 20 63 + + 045A + ds ..001F+30-$,'.' + 046D 24 + db '$' + + ; d (3072 cycles) + 046E FF incd: db 0ffh ; flag mask + tstr 014h,0a0eah,05fbah,065fbh,0981ch,038cch,0debch,043h,05ch,003bdh + 046F 14 + ..0020: db 014h + 0470 + ds ..0020+4-$,0 + 0473 A0EA 5FBA + dw 0a0eah,05fbah,065fbh,0981ch,038cch,0debch + 0477 65FB 981C + + 047B 38CC DEBC + + 047F 43 + db 043h + 0480 5C + db 05ch + 0481 03BD + dw 003bdh + tstr 001h,0,0,0,0,0ff00h,0,0,0,0 ; (512 cycles) + 0483 01 + ..0021: db 001h + 0484 + ds ..0021+4-$,0 + 0487 0000 0000 + dw 0,0,0,0,0ff00h,0 + 048B 0000 0000 + + 048F FF00 0000 + + 0493 00 + db 0 + 0494 00 + db 0 + 0495 0000 + dw 0 + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-9 + + + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + 0497 00 + ..0022: db 0 + 0498 + ds ..0022+4-$,0 + 049B 0000 0000 + dw 0,0,0,0,0,0 + 049F 0000 0000 + + 04A3 0000 0000 + + 04A7 D7 + db 0d7h + 04A8 00 + db 0 + 04A9 0000 + dw 0 + 04AB 15 B5 57 9A db 015h, 0B5h, 057h, 09Ah ; expected crc + tmsg ' d' + 04AF 3C 69 6E 72 + ..0023: db ' d' + 04B3 2C 64 63 72 + + 04B7 3E 20 64 + + 04BA + ds ..0023+30-$,'.' + 04CD 24 + db '$' + + ; de (1536 cycles) + 04CE FF incde: db 0ffh ; flag mask + tstr 013h,0342eh,0131dh,028c9h,00acah,09967h,03a2eh,092h,0f6h,09d54h + 04CF 13 + ..0024: db 013h + 04D0 + ds ..0024+4-$,0 + 04D3 342E 131D + dw 0342eh,0131dh,028c9h,00acah,09967h,03a2eh + 04D7 28C9 0ACA + + 04DB 9967 3A2E + + 04DF 92 + db 092h + 04E0 F6 + db 0f6h + 04E1 9D54 + dw 09d54h + tstr 008h,0,0,0,0,0f821h,0,0,0,0 ; (256 cycles) + 04E3 08 + ..0025: db 008h + 04E4 + ds ..0025+4-$,0 + 04E7 0000 0000 + dw 0,0,0,0,0f821h,0 + 04EB 0000 0000 + + 04EF F821 0000 + + 04F3 00 + db 0 + 04F4 00 + db 0 + 04F5 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + 04F7 00 + ..0026: db 0 + 04F8 + ds ..0026+4-$,0 + 04FB 0000 0000 + dw 0,0,0,0,0,0 + 04FF 0000 0000 + + 0503 0000 0000 + + 0507 D7 + db 0d7h + 0508 00 + db 0 + 0509 0000 + dw 0 + 050B 7F 4E 25 01 db 07Fh, 04Eh, 025h, 001h ; expected crc + tmsg ' d' + 050F 3C 69 6E 78 + ..0027: db ' d' + 0513 2C 64 63 78 + + 0517 3E 20 64 + + 051A + ds ..0027+30-$,'.' + 052D 24 + db '$' + + ; e (3072 cycles) + 052E FF ince: db 0ffh ; flag mask + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-10 + + + tstr 01ch,0602fh,04c0dh,02402h,0e2f5h,0a0f4h,0a10ah,013h,032h,05925h + 052F 1C + ..0028: db 01ch + 0530 + ds ..0028+4-$,0 + 0533 602F 4C0D + dw 0602fh,04c0dh,02402h,0e2f5h,0a0f4h,0a10ah + 0537 2402 E2F5 + + 053B A0F4 A10A + + 053F 13 + db 013h + 0540 32 + db 032h + 0541 5925 + dw 05925h + tstr 001h,0,0,0,0,0ffh,0,0,0,0 ; (512 cycles) + 0543 01 + ..0029: db 001h + 0544 + ds ..0029+4-$,0 + 0547 0000 0000 + dw 0,0,0,0,0ffh,0 + 054B 0000 0000 + + 054F 00FF 0000 + + 0553 00 + db 0 + 0554 00 + db 0 + 0555 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + 0557 00 + ..002A: db 0 + 0558 + ds ..002A+4-$,0 + 055B 0000 0000 + dw 0,0,0,0,0,0 + 055F 0000 0000 + + 0563 0000 0000 + + 0567 D7 + db 0d7h + 0568 00 + db 0 + 0569 0000 + dw 0 + 056B CF 2A B3 96 db 0CFh, 02Ah, 0B3h, 096h ; expected crc + tmsg ' e' + 056F 3C 69 6E 72 + ..002B: db ' e' + 0573 2C 64 63 72 + + 0577 3E 20 65 + + 057A + ds ..002B+30-$,'.' + 058D 24 + db '$' + + ; h (3072 cycles) + 058E FF inch: db 0ffh ; flag mask + tstr 024h,01506h,0f2ebh,0e8ddh,0262bh,011a6h,0bc1ah,017h,006h,02818h + 058F 24 + ..002C: db 024h + 0590 + ds ..002C+4-$,0 + 0593 1506 F2EB + dw 01506h,0f2ebh,0e8ddh,0262bh,011a6h,0bc1ah + 0597 E8DD 262B + + 059B 11A6 BC1A + + 059F 17 + db 017h + 05A0 06 + db 006h + 05A1 2818 + dw 02818h + tstr 001h,0,0,0,0ff00h,0,0,0,0,0 ; (512 cycles) + 05A3 01 + ..002D: db 001h + 05A4 + ds ..002D+4-$,0 + 05A7 0000 0000 + dw 0,0,0,0ff00h,0,0 + 05AB 0000 FF00 + + 05AF 0000 0000 + + 05B3 00 + db 0 + 05B4 00 + db 0 + 05B5 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-11 + + + 05B7 00 + ..002E: db 0 + 05B8 + ds ..002E+4-$,0 + 05BB 0000 0000 + dw 0,0,0,0,0,0 + 05BF 0000 0000 + + 05C3 0000 0000 + + 05C7 D7 + db 0d7h + 05C8 00 + db 0 + 05C9 0000 + dw 0 + 05CB 12 B2 95 2C db 012h, 0B2h, 095h, 02Ch ; expected crc + tmsg ' h' + 05CF 3C 69 6E 72 + ..002F: db ' h' + 05D3 2C 64 63 72 + + 05D7 3E 20 68 + + 05DA + ds ..002F+30-$,'.' + 05ED 24 + db '$' + + ; hl (1536 cycles) + 05EE FF inchl: db 0ffh ; flag mask + tstr 023h,0c3f4h,007a5h,01b6dh,04f04h,0e2c2h,0822ah,057h,0e0h,0c3e1h + 05EF 23 + ..0030: db 023h + 05F0 + ds ..0030+4-$,0 + 05F3 C3F4 07A5 + dw 0c3f4h,007a5h,01b6dh,04f04h,0e2c2h,0822ah + 05F7 1B6D 4F04 + + 05FB E2C2 822A + + 05FF 57 + db 057h + 0600 E0 + db 0e0h + 0601 C3E1 + dw 0c3e1h + tstr 008h,0,0,0,0f821h,0,0,0,0,0 ; (256 cycles) + 0603 08 + ..0031: db 008h + 0604 + ds ..0031+4-$,0 + 0607 0000 0000 + dw 0,0,0,0f821h,0,0 + 060B 0000 F821 + + 060F 0000 0000 + + 0613 00 + db 0 + 0614 00 + db 0 + 0615 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + 0617 00 + ..0032: db 0 + 0618 + ds ..0032+4-$,0 + 061B 0000 0000 + dw 0,0,0,0,0,0 + 061F 0000 0000 + + 0623 0000 0000 + + 0627 D7 + db 0d7h + 0628 00 + db 0 + 0629 0000 + dw 0 + 062B 9F 2B 23 C0 db 09Fh, 02Bh, 023h, 0C0h ; expected crc + tmsg ' h' + 062F 3C 69 6E 78 + ..0033: db ' h' + 0633 2C 64 63 78 + + 0637 3E 20 68 + + 063A + ds ..0033+30-$,'.' + 064D 24 + db '$' + + ; l (3072 cycles) + 064E FF incl: db 0ffh ; flag mask + tstr 02ch,08031h,0a520h,04356h,0b409h,0f4c1h,0dfa2h,0d1h,03ch,03ea2h + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-12 + + + 064F 2C + ..0034: db 02ch + 0650 + ds ..0034+4-$,0 + 0653 8031 A520 + dw 08031h,0a520h,04356h,0b409h,0f4c1h,0dfa2h + 0657 4356 B409 + + 065B F4C1 DFA2 + + 065F D1 + db 0d1h + 0660 3C + db 03ch + 0661 3EA2 + dw 03ea2h + tstr 001h,0,0,0,0ffh,0,0,0,0,0 ; (512 cycles) + 0663 01 + ..0035: db 001h + 0664 + ds ..0035+4-$,0 + 0667 0000 0000 + dw 0,0,0,0ffh,0,0 + 066B 0000 00FF + + 066F 0000 0000 + + 0673 00 + db 0 + 0674 00 + db 0 + 0675 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + 0677 00 + ..0036: db 0 + 0678 + ds ..0036+4-$,0 + 067B 0000 0000 + dw 0,0,0,0,0,0 + 067F 0000 0000 + + 0683 0000 0000 + + 0687 D7 + db 0d7h + 0688 00 + db 0 + 0689 0000 + dw 0 + 068B FF 57 D3 56 db 0FFh, 057h, 0D3h, 056h ; expected crc + tmsg ' l' + 068F 3C 69 6E 72 + ..0037: db ' l' + 0693 2C 64 63 72 + + 0697 3E 20 6C + + 069A + ds ..0037+30-$,'.' + 06AD 24 + db '$' + + ; (hl) (3072 cycles) + 06AE FF incm: db 0ffh ; flag mask + tstr 034h,0b856h,00c7ch,0e53eh,msbt,0877eh,0da58h,015h,05ch,01f37h + 06AF 34 + ..0038: db 034h + 06B0 + ds ..0038+4-$,0 + 06B3 B856 0C7C + dw 0b856h,00c7ch,0e53eh,msbt,0877eh,0da58h + 06B7 E53E 0103 + + 06BB 877E DA58 + + 06BF 15 + db 015h + 06C0 5C + db 05ch + 06C1 1F37 + dw 01f37h + tstr 001h,0ffh,0,0,0,0,0,0,0,0 ; (512 cycles) + 06C3 01 + ..0039: db 001h + 06C4 + ds ..0039+4-$,0 + 06C7 00FF 0000 + dw 0ffh,0,0,0,0,0 + 06CB 0000 0000 + + 06CF 0000 0000 + + 06D3 00 + db 0 + 06D4 00 + db 0 + 06D5 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + 06D7 00 + ..003A: db 0 + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-13 + + + 06D8 + ds ..003A+4-$,0 + 06DB 0000 0000 + dw 0,0,0,0,0,0 + 06DF 0000 0000 + + 06E3 0000 0000 + + 06E7 D7 + db 0d7h + 06E8 00 + db 0 + 06E9 0000 + dw 0 + 06EB 92 E9 63 BD db 092h, 0E9h, 063h, 0BDh ; expected crc + tmsg ' m' + 06EF 3C 69 6E 72 + ..003B: db ' m' + 06F3 2C 64 63 72 + + 06F7 3E 20 6D + + 06FA + ds ..003B+30-$,'.' + 070D 24 + db '$' + + ; sp (1536 cycles) + 070E FF incsp: db 0ffh ; flag mask + tstr 033h,0346fh,0d482h,0d169h,0deb6h,0a494h,0f476h,053h,002h,0855bh + 070F 33 + ..003C: db 033h + 0710 + ds ..003C+4-$,0 + 0713 346F D482 + dw 0346fh,0d482h,0d169h,0deb6h,0a494h,0f476h + 0717 D169 DEB6 + + 071B A494 F476 + + 071F 53 + db 053h + 0720 02 + db 002h + 0721 855B + dw 0855bh + tstr 008h,0,0,0,0,0,0,0,0,0f821h ; (256 cycles) + 0723 08 + ..003D: db 008h + 0724 + ds ..003D+4-$,0 + 0727 0000 0000 + dw 0,0,0,0,0,0 + 072B 0000 0000 + + 072F 0000 0000 + + 0733 00 + db 0 + 0734 00 + db 0 + 0735 F821 + dw 0f821h + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + 0737 00 + ..003E: db 0 + 0738 + ds ..003E+4-$,0 + 073B 0000 0000 + dw 0,0,0,0,0,0 + 073F 0000 0000 + + 0743 0000 0000 + + 0747 D7 + db 0d7h + 0748 00 + db 0 + 0749 0000 + dw 0 + 074B D5 70 2F AB db 0D5h, 070h, 02Fh, 0ABh ; expected crc + tmsg ' sp' + 074F 3C 69 6E 78 + ..003F: db ' sp' + 0753 2C 64 63 78 + + 0757 3E 20 73 70 + + 075B + ds ..003F+30-$,'.' + 076D 24 + db '$' + + ; ld hl,(nnnn) (16 cycles) + 076E FF ld162: db 0ffh ; flag mask + tstr <02ah,low msbt,high msbt>,09863h,07830h,02077h,0b1feh,0b9fah,0abb8h,004h,006h,06015h + 076F 2A 03 01 + ..0040: db 02ah,low msbt,high msbt + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-14 + + + 0772 + ds ..0040+4-$,0 + 0773 9863 7830 + dw 09863h,07830h,02077h,0b1feh,0b9fah,0abb8h + 0777 2077 B1FE + + 077B B9FA ABB8 + + 077F 04 + db 004h + 0780 06 + db 006h + 0781 6015 + dw 06015h + tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) + 0783 00 + ..0041: db 0 + 0784 + ds ..0041+4-$,0 + 0787 0000 0000 + dw 0,0,0,0,0,0 + 078B 0000 0000 + + 078F 0000 0000 + + 0793 00 + db 0 + 0794 00 + db 0 + 0795 0000 + dw 0 + tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) + 0797 00 + ..0042: db 0 + 0798 + ds ..0042+4-$,0 + 079B FFFF 0000 + dw -1,0,0,0,0,0 + 079F 0000 0000 + + 07A3 0000 0000 + + 07A7 00 + db 0 + 07A8 00 + db 0 + 07A9 0000 + dw 0 + 07AB A9 C3 D5 CB db 0A9h, 0C3h, 0D5h, 0CBh ; expected crc + tmsg 'lhld nnnn' + 07AF 6C 68 6C 64 + ..0043: db 'lhld nnnn' + 07B3 20 6E 6E 6E + + 07B7 6E + + 07B8 + ds ..0043+30-$,'.' + 07CD 24 + db '$' + + ; ld (nnnn),hl (16 cycles) + 07CE FF ld166: db 0ffh ; flag mask + tstr <022h,low msbt,high msbt>,0d003h,07772h,07f53h,03f72h,064eah,0e180h,010h,02dh,035e9h + 07CF 22 03 01 + ..0044: db 022h,low msbt,high msbt + 07D2 + ds ..0044+4-$,0 + 07D3 D003 7772 + dw 0d003h,07772h,07f53h,03f72h,064eah,0e180h + 07D7 7F53 3F72 + + 07DB 64EA E180 + + 07DF 10 + db 010h + 07E0 2D + db 02dh + 07E1 35E9 + dw 035e9h + tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) + 07E3 00 + ..0045: db 0 + 07E4 + ds ..0045+4-$,0 + 07E7 0000 0000 + dw 0,0,0,0,0,0 + 07EB 0000 0000 + + 07EF 0000 0000 + + 07F3 00 + db 0 + 07F4 00 + db 0 + 07F5 0000 + dw 0 + tstr 0,0,0,0,-1,0,0,0,0,0 ; (16 cycles) + 07F7 00 + ..0046: db 0 + 07F8 + ds ..0046+4-$,0 + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-15 + + + 07FB 0000 0000 + dw 0,0,0,-1,0,0 + 07FF 0000 FFFF + + 0803 0000 0000 + + 0807 00 + db 0 + 0808 00 + db 0 + 0809 0000 + dw 0 + 080B E8 86 4F 26 db 0E8h, 086h, 04Fh, 026h ; expected crc + tmsg 'shld nnnn' + 080F 73 68 6C 64 + ..0047: db 'shld nnnn' + 0813 20 6E 6E 6E + + 0817 6E + + 0818 + ds ..0047+30-$,'.' + 082D 24 + db '$' + + ; ld ,nnnn (64 cycles) + 082E FF ld16im: db 0ffh ; flag mask + tstr 1,05c1ch,02d46h,08eb9h,06078h,074b1h,0b30eh,046h,0d1h,030cch + 082F 01 + ..0048: db 1 + 0830 + ds ..0048+4-$,0 + 0833 5C1C 2D46 + dw 05c1ch,02d46h,08eb9h,06078h,074b1h,0b30eh + 0837 8EB9 6078 + + 083B 74B1 B30E + + 083F 46 + db 046h + 0840 D1 + db 0d1h + 0841 30CC + dw 030cch + tstr 030h,0,0,0,0,0,0,0,0,0 ; (4 cycles) + 0843 30 + ..0049: db 030h + 0844 + ds ..0049+4-$,0 + 0847 0000 0000 + dw 0,0,0,0,0,0 + 084B 0000 0000 + + 084F 0000 0000 + + 0853 00 + db 0 + 0854 00 + db 0 + 0855 0000 + dw 0 + tstr <0,0ffh,0ffh>,0,0,0,0,0,0,0,0,0 ; (16 cycles) + 0857 00 FF FF + ..004A: db 0,0ffh,0ffh + 085A + ds ..004A+4-$,0 + 085B 0000 0000 + dw 0,0,0,0,0,0 + 085F 0000 0000 + + 0863 0000 0000 + + 0867 00 + db 0 + 0868 00 + db 0 + 0869 0000 + dw 0 + 086B FC F4 6E 12 db 0FCh, 0F4h, 06Eh, 012h ; expected crc + tmsg 'lxi ,nnnn' + 086F 6C 78 69 20 + ..004B: db 'lxi ,nnnn' + 0873 3C 62 2C 64 + + 0877 2C 68 2C 73 + + 087B 70 3E 2C 6E + + 087F 6E 6E 6E + + 0882 + ds ..004B+30-$,'.' + 088D 24 + db '$' + + ; ld a,<(bc),(de)> (44 cycles) + 088E FF ld8bd: db 0ffh ; flag mask + tstr 00ah,0b3a8h,01d2ah,07f8eh,042ach,msbt,msbt,0c6h,0b1h,0ef8eh + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-16 + + + 088F 0A + ..004C: db 00ah + 0890 + ds ..004C+4-$,0 + 0893 B3A8 1D2A + dw 0b3a8h,01d2ah,07f8eh,042ach,msbt,msbt + 0897 7F8E 42AC + + 089B 0103 0103 + + 089F C6 + db 0c6h + 08A0 B1 + db 0b1h + 08A1 EF8E + dw 0ef8eh + tstr 010h,0,0,0,0,0,0,0,0,0 ; (2 cycles) + 08A3 10 + ..004D: db 010h + 08A4 + ds ..004D+4-$,0 + 08A7 0000 0000 + dw 0,0,0,0,0,0 + 08AB 0000 0000 + + 08AF 0000 0000 + + 08B3 00 + db 0 + 08B4 00 + db 0 + 08B5 0000 + dw 0 + tstr 0,0ffh,0,0,0,0,0,0d7h,-1,0 ; (22 cycles) + 08B7 00 + ..004E: db 0 + 08B8 + ds ..004E+4-$,0 + 08BB 00FF 0000 + dw 0ffh,0,0,0,0,0 + 08BF 0000 0000 + + 08C3 0000 0000 + + 08C7 D7 + db 0d7h + 08C8 FF + db -1 + 08C9 0000 + dw 0 + 08CB 2B 82 1D 5F db 02Bh, 082h, 01Dh, 05Fh ; expected crc + tmsg 'ldax ' + 08CF 6C 64 61 78 + ..004F: db 'ldax ' + 08D3 20 3C 62 2C + + 08D7 64 3E + + 08D9 + ds ..004F+30-$,'.' + 08ED 24 + db '$' + + ; ld ,nn (64 cycles) + 08EE FF ld8im: db 0ffh ; flag mask + tstr 6,0c407h,0f49dh,0d13dh,00339h,0de89h,07455h,053h,0c0h,05509h + 08EF 06 + ..0050: db 6 + 08F0 + ds ..0050+4-$,0 + 08F3 C407 F49D + dw 0c407h,0f49dh,0d13dh,00339h,0de89h,07455h + 08F7 D13D 0339 + + 08FB DE89 7455 + + 08FF 53 + db 053h + 0900 C0 + db 0c0h + 0901 5509 + dw 05509h + tstr 038h,0,0,0,0,0,0,0,0,0 ; (8 cycles) + 0903 38 + ..0051: db 038h + 0904 + ds ..0051+4-$,0 + 0907 0000 0000 + dw 0,0,0,0,0,0 + 090B 0000 0000 + + 090F 0000 0000 + + 0913 00 + db 0 + 0914 00 + db 0 + 0915 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0,-1,0 ; (8 cycles) + 0917 00 + ..0052: db 0 + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-17 + + + 0918 + ds ..0052+4-$,0 + 091B 0000 0000 + dw 0,0,0,0,0,0 + 091F 0000 0000 + + 0923 0000 0000 + + 0927 00 + db 0 + 0928 FF + db -1 + 0929 0000 + dw 0 + 092B EA A7 20 44 db 0EAh, 0A7h, 020h, 044h ; expected crc + tmsg 'mvi ,nn' + 092F 6D 76 69 20 + ..0053: db 'mvi ,nn' + 0933 3C 62 2C 63 + + 0937 2C 64 2C 65 + + 093B 2C 68 2C 6C + + 093F 2C 6D 2C 61 + + 0943 3E 2C 6E 6E + + 0947 + ds ..0053+30-$,'.' + 094D 24 + db '$' + + ; ld , (3456 cycles) + 094E FF ld8rr: db 0ffh ; flag mask + tstr 040h,072a4h,0a024h,061ach,msbt,082c7h,0718fh,097h,08fh,0ef8eh + 094F 40 + ..0054: db 040h + 0950 + ds ..0054+4-$,0 + 0953 72A4 A024 + dw 072a4h,0a024h,061ach,msbt,082c7h,0718fh + 0957 61AC 0103 + + 095B 82C7 718F + + 095F 97 + db 097h + 0960 8F + db 08fh + 0961 EF8E + dw 0ef8eh + tstr 03fh,0,0,0,0,0,0,0,0,0 ; (64 cycles) + 0963 3F + ..0055: db 03fh + 0964 + ds ..0055+4-$,0 + 0967 0000 0000 + dw 0,0,0,0,0,0 + 096B 0000 0000 + + 096F 0000 0000 + + 0973 00 + db 0 + 0974 00 + db 0 + 0975 0000 + dw 0 + tstr 0,0ffh,0,0,0,-1,-1,0d7h,-1,0 ; (54 cycles) + 0977 00 + ..0056: db 0 + 0978 + ds ..0056+4-$,0 + 097B 00FF 0000 + dw 0ffh,0,0,0,-1,-1 + 097F 0000 0000 + + 0983 FFFF FFFF + + 0987 D7 + db 0d7h + 0988 FF + db -1 + 0989 0000 + dw 0 + 098B 10 B5 8C EE db 010h, 0B5h, 08Ch, 0EEh ; expected crc + tmsg 'mov ,' + 098F 6D 6F 76 20 + ..0057: db 'mov ,' + 0993 3C 62 63 64 + + 0997 65 68 6C 61 + + 099B 3E 2C 3C 62 + + 099F 63 64 65 68 + + 09A3 6C 61 3E + + 09A6 + ds ..0057+30-$,'.' + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-18 + + + 09AD 24 + db '$' + + ; ld a,(nnnn) / ld (nnnn),a (44 cycles) + 09AE FF lda: db 0ffh ; flag mask + tstr <032h,low msbt,high msbt>,0fd68h,0f4ech,044a0h,0b543h,00653h,0cdbah,0d2h,04fh,01fd8h + 09AF 32 03 01 + ..0058: db 032h,low msbt,high msbt + 09B2 + ds ..0058+4-$,0 + 09B3 FD68 F4EC + dw 0fd68h,0f4ech,044a0h,0b543h,00653h,0cdbah + 09B7 44A0 B543 + + 09BB 0653 CDBA + + 09BF D2 + db 0d2h + 09C0 4F + db 04fh + 09C1 1FD8 + dw 01fd8h + tstr 008h,0,0,0,0,0,0,0,0,0 ; (2 cycle) + 09C3 08 + ..0059: db 008h + 09C4 + ds ..0059+4-$,0 + 09C7 0000 0000 + dw 0,0,0,0,0,0 + 09CB 0000 0000 + + 09CF 0000 0000 + + 09D3 00 + db 0 + 09D4 00 + db 0 + 09D5 0000 + dw 0 + tstr 0,0ffh,0,0,0,0,0,0d7h,-1,0 ; (22 cycles) + 09D7 00 + ..005A: db 0 + 09D8 + ds ..005A+4-$,0 + 09DB 00FF 0000 + dw 0ffh,0,0,0,0,0 + 09DF 0000 0000 + + 09E3 0000 0000 + + 09E7 D7 + db 0d7h + 09E8 FF + db -1 + 09E9 0000 + dw 0 + 09EB ED 57 AF 72 db 0EDh, 057h, 0AFh, 072h ; expected crc + tmsg 'sta nnnn / lda nnnn' + 09EF 73 74 61 20 + ..005B: db 'sta nnnn / lda nnnn' + 09F3 6E 6E 6E 6E + + 09F7 20 2F 20 6C + + 09FB 64 61 20 6E + + 09FF 6E 6E 6E + + 0A02 + ds ..005B+30-$,'.' + 0A0D 24 + db '$' + + ; (6144 cycles) + 0A0E FF rot8080: db 0ffh ; flag mask + tstr 7,0cb92h,06d43h,00a90h,0c284h,00c53h,0f50eh,091h,0ebh,040fch + 0A0F 07 + ..005C: db 7 + 0A10 + ds ..005C+4-$,0 + 0A13 CB92 6D43 + dw 0cb92h,06d43h,00a90h,0c284h,00c53h,0f50eh + 0A17 0A90 C284 + + 0A1B 0C53 F50E + + 0A1F 91 + db 091h + 0A20 EB + db 0ebh + 0A21 40FC + dw 040fch + tstr 018h,0,0,0,0,0,0,0,-1,0 ; (1024 cycles) + 0A23 18 + ..005D: db 018h + 0A24 + ds ..005D+4-$,0 + 0A27 0000 0000 + dw 0,0,0,0,0,0 + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-19 + + + 0A2B 0000 0000 + + 0A2F 0000 0000 + + 0A33 00 + db 0 + 0A34 FF + db -1 + 0A35 0000 + dw 0 + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + 0A37 00 + ..005E: db 0 + 0A38 + ds ..005E+4-$,0 + 0A3B 0000 0000 + dw 0,0,0,0,0,0 + 0A3F 0000 0000 + + 0A43 0000 0000 + + 0A47 D7 + db 0d7h + 0A48 00 + db 0 + 0A49 0000 + dw 0 + 0A4B E0 D8 92 35 db 0E0h, 0D8h, 092h, 035h ; expected crc + tmsg '' + 0A4F 3C 72 6C 63 + ..005F: db '' + 0A53 2C 72 72 63 + + 0A57 2C 72 61 6C + + 0A5B 2C 72 61 72 + + 0A5F 3E + + 0A60 + ds ..005F+30-$,'.' + 0A6D 24 + db '$' + + ; ld (),a (96 cycles) + 0A6E FF stabd: db 0ffh ; flag mask + tstr 2,00c3bh,0b592h,06cffh,0959eh,msbt,msbt+1,0c1h,021h,0bde7h + 0A6F 02 + ..0060: db 2 + 0A70 + ds ..0060+4-$,0 + 0A73 0C3B B592 + dw 00c3bh,0b592h,06cffh,0959eh,msbt,msbt+1 + 0A77 6CFF 959E + + 0A7B 0103 0104 + + 0A7F C1 + db 0c1h + 0A80 21 + db 021h + 0A81 BDE7 + dw 0bde7h + tstr 018h,0,0,0,0,0,0,0,0,0 ; (4 cycles) + 0A83 18 + ..0061: db 018h + 0A84 + ds ..0061+4-$,0 + 0A87 0000 0000 + dw 0,0,0,0,0,0 + 0A8B 0000 0000 + + 0A8F 0000 0000 + + 0A93 00 + db 0 + 0A94 00 + db 0 + 0A95 0000 + dw 0 + tstr 0,-1,0,0,0,0,0,0,-1,0 ; (24 cycles) + 0A97 00 + ..0062: db 0 + 0A98 + ds ..0062+4-$,0 + 0A9B FFFF 0000 + dw -1,0,0,0,0,0 + 0A9F 0000 0000 + + 0AA3 0000 0000 + + 0AA7 00 + db 0 + 0AA8 FF + db -1 + 0AA9 0000 + dw 0 + 0AAB 2B 04 71 E9 db 02Bh, 004h, 071h, 0E9h ; expected crc + tmsg 'stax ' + 0AAF 73 74 61 78 + ..0063: db 'stax ' + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-20 + + + 0AB3 20 3C 62 2C + + 0AB7 64 3E + + 0AB9 + ds ..0063+30-$,'.' + 0ACD 24 + db '$' + + ; start test pointed to by (hl) + 0ACE E5 stt: push h + 0ACF 7E mov a,m ; get pointer to test + 0AD0 23 inx h + 0AD1 66 mov h,m + 0AD2 6F mov l,a + 0AD3 7E mov a,m ; flag mask + 0AD4 32 0D8A sta flgmsk+1 + 0AD7 23 inx h + 0AD8 E5 push h + 0AD9 11 0014 lxi d,20 + 0ADC 19 dad d ; point to incmask + 0ADD 11 0CE9 lxi d,counter + 0AE0 CD 0C58 call initmask + 0AE3 E1 pop h + 0AE4 E5 push h + 0AE5 11 0028 lxi d,20+20 + 0AE8 19 dad d ; point to scanmask + 0AE9 11 0D11 lxi d,shifter + 0AEC CD 0C58 call initmask + 0AEF 21 0D11 lxi h,shifter + 0AF2 36 01 mvi m,1 ; first bit + 0AF4 E1 pop h + 0AF5 E5 push h + 0AF6 11 0D58 lxi d,iut ; copy initial instruction under test + 0AF9 01 0004 lxi b,4 + + ;#idb ldir replaced with following code + 0AFC 7E ldir1: mov a,m + 0AFD 12 stax d + 0AFE 23 inx h + 0AFF 13 inx d + 0B00 0B dcx b + 0B01 78 mov a,b + 0B02 B1 ora c + 0B03 C2 0AFC jnz ldir1 + ;#idb + + 0B06 11 0103 lxi d,msbt ; copy initial machine state + 0B09 01 0010 lxi b,16 + + ;#idb ldir replaced with following code + 0B0C 7E ldir2: mov a,m + 0B0D 12 stax d + 0B0E 23 inx h + 0B0F 13 inx d + 0B10 0B dcx b + 0B11 78 mov a,b + 0B12 B1 ora c + 0B13 C2 0B0C jnz ldir2 + ;#idb + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-21 + + + + 0B16 11 002C lxi d,20+20+4 ; skip incmask, scanmask and expcrc + 0B19 19 dad d + 0B1A EB xchg + 0B1B 0E 09 mvi c,9 + 0B1D CD 0DF5 call bdos ; show test name + 0B20 CD 0EA2 call initcrc ; initialise crc + ; test loop + 0B23 3A 0D58 tlp: lda iut + 0B26 FE 76 cpi 076h ; pragmatically avoid halt intructions + 0B28 CA 0B3A jz tlp2 + 0B2B E6 DF ani 0dfh + 0B2D FE DD cpi 0ddh + 0B2F C2 0B37 jnz tlp1 + 0B32 3A 0D59 lda iut+1 + 0B35 FE 76 cpi 076h + 0B37 C4 0D39 tlp1: cnz test ; execute the test instruction + 0B3A CD 0C98 tlp2: call count ; increment the counter + 0B3D C4 0CBC cnz shift ; shift the scan bit + 0B40 E1 pop h ; pointer to test case + 0B41 CA 0B81 jz tlp3 ; done if shift returned NZ + 0B44 11 003C lxi d,20+20+20 + 0B47 19 dad d ; point to expected crc + 0B48 CD 0E63 call cmpcrc + 0B4B CA 0B73 jz crcGood + 0B4E 11 0E3D lxi d,ermsg1 + 0B51 0E 09 mvi c,9 + 0B53 CD 0DF5 call bdos + 0B56 CD 0DC0 call phex8 + 0B59 11 0E58 lxi d,ermsg2 + 0B5C 0E 09 mvi c,9 + 0B5E CD 0DF5 call bdos + 0B61 21 0EB6 lxi h,crcval + 0B64 CD 0DC0 call phex8 + 0B67 11 0E60 doCrLf: lxi d,crlf + 0B6A 0E 09 tlpok: mvi c,9 + 0B6C CD 0DF5 call bdos + 0B6F E1 pop h + 0B70 23 inx h + 0B71 23 inx h + 0B72 C9 ret + + 0B73 11 0E2D crcGood: lxi d,okMsg + 0B76 0E 09 mvi c,9 + 0B78 CD 0DF5 call bdos + 0B7B CD 0DC0 call phex8 + 0B7E C3 0B67 jmp doCrLf + + 0B81 E5 tlp3: push h + 0B82 3E 01 mvi a,1 ; initialise count and shift scanners + 0B84 32 0BF7 sta cntbit + 0B87 32 0C1B sta shfbit + 0B8A 21 0CE9 lxi h,counter + 0B8D 22 0BF8 shld cntbyt + 0B90 21 0D11 lxi h,shifter + 0B93 22 0C1C shld shfbyt + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-22 + + + + 0B96 06 04 mvi b,4 ; bytes in iut field + 0B98 E1 pop h ; pointer to test case + 0B99 E5 push h + 0B9A 11 0D58 lxi d,iut + 0B9D CD 0BAB call setup ; setup iut + 0BA0 06 10 mvi b,16 ; bytes in machine state + 0BA2 11 0103 lxi d,msbt + 0BA5 CD 0BAB call setup ; setup machine state + 0BA8 C3 0B23 jmp tlp + + ; setup a field of the test case + ; b = number of bytes + ; hl = pointer to base case + ; de = destination + 0BAB CD 0BB4 setup: call subyte + 0BAE 23 inx h + 0BAF 05 dcr b + 0BB0 C2 0BAB jnz setup + 0BB3 C9 ret + + 0BB4 C5 subyte: push b + 0BB5 D5 push d + 0BB6 E5 push h + 0BB7 4E mov c,m ; get base byte + 0BB8 11 0014 lxi d,20 + 0BBB 19 dad d ; point to incmask + 0BBC 7E mov a,m + 0BBD FE 00 cpi 0 + 0BBF CA 0BD5 jz subshf + 0BC2 06 08 mvi b,8 ; 8 bits + 0BC4 0F subclp: rrc + 0BC5 F5 push psw + 0BC6 3E 00 mvi a,0 + 0BC8 DC 0BFA cc nxtcbit ; get next counter bit if mask bit was set + 0BCB A9 xra c ; flip bit if counter bit was set + 0BCC 0F rrc + 0BCD 4F mov c,a + 0BCE F1 pop psw + 0BCF 05 dcr b + 0BD0 C2 0BC4 jnz subclp + 0BD3 06 08 mvi b,8 + 0BD5 11 0014 subshf: lxi d,20 + 0BD8 19 dad d ; point to shift mask + 0BD9 7E mov a,m + 0BDA FE 00 cpi 0 + 0BDC CA 0BF0 jz substr + 0BDF 06 08 mvi b,8 ; 8 bits + 0BE1 0F sbshf1: rrc + 0BE2 F5 push psw + 0BE3 3E 00 mvi a,0 + 0BE5 DC 0C1E cc nxtsbit ; get next shifter bit if mask bit was set + 0BE8 A9 xra c ; flip bit if shifter bit was set + 0BE9 0F rrc + 0BEA 4F mov c,a + 0BEB F1 pop psw + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-23 + + + 0BEC 05 dcr b + 0BED C2 0BE1 jnz sbshf1 + 0BF0 E1 substr: pop h + 0BF1 D1 pop d + 0BF2 79 mov a,c + 0BF3 12 stax d ; mangled byte to destination + 0BF4 13 inx d + 0BF5 C1 pop b + 0BF6 C9 ret + + ; get next counter bit in low bit of a + 0BF7 cntbit: ds 1 + 0BF8 cntbyt: ds 2 + + 0BFA C5 nxtcbit: push b + 0BFB E5 push h + 0BFC 2A 0BF8 lhld cntbyt + 0BFF 46 mov b,m + 0C00 21 0BF7 lxi h,cntbit + 0C03 7E mov a,m + 0C04 4F mov c,a + 0C05 07 rlc + 0C06 77 mov m,a + 0C07 FE 01 cpi 1 + 0C09 C2 0C13 jnz ncb1 + 0C0C 2A 0BF8 lhld cntbyt + 0C0F 23 inx h + 0C10 22 0BF8 shld cntbyt + 0C13 78 ncb1: mov a,b + 0C14 A1 ana c + 0C15 E1 pop h + 0C16 C1 pop b + 0C17 C8 rz + 0C18 3E 01 mvi a,1 + 0C1A C9 ret + + ; get next shifter bit in low bit of a + 0C1B shfbit: ds 1 + 0C1C shfbyt: ds 2 + + 0C1E C5 nxtsbit: push b + 0C1F E5 push h + 0C20 2A 0C1C lhld shfbyt + 0C23 46 mov b,m + 0C24 21 0C1B lxi h,shfbit + 0C27 7E mov a,m + 0C28 4F mov c,a + 0C29 07 rlc + 0C2A 77 mov m,a + 0C2B FE 01 cpi 1 + 0C2D C2 0C37 jnz nsb1 + 0C30 2A 0C1C lhld shfbyt + 0C33 23 inx h + 0C34 22 0C1C shld shfbyt + 0C37 78 nsb1: mov a,b + 0C38 A1 ana c + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-24 + + + 0C39 E1 pop h + 0C3A C1 pop b + 0C3B C8 rz + 0C3C 3E 01 mvi a,1 + 0C3E C9 ret + + + ; clear memory at hl, bc bytes + 0C3F F5 clrmem: push psw + 0C40 C5 push b + 0C41 D5 push d + 0C42 E5 push h + 0C43 36 00 mvi m,0 + 0C45 54 mov d,h + 0C46 5D mov e,l + 0C47 13 inx d + 0C48 0B dcx b + + ;#idb ldir replaced with following code + 0C49 7E ldir3: mov a,m + 0C4A 12 stax d + 0C4B 23 inx h + 0C4C 13 inx d + 0C4D 0B dcx b + 0C4E 78 mov a,b + 0C4F B1 ora c + 0C50 C2 0C49 jnz ldir3 + ;#idb + + 0C53 E1 pop h + 0C54 D1 pop d + 0C55 C1 pop b + 0C56 F1 pop psw + 0C57 C9 ret + + ; initialise counter or shifter + ; de = pointer to work area for counter or shifter + ; hl = pointer to mask + 0C58 initmask: + 0C58 D5 push d + 0C59 EB xchg + 0C5A 01 0028 lxi b,20+20 + 0C5D CD 0C3F call clrmem ; clear work area + 0C60 EB xchg + 0C61 06 14 mvi b,20 ; byte counter + 0C63 0E 01 mvi c,1 ; first bit + 0C65 16 00 mvi d,0 ; bit counter + 0C67 5E imlp: mov e,m + 0C68 7B imlp1: mov a,e + 0C69 A1 ana c + 0C6A CA 0C6E jz imlp2 + 0C6D 14 inr d + 0C6E 79 imlp2: mov a,c + 0C6F 07 rlc + 0C70 4F mov c,a + 0C71 FE 01 cpi 1 + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-25 + + + 0C73 C2 0C68 jnz imlp1 + 0C76 23 inx h + 0C77 05 dcr b + 0C78 C2 0C67 jnz imlp + ; got number of 1-bits in mask in reg d + 0C7B 7A mov a,d + 0C7C E6 F8 ani 0f8h + 0C7E 0F rrc + 0C7F 0F rrc + 0C80 0F rrc ; divide by 8 (get byte offset) + 0C81 6F mov l,a + 0C82 26 00 mvi h,0 + 0C84 7A mov a,d + 0C85 E6 07 ani 7 ; bit offset + 0C87 3C inr a + 0C88 47 mov b,a + 0C89 3E 80 mvi a,080h + 0C8B 07 imlp3: rlc + 0C8C 05 dcr b + 0C8D C2 0C8B jnz imlp3 + 0C90 D1 pop d + 0C91 19 dad d + 0C92 11 0014 lxi d,20 + 0C95 19 dad d + 0C96 77 mov m,a + 0C97 C9 ret + + ; multi-byte counter + 0C98 C5 count: push b + 0C99 D5 push d + 0C9A E5 push h + 0C9B 21 0CE9 lxi h,counter ; 20 byte counter starts here + 0C9E 11 0014 lxi d,20 ; somewhere in here is the stop bit + 0CA1 EB xchg + 0CA2 19 dad d + 0CA3 EB xchg + 0CA4 34 cntlp: inr m + 0CA5 7E mov a,m + 0CA6 FE 00 cpi 0 + 0CA8 CA 0CB7 jz cntlp1 ; overflow to next byte + 0CAB 47 mov b,a + 0CAC 1A ldax d + 0CAD A0 ana b ; test for terminal value + 0CAE CA 0CB3 jz cntend + 0CB1 36 00 mvi m,0 ; reset to zero + 0CB3 C1 cntend: pop b + 0CB4 D1 pop d + 0CB5 E1 pop h + 0CB6 C9 ret + + 0CB7 23 cntlp1: inx h + 0CB8 13 inx d + 0CB9 C3 0CA4 jmp cntlp + + + ; multi-byte shifter + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-26 + + + 0CBC C5 shift: push b + 0CBD D5 push d + 0CBE E5 push h + 0CBF 21 0D11 lxi h,shifter ; 20 byte shift register starts here + 0CC2 11 0014 lxi d,20 ; somewhere in here is the stop bit + 0CC5 EB xchg + 0CC6 19 dad d + 0CC7 EB xchg + 0CC8 7E shflp: mov a,m + 0CC9 B7 ora a + 0CCA CA 0CE4 jz shflp1 + 0CCD 47 mov b,a + 0CCE 1A ldax d + 0CCF A0 ana b + 0CD0 C2 0CE0 jnz shlpe + 0CD3 78 mov a,b + 0CD4 07 rlc + 0CD5 FE 01 cpi 1 + 0CD7 C2 0CDE jnz shflp2 + 0CDA 36 00 mvi m,0 + 0CDC 23 inx h + 0CDD 13 inx d + 0CDE 77 shflp2: mov m,a + 0CDF AF xra a ; set Z + 0CE0 E1 shlpe: pop h + 0CE1 D1 pop d + 0CE2 C1 pop b + 0CE3 C9 ret + 0CE4 23 shflp1: inx h + 0CE5 13 inx d + 0CE6 C3 0CC8 jmp shflp + + 0CE9 counter: ds 2*20 + 0D11 shifter: ds 2*20 + + ; test harness + 0D39 F5 test: push psw + 0D3A C5 push b + 0D3B D5 push d + 0D3C E5 push h + if 0 + lxi d,crlf + mvi c,9 + call bdos + lxi h,iut + mvi b,4 + call hexstr + mvi e,' ' + mvi c,2 + call bdos + mvi b,16 + lxi h,msbt + call hexstr + endif + 0D3D F3 di ; disable interrupts + + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-27 + + + ;#idb ld (spsav),sp replaced by following code + ;#idb All registers and flages are immediately overwritten so + ;#idb no need to preserve any state. + 0D3E 21 0000 lxi h,0 ; save stack pointer + 0D41 39 dad sp + 0D42 22 0DB4 shld spsav + ;#idb + + 0D45 31 0105 lxi sp,msbt+2 ; point to test-case machine state + + ;#idb pop iy + ;#idb pop ix both replaced by following code + ;#idb Just dummy out ix/iy with copies of hl + 0D48 E1 pop h ; and load all regs + 0D49 E1 pop h + ;#idb + + 0D4A E1 pop h + 0D4B D1 pop d + 0D4C C1 pop b + 0D4D F1 pop psw + + ;#idb ld sp,(spbt) replaced with the following code + ;#idb HL is copied/restored before/after load so no state changed + 0D4E 22 0DA2 shld temp + 0D51 2A 0111 lhld spbt + 0D54 F9 sphl + 0D55 2A 0DA2 lhld temp + ;#idb + + 0D58 iut: ds 4 ; max 4 byte instruction under test + + ;#idb ld (spat),sp replaced with the following code + ;#idb Must be very careful to preserve registers and flag + ;#idb state resulting from the test. The temptation is to use the + ;#idb stack - but that doesn't work because of the way the app + ;#idb uses SP as a quick way of pointing to memory. + ;#idb Bit of a code smell, but I can't think of an easier way. + 0D5C 22 0DA2 shld temp + 0D5F 21 0000 lxi h,0 + 0D62 DA 0D69 jc temp1 ;jump on the state of the C flag set in the test + + 0D65 39 dad sp ;this code will clear the C flag (0 + nnnn = nc) + 0D66 C3 0D6B jmp temp2 ;C flag is same state as before + + 0D69 39 temp1: dad sp ;this code will clear the C flag (0 + nnnn = nc) + 0D6A 37 stc ;C flage needs re-setting to preserve state + + 0D6B 22 0DB2 temp2: shld spat + 0D6E 2A 0DA2 lhld temp + ;#idb + + 0D71 31 0DB2 lxi sp,spat + 0D74 F5 push psw ; save other registers + 0D75 C5 push b + 0D76 D5 push d + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-28 + + + 0D77 E5 push h + + ;#idb push ix + ;#idb push iy both replaced by following code + ;#idb Must match change made to pops made before test + 0D78 E5 push h + 0D79 E5 push h + ;#idb + + ;#idb ld sp,(spsav) replaced with following code + ;#idb No need to preserve state + 0D7A 2A 0DB4 lhld spsav ; restore stack pointer + 0D7D F9 sphl + ;#idb + + 0D7E FB ei ; enable interrupts + 0D7F 2A 0103 lhld msbt ; copy memory operand + 0D82 22 0DA4 shld msat + 0D85 21 0DB0 lxi h,flgsat ; flags after test + 0D88 7E mov a,m + 0D89 E6 FF flgmsk: ani 0ffh ; mask-out irrelevant bits (self-modified code!) + 0D8B 77 mov m,a + 0D8C 06 10 mvi b,16 ; total of 16 bytes of state + 0D8E 11 0DA4 lxi d,msat + 0D91 21 0EB6 lxi h,crcval + 0D94 1A tcrc: ldax d + 0D95 13 inx d + 0D96 CD 0E7A call updcrc ; accumulate crc of this test case + 0D99 05 dcr b + 0D9A C2 0D94 jnz tcrc + if 0 + mvi e,' ' + mvi c,2 + call bdos + lxi h,crcval + call phex8 + lxi d,crlf + mvi c,9 + call bdos + lxi h,msat + mvi b,16 + call hexstr + lxi d,crlf + mvi c,9 + call bdos + endif + 0D9D E1 pop h + 0D9E D1 pop d + 0D9F C1 pop b + 0DA0 F1 pop psw + 0DA1 C9 ret + + ;#idb Added to store HL state + 0DA2 temp: ds 2 + ;#idb + + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-29 + + + ; machine state after test + 0DA4 msat: ds 14 ; memop,iy,ix,hl,de,bc,af + 0DB2 spat: ds 2 ; stack pointer after test + 0DB0 flgsat equ spat-2 ; flags + + 0DB4 spsav: ds 2 ; saved stack pointer + + ; display hex string (pointer in hl, byte count in b) + 0DB6 7E hexstr: mov a,m + 0DB7 CD 0DD2 call phex2 + 0DBA 23 inx h + 0DBB 05 dcr b + 0DBC C2 0DB6 jnz hexstr + 0DBF C9 ret + + ; display hex + ; display the big-endian 32-bit value pointed to by hl + 0DC0 F5 phex8: push psw + 0DC1 C5 push b + 0DC2 E5 push h + 0DC3 06 04 mvi b,4 + 0DC5 7E ph8lp: mov a,m + 0DC6 CD 0DD2 call phex2 + 0DC9 23 inx h + 0DCA 05 dcr b + 0DCB C2 0DC5 jnz ph8lp + 0DCE E1 pop h + 0DCF C1 pop b + 0DD0 F1 pop psw + 0DD1 C9 ret + + ; display byte in a + 0DD2 F5 phex2: push psw + 0DD3 0F rrc + 0DD4 0F rrc + 0DD5 0F rrc + 0DD6 0F rrc + 0DD7 CD 0DDB call phex1 + 0DDA F1 pop psw + ; fall through + + ; display low nibble in a + 0DDB F5 phex1: push psw + 0DDC C5 push b + 0DDD D5 push d + 0DDE E5 push h + 0DDF E6 0F ani 0fh + 0DE1 FE 0A cpi 10 + 0DE3 DA 0DE8 jc ph11 + 0DE6 C6 27 adi 'a'-'9'-1 + 0DE8 C6 30 ph11: adi '0' + 0DEA 5F mov e,a + 0DEB 0E 02 mvi c,2 + 0DED CD 0DF5 call bdos + 0DF0 E1 pop h + 0DF1 D1 pop d + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-30 + + + 0DF2 C1 pop b + 0DF3 F1 pop psw + 0DF4 C9 ret + + 0DF5 F5 bdos: push psw + 0DF6 C5 push b + 0DF7 D5 push d + 0DF8 E5 push h + 0DF9 CD 0005 call 5 + 0DFC E1 pop h + 0DFD D1 pop d + 0DFE C1 pop b + 0DFF F1 pop psw + 0E00 C9 ret + + 0E01 38 30 38 30 msg1: db '8080 instruction exerciser',10,13,'$' + 0E05 20 69 6E 73 + 0E09 74 72 75 63 + 0E0D 74 69 6F 6E + 0E11 20 65 78 65 + 0E15 72 63 69 73 + 0E19 65 72 0A 0D + 0E1D 24 + 0E1E 54 65 73 74 msg2: db 'Tests complete$' + 0E22 73 20 63 6F + 0E26 6D 70 6C 65 + 0E2A 74 65 24 + 0E2D 20 20 50 41 okmsg: db ' PASS! crc is:$' + 0E31 53 53 21 20 + 0E35 63 72 63 20 + 0E39 69 73 3A 24 + 0E3D 20 20 45 52 ermsg1: db ' ERROR **** crc expected:$' + 0E41 52 4F 52 20 + 0E45 2A 2A 2A 2A + 0E49 20 63 72 63 + 0E4D 20 65 78 70 + 0E51 65 63 74 65 + 0E55 64 3A 24 + 0E58 20 66 6F 75 ermsg2: db ' found:$' + 0E5C 6E 64 3A 24 + 0E60 0A 0D 24 crlf: db 10,13,'$' + + ; compare crc + ; hl points to value to compare to crcval + 0E63 C5 cmpcrc: push b + 0E64 D5 push d + 0E65 E5 push h + 0E66 11 0EB6 lxi d,crcval + 0E69 06 04 mvi b,4 + 0E6B 1A cclp: ldax d + 0E6C BE cmp m + 0E6D C2 0E76 jnz cce + 0E70 23 inx h + 0E71 13 inx d + 0E72 05 dcr b + 0E73 C2 0E6B jnz cclp + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-31 + + + 0E76 E1 cce: pop h + 0E77 D1 pop d + 0E78 C1 pop b + 0E79 C9 ret + + ; 32-bit crc routine + ; entry: a contains next byte, hl points to crc + ; exit: crc updated + 0E7A F5 updcrc: push psw + 0E7B C5 push b + 0E7C D5 push d + 0E7D E5 push h + 0E7E E5 push h + 0E7F 11 0003 lxi d,3 + 0E82 19 dad d ; point to low byte of old crc + 0E83 AE xra m ; xor with new byte + 0E84 6F mov l,a + 0E85 26 00 mvi h,0 + 0E87 29 dad h ; use result as index into table of 4 byte entries + 0E88 29 dad h + 0E89 EB xchg + 0E8A 21 0EBA lxi h,crctab + 0E8D 19 dad d ; point to selected entry in crctab + 0E8E EB xchg + 0E8F E1 pop h + 0E90 01 0004 lxi b,4 ; c = byte count, b = accumulator + 0E93 1A crclp: ldax d + 0E94 A8 xra b + 0E95 46 mov b,m + 0E96 77 mov m,a + 0E97 13 inx d + 0E98 23 inx h + 0E99 0D dcr c + 0E9A C2 0E93 jnz crclp + if 0 + lxi h,crcval + call phex8 + lxi d,crlf + mvi c,9 + call bdos + endif + 0E9D E1 pop h + 0E9E D1 pop d + 0E9F C1 pop b + 0EA0 F1 pop psw + 0EA1 C9 ret + + 0EA2 F5 initcrc:push psw + 0EA3 C5 push b + 0EA4 E5 push h + 0EA5 21 0EB6 lxi h,crcval + 0EA8 3E FF mvi a,0ffh + 0EAA 06 04 mvi b,4 + 0EAC 77 icrclp: mov m,a + 0EAD 23 inx h + 0EAE 05 dcr b + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-32 + + + 0EAF C2 0EAC jnz icrclp + 0EB2 E1 pop h + 0EB3 C1 pop b + 0EB4 F1 pop psw + 0EB5 C9 ret + + 0EB6 crcval: ds 4 + + 0EBA 00 00 00 00 crctab: db 000h,000h,000h,000h + 0EBE 77 07 30 96 db 077h,007h,030h,096h + 0EC2 EE 0E 61 2C db 0eeh,00eh,061h,02ch + 0EC6 99 09 51 BA db 099h,009h,051h,0bah + 0ECA 07 6D C4 19 db 007h,06dh,0c4h,019h + 0ECE 70 6A F4 8F db 070h,06ah,0f4h,08fh + 0ED2 E9 63 A5 35 db 0e9h,063h,0a5h,035h + 0ED6 9E 64 95 A3 db 09eh,064h,095h,0a3h + 0EDA 0E DB 88 32 db 00eh,0dbh,088h,032h + 0EDE 79 DC B8 A4 db 079h,0dch,0b8h,0a4h + 0EE2 E0 D5 E9 1E db 0e0h,0d5h,0e9h,01eh + 0EE6 97 D2 D9 88 db 097h,0d2h,0d9h,088h + 0EEA 09 B6 4C 2B db 009h,0b6h,04ch,02bh + 0EEE 7E B1 7C BD db 07eh,0b1h,07ch,0bdh + 0EF2 E7 B8 2D 07 db 0e7h,0b8h,02dh,007h + 0EF6 90 BF 1D 91 db 090h,0bfh,01dh,091h + 0EFA 1D B7 10 64 db 01dh,0b7h,010h,064h + 0EFE 6A B0 20 F2 db 06ah,0b0h,020h,0f2h + 0F02 F3 B9 71 48 db 0f3h,0b9h,071h,048h + 0F06 84 BE 41 DE db 084h,0beh,041h,0deh + 0F0A 1A DA D4 7D db 01ah,0dah,0d4h,07dh + 0F0E 6D DD E4 EB db 06dh,0ddh,0e4h,0ebh + 0F12 F4 D4 B5 51 db 0f4h,0d4h,0b5h,051h + 0F16 83 D3 85 C7 db 083h,0d3h,085h,0c7h + 0F1A 13 6C 98 56 db 013h,06ch,098h,056h + 0F1E 64 6B A8 C0 db 064h,06bh,0a8h,0c0h + 0F22 FD 62 F9 7A db 0fdh,062h,0f9h,07ah + 0F26 8A 65 C9 EC db 08ah,065h,0c9h,0ech + 0F2A 14 01 5C 4F db 014h,001h,05ch,04fh + 0F2E 63 06 6C D9 db 063h,006h,06ch,0d9h + 0F32 FA 0F 3D 63 db 0fah,00fh,03dh,063h + 0F36 8D 08 0D F5 db 08dh,008h,00dh,0f5h + 0F3A 3B 6E 20 C8 db 03bh,06eh,020h,0c8h + 0F3E 4C 69 10 5E db 04ch,069h,010h,05eh + 0F42 D5 60 41 E4 db 0d5h,060h,041h,0e4h + 0F46 A2 67 71 72 db 0a2h,067h,071h,072h + 0F4A 3C 03 E4 D1 db 03ch,003h,0e4h,0d1h + 0F4E 4B 04 D4 47 db 04bh,004h,0d4h,047h + 0F52 D2 0D 85 FD db 0d2h,00dh,085h,0fdh + 0F56 A5 0A B5 6B db 0a5h,00ah,0b5h,06bh + 0F5A 35 B5 A8 FA db 035h,0b5h,0a8h,0fah + 0F5E 42 B2 98 6C db 042h,0b2h,098h,06ch + 0F62 DB BB C9 D6 db 0dbh,0bbh,0c9h,0d6h + 0F66 AC BC F9 40 db 0ach,0bch,0f9h,040h + 0F6A 32 D8 6C E3 db 032h,0d8h,06ch,0e3h + 0F6E 45 DF 5C 75 db 045h,0dfh,05ch,075h + 0F72 DC D6 0D CF db 0dch,0d6h,00dh,0cfh + 0F76 AB D1 3D 59 db 0abh,0d1h,03dh,059h + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-33 + + + 0F7A 26 D9 30 AC db 026h,0d9h,030h,0ach + 0F7E 51 DE 00 3A db 051h,0deh,000h,03ah + 0F82 C8 D7 51 80 db 0c8h,0d7h,051h,080h + 0F86 BF D0 61 16 db 0bfh,0d0h,061h,016h + 0F8A 21 B4 F4 B5 db 021h,0b4h,0f4h,0b5h + 0F8E 56 B3 C4 23 db 056h,0b3h,0c4h,023h + 0F92 CF BA 95 99 db 0cfh,0bah,095h,099h + 0F96 B8 BD A5 0F db 0b8h,0bdh,0a5h,00fh + 0F9A 28 02 B8 9E db 028h,002h,0b8h,09eh + 0F9E 5F 05 88 08 db 05fh,005h,088h,008h + 0FA2 C6 0C D9 B2 db 0c6h,00ch,0d9h,0b2h + 0FA6 B1 0B E9 24 db 0b1h,00bh,0e9h,024h + 0FAA 2F 6F 7C 87 db 02fh,06fh,07ch,087h + 0FAE 58 68 4C 11 db 058h,068h,04ch,011h + 0FB2 C1 61 1D AB db 0c1h,061h,01dh,0abh + 0FB6 B6 66 2D 3D db 0b6h,066h,02dh,03dh + 0FBA 76 DC 41 90 db 076h,0dch,041h,090h + 0FBE 01 DB 71 06 db 001h,0dbh,071h,006h + 0FC2 98 D2 20 BC db 098h,0d2h,020h,0bch + 0FC6 EF D5 10 2A db 0efh,0d5h,010h,02ah + 0FCA 71 B1 85 89 db 071h,0b1h,085h,089h + 0FCE 06 B6 B5 1F db 006h,0b6h,0b5h,01fh + 0FD2 9F BF E4 A5 db 09fh,0bfh,0e4h,0a5h + 0FD6 E8 B8 D4 33 db 0e8h,0b8h,0d4h,033h + 0FDA 78 07 C9 A2 db 078h,007h,0c9h,0a2h + 0FDE 0F 00 F9 34 db 00fh,000h,0f9h,034h + 0FE2 96 09 A8 8E db 096h,009h,0a8h,08eh + 0FE6 E1 0E 98 18 db 0e1h,00eh,098h,018h + 0FEA 7F 6A 0D BB db 07fh,06ah,00dh,0bbh + 0FEE 08 6D 3D 2D db 008h,06dh,03dh,02dh + 0FF2 91 64 6C 97 db 091h,064h,06ch,097h + 0FF6 E6 63 5C 01 db 0e6h,063h,05ch,001h + 0FFA 6B 6B 51 F4 db 06bh,06bh,051h,0f4h + 0FFE 1C 6C 61 62 db 01ch,06ch,061h,062h + 1002 85 65 30 D8 db 085h,065h,030h,0d8h + 1006 F2 62 00 4E db 0f2h,062h,000h,04eh + 100A 6C 06 95 ED db 06ch,006h,095h,0edh + 100E 1B 01 A5 7B db 01bh,001h,0a5h,07bh + 1012 82 08 F4 C1 db 082h,008h,0f4h,0c1h + 1016 F5 0F C4 57 db 0f5h,00fh,0c4h,057h + 101A 65 B0 D9 C6 db 065h,0b0h,0d9h,0c6h + 101E 12 B7 E9 50 db 012h,0b7h,0e9h,050h + 1022 8B BE B8 EA db 08bh,0beh,0b8h,0eah + 1026 FC B9 88 7C db 0fch,0b9h,088h,07ch + 102A 62 DD 1D DF db 062h,0ddh,01dh,0dfh + 102E 15 DA 2D 49 db 015h,0dah,02dh,049h + 1032 8C D3 7C F3 db 08ch,0d3h,07ch,0f3h + 1036 FB D4 4C 65 db 0fbh,0d4h,04ch,065h + 103A 4D B2 61 58 db 04dh,0b2h,061h,058h + 103E 3A B5 51 CE db 03ah,0b5h,051h,0ceh + 1042 A3 BC 00 74 db 0a3h,0bch,000h,074h + 1046 D4 BB 30 E2 db 0d4h,0bbh,030h,0e2h + 104A 4A DF A5 41 db 04ah,0dfh,0a5h,041h + 104E 3D D8 95 D7 db 03dh,0d8h,095h,0d7h + 1052 A4 D1 C4 6D db 0a4h,0d1h,0c4h,06dh + 1056 D3 D6 F4 FB db 0d3h,0d6h,0f4h,0fbh + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-34 + + + 105A 43 69 E9 6A db 043h,069h,0e9h,06ah + 105E 34 6E D9 FC db 034h,06eh,0d9h,0fch + 1062 AD 67 88 46 db 0adh,067h,088h,046h + 1066 DA 60 B8 D0 db 0dah,060h,0b8h,0d0h + 106A 44 04 2D 73 db 044h,004h,02dh,073h + 106E 33 03 1D E5 db 033h,003h,01dh,0e5h + 1072 AA 0A 4C 5F db 0aah,00ah,04ch,05fh + 1076 DD 0D 7C C9 db 0ddh,00dh,07ch,0c9h + 107A 50 05 71 3C db 050h,005h,071h,03ch + 107E 27 02 41 AA db 027h,002h,041h,0aah + 1082 BE 0B 10 10 db 0beh,00bh,010h,010h + 1086 C9 0C 20 86 db 0c9h,00ch,020h,086h + 108A 57 68 B5 25 db 057h,068h,0b5h,025h + 108E 20 6F 85 B3 db 020h,06fh,085h,0b3h + 1092 B9 66 D4 09 db 0b9h,066h,0d4h,009h + 1096 CE 61 E4 9F db 0ceh,061h,0e4h,09fh + 109A 5E DE F9 0E db 05eh,0deh,0f9h,00eh + 109E 29 D9 C9 98 db 029h,0d9h,0c9h,098h + 10A2 B0 D0 98 22 db 0b0h,0d0h,098h,022h + 10A6 C7 D7 A8 B4 db 0c7h,0d7h,0a8h,0b4h + 10AA 59 B3 3D 17 db 059h,0b3h,03dh,017h + 10AE 2E B4 0D 81 db 02eh,0b4h,00dh,081h + 10B2 B7 BD 5C 3B db 0b7h,0bdh,05ch,03bh + 10B6 C0 BA 6C AD db 0c0h,0bah,06ch,0adh + 10BA ED B8 83 20 db 0edh,0b8h,083h,020h + 10BE 9A BF B3 B6 db 09ah,0bfh,0b3h,0b6h + 10C2 03 B6 E2 0C db 003h,0b6h,0e2h,00ch + 10C6 74 B1 D2 9A db 074h,0b1h,0d2h,09ah + 10CA EA D5 47 39 db 0eah,0d5h,047h,039h + 10CE 9D D2 77 AF db 09dh,0d2h,077h,0afh + 10D2 04 DB 26 15 db 004h,0dbh,026h,015h + 10D6 73 DC 16 83 db 073h,0dch,016h,083h + 10DA E3 63 0B 12 db 0e3h,063h,00bh,012h + 10DE 94 64 3B 84 db 094h,064h,03bh,084h + 10E2 0D 6D 6A 3E db 00dh,06dh,06ah,03eh + 10E6 7A 6A 5A A8 db 07ah,06ah,05ah,0a8h + 10EA E4 0E CF 0B db 0e4h,00eh,0cfh,00bh + 10EE 93 09 FF 9D db 093h,009h,0ffh,09dh + 10F2 0A 00 AE 27 db 00ah,000h,0aeh,027h + 10F6 7D 07 9E B1 db 07dh,007h,09eh,0b1h + 10FA F0 0F 93 44 db 0f0h,00fh,093h,044h + 10FE 87 08 A3 D2 db 087h,008h,0a3h,0d2h + 1102 1E 01 F2 68 db 01eh,001h,0f2h,068h + 1106 69 06 C2 FE db 069h,006h,0c2h,0feh + 110A F7 62 57 5D db 0f7h,062h,057h,05dh + 110E 80 65 67 CB db 080h,065h,067h,0cbh + 1112 19 6C 36 71 db 019h,06ch,036h,071h + 1116 6E 6B 06 E7 db 06eh,06bh,006h,0e7h + 111A FE D4 1B 76 db 0feh,0d4h,01bh,076h + 111E 89 D3 2B E0 db 089h,0d3h,02bh,0e0h + 1122 10 DA 7A 5A db 010h,0dah,07ah,05ah + 1126 67 DD 4A CC db 067h,0ddh,04ah,0cch + 112A F9 B9 DF 6F db 0f9h,0b9h,0dfh,06fh + 112E 8E BE EF F9 db 08eh,0beh,0efh,0f9h + 1132 17 B7 BE 43 db 017h,0b7h,0beh,043h + 1136 60 B0 8E D5 db 060h,0b0h,08eh,0d5h + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-35 + + + 113A D6 D6 A3 E8 db 0d6h,0d6h,0a3h,0e8h + 113E A1 D1 93 7E db 0a1h,0d1h,093h,07eh + 1142 38 D8 C2 C4 db 038h,0d8h,0c2h,0c4h + 1146 4F DF F2 52 db 04fh,0dfh,0f2h,052h + 114A D1 BB 67 F1 db 0d1h,0bbh,067h,0f1h + 114E A6 BC 57 67 db 0a6h,0bch,057h,067h + 1152 3F B5 06 DD db 03fh,0b5h,006h,0ddh + 1156 48 B2 36 4B db 048h,0b2h,036h,04bh + 115A D8 0D 2B DA db 0d8h,00dh,02bh,0dah + 115E AF 0A 1B 4C db 0afh,00ah,01bh,04ch + 1162 36 03 4A F6 db 036h,003h,04ah,0f6h + 1166 41 04 7A 60 db 041h,004h,07ah,060h + 116A DF 60 EF C3 db 0dfh,060h,0efh,0c3h + 116E A8 67 DF 55 db 0a8h,067h,0dfh,055h + 1172 31 6E 8E EF db 031h,06eh,08eh,0efh + 1176 46 69 BE 79 db 046h,069h,0beh,079h + 117A CB 61 B3 8C db 0cbh,061h,0b3h,08ch + 117E BC 66 83 1A db 0bch,066h,083h,01ah + 1182 25 6F D2 A0 db 025h,06fh,0d2h,0a0h + 1186 52 68 E2 36 db 052h,068h,0e2h,036h + 118A CC 0C 77 95 db 0cch,00ch,077h,095h + 118E BB 0B 47 03 db 0bbh,00bh,047h,003h + 1192 22 02 16 B9 db 022h,002h,016h,0b9h + 1196 55 05 26 2F db 055h,005h,026h,02fh + 119A C5 BA 3B BE db 0c5h,0bah,03bh,0beh + 119E B2 BD 0B 28 db 0b2h,0bdh,00bh,028h + 11A2 2B B4 5A 92 db 02bh,0b4h,05ah,092h + 11A6 5C B3 6A 04 db 05ch,0b3h,06ah,004h + 11AA C2 D7 FF A7 db 0c2h,0d7h,0ffh,0a7h + 11AE B5 D0 CF 31 db 0b5h,0d0h,0cfh,031h + 11B2 2C D9 9E 8B db 02ch,0d9h,09eh,08bh + 11B6 5B DE AE 1D db 05bh,0deh,0aeh,01dh + 11BA 9B 64 C2 B0 db 09bh,064h,0c2h,0b0h + 11BE EC 63 F2 26 db 0ech,063h,0f2h,026h + 11C2 75 6A A3 9C db 075h,06ah,0a3h,09ch + 11C6 02 6D 93 0A db 002h,06dh,093h,00ah + 11CA 9C 09 06 A9 db 09ch,009h,006h,0a9h + 11CE EB 0E 36 3F db 0ebh,00eh,036h,03fh + 11D2 72 07 67 85 db 072h,007h,067h,085h + 11D6 05 00 57 13 db 005h,000h,057h,013h + 11DA 95 BF 4A 82 db 095h,0bfh,04ah,082h + 11DE E2 B8 7A 14 db 0e2h,0b8h,07ah,014h + 11E2 7B B1 2B AE db 07bh,0b1h,02bh,0aeh + 11E6 0C B6 1B 38 db 00ch,0b6h,01bh,038h + 11EA 92 D2 8E 9B db 092h,0d2h,08eh,09bh + 11EE E5 D5 BE 0D db 0e5h,0d5h,0beh,00dh + 11F2 7C DC EF B7 db 07ch,0dch,0efh,0b7h + 11F6 0B DB DF 21 db 00bh,0dbh,0dfh,021h + 11FA 86 D3 D2 D4 db 086h,0d3h,0d2h,0d4h + 11FE F1 D4 E2 42 db 0f1h,0d4h,0e2h,042h + 1202 68 DD B3 F8 db 068h,0ddh,0b3h,0f8h + 1206 1F DA 83 6E db 01fh,0dah,083h,06eh + 120A 81 BE 16 CD db 081h,0beh,016h,0cdh + 120E F6 B9 26 5B db 0f6h,0b9h,026h,05bh + 1212 6F B0 77 E1 db 06fh,0b0h,077h,0e1h + 1216 18 B7 47 77 db 018h,0b7h,047h,077h + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE 1-36 + + + 121A 88 08 5A E6 db 088h,008h,05ah,0e6h + 121E FF 0F 6A 70 db 0ffh,00fh,06ah,070h + 1222 66 06 3B CA db 066h,006h,03bh,0cah + 1226 11 01 0B 5C db 011h,001h,00bh,05ch + 122A 8F 65 9E FF db 08fh,065h,09eh,0ffh + 122E F8 62 AE 69 db 0f8h,062h,0aeh,069h + 1232 61 6B FF D3 db 061h,06bh,0ffh,0d3h + 1236 16 6C CF 45 db 016h,06ch,0cfh,045h + 123A A0 0A E2 78 db 0a0h,00ah,0e2h,078h + 123E D7 0D D2 EE db 0d7h,00dh,0d2h,0eeh + 1242 4E 04 83 54 db 04eh,004h,083h,054h + 1246 39 03 B3 C2 db 039h,003h,0b3h,0c2h + 124A A7 67 26 61 db 0a7h,067h,026h,061h + 124E D0 60 16 F7 db 0d0h,060h,016h,0f7h + 1252 49 69 47 4D db 049h,069h,047h,04dh + 1256 3E 6E 77 DB db 03eh,06eh,077h,0dbh + 125A AE D1 6A 4A db 0aeh,0d1h,06ah,04ah + 125E D9 D6 5A DC db 0d9h,0d6h,05ah,0dch + 1262 40 DF 0B 66 db 040h,0dfh,00bh,066h + 1266 37 D8 3B F0 db 037h,0d8h,03bh,0f0h + 126A A9 BC AE 53 db 0a9h,0bch,0aeh,053h + 126E DE BB 9E C5 db 0deh,0bbh,09eh,0c5h + 1272 47 B2 CF 7F db 047h,0b2h,0cfh,07fh + 1276 30 B5 FF E9 db 030h,0b5h,0ffh,0e9h + 127A BD BD F2 1C db 0bdh,0bdh,0f2h,01ch + 127E CA BA C2 8A db 0cah,0bah,0c2h,08ah + 1282 53 B3 93 30 db 053h,0b3h,093h,030h + 1286 24 B4 A3 A6 db 024h,0b4h,0a3h,0a6h + 128A BA D0 36 05 db 0bah,0d0h,036h,005h + 128E CD D7 06 93 db 0cdh,0d7h,006h,093h + 1292 54 DE 57 29 db 054h,0deh,057h,029h + 1296 23 D9 67 BF db 023h,0d9h,067h,0bfh + 129A B3 66 7A 2E db 0b3h,066h,07ah,02eh + 129E C4 61 4A B8 db 0c4h,061h,04ah,0b8h + 12A2 5D 68 1B 02 db 05dh,068h,01bh,002h + 12A6 2A 6F 2B 94 db 02ah,06fh,02bh,094h + 12AA B4 0B BE 37 db 0b4h,00bh,0beh,037h + 12AE C3 0C 8E A1 db 0c3h,00ch,08eh,0a1h + 12B2 5A 05 DF 1B db 05ah,005h,0dfh,01bh + 12B6 2D 02 EF 8D db 02dh,002h,0efh,08dh + + end + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE S + + +Macros: +TMSG TSTR + +Symbols: +016F ..0000 0183 ..0001 0197 ..0002 +01AF ..0003 01CF ..0004 01E3 ..0005 +01F7 ..0006 020F ..0007 022F ..0008 +0243 ..0009 0257 ..000A 026F ..000B +028F ..000C 02A3 ..000D 02B7 ..000E +02CF ..000F 02EF ..0010 0303 ..0011 +0317 ..0012 032F ..0013 034F ..0014 +0363 ..0015 0377 ..0016 038F ..0017 +03AF ..0018 03C3 ..0019 03D7 ..001A +03EF ..001B 040F ..001C 0423 ..001D +0437 ..001E 044F ..001F 046F ..0020 +0483 ..0021 0497 ..0022 04AF ..0023 +04CF ..0024 04E3 ..0025 04F7 ..0026 +050F ..0027 052F ..0028 0543 ..0029 +0557 ..002A 056F ..002B 058F ..002C +05A3 ..002D 05B7 ..002E 05CF ..002F +05EF ..0030 0603 ..0031 0617 ..0032 +062F ..0033 064F ..0034 0663 ..0035 +0677 ..0036 068F ..0037 06AF ..0038 +06C3 ..0039 06D7 ..003A 06EF ..003B +070F ..003C 0723 ..003D 0737 ..003E +074F ..003F 076F ..0040 0783 ..0041 +0797 ..0042 07AF ..0043 07CF ..0044 +07E3 ..0045 07F7 ..0046 080F ..0047 +082F ..0048 0843 ..0049 0857 ..004A +086F ..004B 088F ..004C 08A3 ..004D +08B7 ..004E 08CF ..004F 08EF ..0050 +0903 ..0051 0917 ..0052 092F ..0053 +094F ..0054 0963 ..0055 0977 ..0056 +098F ..0057 09AF ..0058 09C3 ..0059 +09D7 ..005A 09EF ..005B 0A0F ..005C +0A23 ..005D 0A37 ..005E 0A4F ..005F +0A6F ..0060 0A83 ..0061 0A97 ..0062 +0AAF ..0063 016E ADD16 01CE ALU8I +022E ALU8R 0DF5 BDOS 0100 BEGIN +0E76 CCE 0E6B CCLP 0C3F CLRMEM +0E63 CMPCRC 0BF7 CNTBIT 0BF8 CNTBYT +0CB3 CNTEND 0CA4 CNTLP 0CB7 CNTLP1 +0C98 COUNT 0CE9 COUNTER 0B73 CRCGOOD +0E93 CRCLP 0EBA CRCTAB 0EB6 CRCVAL +0E60 CRLF 028E DAA 0B67 DOCRLF +012F DONE 0E3D ERMSG1 0E58 ERMSG2 +0D89 FLGMSK 0DB0 FLGSAT 0DB6 HEXSTR +0EAC ICRCLP 0C67 IMLP 0C68 IMLP1 +0C6E IMLP2 0C8B IMLP3 02EE INCA +034E INCB 03AE INCBC 040E INCC +046E INCD 04CE INCDE 052E INCE +058E INCH 05EE INCHL 064E INCL +06AE INCM 070E INCSP 0EA2 INITCRC +0C58 INITMASK 0D58 IUT 076E LD162 +07CE LD166 082E LD16IM 088E LD8BD +08EE LD8IM 094E LD8RR 09AE LDA + 'Z80 instruction set exerciser' MACRO-80 3.44 09-Dec-81 PAGE S-1 + + +0AFC LDIR1 0B0C LDIR2 0C49 LDIR3 +0122 LOOP 0DA4 MSAT 0103 MSBT +0E01 MSG1 0E1E MSG2 0C13 NCB1 +0C37 NSB1 0BFA NXTCBIT 0C1E NXTSBIT +0E2D OKMSG 0DE8 PH11 0DC5 PH8LP +0DDB PHEX1 0DD2 PHEX2 0DC0 PHEX8 +0A0E ROT8080 0BE1 SBSHF1 0BAB SETUP +0C1B SHFBIT 0C1C SHFBYT 0CC8 SHFLP +0CE4 SHFLP1 0CDE SHFLP2 0CBC SHIFT +0D11 SHIFTER 0CE0 SHLPE 0DB2 SPAT +0111 SPBT 0DB4 SPSAV 0A6E STABD +0113 START 0ACE STT 0BC4 SUBCLP +0BD5 SUBSHF 0BF0 SUBSTR 0BB4 SUBYTE +0D94 TCRC 0DA2 TEMP 0D69 TEMP1 +0D6B TEMP2 0D39 TEST 013A TESTS +0B23 TLP 0B37 TLP1 0B3A TLP2 +0B81 TLP3 0B6A TLPOK 0E7A UPDCRC + + + +No Fatal error(s) + + diff --git a/Intel8080/Intel8080.Test/roms/8080PRE.PRN b/Intel8080/Intel8080.Test/roms/8080PRE.PRN new file mode 100644 index 0000000..ab84745 --- /dev/null +++ b/Intel8080/Intel8080.Test/roms/8080PRE.PRN @@ -0,0 +1,535 @@ + 'Preliminary Z80 tests' MACRO-80 3.44 09-Dec-81 PAGE 1 + + + title 'Preliminary Z80 tests' + + ; prelim.z80 - Preliminary Z80 tests + ; Copyright (C) 1994 Frank D. Cringle + ; + ; This program is free software; you can redistribute it and/or + ; modify it under the terms of the GNU General Public License + ; as published by the Free Software Foundation; either version 2 + ; of the License, or (at your option) any later version. + ; + ; This program is distributed in the hope that it will be useful, + ; but WITHOUT ANY WARRANTY; without even the implied warranty of + ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ; GNU General Public License for more details. + ; + ; You should have received a copy of the GNU General Public License + ; along with this program; if not, write to the Free Software + ; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + + ; These tests have two goals. To start with, we assume the worst and + ; successively test the instructions needed to continue testing. + ; Then we try to test all instructions which cannot be handled by + ; zexlax - the crc-based instruction exerciser. + + ; Initially errors are 'reported' by jumping to 0. This should reboot + ; cp/m, so if the program terminates without any output one of the + ; early tests failed. Later errors are reported by outputting an + ; address via the bdos conout routine. The address can be located in + ; a listing of this program. + + ; If the program runs to completion it displays a suitable message. + + ;****************************************************************************** + ; + ; Modified by Ian Bartholomew to run a preliminary test on an 8080 CPU + ; + ; Assemble using M80 + ; + ;****************************************************************************** + + .8080 + 0000' aseg + org 100h + + 0100 3E 01 start: mvi a,1 ; test simple compares and z/nz jumps + 0102 FE 02 cpi 2 + 0104 CA 0000 jz 0 + 0107 FE 01 cpi 1 + 0109 C2 0000 jnz 0 + 010C C3 0111 jmp lab0 + 010F 76 hlt ; emergency exit + 0110 FF db 0ffh + + 0111 CD 0117 lab0: call lab2 ; does a simple call work? + 0114 C3 0000 lab1: jmp 0 ; fail + 'Preliminary Z80 tests' MACRO-80 3.44 09-Dec-81 PAGE 1-1 + + + + 0117 E1 lab2: pop h ; check return address + 0118 7C mov a,h + 0119 FE 01 cpi high lab1 + 011B CA 0121 jz lab3 + 011E C3 0000 jmp 0 + 0121 7D lab3: mov a,l + 0122 FE 14 cpi low lab1 + 0124 CA 012A jz lab4 + 0127 C3 0000 jmp 0 + + ; test presence and uniqueness of all machine registers + ; (except ir) + 012A 31 0399 lab4: lxi sp,regs1 + 012D F1 pop psw + 012E C1 pop b + 012F D1 pop d + 0130 E1 pop h + 0131 31 03A9 lxi sp,regs2+8 + 0134 E5 push h + 0135 D5 push d + 0136 C5 push b + 0137 F5 push psw + + 0000 v defl 0 + rept 8 + lda regs2+v/2 + v defl v+2 + cpi v + jnz 0 + endm + 0138 3A 03A1 + lda regs2+v/2 + 013B FE 02 + cpi v + 013D C2 0000 + jnz 0 + 0140 3A 03A2 + lda regs2+v/2 + 0143 FE 04 + cpi v + 0145 C2 0000 + jnz 0 + 0148 3A 03A3 + lda regs2+v/2 + 014B FE 06 + cpi v + 014D C2 0000 + jnz 0 + 0150 3A 03A4 + lda regs2+v/2 + 0153 FE 08 + cpi v + 0155 C2 0000 + jnz 0 + 0158 3A 03A5 + lda regs2+v/2 + 015B FE 0A + cpi v + 015D C2 0000 + jnz 0 + 0160 3A 03A6 + lda regs2+v/2 + 0163 FE 0C + cpi v + 0165 C2 0000 + jnz 0 + 0168 3A 03A7 + lda regs2+v/2 + 016B FE 0E + cpi v + 016D C2 0000 + jnz 0 + 0170 3A 03A8 + lda regs2+v/2 + 0173 FE 10 + cpi v + 0175 C2 0000 + jnz 0 + + 'Preliminary Z80 tests' MACRO-80 3.44 09-Dec-81 PAGE 1-2 + + + ; test access to memory via (hl) + 0178 21 03A9 lxi h,hlval + 017B 7E mov a,m + 017C FE A5 cpi 0a5h + 017E C2 0000 jnz 0 + 0181 21 03AA lxi h,hlval+1 + 0184 7E mov a,m + 0185 FE 3C cpi 03ch + 0187 C2 0000 jnz 0 + + ; test unconditional return + 018A 31 0500 lxi sp,stack + 018D 21 0195 lxi h,reta + 0190 E5 push h + 0191 C9 ret + 0192 C3 0000 jmp 0 + + ; test instructions needed for hex output + 0195 3E FF reta: mvi a,0ffh + 0197 E6 0F ani 0fh + 0199 FE 0F cpi 0fh + 019B C2 0000 jnz 0 + 019E 3E 5A mvi a,05ah + 01A0 E6 0F ani 0fh + 01A2 FE 0A cpi 0ah + 01A4 C2 0000 jnz 0 + 01A7 0F rrc + 01A8 FE 05 cpi 05h + 01AA C2 0000 jnz 0 + 01AD 0F rrc + 01AE FE 82 cpi 82h + 01B0 C2 0000 jnz 0 + 01B3 0F rrc + 01B4 FE 41 cpi 41h + 01B6 C2 0000 jnz 0 + 01B9 0F rrc + 01BA FE A0 cpi 0a0h + 01BC C2 0000 jnz 0 + 01BF 21 1234 lxi h,01234h + 01C2 E5 push h + 01C3 C1 pop b + 01C4 78 mov a,b + 01C5 FE 12 cpi 12h + 01C7 C2 0000 jnz 0 + 01CA 79 mov a,c + 01CB FE 34 cpi 34h + 01CD C2 0000 jnz 0 + + ; from now on we can report errors by displaying an address + + ; test conditional call, ret, jp, jr + tcond macro flag,pcond,ncond,rel + lxi h,&flag + push h + pop psw + c&pcond lab1&pcond + 'Preliminary Z80 tests' MACRO-80 3.44 09-Dec-81 PAGE 1-3 + + + jmp error + lab1&pcond: pop h + lxi h,0d7h xor &flag + push h + pop psw + c&ncond lab2&pcond + jmp error + lab2&pcond: pop h + lxi h,lab3&pcond + push h + lxi h,&flag + push h + pop psw + r&pcond + call error + lab3&pcond: lxi h,lab4&pcond + push h + lxi h,0d7h xor &flag + push h + pop psw + r&ncond + call error + lab4&pcond: lxi h,&flag + push h + pop psw + j&pcond lab5&pcond + call error + lab5&pcond: lxi h,0d7h xor &flag + push h + pop psw + j&ncond lab6&pcond + call error + lab6&pcond: + endm + + tcond 1,c,nc,1 + 01D0 21 0001 + lxi h,&1 + 01D3 E5 + push h + 01D4 F1 + pop psw + 01D5 DC 01DB + c&c lab1&c + 01D8 C3 0352 + jmp error + 01DB E1 + lab1&c: pop h + 01DC 21 00D6 + lxi h,0d7h xor &1 + 01DF E5 + push h + 01E0 F1 + pop psw + 01E1 D4 01E7 + c&nc lab2&c + 01E4 C3 0352 + jmp error + 01E7 E1 + lab2&c: pop h + 01E8 21 01F5 + lxi h,lab3&c + 01EB E5 + push h + 01EC 21 0001 + lxi h,&1 + 01EF E5 + push h + 01F0 F1 + pop psw + 01F1 D8 + r&c + 01F2 CD 0352 + call error + 01F5 21 0202 + lab3&c: lxi h,lab4&c + 'Preliminary Z80 tests' MACRO-80 3.44 09-Dec-81 PAGE 1-4 + + + 01F8 E5 + push h + 01F9 21 00D6 + lxi h,0d7h xor &1 + 01FC E5 + push h + 01FD F1 + pop psw + 01FE D0 + r&nc + 01FF CD 0352 + call error + 0202 21 0001 + lab4&c: lxi h,&1 + 0205 E5 + push h + 0206 F1 + pop psw + 0207 DA 020D + j&c lab5&c + 020A CD 0352 + call error + 020D 21 00D6 + lab5&c: lxi h,0d7h xor &1 + 0210 E5 + push h + 0211 F1 + pop psw + 0212 D2 0218 + j&nc lab6&c + 0215 CD 0352 + call error + 0218 + lab6&c: + tcond 4,pe,po,0 + 0218 21 0004 + lxi h,&4 + 021B E5 + push h + 021C F1 + pop psw + 021D EC 0223 + c&pe lab1&pe + 0220 C3 0352 + jmp error + 0223 E1 + lab1&pe: pop h + 0224 21 00D3 + lxi h,0d7h xor &4 + 0227 E5 + push h + 0228 F1 + pop psw + 0229 E4 022F + c&po lab2&pe + 022C C3 0352 + jmp error + 022F E1 + lab2&pe: pop h + 0230 21 023D + lxi h,lab3&pe + 0233 E5 + push h + 0234 21 0004 + lxi h,&4 + 0237 E5 + push h + 0238 F1 + pop psw + 0239 E8 + r&pe + 023A CD 0352 + call error + 023D 21 024A + lab3&pe: lxi h,lab4&pe + 0240 E5 + push h + 0241 21 00D3 + lxi h,0d7h xor &4 + 0244 E5 + push h + 0245 F1 + pop psw + 0246 E0 + r&po + 0247 CD 0352 + call error + 024A 21 0004 + lab4&pe: lxi h,&4 + 024D E5 + push h + 024E F1 + pop psw + 024F EA 0255 + j&pe lab5&pe + 0252 CD 0352 + call error + 0255 21 00D3 + lab5&pe: lxi h,0d7h xor &4 + 0258 E5 + push h + 0259 F1 + pop psw + 025A E2 0260 + j&po lab6&pe + 025D CD 0352 + call error + 0260 + lab6&pe: + tcond 040h,z,nz,1 + 'Preliminary Z80 tests' MACRO-80 3.44 09-Dec-81 PAGE 1-5 + + + 0260 21 0040 + lxi h,&040h + 0263 E5 + push h + 0264 F1 + pop psw + 0265 CC 026B + c&z lab1&z + 0268 C3 0352 + jmp error + 026B E1 + lab1&z: pop h + 026C 21 0097 + lxi h,0d7h xor &040h + 026F E5 + push h + 0270 F1 + pop psw + 0271 C4 0277 + c&nz lab2&z + 0274 C3 0352 + jmp error + 0277 E1 + lab2&z: pop h + 0278 21 0285 + lxi h,lab3&z + 027B E5 + push h + 027C 21 0040 + lxi h,&040h + 027F E5 + push h + 0280 F1 + pop psw + 0281 C8 + r&z + 0282 CD 0352 + call error + 0285 21 0292 + lab3&z: lxi h,lab4&z + 0288 E5 + push h + 0289 21 0097 + lxi h,0d7h xor &040h + 028C E5 + push h + 028D F1 + pop psw + 028E C0 + r&nz + 028F CD 0352 + call error + 0292 21 0040 + lab4&z: lxi h,&040h + 0295 E5 + push h + 0296 F1 + pop psw + 0297 CA 029D + j&z lab5&z + 029A CD 0352 + call error + 029D 21 0097 + lab5&z: lxi h,0d7h xor &040h + 02A0 E5 + push h + 02A1 F1 + pop psw + 02A2 C2 02A8 + j&nz lab6&z + 02A5 CD 0352 + call error + 02A8 + lab6&z: + tcond 080h,m,p,0 + 02A8 21 0080 + lxi h,&080h + 02AB E5 + push h + 02AC F1 + pop psw + 02AD FC 02B3 + c&m lab1&m + 02B0 C3 0352 + jmp error + 02B3 E1 + lab1&m: pop h + 02B4 21 0057 + lxi h,0d7h xor &080h + 02B7 E5 + push h + 02B8 F1 + pop psw + 02B9 F4 02BF + c&p lab2&m + 02BC C3 0352 + jmp error + 02BF E1 + lab2&m: pop h + 02C0 21 02CD + lxi h,lab3&m + 02C3 E5 + push h + 02C4 21 0080 + lxi h,&080h + 02C7 E5 + push h + 02C8 F1 + pop psw + 02C9 F8 + r&m + 'Preliminary Z80 tests' MACRO-80 3.44 09-Dec-81 PAGE 1-6 + + + 02CA CD 0352 + call error + 02CD 21 02DA + lab3&m: lxi h,lab4&m + 02D0 E5 + push h + 02D1 21 0057 + lxi h,0d7h xor &080h + 02D4 E5 + push h + 02D5 F1 + pop psw + 02D6 F0 + r&p + 02D7 CD 0352 + call error + 02DA 21 0080 + lab4&m: lxi h,&080h + 02DD E5 + push h + 02DE F1 + pop psw + 02DF FA 02E5 + j&m lab5&m + 02E2 CD 0352 + call error + 02E5 21 0057 + lab5&m: lxi h,0d7h xor &080h + 02E8 E5 + push h + 02E9 F1 + pop psw + 02EA F2 02F0 + j&p lab6&m + 02ED CD 0352 + call error + 02F0 + lab6&m: + + ; test indirect jumps + 02F0 21 02F7 lxi h,lab7 + 02F3 E9 pchl + 02F4 CD 0352 call error + + ; djnz (and (partially) inc a, inc hl) + 02F7 3E A5 lab7: mvi a,0a5h + 02F9 06 04 mvi b,4 + 02FB 0F lab8: rrc + 02FC 05 dcr b + 02FD C2 02FB jnz lab8 + 0300 FE 5A cpi 05ah + 0302 C4 0352 cnz error + 0305 06 10 mvi b,16 + 0307 3C lab9: inr a + 0308 05 dcr b + 0309 C2 0307 jnz lab9 + 030C FE 6A cpi 06ah + 030E C4 0352 cnz error + 0311 06 00 mvi b,0 + 0313 21 0000 lxi h,0 + 0316 23 lab10: inx h + 0317 05 dcr b + 0318 C2 0316 jnz lab10 + 031B 7C mov a,h + 031C FE 01 cpi 1 + 031E C4 0352 cnz error + 0321 7D mov a,l + 0322 FE 00 cpi 0 + 0324 C4 0352 cnz error + + 0327 11 0332 allok: lxi d,okmsg + 032A 0E 09 mvi c,9 + 032C CD 0005 call 5 + 032F C3 0000 jmp 0 + + 'Preliminary Z80 tests' MACRO-80 3.44 09-Dec-81 PAGE 1-7 + + + 0332 38 30 38 30 okmsg: db '8080 Preliminary tests complete$' + 0336 20 50 72 65 + 033A 6C 69 6D 69 + 033E 6E 61 72 79 + 0342 20 74 65 73 + 0346 74 73 20 63 + 034A 6F 6D 70 6C + 034E 65 74 65 24 + + ; display address at top of stack and exit + 0352 C1 error: pop b + 0353 26 04 mvi h,high hextab + 0355 78 mov a,b + 0356 0F rrc + 0357 0F rrc + 0358 0F rrc + 0359 0F rrc + 035A E6 0F ani 15 + 035C 6F mov l,a + 035D 7E mov a,m + 035E CD 038A call conout + 0361 78 mov a,b + 0362 E6 0F ani 15 + 0364 6F mov l,a + 0365 7E mov a,m + 0366 CD 038A call conout + 0369 79 mov a,c + 036A 0F rrc + 036B 0F rrc + 036C 0F rrc + 036D 0F rrc + 036E E6 0F ani 15 + 0370 6F mov l,a + 0371 7E mov a,m + 0372 CD 038A call conout + 0375 79 mov a,c + 0376 E6 0F ani 15 + 0378 6F mov l,a + 0379 7E mov a,m + 037A CD 038A call conout + 037D 3E 0D mvi a,13 + 037F CD 038A call conout + 0382 3E 0A mvi a,10 + 0384 CD 038A call conout + 0387 C3 0000 jmp 0 + + 038A F5 conout: push psw + 038B C5 push b + 038C D5 push d + 038D E5 push h + 038E 0E 02 mvi c,2 + 0390 5F mov e,a + 0391 CD 0005 call 5 + 0394 E1 pop h + 0395 D1 pop d + 0396 C1 pop b + 'Preliminary Z80 tests' MACRO-80 3.44 09-Dec-81 PAGE 1-8 + + + 0397 F1 pop psw + 0398 C9 ret + + 0000 v defl 0 + 0399 regs1: rept 8 + v defl v+2 + db v + endm + 0399 02 + db v + 039A 04 + db v + 039B 06 + db v + 039C 08 + db v + 039D 0A + db v + 039E 0C + db v + 039F 0E + db v + 03A0 10 + db v + + 03A1 regs2: ds 8,0 + + 03A9 A5 3C hlval: db 0a5h,03ch + + ; skip to next page boundary + org (($+255)/256)*256 + 0400 30 31 32 33 hextab: db '0123456789abcdef' + 0404 34 35 36 37 + 0408 38 39 61 62 + 040C 63 64 65 66 + 0410 ds 240 + + 0500 stack equ $ + + end start + 'Preliminary Z80 tests' MACRO-80 3.44 09-Dec-81 PAGE S + + +Macros: +TCOND + +Symbols: +0327 ALLOK 038A CONOUT 0352 ERROR +0400 HEXTAB 03A9 HLVAL 0111 LAB0 +0114 LAB1 0316 LAB10 01DB LAB1C +02B3 LAB1M 0223 LAB1PE 026B LAB1Z +0117 LAB2 01E7 LAB2C 02BF LAB2M +022F LAB2PE 0277 LAB2Z 0121 LAB3 +01F5 LAB3C 02CD LAB3M 023D LAB3PE +0285 LAB3Z 012A LAB4 0202 LAB4C +02DA LAB4M 024A LAB4PE 0292 LAB4Z +020D LAB5C 02E5 LAB5M 0255 LAB5PE +029D LAB5Z 0218 LAB6C 02F0 LAB6M +0260 LAB6PE 02A8 LAB6Z 02F7 LAB7 +02FB LAB8 0307 LAB9 0332 OKMSG +0399 REGS1 03A1 REGS2 0195 RETA +0500 STACK 0100 START 0010 V + + + +No Fatal error(s) + + diff --git a/Intel8080/Intel8080.Test/roms/README.TXT b/Intel8080/Intel8080.Test/roms/README.TXT new file mode 100644 index 0000000..ca2c950 --- /dev/null +++ b/Intel8080/Intel8080.Test/roms/README.TXT @@ -0,0 +1,31 @@ +This folder contains 8080 CPU test programs that run under CP/M + +TST8080 + 8080/8085 CPU Diagnostic, version 1.0, by Microcosm Associates + (Kelly Smith test) + +8080PRE + Preliminary test for 8080/8085 CPU Exerciser by Ian Bartholomew + and Frank Cringles. + +8080EXER + 8080/8085 CPU Exerciser by Ian Bartholomew and Frank Cringles. + This is a very thorough test that generates a CRC code for each + group of tests. The program will say "Error" for every test, but + it's not actually an error. Instead, compare the reported CRC + with results from tests against real silicon. See 8080EXER.PNG in + this directory and http://www.idb.me.uk/sunhillow/8080.html. The + full test takes several hours. The "aluop " section + takes especially long. + +8080EXM + 8080/80805 Exerciser "M"odified with the correct result CRCs in + the program so it can display "pass" or "fail" correctly. + +CPUTEST + SuperSoft Associates CPU test from the Diagnostic II + suite. When it displays "ABCDEF..." those are actually + indications of test that have passed. Additional testing + occurs during the "Begin Timing Test" and "End Timing Test" + period. On a 2MHz 8080, the timing test period lasts about + two minutes. diff --git a/Intel8080/Intel8080.Test/roms/TST8080.ASM b/Intel8080/Intel8080.Test/roms/TST8080.ASM new file mode 100644 index 0000000..a90793a --- /dev/null +++ b/Intel8080/Intel8080.Test/roms/TST8080.ASM @@ -0,0 +1,819 @@ +;*********************************************************************** +; MICROCOSM ASSOCIATES 8080/8085 CPU DIAGNOSTIC VERSION 1.0 (C) 1980 +;*********************************************************************** +; +;DONATED TO THE "SIG/M" CP/M USER'S GROUP BY: +;KELLY SMITH, MICROCOSM ASSOCIATES +;3055 WACO AVENUE +;SIMI VALLEY, CALIFORNIA, 93065 +;(805) 527-9321 (MODEM, CP/M-NET (TM)) +;(805) 527-0518 (VERBAL) +; +; Updated by Mike Douglas October, 2012 +; +; Added the following tests that were missing: +; mov c,m +; mov m,c +; ana b +; +; Fixed the CPUER exit routine which did not display the +; low byte of the failure address properly. +; +; Added display of the Microcosm welcome message +; + ORG 00100H + +; + JMP CPU ;JUMP TO 8080 CPU DIAGNOSTIC +; +WELCOM DB 'MICROCOSM ASSOCIATES 8080/8085 CPU DIAGNOSTIC',13,10 + DB ' VERSION 1.0 (C) 1980',13,10,'$' +; +BDOS EQU 00005H ;BDOS ENTRY TO CP/M +WBOOT EQU 00000H ;RE-ENTRY TO CP/M WARM BOOT +; +; +; +;MESSAGE OUTPUT ROUTINE +; +MSG: PUSH D ;EXILE D REG. + XCHG ;SWAP H&L REGS. TO D&E REGS. + MVI C,9 ;LET BDOS KNOW WE WANT TO SEND A MESSAGE + CALL BDOS + POP D ;BACK FROM EXILE + RET +; +; +; +;CHARACTER OUTPUT ROUTINE +; +PCHAR: MVI C,2 + CALL BDOS + RET +; +; +; +BYTEO: PUSH PSW + CALL BYTO1 + MOV E,A + CALL PCHAR + POP PSW + CALL BYTO2 + MOV E,A + JMP PCHAR +BYTO1: RRC + RRC + RRC + RRC +BYTO2: ANI 0FH + CPI 0AH + JM BYTO3 + ADI 7 +BYTO3: ADI 30H + RET +; +; +; +;************************************************************ +; MESSAGE TABLE FOR OPERATIONAL CPU TEST +;************************************************************ +; +OKCPU: DB 0DH,0AH,' CPU IS OPERATIONAL$' +; +NGCPU: DB 0DH,0AH,' CPU HAS FAILED! ERROR EXIT=$' +; +; +; +;************************************************************ +; 8080/8085 CPU TEST/DIAGNOSTIC +;************************************************************ +; +;NOTE: (1) PROGRAM ASSUMES "CALL",AND "LXI SP" INSTRUCTIONS WORK! +; +; (2) INSTRUCTIONS NOT TESTED ARE "HLT","DI","EI","RIM","SIM", +; AND "RST 0" THRU "RST 7" +; +; +; +;TEST JUMP INSTRUCTIONS AND FLAGS +; +CPU: LXI SP,STACK ;SET THE STACK POINTER + LXI H,WELCOM + CALL MSG + ANI 0 ;INITIALIZE A REG. AND CLEAR ALL FLAGS + JZ J010 ;TEST "JZ" + CALL CPUER +J010: JNC J020 ;TEST "JNC" + CALL CPUER +J020: JPE J030 ;TEST "JPE" + CALL CPUER +J030: JP J040 ;TEST "JP" + CALL CPUER +J040: JNZ J050 ;TEST "JNZ" + JC J050 ;TEST "JC" + JPO J050 ;TEST "JPO" + JM J050 ;TEST "JM" + JMP J060 ;TEST "JMP" (IT'S A LITTLE LATE,BUT WHAT THE HELL! +J050: CALL CPUER +J060: ADI 6 ;A=6,C=0,P=1,S=0,Z=0 + JNZ J070 ;TEST "JNZ" + CALL CPUER +J070: JC J080 ;TEST "JC" + JPO J080 ;TEST "JPO" + JP J090 ;TEST "JP" +J080: CALL CPUER +J090: ADI 070H ;A=76H,C=0,P=0,S=0,Z=0 + JPO J100 ;TEST "JPO" + CALL CPUER +J100: JM J110 ;TEST "JM" + JZ J110 ;TEST "JZ" + JNC J120 ;TEST "JNC" +J110: CALL CPUER +J120: ADI 081H ;A=F7H,C=0,P=0,S=1,Z=0 + JM J130 ;TEST "JM" + CALL CPUER +J130: JZ J140 ;TEST "JZ" + JC J140 ;TEST "JC" + JPO J150 ;TEST "JPO" +J140: CALL CPUER +J150: ADI 0FEH ;A=F5H,C=1,P=1,S=1,Z=0 + JC J160 ;TEST "JC" + CALL CPUER +J160: JZ J170 ;TEST "JZ" + JPO J170 ;TEST "JPO" + JM AIMM ;TEST "JM" +J170: CALL CPUER +; +; +; +;TEST ACCUMULATOR IMMEDIATE INSTRUCTIONS +; +AIMM: CPI 0 ;A=F5H,C=0,Z=0 + JC CPIE ;TEST "CPI" FOR RE-SET CARRY + JZ CPIE ;TEST "CPI" FOR RE-SET ZERO + CPI 0F5H ;A=F5H,C=0,Z=1 + JC CPIE ;TEST "CPI" FOR RE-SET CARRY ("ADI") + JNZ CPIE ;TEST "CPI" FOR RE-SET ZERO + CPI 0FFH ;A=F5H,C=1,Z=0 + JZ CPIE ;TEST "CPI" FOR RE-SET ZERO + JC ACII ;TEST "CPI" FOR SET CARRY +CPIE: CALL CPUER +ACII: ACI 00AH ;A=F5H+0AH+CARRY(1)=0,C=1 + ACI 00AH ;A=0+0AH+CARRY(0)=0BH,C=0 + CPI 00BH + JZ SUII ;TEST "ACI" + CALL CPUER +SUII: SUI 00CH ;A=FFH,C=0 + SUI 00FH ;A=F0H,C=1 + CPI 0F0H + JZ SBII ;TEST "SUI" + CALL CPUER +SBII: SBI 0F1H ;A=F0H-0F1H-CARRY(0)=FFH,C=1 + SBI 00EH ;A=FFH-OEH-CARRY(1)=F0H,C=0 + CPI 0F0H + JZ ANII ;TEST "SBI" + CALL CPUER +ANII: ANI 055H ;A=F0H55H=50H,C=0,P=1,S=0,Z=0 + CPI 050H + JZ ORII ;TEST "ANI" + CALL CPUER +ORII: ORI 03AH ;A=50H3AH=7AH,C=0,P=0,S=0,Z=0 + CPI 07AH + JZ XRII ;TEST "ORI" + CALL CPUER +XRII: XRI 00FH ;A=7AH0FH=75H,C=0,P=0,S=0,Z=0 + CPI 075H + JZ C010 ;TEST "XRI" + CALL CPUER +; +; +; +;TEST CALLS AND RETURNS +; +C010: ANI 000H ;A=0,C=0,P=1,S=0,Z=1 + CC CPUER ;TEST "CC" + CPO CPUER ;TEST "CPO" + CM CPUER ;TEST "CM" + CNZ CPUER ;TEST "CNZ" + CPI 000H + JZ C020 ;A=0,C=0,P=0,S=0,Z=1 + CALL CPUER +C020: SUI 077H ;A=89H,C=1,P=0,S=1,Z=0 + CNC CPUER ;TEST "CNC" + CPE CPUER ;TEST "CPE" + CP CPUER ;TEST "CP" + CZ CPUER ;TEST "CZ" + CPI 089H + JZ C030 ;TEST FOR "CALLS" TAKING BRANCH + CALL CPUER +C030: ANI 0FFH ;SET FLAGS BACK! + CPO CPOI ;TEST "CPO" + CPI 0D9H + JZ MOVI ;TEST "CALL" SEQUENCE SUCCESS + CALL CPUER +CPOI: RPE ;TEST "RPE" + ADI 010H ;A=99H,C=0,P=0,S=1,Z=0 + CPE CPEI ;TEST "CPE" + ADI 002H ;A=D9H,C=0,P=0,S=1,Z=0 + RPO ;TEST "RPO" + CALL CPUER +CPEI: RPO ;TEST "RPO" + ADI 020H ;A=B9H,C=0,P=0,S=1,Z=0 + CM CMI ;TEST "CM" + ADI 004H ;A=D7H,C=0,P=1,S=1,Z=0 + RPE ;TEST "RPE" + CALL CPUER +CMI: RP ;TEST "RP" + ADI 080H ;A=39H,C=1,P=1,S=0,Z=0 + CP TCPI ;TEST "CP" + ADI 080H ;A=D3H,C=0,P=0,S=1,Z=0 + RM ;TEST "RM" + CALL CPUER +TCPI: RM ;TEST "RM" + ADI 040H ;A=79H,C=0,P=0,S=0,Z=0 + CNC CNCI ;TEST "CNC" + ADI 040H ;A=53H,C=0,P=1,S=0,Z=0 + RP ;TEST "RP" + CALL CPUER +CNCI: RC ;TEST "RC" + ADI 08FH ;A=08H,C=1,P=0,S=0,Z=0 + CC CCI ;TEST "CC" + SUI 002H ;A=13H,C=0,P=0,S=0,Z=0 + RNC ;TEST "RNC" + CALL CPUER +CCI: RNC ;TEST "RNC" + ADI 0F7H ;A=FFH,C=0,P=1,S=1,Z=0 + CNZ CNZI ;TEST "CNZ" + ADI 0FEH ;A=15H,C=1,P=0,S=0,Z=0 + RC ;TEST "RC" + CALL CPUER +CNZI: RZ ;TEST "RZ" + ADI 001H ;A=00H,C=1,P=1,S=0,Z=1 + CZ CZI ;TEST "CZ" + ADI 0D0H ;A=17H,C=1,P=1,S=0,Z=0 + RNZ ;TEST "RNZ" + CALL CPUER +CZI: RNZ ;TEST "RNZ" + ADI 047H ;A=47H,C=0,P=1,S=0,Z=0 + CPI 047H ;A=47H,C=0,P=1,S=0,Z=1 + RZ ;TEST "RZ" + CALL CPUER +; +; +; +;TEST "MOV","INR",AND "DCR" INSTRUCTIONS +; +MOVI: MVI A,077H + INR A + MOV B,A + INR B + MOV C,B + DCR C + MOV D,C + MOV E,D + MOV H,E + MOV L,H + MOV A,L ;TEST "MOV" A,L,H,E,D,C,B,A + DCR A + MOV C,A + MOV E,C + MOV L,E + MOV B,L + MOV D,B + MOV H,D + MOV A,H ;TEST "MOV" A,H,D,B,L,E,C,A + MOV D,A + INR D + MOV L,D + MOV C,L + INR C + MOV H,C + MOV B,H + DCR B + MOV E,B + MOV A,E ;TEST "MOV" A,E,B,H,C,L,D,A + MOV E,A + INR E + MOV B,E + MOV H,B + INR H + MOV C,H + MOV L,C + MOV D,L + DCR D + MOV A,D ;TEST "MOV" A,D,L,C,H,B,E,A + MOV H,A + DCR H + MOV D,H + MOV B,D + MOV L,B + INR L + MOV E,L + DCR E + MOV C,E + MOV A,C ;TEST "MOV" A,C,E,L,B,D,H,A + MOV L,A + DCR L + MOV H,L + MOV E,H + MOV D,E + MOV C,D + MOV B,C + MOV A,B + CPI 077H + CNZ CPUER ;TEST "MOV" A,B,C,D,E,H,L,A +; +; +; +;TEST ARITHMETIC AND LOGIC INSTRUCTIONS +; + XRA A + MVI B,001H + MVI C,003H + MVI D,007H + MVI E,00FH + MVI H,01FH + MVI L,03FH + ADD B + ADD C + ADD D + ADD E + ADD H + ADD L + ADD A + CPI 0F0H + CNZ CPUER ;TEST "ADD" B,C,D,E,H,L,A + SUB B + SUB C + SUB D + SUB E + SUB H + SUB L + CPI 078H + CNZ CPUER ;TEST "SUB" B,C,D,E,H,L + SUB A + CNZ CPUER ;TEST "SUB" A + MVI A,080H + ADD A + MVI B,001H + MVI C,002H + MVI D,003H + MVI E,004H + MVI H,005H + MVI L,006H + ADC B + MVI B,080H + ADD B + ADD B + ADC C + ADD B + ADD B + ADC D + ADD B + ADD B + ADC E + ADD B + ADD B + ADC H + ADD B + ADD B + ADC L + ADD B + ADD B + ADC A + CPI 037H + CNZ CPUER ;TEST "ADC" B,C,D,E,H,L,A + MVI A,080H + ADD A + MVI B,001H + SBB B + MVI B,0FFH + ADD B + SBB C + ADD B + SBB D + ADD B + SBB E + ADD B + SBB H + ADD B + SBB L + CPI 0E0H + CNZ CPUER ;TEST "SBB" B,C,D,E,H,L + MVI A,080H + ADD A + SBB A + CPI 0FFH + CNZ CPUER ;TEST "SBB" A + MVI A,0FFH + MVI B,0FEH + MVI C,0FCH + MVI D,0EFH + MVI E,07FH + MVI H,0F4H + MVI L,0BFH + ANA B ;changed from ANA A (mwd) + ANA C + ANA D + ANA E + ANA H + ANA L + ANA A + CPI 024H + CNZ CPUER ;TEST "ANA" B,C,D,E,H,L,A + XRA A + MVI B,001H + MVI C,002H + MVI D,004H + MVI E,008H + MVI H,010H + MVI L,020H + ORA B + ORA C + ORA D + ORA E + ORA H + ORA L + ORA A + CPI 03FH + CNZ CPUER ;TEST "ORA" B,C,D,E,H,L,A + MVI A,000H + MVI H,08FH + MVI L,04FH + XRA B + XRA C + XRA D + XRA E + XRA H + XRA L + CPI 0CFH + CNZ CPUER ;TEST "XRA" B,C,D,E,H,L + XRA A + CNZ CPUER ;TEST "XRA" A + MVI B,044H + MVI C,045H + MVI D,046H + MVI E,047H + MVI H,(TEMP0 / 0FFH) ;HIGH BYTE OF TEST MEMORY LOCATION + MVI L,(TEMP0 AND 0FFH) ;LOW BYTE OF TEST MEMORY LOCATION + MOV M,B + MVI B,000H + MOV B,M + MVI A,044H + CMP B + CNZ CPUER ;TEST "MOV" M,B AND B,M + MOV M,C ;added (mwd) + MVI C,000H ;added (mwd) + MOV C,M ;added (mwd) + MVI A,045H ;added (mwd) + CMP C ;added (mwd) + CNZ CPUER ;TEST "MOV" M,C AND C,M added (mwd) + MOV M,D + MVI D,000H + MOV D,M + MVI A,046H + CMP D + CNZ CPUER ;TEST "MOV" M,D AND D,M + MOV M,E + MVI E,000H + MOV E,M + MVI A,047H + CMP E + CNZ CPUER ;TEST "MOV" M,E AND E,M + MOV M,H + MVI H,(TEMP0 / 0FFH) + MVI L,(TEMP0 AND 0FFH) + MOV H,M + MVI A,(TEMP0 / 0FFH) + CMP H + CNZ CPUER ;TEST "MOV" M,H AND H,M + MOV M,L + MVI H,(TEMP0 / 0FFH) + MVI L,(TEMP0 AND 0FFH) + MOV L,M + MVI A,(TEMP0 AND 0FFH) + CMP L + CNZ CPUER ;TEST "MOV" M,L AND L,M + MVI H,(TEMP0 / 0FFH) + MVI L,(TEMP0 AND 0FFH) + MVI A,032H + MOV M,A + CMP M + CNZ CPUER ;TEST "MOV" M,A + ADD M + CPI 064H + CNZ CPUER ;TEST "ADD" M + XRA A + MOV A,M + CPI 032H + CNZ CPUER ;TEST "MOV" A,M + MVI H,(TEMP0 / 0FFH) + MVI L,(TEMP0 AND 0FFH) + MOV A,M + SUB M + CNZ CPUER ;TEST "SUB" M + MVI A,080H + ADD A + ADC M + CPI 033H + CNZ CPUER ;TEST "ADC" M + MVI A,080H + ADD A + SBB M + CPI 0CDH + CNZ CPUER ;TEST "SBB" M + ANA M + CNZ CPUER ;TEST "ANA" M + MVI A,025H + ORA M + CPI 037H + CNZ CPUER ;TEST "ORA" M + XRA M + CPI 005H + CNZ CPUER ;TEST "XRA" M + MVI M,055H + INR M + DCR M + ADD M + CPI 05AH + CNZ CPUER ;TEST "INR","DCR",AND "MVI" M + LXI B,12FFH + LXI D,12FFH + LXI H,12FFH + INX B + INX D + INX H + MVI A,013H + CMP B + CNZ CPUER ;TEST "LXI" AND "INX" B + CMP D + CNZ CPUER ;TEST "LXI" AND "INX" D + CMP H + CNZ CPUER ;TEST "LXI" AND "INX" H + MVI A,000H + CMP C + CNZ CPUER ;TEST "LXI" AND "INX" B + CMP E + CNZ CPUER ;TEST "LXI" AND "INX" D + CMP L + CNZ CPUER ;TEST "LXI" AND "INX" H + DCX B + DCX D + DCX H + MVI A,012H + CMP B + CNZ CPUER ;TEST "DCX" B + CMP D + CNZ CPUER ;TEST "DCX" D + CMP H + CNZ CPUER ;TEST "DCX" H + MVI A,0FFH + CMP C + CNZ CPUER ;TEST "DCX" B + CMP E + CNZ CPUER ;TEST "DCX" D + CMP L + CNZ CPUER ;TEST "DCX" H + STA TEMP0 + XRA A + LDA TEMP0 + CPI 0FFH + CNZ CPUER ;TEST "LDA" AND "STA" + LHLD TEMPP + SHLD TEMP0 + LDA TEMPP + MOV B,A + LDA TEMP0 + CMP B + CNZ CPUER ;TEST "LHLD" AND "SHLD" + LDA TEMPP+1 + MOV B,A + LDA TEMP0+1 + CMP B + CNZ CPUER ;TEST "LHLD" AND "SHLD" + MVI A,0AAH + STA TEMP0 + MOV B,H + MOV C,L + XRA A + LDAX B + CPI 0AAH + CNZ CPUER ;TEST "LDAX" B + INR A + STAX B + LDA TEMP0 + CPI 0ABH + CNZ CPUER ;TEST "STAX" B + MVI A,077H + STA TEMP0 + LHLD TEMPP + LXI D,00000H + XCHG + XRA A + LDAX D + CPI 077H + CNZ CPUER ;TEST "LDAX" D AND "XCHG" + XRA A + ADD H + ADD L + CNZ CPUER ;TEST "XCHG" + MVI A,0CCH + STAX D + LDA TEMP0 + CPI 0CCH + STAX D + LDA TEMP0 + CPI 0CCH + CNZ CPUER ;TEST "STAX" D + LXI H,07777H + DAD H + MVI A,0EEH + CMP H + CNZ CPUER ;TEST "DAD" H + CMP L + CNZ CPUER ;TEST "DAD" H + LXI H,05555H + LXI B,0FFFFH + DAD B + MVI A,055H + CNC CPUER ;TEST "DAD" B + CMP H + CNZ CPUER ;TEST "DAD" B + MVI A,054H + CMP L + CNZ CPUER ;TEST "DAD" B + LXI H,0AAAAH + LXI D,03333H + DAD D + MVI A,0DDH + CMP H + CNZ CPUER ;TEST "DAD" D + CMP L + CNZ CPUER ;TEST "DAD" B + STC + CNC CPUER ;TEST "STC" + CMC + CC CPUER ;TEST "CMC + MVI A,0AAH + CMA + CPI 055H + CNZ CPUER ;TEST "CMA" + ORA A ;RE-SET AUXILIARY CARRY + DAA + CPI 055H + CNZ CPUER ;TEST "DAA" + MVI A,088H + ADD A + DAA + CPI 076H + CNZ CPUER ;TEST "DAA" + XRA A + MVI A,0AAH + DAA + CNC CPUER ;TEST "DAA" + CPI 010H + CNZ CPUER ;TEST "DAA" + XRA A + MVI A,09AH + DAA + CNC CPUER ;TEST "DAA" + CNZ CPUER ;TEST "DAA" + STC + MVI A,042H + RLC + CC CPUER ;TEST "RLC" FOR RE-SET CARRY + RLC + CNC CPUER ;TEST "RLC" FOR SET CARRY + CPI 009H + CNZ CPUER ;TEST "RLC" FOR ROTATION + RRC + CNC CPUER ;TEST "RRC" FOR SET CARRY + RRC + CPI 042H + CNZ CPUER ;TEST "RRC" FOR ROTATION + RAL + RAL + CNC CPUER ;TEST "RAL" FOR SET CARRY + CPI 008H + CNZ CPUER ;TEST "RAL" FOR ROTATION + RAR + RAR + CC CPUER ;TEST "RAR" FOR RE-SET CARRY + CPI 002H + CNZ CPUER ;TEST "RAR" FOR ROTATION + LXI B,01234H + LXI D,0AAAAH + LXI H,05555H + XRA A + PUSH B + PUSH D + PUSH H + PUSH PSW + LXI B,00000H + LXI D,00000H + LXI H,00000H + MVI A,0C0H + ADI 0F0H + POP PSW + POP H + POP D + POP B + CC CPUER ;TEST "PUSH PSW" AND "POP PSW" + CNZ CPUER ;TEST "PUSH PSW" AND "POP PSW" + CPO CPUER ;TEST "PUSH PSW" AND "POP PSW" + CM CPUER ;TEST "PUSH PSW" AND "POP PSW" + MVI A,012H + CMP B + CNZ CPUER ;TEST "PUSH B" AND "POP B" + MVI A,034H + CMP C + CNZ CPUER ;TEST "PUSH B" AND "POP B" + MVI A,0AAH + CMP D + CNZ CPUER ;TEST "PUSH D" AND "POP D" + CMP E + CNZ CPUER ;TEST "PUSH D" AND "POP D" + MVI A,055H + CMP H + CNZ CPUER ;TEST "PUSH H" AND "POP H" + CMP L + CNZ CPUER ;TEST "PUSH H" AND "POP H" + LXI H,00000H + DAD SP + SHLD SAVSTK ;SAVE THE "OLD" STACK-POINTER! + LXI SP,TEMP4 + DCX SP + DCX SP + INX SP + DCX SP + MVI A,055H + STA TEMP2 + CMA + STA TEMP3 + POP B + CMP B + CNZ CPUER ;TEST "LXI","DAD","INX",AND "DCX" SP + CMA + CMP C + CNZ CPUER ;TEST "LXI","DAD","INX", AND "DCX" SP + LXI H,TEMP4 + SPHL + LXI H,07733H + DCX SP + DCX SP + XTHL + LDA TEMP3 + CPI 077H + CNZ CPUER ;TEST "SPHL" AND "XTHL" + LDA TEMP2 + CPI 033H + CNZ CPUER ;TEST "SPHL" AND "XTHL" + MVI A,055H + CMP L + CNZ CPUER ;TEST "SPHL" AND "XTHL" + CMA + CMP H + CNZ CPUER ;TEST "SPHL" AND "XTHL" + LHLD SAVSTK ;RESTORE THE "OLD" STACK-POINTER + SPHL + LXI H,CPUOK + PCHL ;TEST "PCHL" +; +; +; +CPUER: LXI H,NGCPU ;OUTPUT "CPU HAS FAILED ERROR EXIT=" TO CONSOLE + CALL MSG + POP H ;HL = ADDRESS FOLLOWING CALL CPUER + PUSH H + MOV A,H + CALL BYTEO ;SHOW ERROR EXIT ADDRESS HIGH BYTE + POP H + MOV A,L + CALL BYTEO ;SHOW ERROR EXIT ADDRESS LOW BYTE + JMP WBOOT ;EXIT TO CP/M WARM BOOT +; +; +; +CPUOK: LXI H,OKCPU ;OUTPUT "CPU IS OPERATIONAL" TO CONSOLE + CALL MSG + JMP WBOOT ;EXIT TO CP/M WARM BOOT +; +; +; +TEMPP: DW TEMP0 ;POINTER USED TO TEST "LHLD","SHLD", + ; AND "LDAX" INSTRUCTIONS +; +TEMP0: DS 1 ;TEMPORARY STORAGE FOR CPU TEST MEMORY LOCATIONS +TEMP1: DS 1 ;TEMPORARY STORAGE FOR CPU TEST MEMORY LOCATIONS +TEMP2 DS 1 ;TEMPORARY STORAGE FOR CPU TEST MEMORY LOCATIONS +TEMP3: DS 1 ;TEMPORARY STORAGE FOR CPU TEST MEMORY LOCATIONS +TEMP4: DS 1 ;TEMPORARY STORAGE FOR CPU TEST MEMORY LOCATIONS +SAVSTK: DS 2 ;TEMPORARY STACK-POINTER STORAGE LOCATION +; +; +; +STACK EQU TEMPP+256 ;DE-BUG STACK POINTER STORAGE AREA +; +; +; + END diff --git a/Intel8080/Intel8080.Test/roms/TST8080.COM b/Intel8080/Intel8080.Test/roms/TST8080.COM new file mode 100644 index 0000000000000000000000000000000000000000..d16eeb835547b58a0f5a5c99ce7a211af1196dfc GIT binary patch literal 1536 zcmbu9dr(wW9LMjy3kN~i1xKuBD>( zz{+0s+TOKRTV~k{7g)L@JFKE3j56i`EoA8^I8a1%w%_jpGxc|O=AQF8-{1Fl?(h8W z-VN;IE3HPm&1iE}iUxvb-gQO*) z93$tn!%n!h)gjud&31zmwlq|vPpQic4zb)|tuUK(B3x#>-DVffE3M8Y>A6iYIu##U z&JS|I03Y&@W9>Npb_B7YO5p$c*c;2|=5{MqzG+IRc9wJBAL& z9gbr&gR79ccI z!$$?ZsCK)Ld&oHt8S#(~PlUQ64=RLmI^Fq~atMIB z7h9s1C0t)~`~4f2*lxVfTz%Vy8!oAw*xmr9$Tcyi0u1~vqNUC%xL!tNK@dcc?Arcwhq z1+6MIDkEA?wi8K`c1Y4rNqS0>o|dF%B&m@VP8(k#5$RQFkMx@Ky7UI?os{2V5rha~ z>IvlyX=amV%F+dHDjG{GV{--{Cwz@fG`t(zUE6 zGRIGfn}`JzOesDH*sLJ+g40y#i(_60EEX_lFA#Nu4v9$|ch+~=3J*=%hI`Ad?XS}UGT$Jigqfh*PE1|e<}TG+ExhRQurdMH=DU2?Lek7(d`YH zY#pq9)SC$wmZR|o20+8gfKpOWn*o%T1`Z|w@de3AUN02n`>|_a zl;=1&i;m-Hvph81ceDj;UY6SW(iY8WBe?-mQj%XnU3o1e zJFk_rU^BBZNf#i0>hj$sB|jIp5~W+kEoAbgyRZS-xKmaenD&!jb-VDdu5VyNsD|&` R2txo0t49sMPq_bk{R4HVdRqVh literal 0 HcmV?d00001 diff --git a/Intel8080/Intel8080.Test/roms/TST8080.PRN b/Intel8080/Intel8080.Test/roms/TST8080.PRN new file mode 100644 index 0000000..111f5f9 --- /dev/null +++ b/Intel8080/Intel8080.Test/roms/TST8080.PRN @@ -0,0 +1,821 @@ + + + ;*********************************************************************** + ; MICROCOSM ASSOCIATES 8080/8085 CPU DIAGNOSTIC VERSION 1.0 (C) 1980 + ;*********************************************************************** + ; + ;DONATED TO THE "SIG/M" CP/M USER'S GROUP BY: + ;KELLY SMITH, MICROCOSM ASSOCIATES + ;3055 WACO AVENUE + ;SIMI VALLEY, CALIFORNIA, 93065 + ;(805) 527-9321 (MODEM, CP/M-NET (TM)) + ;(805) 527-0518 (VERBAL) + ; + ; Updated by Mike Douglas October, 2012 + ; + ; Added the following tests that were missing: + ; mov c,m + ; mov m,c + ; ana b + ; + ; Fixed the CPUER exit routine which did not display the + ; low byte of the failure address properly. + ; + ; Added display of the Microcosm welcome message + ; + 0100 ORG 00100H + + ; + 0100 C3B201 JMP CPU ;JUMP TO 8080 CPU DIAGNOSTIC + ; + 0103 4D4943524FWELCOM DB 'MICROCOSM ASSOCIATES 8080/8085 CPU DIAGNOSTIC',13,10 + 0132 2056455253 DB ' VERSION 1.0 (C) 1980',13,10,'$' + ; + 0005 = BDOS EQU 00005H ;BDOS ENTRY TO CP/M + 0000 = WBOOT EQU 00000H ;RE-ENTRY TO CP/M WARM BOOT + ; + ; + ; + ;MESSAGE OUTPUT ROUTINE + ; + 014B D5 MSG: PUSH D ;EXILE D REG. + 014C EB XCHG ;SWAP H&L REGS. TO D&E REGS. + 014D 0E09 MVI C,9 ;LET BDOS KNOW WE WANT TO SEND A MESSAGE + 014F CD0500 CALL BDOS + 0152 D1 POP D ;BACK FROM EXILE + 0153 C9 RET + ; + ; + ; + ;CHARACTER OUTPUT ROUTINE + ; + 0154 0E02 PCHAR: MVI C,2 + 0156 CD0500 CALL BDOS + 0159 C9 RET + ; + ; + ; + 015A F5 BYTEO: PUSH PSW + 015B CD6A01 CALL BYTO1 + 015E 5F MOV E,A + 015F CD5401 CALL PCHAR + 0162 F1 POP PSW + 0163 CD6E01 CALL BYTO2 + 0166 5F MOV E,A + 0167 C35401 JMP PCHAR + 016A 0F BYTO1: RRC + 016B 0F RRC + 016C 0F RRC + 016D 0F RRC + 016E E60F BYTO2: ANI 0FH + 0170 FE0A CPI 0AH + 0172 FA7701 JM BYTO3 + 0175 C607 ADI 7 + 0177 C630 BYTO3: ADI 30H + 0179 C9 RET + ; + ; + ; + ;************************************************************ + ; MESSAGE TABLE FOR OPERATIONAL CPU TEST + ;************************************************************ + ; + 017A 0D0A204350OKCPU: DB 0DH,0AH,' CPU IS OPERATIONAL$' + ; + 0190 0D0A204350NGCPU: DB 0DH,0AH,' CPU HAS FAILED! ERROR EXIT=$' + ; + ; + ; + ;************************************************************ + ; 8080/8085 CPU TEST/DIAGNOSTIC + ;************************************************************ + ; + ;NOTE: (1) PROGRAM ASSUMES "CALL",AND "LXI SP" INSTRUCTIONS WORK! + ; + ; (2) INSTRUCTIONS NOT TESTED ARE "HLT","DI","EI","RIM","SIM", + ; AND "RST 0" THRU "RST 7" + ; + ; + ; + ;TEST JUMP INSTRUCTIONS AND FLAGS + ; + 01B2 31BD07 CPU: LXI SP,STACK ;SET THE STACK POINTER + 01B5 210301 LXI H,WELCOM + 01B8 CD4B01 CALL MSG + 01BB E600 ANI 0 ;INITIALIZE A REG. AND CLEAR ALL FLAGS + 01BD CAC301 JZ J010 ;TEST "JZ" + 01C0 CDA006 CALL CPUER + 01C3 D2C901 J010: JNC J020 ;TEST "JNC" + 01C6 CDA006 CALL CPUER + 01C9 EACF01 J020: JPE J030 ;TEST "JPE" + 01CC CDA006 CALL CPUER + 01CF F2D501 J030: JP J040 ;TEST "JP" + 01D2 CDA006 CALL CPUER + 01D5 C2E401 J040: JNZ J050 ;TEST "JNZ" + 01D8 DAE401 JC J050 ;TEST "JC" + 01DB E2E401 JPO J050 ;TEST "JPO" + 01DE FAE401 JM J050 ;TEST "JM" + 01E1 C3E701 JMP J060 ;TEST "JMP" (IT'S A LITTLE LATE,BUT WHAT THE HELL! + 01E4 CDA006 J050: CALL CPUER + 01E7 C606 J060: ADI 6 ;A=6,C=0,P=1,S=0,Z=0 + 01E9 C2EF01 JNZ J070 ;TEST "JNZ" + 01EC CDA006 CALL CPUER + 01EF DAF801 J070: JC J080 ;TEST "JC" + 01F2 E2F801 JPO J080 ;TEST "JPO" + 01F5 F2FB01 JP J090 ;TEST "JP" + 01F8 CDA006 J080: CALL CPUER + 01FB C670 J090: ADI 070H ;A=76H,C=0,P=0,S=0,Z=0 + 01FD E20302 JPO J100 ;TEST "JPO" + 0200 CDA006 CALL CPUER + 0203 FA0C02 J100: JM J110 ;TEST "JM" + 0206 CA0C02 JZ J110 ;TEST "JZ" + 0209 D20F02 JNC J120 ;TEST "JNC" + 020C CDA006 J110: CALL CPUER + 020F C681 J120: ADI 081H ;A=F7H,C=0,P=0,S=1,Z=0 + 0211 FA1702 JM J130 ;TEST "JM" + 0214 CDA006 CALL CPUER + 0217 CA2002 J130: JZ J140 ;TEST "JZ" + 021A DA2002 JC J140 ;TEST "JC" + 021D E22302 JPO J150 ;TEST "JPO" + 0220 CDA006 J140: CALL CPUER + 0223 C6FE J150: ADI 0FEH ;A=F5H,C=1,P=1,S=1,Z=0 + 0225 DA2B02 JC J160 ;TEST "JC" + 0228 CDA006 CALL CPUER + 022B CA3402 J160: JZ J170 ;TEST "JZ" + 022E E23402 JPO J170 ;TEST "JPO" + 0231 FA3702 JM AIMM ;TEST "JM" + 0234 CDA006 J170: CALL CPUER + ; + ; + ; + ;TEST ACCUMULATOR IMMEDIATE INSTRUCTIONS + ; + 0237 FE00 AIMM: CPI 0 ;A=F5H,C=0,Z=0 + 0239 DA4F02 JC CPIE ;TEST "CPI" FOR RE-SET CARRY + 023C CA4F02 JZ CPIE ;TEST "CPI" FOR RE-SET ZERO + 023F FEF5 CPI 0F5H ;A=F5H,C=0,Z=1 + 0241 DA4F02 JC CPIE ;TEST "CPI" FOR RE-SET CARRY ("ADI") + 0244 C24F02 JNZ CPIE ;TEST "CPI" FOR RE-SET ZERO + 0247 FEFF CPI 0FFH ;A=F5H,C=1,Z=0 + 0249 CA4F02 JZ CPIE ;TEST "CPI" FOR RE-SET ZERO + 024C DA5202 JC ACII ;TEST "CPI" FOR SET CARRY + 024F CDA006 CPIE: CALL CPUER + 0252 CE0A ACII: ACI 00AH ;A=F5H+0AH+CARRY(1)=0,C=1 + 0254 CE0A ACI 00AH ;A=0+0AH+CARRY(0)=0BH,C=0 + 0256 FE0B CPI 00BH + 0258 CA5E02 JZ SUII ;TEST "ACI" + 025B CDA006 CALL CPUER + 025E D60C SUII: SUI 00CH ;A=FFH,C=0 + 0260 D60F SUI 00FH ;A=F0H,C=1 + 0262 FEF0 CPI 0F0H + 0264 CA6A02 JZ SBII ;TEST "SUI" + 0267 CDA006 CALL CPUER + 026A DEF1 SBII: SBI 0F1H ;A=F0H-0F1H-CARRY(0)=FFH,C=1 + 026C DE0E SBI 00EH ;A=FFH-OEH-CARRY(1)=F0H,C=0 + 026E FEF0 CPI 0F0H + 0270 CA7602 JZ ANII ;TEST "SBI" + 0273 CDA006 CALL CPUER + 0276 E655 ANII: ANI 055H ;A=F0H55H=50H,C=0,P=1,S=0,Z=0 + 0278 FE50 CPI 050H + 027A CA8002 JZ ORII ;TEST "ANI" + 027D CDA006 CALL CPUER + 0280 F63A ORII: ORI 03AH ;A=50H3AH=7AH,C=0,P=0,S=0,Z=0 + 0282 FE7A CPI 07AH + 0284 CA8A02 JZ XRII ;TEST "ORI" + 0287 CDA006 CALL CPUER + 028A EE0F XRII: XRI 00FH ;A=7AH0FH=75H,C=0,P=0,S=0,Z=0 + 028C FE75 CPI 075H + 028E CA9402 JZ C010 ;TEST "XRI" + 0291 CDA006 CALL CPUER + ; + ; + ; + ;TEST CALLS AND RETURNS + ; + 0294 E600 C010: ANI 000H ;A=0,C=0,P=1,S=0,Z=1 + 0296 DCA006 CC CPUER ;TEST "CC" + 0299 E4A006 CPO CPUER ;TEST "CPO" + 029C FCA006 CM CPUER ;TEST "CM" + 029F C4A006 CNZ CPUER ;TEST "CNZ" + 02A2 FE00 CPI 000H + 02A4 CAAA02 JZ C020 ;A=0,C=0,P=0,S=0,Z=1 + 02A7 CDA006 CALL CPUER + 02AA D677 C020: SUI 077H ;A=89H,C=1,P=0,S=1,Z=0 + 02AC D4A006 CNC CPUER ;TEST "CNC" + 02AF ECA006 CPE CPUER ;TEST "CPE" + 02B2 F4A006 CP CPUER ;TEST "CP" + 02B5 CCA006 CZ CPUER ;TEST "CZ" + 02B8 FE89 CPI 089H + 02BA CAC002 JZ C030 ;TEST FOR "CALLS" TAKING BRANCH + 02BD CDA006 CALL CPUER + 02C0 E6FF C030: ANI 0FFH ;SET FLAGS BACK! + 02C2 E4CD02 CPO CPOI ;TEST "CPO" + 02C5 FED9 CPI 0D9H + 02C7 CA2A03 JZ MOVI ;TEST "CALL" SEQUENCE SUCCESS + 02CA CDA006 CALL CPUER + 02CD E8 CPOI: RPE ;TEST "RPE" + 02CE C610 ADI 010H ;A=99H,C=0,P=0,S=1,Z=0 + 02D0 ECD902 CPE CPEI ;TEST "CPE" + 02D3 C602 ADI 002H ;A=D9H,C=0,P=0,S=1,Z=0 + 02D5 E0 RPO ;TEST "RPO" + 02D6 CDA006 CALL CPUER + 02D9 E0 CPEI: RPO ;TEST "RPO" + 02DA C620 ADI 020H ;A=B9H,C=0,P=0,S=1,Z=0 + 02DC FCE502 CM CMI ;TEST "CM" + 02DF C604 ADI 004H ;A=D7H,C=0,P=1,S=1,Z=0 + 02E1 E8 RPE ;TEST "RPE" + 02E2 CDA006 CALL CPUER + 02E5 F0 CMI: RP ;TEST "RP" + 02E6 C680 ADI 080H ;A=39H,C=1,P=1,S=0,Z=0 + 02E8 F4F102 CP TCPI ;TEST "CP" + 02EB C680 ADI 080H ;A=D3H,C=0,P=0,S=1,Z=0 + 02ED F8 RM ;TEST "RM" + 02EE CDA006 CALL CPUER + 02F1 F8 TCPI: RM ;TEST "RM" + 02F2 C640 ADI 040H ;A=79H,C=0,P=0,S=0,Z=0 + 02F4 D4FD02 CNC CNCI ;TEST "CNC" + 02F7 C640 ADI 040H ;A=53H,C=0,P=1,S=0,Z=0 + 02F9 F0 RP ;TEST "RP" + 02FA CDA006 CALL CPUER + 02FD D8 CNCI: RC ;TEST "RC" + 02FE C68F ADI 08FH ;A=08H,C=1,P=0,S=0,Z=0 + 0300 DC0903 CC CCI ;TEST "CC" + 0303 D602 SUI 002H ;A=13H,C=0,P=0,S=0,Z=0 + 0305 D0 RNC ;TEST "RNC" + 0306 CDA006 CALL CPUER + 0309 D0 CCI: RNC ;TEST "RNC" + 030A C6F7 ADI 0F7H ;A=FFH,C=0,P=1,S=1,Z=0 + 030C C41503 CNZ CNZI ;TEST "CNZ" + 030F C6FE ADI 0FEH ;A=15H,C=1,P=0,S=0,Z=0 + 0311 D8 RC ;TEST "RC" + 0312 CDA006 CALL CPUER + 0315 C8 CNZI: RZ ;TEST "RZ" + 0316 C601 ADI 001H ;A=00H,C=1,P=1,S=0,Z=1 + 0318 CC2103 CZ CZI ;TEST "CZ" + 031B C6D0 ADI 0D0H ;A=17H,C=1,P=1,S=0,Z=0 + 031D C0 RNZ ;TEST "RNZ" + 031E CDA006 CALL CPUER + 0321 C0 CZI: RNZ ;TEST "RNZ" + 0322 C647 ADI 047H ;A=47H,C=0,P=1,S=0,Z=0 + 0324 FE47 CPI 047H ;A=47H,C=0,P=1,S=0,Z=1 + 0326 C8 RZ ;TEST "RZ" + 0327 CDA006 CALL CPUER + ; + ; + ; + ;TEST "MOV","INR",AND "DCR" INSTRUCTIONS + ; + 032A 3E77 MOVI: MVI A,077H + 032C 3C INR A + 032D 47 MOV B,A + 032E 04 INR B + 032F 48 MOV C,B + 0330 0D DCR C + 0331 51 MOV D,C + 0332 5A MOV E,D + 0333 63 MOV H,E + 0334 6C MOV L,H + 0335 7D MOV A,L ;TEST "MOV" A,L,H,E,D,C,B,A + 0336 3D DCR A + 0337 4F MOV C,A + 0338 59 MOV E,C + 0339 6B MOV L,E + 033A 45 MOV B,L + 033B 50 MOV D,B + 033C 62 MOV H,D + 033D 7C MOV A,H ;TEST "MOV" A,H,D,B,L,E,C,A + 033E 57 MOV D,A + 033F 14 INR D + 0340 6A MOV L,D + 0341 4D MOV C,L + 0342 0C INR C + 0343 61 MOV H,C + 0344 44 MOV B,H + 0345 05 DCR B + 0346 58 MOV E,B + 0347 7B MOV A,E ;TEST "MOV" A,E,B,H,C,L,D,A + 0348 5F MOV E,A + 0349 1C INR E + 034A 43 MOV B,E + 034B 60 MOV H,B + 034C 24 INR H + 034D 4C MOV C,H + 034E 69 MOV L,C + 034F 55 MOV D,L + 0350 15 DCR D + 0351 7A MOV A,D ;TEST "MOV" A,D,L,C,H,B,E,A + 0352 67 MOV H,A + 0353 25 DCR H + 0354 54 MOV D,H + 0355 42 MOV B,D + 0356 68 MOV L,B + 0357 2C INR L + 0358 5D MOV E,L + 0359 1D DCR E + 035A 4B MOV C,E + 035B 79 MOV A,C ;TEST "MOV" A,C,E,L,B,D,H,A + 035C 6F MOV L,A + 035D 2D DCR L + 035E 65 MOV H,L + 035F 5C MOV E,H + 0360 53 MOV D,E + 0361 4A MOV C,D + 0362 41 MOV B,C + 0363 78 MOV A,B + 0364 FE77 CPI 077H + 0366 C4A006 CNZ CPUER ;TEST "MOV" A,B,C,D,E,H,L,A + ; + ; + ; + ;TEST ARITHMETIC AND LOGIC INSTRUCTIONS + ; + 0369 AF XRA A + 036A 0601 MVI B,001H + 036C 0E03 MVI C,003H + 036E 1607 MVI D,007H + 0370 1E0F MVI E,00FH + 0372 261F MVI H,01FH + 0374 2E3F MVI L,03FH + 0376 80 ADD B + 0377 81 ADD C + 0378 82 ADD D + 0379 83 ADD E + 037A 84 ADD H + 037B 85 ADD L + 037C 87 ADD A + 037D FEF0 CPI 0F0H + 037F C4A006 CNZ CPUER ;TEST "ADD" B,C,D,E,H,L,A + 0382 90 SUB B + 0383 91 SUB C + 0384 92 SUB D + 0385 93 SUB E + 0386 94 SUB H + 0387 95 SUB L + 0388 FE78 CPI 078H + 038A C4A006 CNZ CPUER ;TEST "SUB" B,C,D,E,H,L + 038D 97 SUB A + 038E C4A006 CNZ CPUER ;TEST "SUB" A + 0391 3E80 MVI A,080H + 0393 87 ADD A + 0394 0601 MVI B,001H + 0396 0E02 MVI C,002H + 0398 1603 MVI D,003H + 039A 1E04 MVI E,004H + 039C 2605 MVI H,005H + 039E 2E06 MVI L,006H + 03A0 88 ADC B + 03A1 0680 MVI B,080H + 03A3 80 ADD B + 03A4 80 ADD B + 03A5 89 ADC C + 03A6 80 ADD B + 03A7 80 ADD B + 03A8 8A ADC D + 03A9 80 ADD B + 03AA 80 ADD B + 03AB 8B ADC E + 03AC 80 ADD B + 03AD 80 ADD B + 03AE 8C ADC H + 03AF 80 ADD B + 03B0 80 ADD B + 03B1 8D ADC L + 03B2 80 ADD B + 03B3 80 ADD B + 03B4 8F ADC A + 03B5 FE37 CPI 037H + 03B7 C4A006 CNZ CPUER ;TEST "ADC" B,C,D,E,H,L,A + 03BA 3E80 MVI A,080H + 03BC 87 ADD A + 03BD 0601 MVI B,001H + 03BF 98 SBB B + 03C0 06FF MVI B,0FFH + 03C2 80 ADD B + 03C3 99 SBB C + 03C4 80 ADD B + 03C5 9A SBB D + 03C6 80 ADD B + 03C7 9B SBB E + 03C8 80 ADD B + 03C9 9C SBB H + 03CA 80 ADD B + 03CB 9D SBB L + 03CC FEE0 CPI 0E0H + 03CE C4A006 CNZ CPUER ;TEST "SBB" B,C,D,E,H,L + 03D1 3E80 MVI A,080H + 03D3 87 ADD A + 03D4 9F SBB A + 03D5 FEFF CPI 0FFH + 03D7 C4A006 CNZ CPUER ;TEST "SBB" A + 03DA 3EFF MVI A,0FFH + 03DC 06FE MVI B,0FEH + 03DE 0EFC MVI C,0FCH + 03E0 16EF MVI D,0EFH + 03E2 1E7F MVI E,07FH + 03E4 26F4 MVI H,0F4H + 03E6 2EBF MVI L,0BFH + 03E8 A0 ANA B ;changed from ANA A (mwd) + 03E9 A1 ANA C + 03EA A2 ANA D + 03EB A3 ANA E + 03EC A4 ANA H + 03ED A5 ANA L + 03EE A7 ANA A + 03EF FE24 CPI 024H + 03F1 C4A006 CNZ CPUER ;TEST "ANA" B,C,D,E,H,L,A + 03F4 AF XRA A + 03F5 0601 MVI B,001H + 03F7 0E02 MVI C,002H + 03F9 1604 MVI D,004H + 03FB 1E08 MVI E,008H + 03FD 2610 MVI H,010H + 03FF 2E20 MVI L,020H + 0401 B0 ORA B + 0402 B1 ORA C + 0403 B2 ORA D + 0404 B3 ORA E + 0405 B4 ORA H + 0406 B5 ORA L + 0407 B7 ORA A + 0408 FE3F CPI 03FH + 040A C4A006 CNZ CPUER ;TEST "ORA" B,C,D,E,H,L,A + 040D 3E00 MVI A,000H + 040F 268F MVI H,08FH + 0411 2E4F MVI L,04FH + 0413 A8 XRA B + 0414 A9 XRA C + 0415 AA XRA D + 0416 AB XRA E + 0417 AC XRA H + 0418 AD XRA L + 0419 FECF CPI 0CFH + 041B C4A006 CNZ CPUER ;TEST "XRA" B,C,D,E,H,L + 041E AF XRA A + 041F C4A006 CNZ CPUER ;TEST "XRA" A + 0422 0644 MVI B,044H + 0424 0E45 MVI C,045H + 0426 1646 MVI D,046H + 0428 1E47 MVI E,047H + 042A 2606 MVI H,(TEMP0 / 0FFH) ;HIGH BYTE OF TEST MEMORY LOCATION + 042C 2EBF MVI L,(TEMP0 AND 0FFH) ;LOW BYTE OF TEST MEMORY LOCATION + 042E 70 MOV M,B + 042F 0600 MVI B,000H + 0431 46 MOV B,M + 0432 3E44 MVI A,044H + 0434 B8 CMP B + 0435 C4A006 CNZ CPUER ;TEST "MOV" M,B AND B,M + 0438 71 MOV M,C ;added (mwd) + 0439 0E00 MVI C,000H ;added (mwd) + 043B 4E MOV C,M ;added (mwd) + 043C 3E45 MVI A,045H ;added (mwd) + 043E B9 CMP C ;added (mwd) + 043F C4A006 CNZ CPUER ;TEST "MOV" M,C AND C,M added (mwd) + 0442 72 MOV M,D + 0443 1600 MVI D,000H + 0445 56 MOV D,M + 0446 3E46 MVI A,046H + 0448 BA CMP D + 0449 C4A006 CNZ CPUER ;TEST "MOV" M,D AND D,M + 044C 73 MOV M,E + 044D 1E00 MVI E,000H + 044F 5E MOV E,M + 0450 3E47 MVI A,047H + 0452 BB CMP E + 0453 C4A006 CNZ CPUER ;TEST "MOV" M,E AND E,M + 0456 74 MOV M,H + 0457 2606 MVI H,(TEMP0 / 0FFH) + 0459 2EBF MVI L,(TEMP0 AND 0FFH) + 045B 66 MOV H,M + 045C 3E06 MVI A,(TEMP0 / 0FFH) + 045E BC CMP H + 045F C4A006 CNZ CPUER ;TEST "MOV" M,H AND H,M + 0462 75 MOV M,L + 0463 2606 MVI H,(TEMP0 / 0FFH) + 0465 2EBF MVI L,(TEMP0 AND 0FFH) + 0467 6E MOV L,M + 0468 3EBF MVI A,(TEMP0 AND 0FFH) + 046A BD CMP L + 046B C4A006 CNZ CPUER ;TEST "MOV" M,L AND L,M + 046E 2606 MVI H,(TEMP0 / 0FFH) + 0470 2EBF MVI L,(TEMP0 AND 0FFH) + 0472 3E32 MVI A,032H + 0474 77 MOV M,A + 0475 BE CMP M + 0476 C4A006 CNZ CPUER ;TEST "MOV" M,A + 0479 86 ADD M + 047A FE64 CPI 064H + 047C C4A006 CNZ CPUER ;TEST "ADD" M + 047F AF XRA A + 0480 7E MOV A,M + 0481 FE32 CPI 032H + 0483 C4A006 CNZ CPUER ;TEST "MOV" A,M + 0486 2606 MVI H,(TEMP0 / 0FFH) + 0488 2EBF MVI L,(TEMP0 AND 0FFH) + 048A 7E MOV A,M + 048B 96 SUB M + 048C C4A006 CNZ CPUER ;TEST "SUB" M + 048F 3E80 MVI A,080H + 0491 87 ADD A + 0492 8E ADC M + 0493 FE33 CPI 033H + 0495 C4A006 CNZ CPUER ;TEST "ADC" M + 0498 3E80 MVI A,080H + 049A 87 ADD A + 049B 9E SBB M + 049C FECD CPI 0CDH + 049E C4A006 CNZ CPUER ;TEST "SBB" M + 04A1 A6 ANA M + 04A2 C4A006 CNZ CPUER ;TEST "ANA" M + 04A5 3E25 MVI A,025H + 04A7 B6 ORA M + 04A8 FE37 CPI 037H + 04AA C4A006 CNZ CPUER ;TEST "ORA" M + 04AD AE XRA M + 04AE FE05 CPI 005H + 04B0 C4A006 CNZ CPUER ;TEST "XRA" M + 04B3 3655 MVI M,055H + 04B5 34 INR M + 04B6 35 DCR M + 04B7 86 ADD M + 04B8 FE5A CPI 05AH + 04BA C4A006 CNZ CPUER ;TEST "INR","DCR",AND "MVI" M + 04BD 01FF12 LXI B,12FFH + 04C0 11FF12 LXI D,12FFH + 04C3 21FF12 LXI H,12FFH + 04C6 03 INX B + 04C7 13 INX D + 04C8 23 INX H + 04C9 3E13 MVI A,013H + 04CB B8 CMP B + 04CC C4A006 CNZ CPUER ;TEST "LXI" AND "INX" B + 04CF BA CMP D + 04D0 C4A006 CNZ CPUER ;TEST "LXI" AND "INX" D + 04D3 BC CMP H + 04D4 C4A006 CNZ CPUER ;TEST "LXI" AND "INX" H + 04D7 3E00 MVI A,000H + 04D9 B9 CMP C + 04DA C4A006 CNZ CPUER ;TEST "LXI" AND "INX" B + 04DD BB CMP E + 04DE C4A006 CNZ CPUER ;TEST "LXI" AND "INX" D + 04E1 BD CMP L + 04E2 C4A006 CNZ CPUER ;TEST "LXI" AND "INX" H + 04E5 0B DCX B + 04E6 1B DCX D + 04E7 2B DCX H + 04E8 3E12 MVI A,012H + 04EA B8 CMP B + 04EB C4A006 CNZ CPUER ;TEST "DCX" B + 04EE BA CMP D + 04EF C4A006 CNZ CPUER ;TEST "DCX" D + 04F2 BC CMP H + 04F3 C4A006 CNZ CPUER ;TEST "DCX" H + 04F6 3EFF MVI A,0FFH + 04F8 B9 CMP C + 04F9 C4A006 CNZ CPUER ;TEST "DCX" B + 04FC BB CMP E + 04FD C4A006 CNZ CPUER ;TEST "DCX" D + 0500 BD CMP L + 0501 C4A006 CNZ CPUER ;TEST "DCX" H + 0504 32BF06 STA TEMP0 + 0507 AF XRA A + 0508 3ABF06 LDA TEMP0 + 050B FEFF CPI 0FFH + 050D C4A006 CNZ CPUER ;TEST "LDA" AND "STA" + 0510 2ABD06 LHLD TEMPP + 0513 22BF06 SHLD TEMP0 + 0516 3ABD06 LDA TEMPP + 0519 47 MOV B,A + 051A 3ABF06 LDA TEMP0 + 051D B8 CMP B + 051E C4A006 CNZ CPUER ;TEST "LHLD" AND "SHLD" + 0521 3ABE06 LDA TEMPP+1 + 0524 47 MOV B,A + 0525 3AC006 LDA TEMP0+1 + 0528 B8 CMP B + 0529 C4A006 CNZ CPUER ;TEST "LHLD" AND "SHLD" + 052C 3EAA MVI A,0AAH + 052E 32BF06 STA TEMP0 + 0531 44 MOV B,H + 0532 4D MOV C,L + 0533 AF XRA A + 0534 0A LDAX B + 0535 FEAA CPI 0AAH + 0537 C4A006 CNZ CPUER ;TEST "LDAX" B + 053A 3C INR A + 053B 02 STAX B + 053C 3ABF06 LDA TEMP0 + 053F FEAB CPI 0ABH + 0541 C4A006 CNZ CPUER ;TEST "STAX" B + 0544 3E77 MVI A,077H + 0546 32BF06 STA TEMP0 + 0549 2ABD06 LHLD TEMPP + 054C 110000 LXI D,00000H + 054F EB XCHG + 0550 AF XRA A + 0551 1A LDAX D + 0552 FE77 CPI 077H + 0554 C4A006 CNZ CPUER ;TEST "LDAX" D AND "XCHG" + 0557 AF XRA A + 0558 84 ADD H + 0559 85 ADD L + 055A C4A006 CNZ CPUER ;TEST "XCHG" + 055D 3ECC MVI A,0CCH + 055F 12 STAX D + 0560 3ABF06 LDA TEMP0 + 0563 FECC CPI 0CCH + 0565 12 STAX D + 0566 3ABF06 LDA TEMP0 + 0569 FECC CPI 0CCH + 056B C4A006 CNZ CPUER ;TEST "STAX" D + 056E 217777 LXI H,07777H + 0571 29 DAD H + 0572 3EEE MVI A,0EEH + 0574 BC CMP H + 0575 C4A006 CNZ CPUER ;TEST "DAD" H + 0578 BD CMP L + 0579 C4A006 CNZ CPUER ;TEST "DAD" H + 057C 215555 LXI H,05555H + 057F 01FFFF LXI B,0FFFFH + 0582 09 DAD B + 0583 3E55 MVI A,055H + 0585 D4A006 CNC CPUER ;TEST "DAD" B + 0588 BC CMP H + 0589 C4A006 CNZ CPUER ;TEST "DAD" B + 058C 3E54 MVI A,054H + 058E BD CMP L + 058F C4A006 CNZ CPUER ;TEST "DAD" B + 0592 21AAAA LXI H,0AAAAH + 0595 113333 LXI D,03333H + 0598 19 DAD D + 0599 3EDD MVI A,0DDH + 059B BC CMP H + 059C C4A006 CNZ CPUER ;TEST "DAD" D + 059F BD CMP L + 05A0 C4A006 CNZ CPUER ;TEST "DAD" B + 05A3 37 STC + 05A4 D4A006 CNC CPUER ;TEST "STC" + 05A7 3F CMC + 05A8 DCA006 CC CPUER ;TEST "CMC + 05AB 3EAA MVI A,0AAH + 05AD 2F CMA + 05AE FE55 CPI 055H + 05B0 C4A006 CNZ CPUER ;TEST "CMA" + 05B3 B7 ORA A ;RE-SET AUXILIARY CARRY + 05B4 27 DAA + 05B5 FE55 CPI 055H + 05B7 C4A006 CNZ CPUER ;TEST "DAA" + 05BA 3E88 MVI A,088H + 05BC 87 ADD A + 05BD 27 DAA + 05BE FE76 CPI 076H + 05C0 C4A006 CNZ CPUER ;TEST "DAA" + 05C3 AF XRA A + 05C4 3EAA MVI A,0AAH + 05C6 27 DAA + 05C7 D4A006 CNC CPUER ;TEST "DAA" + 05CA FE10 CPI 010H + 05CC C4A006 CNZ CPUER ;TEST "DAA" + 05CF AF XRA A + 05D0 3E9A MVI A,09AH + 05D2 27 DAA + 05D3 D4A006 CNC CPUER ;TEST "DAA" + 05D6 C4A006 CNZ CPUER ;TEST "DAA" + 05D9 37 STC + 05DA 3E42 MVI A,042H + 05DC 07 RLC + 05DD DCA006 CC CPUER ;TEST "RLC" FOR RE-SET CARRY + 05E0 07 RLC + 05E1 D4A006 CNC CPUER ;TEST "RLC" FOR SET CARRY + 05E4 FE09 CPI 009H + 05E6 C4A006 CNZ CPUER ;TEST "RLC" FOR ROTATION + 05E9 0F RRC + 05EA D4A006 CNC CPUER ;TEST "RRC" FOR SET CARRY + 05ED 0F RRC + 05EE FE42 CPI 042H + 05F0 C4A006 CNZ CPUER ;TEST "RRC" FOR ROTATION + 05F3 17 RAL + 05F4 17 RAL + 05F5 D4A006 CNC CPUER ;TEST "RAL" FOR SET CARRY + 05F8 FE08 CPI 008H + 05FA C4A006 CNZ CPUER ;TEST "RAL" FOR ROTATION + 05FD 1F RAR + 05FE 1F RAR + 05FF DCA006 CC CPUER ;TEST "RAR" FOR RE-SET CARRY + 0602 FE02 CPI 002H + 0604 C4A006 CNZ CPUER ;TEST "RAR" FOR ROTATION + 0607 013412 LXI B,01234H + 060A 11AAAA LXI D,0AAAAH + 060D 215555 LXI H,05555H + 0610 AF XRA A + 0611 C5 PUSH B + 0612 D5 PUSH D + 0613 E5 PUSH H + 0614 F5 PUSH PSW + 0615 010000 LXI B,00000H + 0618 110000 LXI D,00000H + 061B 210000 LXI H,00000H + 061E 3EC0 MVI A,0C0H + 0620 C6F0 ADI 0F0H + 0622 F1 POP PSW + 0623 E1 POP H + 0624 D1 POP D + 0625 C1 POP B + 0626 DCA006 CC CPUER ;TEST "PUSH PSW" AND "POP PSW" + 0629 C4A006 CNZ CPUER ;TEST "PUSH PSW" AND "POP PSW" + 062C E4A006 CPO CPUER ;TEST "PUSH PSW" AND "POP PSW" + 062F FCA006 CM CPUER ;TEST "PUSH PSW" AND "POP PSW" + 0632 3E12 MVI A,012H + 0634 B8 CMP B + 0635 C4A006 CNZ CPUER ;TEST "PUSH B" AND "POP B" + 0638 3E34 MVI A,034H + 063A B9 CMP C + 063B C4A006 CNZ CPUER ;TEST "PUSH B" AND "POP B" + 063E 3EAA MVI A,0AAH + 0640 BA CMP D + 0641 C4A006 CNZ CPUER ;TEST "PUSH D" AND "POP D" + 0644 BB CMP E + 0645 C4A006 CNZ CPUER ;TEST "PUSH D" AND "POP D" + 0648 3E55 MVI A,055H + 064A BC CMP H + 064B C4A006 CNZ CPUER ;TEST "PUSH H" AND "POP H" + 064E BD CMP L + 064F C4A006 CNZ CPUER ;TEST "PUSH H" AND "POP H" + 0652 210000 LXI H,00000H + 0655 39 DAD SP + 0656 22C406 SHLD SAVSTK ;SAVE THE "OLD" STACK-POINTER! + 0659 31C306 LXI SP,TEMP4 + 065C 3B DCX SP + 065D 3B DCX SP + 065E 33 INX SP + 065F 3B DCX SP + 0660 3E55 MVI A,055H + 0662 32C106 STA TEMP2 + 0665 2F CMA + 0666 32C206 STA TEMP3 + 0669 C1 POP B + 066A B8 CMP B + 066B C4A006 CNZ CPUER ;TEST "LXI","DAD","INX",AND "DCX" SP + 066E 2F CMA + 066F B9 CMP C + 0670 C4A006 CNZ CPUER ;TEST "LXI","DAD","INX", AND "DCX" SP + 0673 21C306 LXI H,TEMP4 + 0676 F9 SPHL + 0677 213377 LXI H,07733H + 067A 3B DCX SP + 067B 3B DCX SP + 067C E3 XTHL + 067D 3AC206 LDA TEMP3 + 0680 FE77 CPI 077H + 0682 C4A006 CNZ CPUER ;TEST "SPHL" AND "XTHL" + 0685 3AC106 LDA TEMP2 + 0688 FE33 CPI 033H + 068A C4A006 CNZ CPUER ;TEST "SPHL" AND "XTHL" + 068D 3E55 MVI A,055H + 068F BD CMP L + 0690 C4A006 CNZ CPUER ;TEST "SPHL" AND "XTHL" + 0693 2F CMA + 0694 BC CMP H + 0695 C4A006 CNZ CPUER ;TEST "SPHL" AND "XTHL" + 0698 2AC406 LHLD SAVSTK ;RESTORE THE "OLD" STACK-POINTER + 069B F9 SPHL + 069C 21B406 LXI H,CPUOK + 069F E9 PCHL ;TEST "PCHL" + ; + ; + ; + 06A0 219001 CPUER: LXI H,NGCPU ;OUTPUT "CPU HAS FAILED ERROR EXIT=" TO CONSOLE + 06A3 CD4B01 CALL MSG + 06A6 E1 POP H ;HL = ADDRESS FOLLOWING CALL CPUER + 06A7 E5 PUSH H + 06A8 7C MOV A,H + 06A9 CD5A01 CALL BYTEO ;SHOW ERROR EXIT ADDRESS HIGH BYTE + 06AC E1 POP H + 06AD 7D MOV A,L + 06AE CD5A01 CALL BYTEO ;SHOW ERROR EXIT ADDRESS LOW BYTE + 06B1 C30000 JMP WBOOT ;EXIT TO CP/M WARM BOOT + ; + ; + ; + 06B4 217A01 CPUOK: LXI H,OKCPU ;OUTPUT "CPU IS OPERATIONAL" TO CONSOLE + 06B7 CD4B01 CALL MSG + 06BA C30000 JMP WBOOT ;EXIT TO CP/M WARM BOOT + ; + ; + ; + 06BD BF06 TEMPP: DW TEMP0 ;POINTER USED TO TEST "LHLD","SHLD", + ; AND "LDAX" INSTRUCTIONS + ; + 06BF TEMP0: DS 1 ;TEMPORARY STORAGE FOR CPU TEST MEMORY LOCATIONS + 06C0 TEMP1: DS 1 ;TEMPORARY STORAGE FOR CPU TEST MEMORY LOCATIONS + 06C1 TEMP2 DS 1 ;TEMPORARY STORAGE FOR CPU TEST MEMORY LOCATIONS + 06C2 TEMP3: DS 1 ;TEMPORARY STORAGE FOR CPU TEST MEMORY LOCATIONS + 06C3 TEMP4: DS 1 ;TEMPORARY STORAGE FOR CPU TEST MEMORY LOCATIONS + 06C4 SAVSTK: DS 2 ;TEMPORARY STACK-POINTER STORAGE LOCATION + ; + ; + ; + 07BD = STACK EQU TEMPP+256 ;DE-BUG STACK POINTER STORAGE AREA + ; + ; + ; + 06C6 END diff --git a/Intel8080/Intel8080.cs b/Intel8080/Intel8080.cs index 075ab45..9769914 100644 --- a/Intel8080/Intel8080.cs +++ b/Intel8080/Intel8080.cs @@ -6,6 +6,8 @@ namespace Intel8080 { using EightBit; + using System; + using System.Diagnostics; public class Intel8080(Bus bus, InputOutput ports) : IntelProcessor(bus) { @@ -63,17 +65,62 @@ namespace Intel8080 } } + private void MemoryUpdate(int ticks) + { + Debug.Assert(ticks > 0, "Ticks must be greater than zero"); + this.OnWritingMemory(); + this.Tick(ticks + 1); + base.MemoryWrite(); + this.Tick(); + this.OnWrittenMemory(); + } + + protected override void MemoryWrite() + { + this.MemoryUpdate(1); + } + + protected override byte MemoryRead() + { + this.OnReadingMemory(); + this.Tick(2); + base.MemoryRead(); + this.OnReadMemory(); + this.Tick(2); + return this.Bus.Data; + } + protected override void HandleRESET() { base.HandleRESET(); - this.Tick(3); + this.DisableInterrupts(); + this.SP.Word = this.AF.Word = (ushort)Mask.Sixteen; + } + + private byte ReadDataUnderInterrupt() + { + this.Tick(4); + return this.Bus.Data; + } + + protected override void Call(Register16 destination) + { + this.Tick(); + base.Call(destination); + } + + protected override void JumpRelative(sbyte offset) + { + base.JumpRelative(offset); + this.Tick(5); } protected override void HandleINT() { base.HandleINT(); - this.Execute(this.Bus.Data); - this.Tick(3); + var data = this.ReadDataUnderInterrupt(); + this.Tick(); + this.Execute(data); } private int Zero() => ZeroTest(this.F); @@ -132,52 +179,53 @@ namespace Intel8080 protected override void EnableInterrupts() => this.interruptEnable = true; - private byte R(int r) => r switch - { - 0 => this.B, - 1 => this.C, - 2 => this.D, - 3 => this.E, - 4 => this.H, - 5 => this.L, - 6 => this.MemoryRead(this.HL), - 7 => this.A, - _ => throw new ArgumentOutOfRangeException(nameof(r)), - }; - - private void R(int r, byte value) + private ref byte R(int r, AccessLevel access = AccessLevel.ReadOnly) { switch (r) { case 0: - this.B = value; - break; + return ref this.B; case 1: - this.C = value; - break; + return ref this.C; case 2: - this.D = value; - break; + return ref this.D; case 3: - this.E = value; - break; + return ref this.E; case 4: - this.H = value; - break; + return ref this.H; case 5: - this.L = value; - break; + return ref this.L; case 6: - this.MemoryWrite(this.HL, value); - break; + this.Bus.Address.Assign(this.HL); + switch (access) + { + case AccessLevel.ReadOnly: + this.MemoryRead(); + break; + case AccessLevel.WriteOnly: + break; + default: + throw new NotSupportedException("Invalid access level"); + } + + // Will need a post-MemoryWrite + return ref this.Bus.Data; case 7: - this.A = value; - break; + return ref this.A; default: throw new ArgumentOutOfRangeException(nameof(r)); } } + private void R(int r, byte value, int ticks = 1) + { + this.R(r, AccessLevel.WriteOnly) = value; + if (r == 6) + { + this.MemoryUpdate(ticks); + } + } + private Register16 RP(int rp) => rp switch { 0 => this.BC, @@ -198,6 +246,8 @@ namespace Intel8080 private void Execute(int x, int y, int z, int p, int q) { + var memoryY = y == 6; + var memoryZ = z == 6; switch (x) { case 0: @@ -207,7 +257,6 @@ namespace Intel8080 switch (y) { case 0: // NOP - this.Tick(4); break; default: break; @@ -219,11 +268,10 @@ namespace Intel8080 { case 0: // LD rp,nn this.RP(p).Assign(this.FetchWord()); - this.Tick(10); break; case 1: // ADD HL,rp this.Add(this.RP(p)); - this.Tick(11); + this.Tick(7); break; default: throw new NotSupportedException("Invalid operation mode"); @@ -238,21 +286,17 @@ namespace Intel8080 { case 0: // LD (BC),A this.WriteMemoryIndirect(this.BC, this.A); - this.Tick(7); break; case 1: // LD (DE),A this.WriteMemoryIndirect(this.DE, this.A); - this.Tick(7); break; case 2: // LD (nn),HL this.FetchWordAddress(); this.SetWord(this.HL); - this.Tick(16); break; case 3: // LD (nn),A - this.FetchWordMEMPTR(); + this.FetchInto(this.MEMPTR); this.WriteMemoryIndirect(this.A); - this.Tick(13); break; default: throw new NotSupportedException("Invalid operation mode"); @@ -264,21 +308,17 @@ namespace Intel8080 { case 0: // LD A,(BC) this.A = this.ReadMemoryIndirect(this.BC); - this.Tick(7); break; case 1: // LD A,(DE) this.A = this.ReadMemoryIndirect(this.DE); - this.Tick(7); break; case 2: // LD HL,(nn) this.FetchWordAddress(); - this.HL.Assign(this.GetWord()); - this.Tick(16); + this.GetInto(this.HL); break; case 3: // LD A,(nn) - this.FetchWordMEMPTR(); + this.FetchInto(this.MEMPTR); this.A = this.ReadMemoryIndirect(); - this.Tick(13); break; default: throw new NotSupportedException("Invalid operation mode"); @@ -291,41 +331,31 @@ namespace Intel8080 break; case 3: // 16-bit INC/DEC - switch (q) + _ = q switch { - case 0: // INC rp - _ = this.RP(p).Increment(); - break; - case 1: // DEC rp - _ = this.RP(p).Decrement(); - break; - default: - throw new NotSupportedException("Invalid operation mode"); - } - - this.Tick(6); + // INC rp + 0 => this.RP(p).Increment(), + // DEC rp + 1 => this.RP(p).Decrement(), + _ => throw new NotSupportedException("Invalid operation mode"), + }; + this.Tick(2); break; case 4: // 8-bit INC - this.R(y, this.Increment(this.R(y))); - this.Tick(4); + this.R(y, this.Increment(this.R(y)), 2); break; case 5: // 8-bit DEC - this.R(y, this.Decrement(this.R(y))); - this.Tick(4); - if (y == 6) - { - this.Tick(7); - } - + this.R(y, this.Decrement(this.R(y)), 2); break; case 6: // 8-bit load immediate - this.R(y, this.FetchByte()); - this.Tick(7); - if (y == 6) { - this.Tick(3); + _ = this.FetchByte(); // LD r,n + if (memoryY) + { + this.Tick(2); + } + this.R(y, this.Bus.Data); } - break; case 7: // Assorted operations on accumulator/flags switch (y) @@ -357,8 +387,6 @@ namespace Intel8080 default: throw new NotSupportedException("Invalid operation mode"); } - - this.Tick(4); break; default: throw new NotSupportedException("Invalid operation mode"); @@ -366,20 +394,14 @@ namespace Intel8080 break; case 1: // 8-bit loading - if (z == 6 && y == 6) + if (memoryZ && memoryY) { this.LowerHALT(); // Exception (replaces LD (HL), (HL)) } else { this.R(y, this.R(z)); - if (y == 6 || z == 6) - { - this.Tick(3); // M operations - } } - - this.Tick(4); break; case 2: // Operate on accumulator and register/memory location switch (y) @@ -411,46 +433,31 @@ namespace Intel8080 default: throw new NotSupportedException("Invalid operation mode"); } - - this.Tick(4); - if (z == 6) - { - this.Tick(3); - } - break; case 3: switch (z) { case 0: // Conditional return - if (this.ReturnConditionalFlag(y)) - { - this.Tick(6); - } - - this.Tick(5); + this.ReturnConditionalFlag(y); break; case 1: // POP & various ops switch (q) { case 0: // POP rp2[p] - this.RP2(p).Assign(this.PopWord()); - this.Tick(10); + this.PopInto(this.RP2(p)); break; case 1: switch (p) { case 0: // RET this.Return(); - this.Tick(10); break; case 2: // JP HL this.Jump(this.HL); - this.Tick(4); break; case 3: // LD SP,HL this.SP.Assign(this.HL); - this.Tick(4); + this.Tick(2); break; default: break; @@ -463,39 +470,32 @@ namespace Intel8080 break; case 2: // Conditional jump - _ = this.JumpConditionalFlag(y); - this.Tick(10); + this.JumpConditionalFlag(y); break; case 3: // Assorted operations switch (y) { case 0: // JP nn this.JumpIndirect(); - this.Tick(10); break; case 2: // OUT (n),A this.WritePort(this.FetchByte()); - this.Tick(11); break; case 3: // IN A,(n) this.A = this.ReadPort(this.FetchByte()); - this.Tick(11); break; case 4: // EX (SP),HL this.XHTL(this.HL); - this.Tick(19); break; case 5: // EX DE,HL - (this.DE.Word, this.HL.Word) = (this.HL.Word, this.DE.Word); - this.Tick(4); + (this.HL.Low, this.DE.Low) = (this.DE.Low, this.HL.Low); + (this.HL.High, this.DE.High) = (this.DE.High, this.HL.High); break; case 6: // DI this.DisableInterrupts(); - this.Tick(4); break; case 7: // EI this.EnableInterrupts(); - this.Tick(4); break; default: break; @@ -503,26 +503,20 @@ namespace Intel8080 break; case 4: // Conditional call: CALL cc[y], nn - if (this.CallConditionalFlag(y)) - { - this.Tick(7); - } - - this.Tick(10); + this.CallConditionalFlag(y); break; case 5: // PUSH & various ops switch (q) { case 0: // PUSH rp2[p] + this.Tick(); this.PushWord(this.RP2(p)); - this.Tick(11); break; case 1: switch (p) { case 0: // CALL nn this.CallIndirect(); - this.Tick(17); break; default: break; @@ -535,41 +529,39 @@ namespace Intel8080 break; case 6: // Operate on accumulator and immediate operand: alu[y] n + _ = this.FetchByte(); switch (y) { case 0: // ADD A,n - this.Add(this.FetchByte()); + this.Add(this.Bus.Data); break; case 1: // ADC A,n - this.ADC(this.FetchByte()); + this.ADC(this.Bus.Data); break; case 2: // SUB n - this.SUB(this.FetchByte()); + this.SUB(this.Bus.Data); break; case 3: // SBC A,n - this.SBB(this.FetchByte()); + this.SBB(this.Bus.Data); break; case 4: // AND n - this.AndR(this.FetchByte()); + this.AndR(this.Bus.Data); break; case 5: // XOR n - this.XorR(this.FetchByte()); + this.XorR(this.Bus.Data); break; case 6: // OR n - this.OrR(this.FetchByte()); + this.OrR(this.Bus.Data); break; case 7: // CP n - this.Compare(this.FetchByte()); + this.Compare(this.Bus.Data); break; default: throw new NotSupportedException("Invalid operation mode"); } - - this.Tick(7); break; case 7: // Restart: RST y * 8 this.Restart((byte)(y << 3)); - this.Tick(11); break; default: throw new NotSupportedException("Invalid operation mode"); @@ -608,6 +600,16 @@ namespace Intel8080 _ => throw new ArgumentOutOfRangeException(nameof(flag)), }; + protected sealed override void ReturnConditionalFlag(int flag) + { + var condition = this.ConvertCondition(flag); + this.Tick(); + if (condition) + { + this.Return(); + } + } + private void Add(Register16 value) { var result = this.HL.Word + value.Word; @@ -725,13 +727,16 @@ namespace Intel8080 private void XHTL(Register16 exchange) { this.MEMPTR.Low = this.MemoryRead(this.SP); - _ = this.Bus.Address.Increment(); + this.Bus.Address.Increment(); this.MEMPTR.High = this.MemoryRead(); - this.MemoryWrite(exchange.High); + this.Bus.Data = exchange.High; exchange.High = this.MEMPTR.High; + this.MemoryUpdate(2); _ = this.Bus.Address.Decrement(); - this.MemoryWrite(exchange.Low); + this.Bus.Data = exchange.Low; exchange.Low = this.MEMPTR.Low; + this.MemoryUpdate(1); + this.Tick(2); } private byte ReadMemoryIndirect(Register16 via) @@ -768,7 +773,12 @@ namespace Intel8080 this.WritePort(); } - private void WritePort() => this.ports.Write(this.Bus.Address, this.Bus.Data); + private void WritePort() + { + this.Tick(3); + this.ports.Write(this.Bus.Address, this.Bus.Data); + this.Tick(1); + } private byte ReadPort(byte port) { @@ -776,6 +786,12 @@ namespace Intel8080 return this.ReadPort(); } - private byte ReadPort() => this.Bus.Data = this.ports.Read(this.Bus.Address); + private byte ReadPort() + { + this.Tick(2); + this.Bus.Data = this.ports.Read(this.Bus.Address); + this.Tick(2); + return this.Bus.Data; + } } } \ No newline at end of file diff --git a/LR35902/LR35902.BlarggTest/Board.cs b/LR35902/LR35902.BlarggTest/Board.cs index 8cef5b8..185b30f 100644 --- a/LR35902/LR35902.BlarggTest/Board.cs +++ b/LR35902/LR35902.BlarggTest/Board.cs @@ -6,7 +6,7 @@ namespace LR35902.BlarggTest { using System; - internal class Board : Bus + internal sealed class Board : Bus { private readonly Configuration configuration; private readonly Disassembler disassembler; diff --git a/LR35902/LR35902.BlarggTest/Computer.cs b/LR35902/LR35902.BlarggTest/Computer.cs index db1af2a..ab5dbfa 100644 --- a/LR35902/LR35902.BlarggTest/Computer.cs +++ b/LR35902/LR35902.BlarggTest/Computer.cs @@ -4,7 +4,7 @@ namespace LR35902.BlarggTest { - internal class Computer(Configuration configuration) + internal sealed class Computer(Configuration configuration) { private readonly Board board = new(configuration); diff --git a/LR35902/LR35902.BlarggTest/Configuration.cs b/LR35902/LR35902.BlarggTest/Configuration.cs index bc69075..0197d18 100644 --- a/LR35902/LR35902.BlarggTest/Configuration.cs +++ b/LR35902/LR35902.BlarggTest/Configuration.cs @@ -4,7 +4,7 @@ namespace LR35902.BlarggTest { - internal class Configuration + internal sealed class Configuration { public bool DebugMode { get; set; } diff --git a/LR35902/LR35902.FuseTest/TestSuite.cs b/LR35902/LR35902.FuseTest/TestSuite.cs index 91ba748..0b29be5 100644 --- a/LR35902/LR35902.FuseTest/TestSuite.cs +++ b/LR35902/LR35902.FuseTest/TestSuite.cs @@ -6,17 +6,11 @@ namespace LR35902.FuseTest { using Fuse; - public class TestSuite + public class TestSuite(string path) where T : IRegisterState, new() { - private readonly Tests tests; - private readonly Results results; - - public TestSuite(string path) - { - this.tests = new Tests(path + ".in"); - this.results = new Results(path + ".expected"); - } + private readonly Tests tests = new(path + ".in"); + private readonly Results results = new(path + ".expected"); public void Read() { diff --git a/LR35902/LR35902.cs b/LR35902/LR35902.cs index a05940c..75a6634 100644 --- a/LR35902/LR35902.cs +++ b/LR35902/LR35902.cs @@ -369,19 +369,19 @@ namespace LR35902 this.TickMachine(); } - protected override bool JumpConditional(bool condition) + protected override void JumpConditional(bool condition) { - if (base.JumpConditional(condition)) + base.JumpConditional(condition); + if (condition) { this.TickMachine(); } - return condition; } - protected override bool ReturnConditional(bool condition) + protected override void ReturnConditional(bool condition) { this.TickMachine(); - return base.ReturnConditional(condition); + base.ReturnConditional(condition); } protected override void Return() @@ -528,7 +528,7 @@ namespace LR35902 case 5: case 6: case 7: - _ = this.JumpRelativeConditionalFlag(y - 4); + this.JumpRelativeConditionalFlag(y - 4); break; default: throw new InvalidOperationException("Unreachable code block reached"); @@ -727,7 +727,7 @@ namespace LR35902 case 1: case 2: case 3: - _ = this.ReturnConditionalFlag(y); + this.ReturnConditionalFlag(y); break; case 4: // GB: LD (FF00 + n),A @@ -775,7 +775,7 @@ namespace LR35902 switch (q) { case 0: // POP rp2[p] - this.RP2(p).Assign(this.PopWord()); + this.PopInto(this.RP2(p)); break; case 1: switch (p) @@ -811,20 +811,20 @@ namespace LR35902 case 1: case 2: case 3: - _ = this.JumpConditionalFlag(y); + this.JumpConditionalFlag(y); break; case 4: // GB: LD (FF00 + C),A this.MemoryWrite(this.C, IoRegisters.BasePage, this.A); break; case 5: // GB: LD (nn),A - this.FetchWordMEMPTR(); + this.FetchInto(this.MEMPTR); this.MemoryWrite(this.MEMPTR, this.A); break; case 6: // GB: LD A,(FF00 + C) this.A = this.MemoryRead(this.C, IoRegisters.BasePage); break; case 7: // GB: LD A,(nn) - this.FetchWordMEMPTR(); + this.FetchInto(this.MEMPTR); this.A = this.MemoryRead(this.MEMPTR); break; default: @@ -855,7 +855,7 @@ namespace LR35902 break; case 4: // Conditional call: CALL cc[y], nn - _ = this.CallConditionalFlag(y); + this.CallConditionalFlag(y); break; case 5: // PUSH & various ops @@ -884,31 +884,32 @@ namespace LR35902 break; case 6: // Operate on accumulator and immediate operand: alu[y] n + _ = this.FetchByte(); switch (y) { case 0: // ADD A,n - this.A = this.Add(this.A, this.FetchByte()); + this.A = this.Add(this.A, this.Bus.Data); break; case 1: // ADC A,n - this.A = this.ADC(this.A, this.FetchByte()); + this.A = this.ADC(this.A, this.Bus.Data); break; case 2: // SUB n - this.A = this.Subtract(this.A, this.FetchByte()); + this.A = this.Subtract(this.A, this.Bus.Data); break; case 3: // SBC A,n - this.A = this.SBC(this.A, this.FetchByte()); + this.A = this.SBC(this.A, this.Bus.Data); break; case 4: // AND n - this.AndR(this.FetchByte()); + this.AndR(this.Bus.Data); break; case 5: // XOR n - this.XorR(this.FetchByte()); + this.XorR(this.Bus.Data); break; case 6: // OR n - this.OrR(this.FetchByte()); + this.OrR(this.Bus.Data); break; case 7: // CP n - this.Compare(this.FetchByte()); + this.Compare(this.Bus.Data); break; default: throw new InvalidOperationException("Invalid operation mode"); diff --git a/M6502/Core.cs b/M6502/Core.cs index 86074f2..80aa131 100644 --- a/M6502/Core.cs +++ b/M6502/Core.cs @@ -308,11 +308,11 @@ namespace M6502 #region Cycle wastage - protected void SwallowRead() => this.MemoryRead(this.PC); + protected void SwallowRead() => _ = this.MemoryRead(this.PC); - protected void SwallowPop() => this.MemoryRead(this.S, 1); + protected void SwallowPop() => _ = this.MemoryRead(this.S, 1); - protected void SwallowFetch() => this.FetchByte(); + protected void SwallowFetch() => _ = this.FetchByte(); #endregion @@ -326,17 +326,17 @@ namespace M6502 switch (this.OpCode) { case 0x00: this.SwallowFetch(); this.Interrupt(IRQ_vector, InterruptSource.software); break;// BRK (implied) - case 0x01: this.IndexedIndirectXRead(); this.OrR(); break; // ORA (indexed indirect X) + case 0x01: this.OrR(this.IndexedIndirectXRead()); break; // ORA (indexed indirect X) case 0x05: this.ZeroPageRead(); this.OrR(); break; // ORA (zero page) case 0x06: this.ZeroPageRead(); this.ModifyWrite(this.ASL()); break; // ASL (zero page) case 0x08: this.SwallowRead(); this.PHP(); break; // PHP (implied) - case 0x09: this.FetchByte(); this.OrR(); break; // ORA (immediate) + case 0x09: this.OrR(this.FetchByte()); break; // ORA (immediate) case 0x0a: this.SwallowRead(); this.A = this.ASL(this.A); break; // ASL A (implied) case 0x0d: this.AbsoluteRead(); this.OrR(); break; // ORA (absolute) case 0x0e: this.AbsoluteRead(); this.ModifyWrite(this.ASL()); break; // ASL (absolute) case 0x10: this.BranchNot(this.Negative); break; // BPL (relative) - case 0x11: this.IndirectIndexedYRead(); this.OrR(); break; // ORA (indirect indexed Y) + case 0x11: this.OrR(this.IndirectIndexedYRead()); break; // ORA (indirect indexed Y) case 0x15: this.ZeroPageXRead(); this.OrR(); break; // ORA (zero page, X) case 0x16: this.ZeroPageXRead(); this.ModifyWrite(this.ASL()); break; // ASL (zero page, X) case 0x18: this.SwallowRead(); this.ResetFlag(StatusBits.CF); break; // CLC (implied) @@ -345,19 +345,19 @@ namespace M6502 case 0x1e: this.AbsoluteXAddress(); this.FixupRead(); this.ModifyWrite(this.ASL()); break; // ASL (absolute, X) case 0x20: this.JSR(); break; // JSR (absolute) - case 0x21: this.IndexedIndirectXRead(); this.AndR(); break; // AND (indexed indirect X) + case 0x21: this.AndR(this.IndexedIndirectXRead()); break; // AND (indexed indirect X) case 0x24: this.ZeroPageRead(); this.BIT(); break; // BIT (zero page) case 0x25: this.ZeroPageRead(); this.AndR(); break; // AND (zero page) case 0x26: this.ZeroPageRead(); this.ModifyWrite(this.ROL()); break; // ROL (zero page) case 0x28: this.SwallowRead(); this.PLP(); break; // PLP (implied) - case 0x29: this.FetchByte(); this.AndR(); break; // AND (immediate) + case 0x29: this.AndR(this.FetchByte()); break; // AND (immediate) case 0x2a: this.SwallowRead(); this.A = this.ROL(this.A); break; // ROL A (implied) case 0x2c: this.AbsoluteRead(); this.BIT(); break; // BIT (absolute) case 0x2d: this.AbsoluteRead(); this.AndR(); break; // AND (absolute) case 0x2e: this.AbsoluteRead(); this.ModifyWrite(this.ROL()); break; // ROL (absolute) case 0x30: this.Branch(this.Negative); break; // BMI (relative) - case 0x31: this.IndirectIndexedYRead(); this.AndR(); break; // AND (indirect indexed Y) + case 0x31: this.AndR(this.IndirectIndexedYRead()); break; // AND (indirect indexed Y) case 0x35: this.ZeroPageXRead(); this.AndR(); break; // AND (zero page, X) case 0x36: this.ZeroPageXRead(); this.ModifyWrite(this.ROL()); break; // ROL (zero page, X) case 0x38: this.SwallowRead(); this.SetFlag(StatusBits.CF); break; // SEC (implied) @@ -366,19 +366,19 @@ namespace M6502 case 0x3e: this.AbsoluteXAddress(); this.FixupRead(); this.ModifyWrite(this.ROL()); break; // ROL (absolute, X) case 0x40: this.SwallowRead(); this.RTI(); break; // RTI (implied) - case 0x41: this.IndexedIndirectXRead(); this.EorR(); break; // EOR (indexed indirect X) + case 0x41: this.EorR(this.IndexedIndirectXRead()); break; // EOR (indexed indirect X) case 0x44: this.ZeroPageRead(); break; // *NOP (zero page) case 0x45: this.ZeroPageRead(); this.EorR(); break; // EOR (zero page) case 0x46: this.ZeroPageRead(); this.ModifyWrite(this.LSR()); break; // LSR (zero page) case 0x48: this.SwallowRead(); this.Push(this.A); break; // PHA (implied) - case 0x49: this.FetchByte(); this.EorR(); break; // EOR (immediate) + case 0x49: this.EorR(this.FetchByte()); break; // EOR (immediate) case 0x4a: this.SwallowRead(); this.A = this.LSR(this.A); break; // LSR A (implied) case 0x4c: this.AbsoluteAddress(); this.Jump(this.Bus.Address); break; // JMP (absolute) case 0x4d: this.AbsoluteRead(); this.EorR(); break; // EOR (absolute) case 0x4e: this.AbsoluteRead(); this.ModifyWrite(this.LSR()); break; // LSR (absolute) case 0x50: this.BranchNot(this.Overflow); break; // BVC (relative) - case 0x51: this.IndirectIndexedYRead(); this.EorR(); break; // EOR (indirect indexed Y) + case 0x51: this.EorR(this.IndirectIndexedYRead()); break; // EOR (indirect indexed Y) case 0x54: this.ZeroPageXRead(); break; // *NOP (zero page, X) case 0x55: this.ZeroPageXRead(); this.EorR(); break; // EOR (zero page, X) case 0x56: this.ZeroPageXRead(); this.ModifyWrite(this.LSR()); break; // LSR (zero page, X) @@ -388,27 +388,27 @@ namespace M6502 case 0x5e: this.AbsoluteXAddress(); this.FixupRead(); this.ModifyWrite(this.LSR()); break; // LSR (absolute, X) case 0x60: this.SwallowRead(); this.Return(); break; // RTS (implied) - case 0x61: this.IndexedIndirectXRead(); this.ADC(); break; // ADC (indexed indirect X) - case 0x65: this.ZeroPageRead(); this.ADC(); break; // ADC (zero page) + case 0x61: this.ADC(this.IndexedIndirectXRead()); break; // ADC (indexed indirect X) + case 0x65: this.ADC(this.ZeroPageRead()); break; // ADC (zero page) case 0x66: this.ZeroPageRead(); this.ModifyWrite(this.ROR()); break; // ROR (zero page) case 0x68: this.SwallowRead(); this.SwallowPop(); this.A = this.Through(this.Pop()); break; // PLA (implied) - case 0x69: this.FetchByte(); this.ADC(); break; // ADC (immediate) + case 0x69: this.ADC(this.FetchByte()); break; // ADC (immediate) case 0x6a: this.SwallowRead(); this.A = this.ROR(this.A); break; // ROR A (implied) case 0x6c: this.IndirectAddress(); this.Jump(this.Bus.Address); break; // JMP (indirect) - case 0x6d: this.AbsoluteRead(); this.ADC(); break; // ADC (absolute) + case 0x6d: this.ADC(this.AbsoluteRead()); break; // ADC (absolute) case 0x6e: this.AbsoluteRead(); this.ModifyWrite(this.ROR()); break; // ROR (absolute) case 0x70: this.Branch(this.Overflow); break; // BVS (relative) - case 0x71: this.IndirectIndexedYRead(); this.ADC(); break; // ADC (indirect indexed Y) - case 0x75: this.ZeroPageXRead(); this.ADC(); break; // ADC (zero page, X) + case 0x71: this.ADC(this.IndirectIndexedYRead()); break; // ADC (indirect indexed Y) + case 0x75: this.ADC(this.ZeroPageXRead()); break; // ADC (zero page, X) case 0x76: this.ZeroPageXRead(); this.ModifyWrite(this.ROR()); break; // ROR (zero page, X) case 0x78: this.SwallowRead(); this.SetFlag(StatusBits.IF); break; // SEI (implied) - case 0x79: this.AbsoluteYRead(); this.ADC(); break; // ADC (absolute, Y) - case 0x7d: this.AbsoluteXRead(); this.ADC(); break; // ADC (absolute, X) + case 0x79: this.ADC(this.AbsoluteYRead()); break; // ADC (absolute, Y) + case 0x7d: this.ADC(this.AbsoluteXRead()); break; // ADC (absolute, X) case 0x7e: this.AbsoluteXAddress(); this.FixupRead(); this.ModifyWrite(this.ROR()); break; // ROR (absolute, X) case 0x81: this.IndexedIndirectXAddress(); this.MemoryWrite(this.A); break; // STA (indexed indirect X) - case 0x82: this.FetchByte(); break; // *NOP (immediate) + case 0x82: _ = this.FetchByte(); break; // *NOP (immediate) case 0x84: this.ZeroPageAddress(); this.MemoryWrite(this.Y); break; // STY (zero page) case 0x85: this.ZeroPageAddress(); this.MemoryWrite(this.A); break; // STA (zero page) case 0x86: this.ZeroPageAddress(); this.MemoryWrite(this.X); break; // STX (zero page) @@ -428,21 +428,21 @@ namespace M6502 case 0x9a: this.SwallowRead(); this.S = this.X; break; // TXS (implied) case 0x9d: this.AbsoluteXAddress(); this.Fixup(); this.MemoryWrite(this.A); break; // STA (absolute, X) - case 0xa0: this.FetchByte(); this.Y = this.Through(); break; // LDY (immediate) - case 0xa1: this.IndexedIndirectXRead(); this.A = this.Through(); break; // LDA (indexed indirect X) - case 0xa2: this.FetchByte(); this.X = this.Through(); break; // LDX (immediate) + case 0xa0: this.Y = this.Through(this.FetchByte()); break; // LDY (immediate) + case 0xa1: this.A = this.Through(this.IndexedIndirectXRead()); break; // LDA (indexed indirect X) + case 0xa2: this.X = this.Through(this.FetchByte()); break; // LDX (immediate) case 0xa4: this.ZeroPageRead(); this.Y = this.Through(); break; // LDY (zero page) case 0xa5: this.ZeroPageRead(); this.A = this.Through(); break; // LDA (zero page) case 0xa6: this.ZeroPageRead(); this.X = this.Through(); break; // LDX (zero page) case 0xa8: this.SwallowRead(); this.Y = this.Through(this.A); break; // TAY (implied) - case 0xa9: this.FetchByte(); this.A = this.Through(); break; // LDA (immediate) + case 0xa9: this.A = this.Through(this.FetchByte()); break; // LDA (immediate) case 0xaa: this.SwallowRead(); this.X = this.Through(this.A); break; // TAX (implied) - case 0xac: this.AbsoluteRead(); this.Y = this.Through(); break; // LDY (absolute) - case 0xad: this.AbsoluteRead(); this.A = this.Through(); break; // LDA (absolute) - case 0xae: this.AbsoluteRead(); this.X = this.Through(); break; // LDX (absolute) + case 0xac: this.Y = this.Through(this.AbsoluteRead()); break; // LDY (absolute) + case 0xad: this.A = this.Through(this.AbsoluteRead()); break; // LDA (absolute) + case 0xae: this.X = this.Through(this.AbsoluteRead()); break; // LDX (absolute) case 0xb0: this.Branch(this.Carry); break; // BCS (relative) - case 0xb1: this.IndirectIndexedYRead(); this.A = this.Through(); break; // LDA (indirect indexed Y) + case 0xb1: this.A = this.Through(this.IndirectIndexedYRead()); break; // LDA (indirect indexed Y) case 0xb4: this.ZeroPageXRead(); this.Y = this.Through(); break; // LDY (zero page, X) case 0xb5: this.ZeroPageXRead(); this.A = this.Through(); break; // LDA (zero page, X) case 0xb6: this.ZeroPageYRead(); this.X = this.Through(); break; // LDX (zero page, Y) @@ -453,39 +453,39 @@ namespace M6502 case 0xbd: this.AbsoluteXRead(); this.A = this.Through(); break; // LDA (absolute, X) case 0xbe: this.AbsoluteYRead(); this.X = this.Through(); break; // LDX (absolute, Y) - case 0xc0: this.FetchByte(); this.CMP(this.Y); break; // CPY (immediate) - case 0xc1: this.IndexedIndirectXRead(); this.CMP(this.A); break; // CMP (indexed indirect X) - case 0xc2: this.FetchByte(); break; // *NOP (immediate) - case 0xc4: this.ZeroPageRead(); this.CMP(this.Y); break; // CPY (zero page) - case 0xc5: this.ZeroPageRead(); this.CMP(this.A); break; // CMP (zero page) + case 0xc0: this.CMP(this.Y, this.FetchByte()); break; // CPY (immediate) + case 0xc1: this.CMP(this.A, this.IndexedIndirectXRead()); break; // CMP (indexed indirect X) + case 0xc2: _ = this.FetchByte(); break; // *NOP (immediate) + case 0xc4: this.CMP(this.Y, this.ZeroPageRead()); break; // CPY (zero page) + case 0xc5: this.CMP(this.A, this.ZeroPageRead()); break; // CMP (zero page) case 0xc6: this.ZeroPageRead(); this.ModifyWrite(this.DEC()); break; // DEC (zero page) case 0xc8: this.SwallowRead(); this.Y = this.INC(this.Y); break; // INY (implied) - case 0xc9: this.FetchByte(); this.CMP(this.A); break; // CMP (immediate) + case 0xc9: this.CMP(this.A, this.FetchByte()); break; // CMP (immediate) case 0xca: this.SwallowRead(); this.X = this.DEC(this.X); break; // DEX (implied) - case 0xcc: this.AbsoluteRead(); this.CMP(this.Y); break; // CPY (absolute) - case 0xcd: this.AbsoluteRead(); this.CMP(this.A); break; // CMP (absolute) + case 0xcc: this.CMP(this.Y, this.AbsoluteRead()); break; // CPY (absolute) + case 0xcd: this.CMP(this.A, this.AbsoluteRead()); break; // CMP (absolute) case 0xce: this.AbsoluteRead(); this.ModifyWrite(this.DEC()); break; // DEC (absolute) case 0xd0: this.BranchNot(this.Zero); break; // BNE (relative) - case 0xd1: this.IndirectIndexedYRead(); this.CMP(this.A); break; // CMP (indirect indexed Y) + case 0xd1: this.CMP(this.A, this.IndirectIndexedYRead()); break; // CMP (indirect indexed Y) case 0xd4: this.ZeroPageXRead(); break; // *NOP (zero page, X) - case 0xd5: this.ZeroPageXRead(); this.CMP(this.A); break; // CMP (zero page, X) + case 0xd5: this.CMP(this.A, this.ZeroPageXRead()); break; // CMP (zero page, X) case 0xd6: this.ZeroPageXRead(); this.ModifyWrite(this.DEC()); break; // DEC (zero page, X) case 0xd8: this.SwallowRead(); this.ResetFlag(StatusBits.DF); break; // CLD (implied) - case 0xd9: this.AbsoluteYRead(); this.CMP(this.A); break; // CMP (absolute, Y) - case 0xdd: this.AbsoluteXRead(); this.CMP(this.A); break; // CMP (absolute, X) + case 0xd9: this.CMP(this.A, this.AbsoluteYRead()); break; // CMP (absolute, Y) + case 0xdd: this.CMP(this.A, this.AbsoluteXRead()); break; // CMP (absolute, X) case 0xde: this.AbsoluteXAddress(); this.FixupRead(); this.ModifyWrite(this.DEC()); break; // DEC (absolute, X) - case 0xe0: this.FetchByte(); this.CMP(this.X); break; // CPX (immediate) + case 0xe0: this.CMP(this.X, this.FetchByte()); break; // CPX (immediate) case 0xe1: this.IndexedIndirectXRead(); this.SBC(); break; // SBC (indexed indirect X) - case 0xe2: this.FetchByte(); break; // *NOP (immediate) - case 0xe4: this.ZeroPageRead(); this.CMP(this.X); break; // CPX (zero page) + case 0xe2: _ = this.FetchByte(); break; // *NOP (immediate) + case 0xe4: this.CMP(this.X, this.ZeroPageRead()); break; // CPX (zero page) case 0xe5: this.ZeroPageRead(); this.SBC(); break; // SBC (zero page) case 0xe6: this.ZeroPageRead(); this.ModifyWrite(this.INC()); break; // INC (zero page) case 0xe8: this.SwallowRead(); this.X = this.INC(this.X); break; // INX (implied) - case 0xe9: this.FetchByte(); this.SBC(); break; // SBC (immediate) + case 0xe9: _ = this.FetchByte(); this.SBC(); break; // SBC (immediate) case 0xea: this.SwallowRead(); break; // NOP (implied) - case 0xec: this.AbsoluteRead(); this.CMP(this.X); break; // CPX (absolute) + case 0xec: this.CMP(this.X, this.AbsoluteRead()); break; // CPX (absolute) case 0xed: this.AbsoluteRead(); this.SBC(); break; // SBC (absolute) case 0xee: this.AbsoluteRead(); this.ModifyWrite(this.INC()); break; // INC (absolute) @@ -543,7 +543,7 @@ namespace M6502 // Can't use "FetchByte", since that would add an extra tick. this.ImmediateAddress(); - _ = this.ReadFromBus(); + this.ReadFromBus(); System.Diagnostics.Debug.Assert(this.Cycles == 1, "BUS read has introduced stray cycles"); this.RaiseSYNC(); @@ -631,16 +631,16 @@ namespace M6502 protected abstract void Fixup(); - protected void MaybeFixupRead() + protected byte MaybeFixupRead() { this.MaybeFixup(); - _ = this.MemoryRead(); + return this.MemoryRead(); } - protected void FixupRead() + protected byte FixupRead() { this.Fixup(); - _ = this.MemoryRead(); + return this.MemoryRead(); } #endregion @@ -711,52 +711,52 @@ namespace M6502 #region Address and read - protected void AbsoluteRead() + protected byte AbsoluteRead() { this.AbsoluteAddress(); - _ = this.MemoryRead(); + return this.MemoryRead(); } - protected void ZeroPageRead() + protected byte ZeroPageRead() { this.ZeroPageAddress(); - _ = this.MemoryRead(); + return this.MemoryRead(); } - protected void ZeroPageXRead() + protected byte ZeroPageXRead() { this.ZeroPageXAddress(); - _ = this.MemoryRead(); + return this.MemoryRead(); } - protected void ZeroPageYRead() + protected byte ZeroPageYRead() { this.ZeroPageYAddress(); - _ = this.MemoryRead(); + return this.MemoryRead(); } - protected void IndexedIndirectXRead() + protected byte IndexedIndirectXRead() { this.IndexedIndirectXAddress(); - _ = this.MemoryRead(); + return this.MemoryRead(); } - protected void AbsoluteXRead() + protected byte AbsoluteXRead() { this.AbsoluteXAddress(); - this.MaybeFixupRead(); + return this.MaybeFixupRead(); } - protected void AbsoluteYRead() + protected byte AbsoluteYRead() { this.AbsoluteYAddress(); - this.MaybeFixupRead(); + return this.MaybeFixupRead(); } - protected void IndirectIndexedYRead() + protected byte IndirectIndexedYRead() { this.IndirectIndexedYAddress(); - this.MaybeFixupRead(); + return this.MaybeFixupRead(); } #endregion @@ -771,7 +771,7 @@ namespace M6502 protected void Branch(bool condition) { - this.FetchByte(); + _ = this.FetchByte(); if (condition) { var relative = (sbyte)this.Bus.Data; @@ -876,12 +876,11 @@ namespace M6502 this.SetFlag(StatusBits.VF, NegativeTest((byte)(~(operand ^ data) & (operand ^ intermediate)))); } - protected void ADC() => this.A = this.DecimalMasked != 0 ? this.DecimalADC() : this.BinaryADC(); + protected void ADC(byte data) => this.A = this.DecimalMasked != 0 ? this.DecimalADC(data) : this.BinaryADC(data); - private byte BinaryADC() + private byte BinaryADC(byte data) { var operand = this.A; - var data = this.Bus.Data; this.Intermediate.Word = (ushort)(operand + data + this.Carry); this.AdjustOverflowAdd(operand); @@ -892,10 +891,9 @@ namespace M6502 return this.Intermediate.Low; } - private byte DecimalADC() + private byte DecimalADC(byte data) { var operand = this.A; - var data = this.Bus.Data; var low = (ushort)(LowerNibble(operand) + LowerNibble(data) + this.Carry); this.Intermediate.Word = (ushort)(HigherNibble(operand) + HigherNibble(data)); @@ -929,11 +927,17 @@ namespace M6502 #region Bitwise operations - protected void OrR() => this.A = this.Through(this.A | this.Bus.Data); + protected void OrR(byte data) => this.A = this.Through(this.A | data); - protected void AndR() => this.A = this.Through(this.A & this.Bus.Data); + protected void OrR() => this.OrR(this.Bus.Data); - protected void EorR() => this.A = this.Through(this.A ^ this.Bus.Data); + protected void AndR(byte data) => this.A = this.Through(this.A & data); + + protected void AndR() => this.AndR(this.Bus.Data); + + protected void EorR(byte data) => this.A = this.Through(this.A ^ data); + + protected void EorR() => this.EorR(this.Bus.Data); protected void BIT() { @@ -945,9 +949,8 @@ namespace M6502 #endregion - protected void CMP(byte first) + protected void CMP(byte first, byte second) { - var second = this.Bus.Data; this.Intermediate.Word = (ushort)(first - second); this.AdjustNZ(this.Intermediate.Low); this.ResetFlag(StatusBits.CF, this.Intermediate.High); @@ -981,7 +984,8 @@ namespace M6502 private void PLP() { this.SwallowPop(); - this.P = ClearBit(SetBit(this.Pop(), StatusBits.RF), StatusBits.BF); + this.Pop(); + this.P = ClearBit(SetBit(this.Bus.Data, StatusBits.RF), StatusBits.BF); } private void RTI() diff --git a/M6502/MOS6502.cs b/M6502/MOS6502.cs index db26c92..236361c 100644 --- a/M6502/MOS6502.cs +++ b/M6502/MOS6502.cs @@ -323,7 +323,7 @@ namespace M6502 private void RRA() { this.ModifyWrite(this.ROR()); - this.ADC(); + this.ADC(this.Bus.Data); } private void SLO() @@ -341,7 +341,7 @@ namespace M6502 private void DCP() { this.ModifyWrite(this.DEC()); - this.CMP(this.A); + this.CMP(this.A, this.Bus.Data); } #endregion diff --git a/M6502/WDC65C02.cs b/M6502/WDC65C02.cs index 16140cc..ac58812 100644 --- a/M6502/WDC65C02.cs +++ b/M6502/WDC65C02.cs @@ -61,7 +61,7 @@ namespace M6502 case 0x0c: this.AbsoluteRead(); this.TSB(); break; // TSB a case 0x0f: this.ZeroPageRead(); this.BBR(Bit(0)); break; // BBR0 r - case 0x12: this.ZeroPageIndirectRead(); this.OrR(); break; // ORA (zp),y + case 0x12: this.OrR(this.ZeroPageIndirectRead()); break; // ORA (zp),y case 0x13: break; // null case 0x14: this.ZeroPageRead(); this.TRB(); break; // TRB zp case 0x17: this.ZeroPageRead(); this.RMB(Bit(1)); break; // RMB1 zp @@ -109,11 +109,11 @@ namespace M6502 case 0x6b: break; // null case 0x6f: this.ZeroPageRead(); this.BBR(Bit(6)); break; // BBR6 r - case 0x72: this.ZeroPageIndirectRead(); this.ADC(); break; // ADC (zp) + case 0x72: this.ADC(this.ZeroPageIndirectRead()); break; // ADC (zp) case 0x73: break; // null case 0x74: this.ZeroPageXAddress(); this.MemoryWrite(0); break; // STZ zp,x case 0x77: this.ZeroPageRead(); this.RMB(Bit(7)); break; // RMB7 zp - case 0x7a: this.SwallowRead(); this.SwallowPop(); this.Y = this.Through(this.Pop()); break; // PLY s + case 0x7a: this.SwallowRead(); this.SwallowPop(); this.Pop(); this.Y = this.Through(); break; // PLY s case 0x7b: break; // null case 0x7c: this.AbsoluteXAddress(); this.Bus.Address.Assign(this.Intermediate); this.GetAddressPaged(); this.Jump(this.Bus.Address); break; // JMP (a,x) case 0x7f: this.ZeroPageRead(); this.BBR(Bit(7)); break; // BBR7 r @@ -149,7 +149,7 @@ namespace M6502 case 0xcb: this.SwallowRead(); this.Waiting = true; break; // WAI i case 0xcf: this.ZeroPageRead(); this.BBS(Bit(4)); break; // BBS4 r - case 0xd2: this.ZeroPageIndirectRead(); this.CMP(this.A); break; // CMP (zp) + case 0xd2: this.CMP(this.A, this.ZeroPageIndirectRead()); break; // CMP (zp) case 0xd3: break; // null case 0xd7: this.ZeroPageRead(); this.SMB(Bit(5)); break; // SMB5 zp case 0xda: this.SwallowRead(); this.Push(this.X); break; // PHX s @@ -165,7 +165,7 @@ namespace M6502 case 0xf2: this.ZeroPageIndirectRead(); this.SBC(); break; // SBC (zp) case 0xf3: break; // null case 0xf7: this.ZeroPageRead(); this.SMB(Bit(7)); break; // SMB7 zp - case 0xfa: this.SwallowRead(); this.SwallowPop(); this.X = this.Through(this.Pop()); break; // PLX s + case 0xfa: this.SwallowRead(); this.SwallowPop(); this.Pop(); this.X = this.Through(); break; // PLX s case 0xfb: break; // null case 0xfc: break; // null case 0xff: this.ZeroPageRead(); this.BBS(Bit(7)); break; // BBS7 r @@ -263,10 +263,10 @@ namespace M6502 #region Address and read - private void ZeroPageIndirectRead() + private byte ZeroPageIndirectRead() { this.ZeroPageIndirectAddress(); - this.MemoryRead(); + return this.MemoryRead(); } #endregion @@ -290,7 +290,7 @@ namespace M6502 private void BranchBit(bool condition) { - this.FetchByte(); + _ = this.FetchByte(); if (condition) { var relative = (sbyte)this.Bus.Data; diff --git a/MC6809/MC6809.Test/Board.cs b/MC6809/MC6809.Test/Board.cs index 3be3340..0b62761 100644 --- a/MC6809/MC6809.Test/Board.cs +++ b/MC6809/MC6809.Test/Board.cs @@ -2,17 +2,18 @@ // Copyright (c) Adrian Conlon. All rights reserved. // -namespace EightBit +namespace MC6809.Test { + using EightBit; using System; public sealed class Board : Bus { private readonly Configuration configuration; - private readonly Ram ram = new Ram(0x8000); // 0000 - 7FFF, 32K RAM - private readonly UnusedMemory unused2000 = new UnusedMemory(0x2000, 0xff); // 8000 - 9FFF, 8K unused - private readonly Ram io = new Ram(0x2000); // A000 - BFFF, 8K serial interface, minimally decoded - private readonly Rom rom = new Rom(0x4000); // C000 - FFFF, 16K ROM + private readonly Ram ram = new(0x8000); // 0000 - 7FFF, 32K RAM + private readonly UnusedMemory unused2000 = new(0x2000, 0xff); // 8000 - 9FFF, 8K unused + private readonly Ram io = new(0x2000); // A000 - BFFF, 8K serial interface, minimally decoded + private readonly Rom rom = new(0x4000); // C000 - FFFF, 16K ROM private readonly Disassembler disassembler; private readonly Profiler profiler; @@ -27,9 +28,9 @@ namespace EightBit public Board(Configuration configuration) { this.configuration = configuration; - this.CPU = new MC6809(this); - this.disassembler = new Disassembler(this, this.CPU); - this.profiler = new Profiler(this, this.CPU, this.disassembler); + CPU = new MC6809(this); + disassembler = new Disassembler(this, CPU); + profiler = new Profiler(this, CPU, disassembler); } public MC6809 CPU { get; } @@ -40,20 +41,20 @@ namespace EightBit { if (absolute < 0x8000) { - return new MemoryMapping(this.ram, 0x0000, Mask.Sixteen, AccessLevel.ReadWrite); + return new MemoryMapping(ram, 0x0000, Mask.Sixteen, AccessLevel.ReadWrite); } if (absolute < 0xa000) { - return new MemoryMapping(this.unused2000, 0x8000, Mask.Sixteen, AccessLevel.ReadOnly); + return new MemoryMapping(unused2000, 0x8000, Mask.Sixteen, AccessLevel.ReadOnly); } if (absolute < 0xc000) { - return new MemoryMapping(this.io, 0xa000, Mask.Sixteen, AccessLevel.ReadWrite); + return new MemoryMapping(io, 0xa000, Mask.Sixteen, AccessLevel.ReadWrite); } - return new MemoryMapping(this.rom, 0xc000, Mask.Sixteen, AccessLevel.ReadOnly); + return new MemoryMapping(rom, 0xc000, Mask.Sixteen, AccessLevel.ReadOnly); } public override void RaisePOWER() @@ -61,166 +62,167 @@ namespace EightBit base.RaisePOWER(); // Get the CPU ready for action - this.CPU.RaisePOWER(); - this.CPU.LowerRESET(); - this.CPU.RaiseINT(); - this.CPU.RaiseNMI(); - this.CPU.RaiseFIRQ(); - this.CPU.RaiseHALT(); + CPU.RaisePOWER(); + CPU.LowerRESET(); + CPU.RaiseINT(); + CPU.RaiseNMI(); + CPU.RaiseFIRQ(); + CPU.RaiseHALT(); // Get the ACIA ready for action - this.Address.Word = 0b1010000000000000; - this.Data = (byte)(MC6850.ControlRegister.CR0 | MC6850.ControlRegister.CR1); // Master reset - this.ACIA.CTS.Lower(); - this.ACIA.RW.Lower(); - this.UpdateAciaPins(); - this.ACIA.RaisePOWER(); - this.AccessAcia(); + Address.Word = 0b1010000000000000; + Data = (byte)(MC6850.ControlRegister.CR0 | MC6850.ControlRegister.CR1); // Master reset + ACIA.CTS.Lower(); + ACIA.RW.Lower(); + UpdateAciaPins(); + ACIA.RaisePOWER(); + AccessAcia(); } public override void LowerPOWER() { ////this.profiler.Generate(); - this.ACIA.LowerPOWER(); - this.CPU.LowerPOWER(); + ACIA.LowerPOWER(); + CPU.LowerPOWER(); base.LowerPOWER(); } public override void Initialize() { - System.Console.TreatControlCAsInput = true; + Console.TreatControlCAsInput = true; // Load our BASIC interpreter - var directory = this.configuration.RomDirectory + "\\"; - this.LoadHexFile(directory + "ExBasROM.hex"); + var directory = configuration.RomDirectory + "\\"; + LoadHexFile(directory + "ExBasROM.hex"); // Catch a byte being transmitted - this.ACIA.Transmitting += this.ACIA_Transmitting; + ACIA.Transmitting += ACIA_Transmitting; // Keyboard wiring, check for input once per frame - this.CPU.ExecutedInstruction += this.CPU_ExecutedInstruction; + CPU.ExecutedInstruction += CPU_ExecutedInstruction; - if (this.configuration.DebugMode) + // Marshal data from ACIA -> memory + this.ReadingByte += Board_ReadingByte; + + // Marshal data from memory -> ACIA + this.WrittenByte += Board_WrittenByte; + + if (configuration.DebugMode) { // MC6809 disassembly wiring - this.CPU.ExecutingInstruction += this.CPU_ExecutingInstruction; - this.CPU.ExecutedInstruction += this.CPU_ExecutedInstruction_Debug; + CPU.ExecutingInstruction += CPU_ExecutingInstruction; + CPU.ExecutedInstruction += CPU_ExecutedInstruction_Debug; } - if (this.configuration.TerminatesEarly) + if (configuration.TerminatesEarly) { // Early termination condition for CPU timing code - this.CPU.ExecutedInstruction += this.CPU_ExecutedInstruction_Termination; + CPU.ExecutedInstruction += CPU_ExecutedInstruction_Termination; } ////this.profiler.Enable(); ////this.profiler.EmitLine += this.Profiler_EmitLine; } - // Marshal data from ACIA -> memory - protected override void OnReadingByte() + private void Board_ReadingByte(object? sender, EventArgs e) { - this.UpdateAciaPins(); - this.ACIA.RW.Raise(); - if (this.AccessAcia()) + UpdateAciaPins(); + ACIA.RW.Raise(); + if (AccessAcia()) { - this.Poke(this.ACIA.DATA); - } - - base.OnReadingByte(); - } - - // Marshal data from memory -> ACIA - protected override void OnWrittenByte() - { - base.OnWrittenByte(); - this.UpdateAciaPins(); - if (this.ACIA.Selected) - { - this.ACIA.RW.Lower(); - this.AccessAcia(); + Poke(ACIA.DATA); } } - private void Profiler_EmitLine(object sender, ProfileLineEventArgs e) + private void Board_WrittenByte(object? sender, EventArgs e) + { + UpdateAciaPins(); + if (ACIA.Selected) + { + ACIA.RW.Lower(); + AccessAcia(); + } + } + + private void Profiler_EmitLine(object? sender, ProfileLineEventArgs e) { var cycles = e.Cycles; var disassembled = e.Source; - System.Console.Error.WriteLine(disassembled); + Console.Error.WriteLine(disassembled); } - private void CPU_ExecutedInstruction_Termination(object sender, EventArgs e) + private void CPU_ExecutedInstruction_Termination(object? sender, EventArgs e) { - this.totalCycleCount += (ulong)this.CPU.Cycles; - if (this.totalCycleCount > Configuration.TerminationCycles) + totalCycleCount += (ulong)CPU.Cycles; + if (totalCycleCount > Configuration.TerminationCycles) { - this.LowerPOWER(); + LowerPOWER(); } } - private void CPU_ExecutedInstruction_Debug(object sender, EventArgs e) + private void CPU_ExecutedInstruction_Debug(object? sender, EventArgs e) { - if (!this.ignoreDisassembly) + if (!ignoreDisassembly) { - var disassembled = $"{this.disassembler.Trace(this.disassembleAt)}\t{this.ACIA.DumpStatus()}"; - System.Console.Error.WriteLine(disassembled); + var disassembled = $"{disassembler.Trace(disassembleAt)}\t{ACIA.DumpStatus()}"; + Console.Error.WriteLine(disassembled); } } - private void CPU_ExecutingInstruction(object sender, EventArgs e) + private void CPU_ExecutingInstruction(object? sender, EventArgs e) { - this.disassembleAt = this.CPU.PC.Word; - this.ignoreDisassembly = this.disassembler.Ignore || this.disassembler.Pause; + disassembleAt = CPU.PC.Word; + ignoreDisassembly = disassembler.Ignore || disassembler.Pause; } - private void CPU_ExecutedInstruction(object sender, EventArgs e) + private void CPU_ExecutedInstruction(object? sender, EventArgs e) { - this.frameCycleCount -= this.CPU.Cycles; - if (this.frameCycleCount < 0) + frameCycleCount -= CPU.Cycles; + if (frameCycleCount < 0) { - if (System.Console.KeyAvailable) + if (Console.KeyAvailable) { - var key = System.Console.ReadKey(true); + var key = Console.ReadKey(true); if (key.Key == ConsoleKey.F12) { - this.LowerPOWER(); + LowerPOWER(); } - this.ACIA.RDR = System.Convert.ToByte(key.KeyChar); - this.ACIA.MarkReceiveStarting(); + ACIA.RDR = Convert.ToByte(key.KeyChar); + ACIA.MarkReceiveStarting(); } - this.frameCycleCount = (long)Configuration.FrameCycleInterval; + frameCycleCount = (long)Configuration.FrameCycleInterval; } } - private void ACIA_Transmitting(object sender, EventArgs e) + private void ACIA_Transmitting(object? sender, EventArgs e) { - System.Console.Out.Write(Convert.ToChar(this.ACIA.TDR)); - this.ACIA.MarkTransmitComplete(); + Console.Out.Write(Convert.ToChar(ACIA.TDR)); + ACIA.MarkTransmitComplete(); } private void UpdateAciaPins() { - this.ACIA.DATA = this.Data; - this.ACIA.RS.Match(this.Address.Word & (ushort)Bits.Bit0); - this.ACIA.CS0.Match(this.Address.Word & (ushort)Bits.Bit15); - this.ACIA.CS1.Match(this.Address.Word & (ushort)Bits.Bit13); - this.ACIA.CS2.Match(this.Address.Word & (ushort)Bits.Bit14); + ACIA.DATA = Data; + ACIA.RS.Match(Address.Word & (ushort)Bits.Bit0); + ACIA.CS0.Match(Address.Word & (ushort)Bits.Bit15); + ACIA.CS1.Match(Address.Word & (ushort)Bits.Bit13); + ACIA.CS2.Match(Address.Word & (ushort)Bits.Bit14); } private bool AccessAcia() { - this.ACIA.E.Raise(); + ACIA.E.Raise(); try { - this.ACIA.Tick(); - return this.ACIA.Activated; + ACIA.Tick(); + return ACIA.Activated; } finally { - this.ACIA.E.Lower(); + ACIA.E.Lower(); } } } diff --git a/MC6809/MC6809.Test/TestHarness.cs b/MC6809/MC6809.Test/TestHarness.cs index d9dd6f8..e120216 100644 --- a/MC6809/MC6809.Test/TestHarness.cs +++ b/MC6809/MC6809.Test/TestHarness.cs @@ -4,6 +4,7 @@ namespace EightBit { + using MC6809.Test; using System.Diagnostics; internal sealed class TestHarness(Configuration configuration) diff --git a/MC6809/MC6809.cs b/MC6809/MC6809.cs index a08fd83..e75b370 100644 --- a/MC6809/MC6809.cs +++ b/MC6809/MC6809.cs @@ -580,17 +580,19 @@ namespace MC6809 private byte Pop(Register16 stack) { - var read = this.MemoryRead(stack); + _ = this.MemoryRead(stack); stack.Increment(); - return read; + return this.Bus.Data; } private byte PopS() => this.Pop(this.S); private Register16 PopWord(Register16 stack) { - this.Intermediate.High = this.Pop(stack); - this.Intermediate.Low = this.Pop(stack); + this.Pop(stack); + this.Intermediate.High = this.Bus.Data; + this.Pop(stack); + this.Intermediate.Low = this.Bus.Data; return this.Intermediate; } @@ -600,7 +602,8 @@ namespace MC6809 private Register16 Address_relative_byte() { - var offset = (sbyte)this.FetchByte(); + this.FetchByte(); + var offset = (sbyte)this.Bus.Data; this.Intermediate.Word = (ushort)(this.PC.Word + offset); return this.Intermediate; } @@ -614,7 +617,8 @@ namespace MC6809 private Register16 Address_direct() { - this.Intermediate.Assign(this.FetchByte(), this.DP); + this.FetchByte(); + this.Intermediate.Assign(this.Bus.Data, this.DP); return this.Intermediate; } @@ -634,7 +638,8 @@ namespace MC6809 private Register16 Address_indexed() { - var type = this.FetchByte(); + this.FetchByte(); + var type = this.Bus.Data; var r = this.RR((type & (byte)(Bits.Bit6 | Bits.Bit5)) >> 5); if ((type & (byte)Bits.Bit7) != 0) @@ -672,7 +677,8 @@ namespace MC6809 break; case 0b1000: // n,R (eight-bit) this.Tick(); - this.Intermediate.Word = (ushort)(r.Word + (sbyte)this.FetchByte()); + this.FetchByte(); + this.Intermediate.Word = (ushort)(r.Word + (sbyte)this.Bus.Data); break; case 0b1001: // n,R (sixteen-bit) this.Tick(4); @@ -715,13 +721,29 @@ namespace MC6809 return this.Intermediate; } - private byte AM_immediate_byte() => this.FetchByte(); + private byte AM_immediate_byte() + { + this.FetchByte(); + return this.Bus.Data; + } - private byte AM_direct_byte() => this.MemoryRead(this.Address_direct()); + private byte AM_direct_byte() + { + this.MemoryRead(this.Address_direct()); + return this.Bus.Data; + } - private byte AM_indexed_byte() => this.MemoryRead(this.Address_indexed()); + private byte AM_indexed_byte() + { + this.MemoryRead(this.Address_indexed()); + return this.Bus.Data; + } - private byte AM_extended_byte() => this.MemoryRead(this.Address_extended()); + private byte AM_extended_byte() + { + this.MemoryRead(this.Address_extended()); + return this.Bus.Data; + } private Register16 AM_immediate_word() => this.FetchWord(); @@ -859,25 +881,29 @@ namespace MC6809 if ((data & (byte)Bits.Bit0) != 0) { this.Tick(); - this.CC = this.Pop(stack); + this.Pop(stack); + this.CC = this.Bus.Data; } if ((data & (byte)Bits.Bit1) != 0) { this.Tick(); - this.A = this.Pop(stack); + this.Pop(stack); + this.A = this.Bus.Data; } if ((data & (byte)Bits.Bit2) != 0) { this.Tick(); - this.B = this.Pop(stack); + this.Pop(stack); + this.B = this.Bus.Data; } if ((data & (byte)Bits.Bit3) != 0) { this.Tick(); - this.DP = this.Pop(stack); + this.Pop(stack); + this.DP = this.Bus.Data; } if ((data & (byte)Bits.Bit4) != 0) @@ -1050,7 +1076,8 @@ namespace MC6809 } else { - this.Execute(this.FetchByte()); + this.FetchByte(); + this.Execute(this.Bus.Data); } } @@ -1079,8 +1106,8 @@ namespace MC6809 { switch (this.OpCode) { - case 0x10: this.prefix10 = true; this.Execute(this.FetchByte()); break; - case 0x11: this.prefix11 = true; this.Execute(this.FetchByte()); break; + case 0x10: this.prefix10 = true; this.FetchByte(); this.Execute(this.Bus.Data); break; + case 0x11: this.prefix11 = true; this.FetchByte(); this.Execute(this.Bus.Data); break; // ABX case 0x3a: this.Tick(3); this.X.Word += this.B; break; // ABX (inherent) diff --git a/Z80/Z80.cs b/Z80/Z80.cs index 5cce394..e6c8a35 100644 --- a/Z80/Z80.cs +++ b/Z80/Z80.cs @@ -549,14 +549,14 @@ namespace Z80 private byte ReadDataUnderInterrupt() { this.LowerM1(); - this.Tick(3); - this.LowerIORQ(); - this.Tick(); - _ = this.Bus.Data; - this.RaiseIORQ(); - Debug.Assert(this.Cycles == 4); - this.RefreshMemory(); - Debug.Assert(this.Cycles == 5); + this.Tick(3); + this.LowerIORQ(); + this.Tick(); + _ = this.Bus.Data; + this.RaiseIORQ(); + Debug.Assert(this.Cycles == 4); + this.RefreshMemory(); + Debug.Assert(this.Cycles == 5); this.RaiseM1(); return this.Bus.Data; } @@ -933,7 +933,7 @@ namespace Z80 switch (z) { case 0: // Input from port with 16-bit address - this.ReadPort(this.BC); + _ = this.ReadPort(this.BC); this.MEMPTR.Increment(); if (y != 6) { @@ -1149,7 +1149,7 @@ namespace Z80 break; case 2: // DJNZ d this.Tick(); - _ = this.JumpRelativeConditional(--this.B != 0); + this.JumpRelativeConditional(--this.B != 0); break; case 3: // JR d this.JumpRelative(this.FetchByte()); @@ -1158,7 +1158,7 @@ namespace Z80 case 5: case 6: case 7: - _ = this.JumpRelativeConditionalFlag(y - 4); + this.JumpRelativeConditionalFlag(y - 4); break; default: throw new NotSupportedException("Invalid operation mode"); @@ -1197,7 +1197,7 @@ namespace Z80 this.SetWord(this.HL2()); break; case 3: // LD (nn),A - this.FetchWordMEMPTR(); + this.FetchInto(this.MEMPTR); WriteMemoryIndirect(this.A); break; default: @@ -1219,7 +1219,7 @@ namespace Z80 this.HL2().Assign(this.GetWord()); break; case 3: // LD A,(nn) - this.FetchWordMEMPTR(); + this.FetchInto(this.MEMPTR); this.A = this.ReadMemoryIndirect(); break; default: @@ -1270,14 +1270,12 @@ namespace Z80 this.FetchDisplacement(); } + _ = this.FetchByte(); // LD r,n + if (memoryY) { - var value = this.FetchByte(); // LD r,n - if (memoryY) - { - this.Tick(2); - } - this.R(y, value); + this.Tick(2); } + this.R(y, this.Bus.Data); break; case 7: // Assorted operations on accumulator/flags @@ -1422,13 +1420,13 @@ namespace Z80 switch (z) { case 0: // Conditional return - _ = this.ReturnConditionalFlag(y); + this.ReturnConditionalFlag(y); break; case 1: // POP & various ops switch (q) { case 0: // POP rp2[p] - this.RP2(p).Assign(this.PopWord()); + this.PopInto(this.RP2(p)); break; case 1: switch (p) @@ -1457,7 +1455,7 @@ namespace Z80 break; case 2: // Conditional jump - _ = this.JumpConditionalFlag(y); + this.JumpConditionalFlag(y); break; case 3: // Assorted operations switch (y) @@ -1482,8 +1480,7 @@ namespace Z80 this.WritePort(this.FetchByte()); break; case 3: // IN A,(n) - this.ReadPort(this.FetchByte()); - this.A = this.Bus.Data; + this.A = this.ReadPort(this.FetchByte()); break; case 4: // EX (SP),HL this.XHTL(this.HL2()); @@ -1504,7 +1501,7 @@ namespace Z80 break; case 4: // Conditional call: CALL cc[y], nn - _ = this.CallConditionalFlag(y); + this.CallConditionalFlag(y); break; case 5: // PUSH & various ops switch (q) @@ -1682,7 +1679,7 @@ namespace Z80 _ => throw new ArgumentOutOfRangeException(nameof(flag)), }; - protected sealed override bool ReturnConditionalFlag(int flag) + protected sealed override void ReturnConditionalFlag(int flag) { var condition = this.ConvertCondition(flag); this.Tick(); @@ -1690,7 +1687,6 @@ namespace Z80 { this.Return(); } - return condition; } private Register16 SBC(Register16 operand, Register16 value) @@ -2041,7 +2037,7 @@ namespace Z80 private void BlockLoad() { - this.MemoryRead(this.HL); + _ = this.MemoryRead(this.HL); this.Bus.Address.Assign(this.DE); this.MemoryUpdate(1); this.Tick(2); @@ -2142,7 +2138,7 @@ namespace Z80 private void BlockIn() { this.Tick(); - this.ReadPort(this.BC); + _ = this.ReadPort(this.BC); this.Bus.Address.Assign(this.HL); this.MemoryUpdate(1); this.AdjustSZXY(--this.B); @@ -2357,20 +2353,21 @@ namespace Z80 this.Tick(); } - private void ReadPort(byte port) + private byte ReadPort(byte port) { this.Bus.Address.Assign(port, this.Bus.Data = this.A); - this.ReadPort(); + _ = this.ReadPort(); this.MEMPTR.Increment(); + return this.Bus.Data; } - private void ReadPort(Register16 port) + private byte ReadPort(Register16 port) { this.Bus.Address.Assign(port); - this.ReadPort(); + return this.ReadPort(); } - private void ReadPort() + private byte ReadPort() { this.MEMPTR.Assign(this.Bus.Address); this.Tick(2); @@ -2381,6 +2378,7 @@ namespace Z80 this.RaiseRD(); this.RaiseIORQ(); this.Tick(); + return this.Bus.Data; } #endregion