1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-29 15:29:36 +00:00

Starts introducing the Patrik Rak tests.

This commit is contained in:
Thomas Harte 2020-02-22 15:49:36 -05:00
parent 825b68e5c4
commit 2370575eb5
27 changed files with 3430 additions and 2 deletions

View File

@ -1012,6 +1012,9 @@ template <bool has_fdc> class ConcreteMachine:
default: break;
}
// Check whether the interrupt signal has changed the other way.
if(interrupt_timer_.request_has_changed()) z80_.set_interrupt_line(interrupt_timer_.get_request());
// This implementation doesn't use time-stuffing; once in-phase waits won't be longer
// than a single cycle so there's no real performance benefit to trying to find the
// next non-wait when a wait cycle comes in, and there'd be no benefit to reproducing
@ -1228,7 +1231,7 @@ template <bool has_fdc> class ConcreteMachine:
KeyboardState key_state_;
AmstradCPC::KeyboardMapper keyboard_mapper_;
uint8_t ram_[128 * 1024];
uint8_t ram_[1024 * 1024];
};
}

View File

@ -817,6 +817,8 @@
4BD67DCC209BE4D700AB2146 /* StaticAnalyser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD67DCA209BE4D600AB2146 /* StaticAnalyser.cpp */; };
4BD67DD0209BF27B00AB2146 /* Encoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD67DCE209BF27B00AB2146 /* Encoder.cpp */; };
4BD67DD1209BF27B00AB2146 /* Encoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD67DCE209BF27B00AB2146 /* Encoder.cpp */; };
4BD91D732401960C007BDC91 /* STX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7BA03323C58B1E00B98D9E /* STX.cpp */; };
4BD91D772401C2B8007BDC91 /* PatrikRakTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BD91D762401C2B8007BDC91 /* PatrikRakTests.swift */; };
4BDA00DA22E60EE300AC3CD0 /* ROMRequester.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4BDA00D922E60EE300AC3CD0 /* ROMRequester.xib */; };
4BDA00DD22E622C200AC3CD0 /* ROMImages in Resources */ = {isa = PBXBuildFile; fileRef = 4BC9DF441D044FCA00F44158 /* ROMImages */; };
4BDA00E022E644AF00AC3CD0 /* CSROMReceiverView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BDA00DF22E644AF00AC3CD0 /* CSROMReceiverView.m */; };
@ -1696,6 +1698,7 @@
4BD67DCE209BF27B00AB2146 /* Encoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Encoder.cpp; sourceTree = "<group>"; };
4BD67DCF209BF27B00AB2146 /* Encoder.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Encoder.hpp; sourceTree = "<group>"; };
4BD9137D1F311BC5009BCF85 /* i8255.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = i8255.hpp; path = 8255/i8255.hpp; sourceTree = "<group>"; };
4BD91D762401C2B8007BDC91 /* PatrikRakTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PatrikRakTests.swift; sourceTree = "<group>"; };
4BDA00D922E60EE300AC3CD0 /* ROMRequester.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ROMRequester.xib; sourceTree = "<group>"; };
4BDA00DE22E644AF00AC3CD0 /* CSROMReceiverView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSROMReceiverView.h; sourceTree = "<group>"; };
4BDA00DF22E644AF00AC3CD0 /* CSROMReceiverView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CSROMReceiverView.m; sourceTree = "<group>"; };
@ -3316,6 +3319,7 @@
4BEF6AAB1D35D1C400E73575 /* DPLLTests.swift */,
4BBF49AE1ED2880200AB3669 /* FUSETests.swift */,
4B1414611B58888700E04248 /* KlausDormannTests.swift */,
4BD91D762401C2B8007BDC91 /* PatrikRakTests.swift */,
4B14145F1B58885000E04248 /* WolfgangLorenzTests.swift */,
4B08A2741EE35D56008B7065 /* Z80InterruptTests.swift */,
4BDDBA981EF3451200347E61 /* Z80MachineCycleTests.swift */,
@ -4643,6 +4647,7 @@
4BEF6AAA1D35CE9E00E73575 /* DigitalPhaseLockedLoopBridge.mm in Sources */,
4B778F3123A5F0CB0000D260 /* Keyboard.cpp in Sources */,
4B778F4A23A5F1FB0000D260 /* StaticAnalyser.cpp in Sources */,
4BD91D772401C2B8007BDC91 /* PatrikRakTests.swift in Sources */,
4B680CE223A5553100451D43 /* 68000ComparativeTests.mm in Sources */,
4B778F3723A5F11C0000D260 /* Parser.cpp in Sources */,
4B778F4523A5F1CD0000D260 /* SegmentParser.cpp in Sources */,
@ -4780,6 +4785,7 @@
4B778F0223A5EBA40000D260 /* MFMSectorDump.cpp in Sources */,
4BFCA1271ECBE33200AC40C1 /* TestMachineZ80.mm in Sources */,
4B778F3E23A5F17C0000D260 /* IWM.cpp in Sources */,
4BD91D732401960C007BDC91 /* STX.cpp in Sources */,
4B778F1023A5EC5D0000D260 /* Drive.cpp in Sources */,
4B9D0C4F22C7E0CF00DE1AD3 /* 68000RollShiftTests.mm in Sources */,
);

View File

@ -67,7 +67,7 @@
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Release"
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
enableASanStackUseAfterReturn = "YES"

View File

@ -0,0 +1,3 @@
1.0 (7.12.2012)
+ First release.

View File

@ -0,0 +1,19 @@
Copyright (c) 2012 Patrik Rak (patrik@raxoft.cz)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,28 @@
Welcome to the Zilog Z80 CPU test suite.
This set of programs is intended to help the emulator authors to reach the
desired level of the CPU emulation authenticity. Each of the included programs
performs an exhaustive computation using each of the tested Z80 instructions,
compares the results with values obtained from a real 48K Spectrum with Zilog Z80 CPU,
and reports any deviations detected.
The following variants are available:
- z80full - tests all flags and registers.
- z80doc - tests all registers, but only officially documented flags.
- z80flags - tests all flags, ignores registers.
- z80docflags - tests documented flags only, ignores registers.
- z80ccf - tests all flags after executing CCF after each instruction tested.
- z80memptr - tests all flags after executing BIT N,(HL) after each instruction tested.
The first four are the standard tests for CPU emulation. The CCF variant is
used to thoroughly test the authentic SCF/CCF behavior after each Z80
instruction. Finally the MEMPTR variant can be used to discover problems in
the MEMPTR emulation - however note that the current set of test was not
specifically designed to stress test MEMPTR, so many of the possible
problems are very likely left undetected. I may eventually add specific
MEMPTR tests in later releases.
Enjoy!
Patrik Rak

View File

@ -0,0 +1,34 @@
# gmake
NAME = z80test
VERSION = 1.0
PKG := $(NAME)-$(VERSION)
PROGS := z80full z80flags z80doc z80docflags z80ccf z80memptr
SRCS := main idea crctab tests testmacros print
all: $(addsuffix .tap,$(PROGS))
.DELETE_ON_ERROR: %.out
%.out : %.asm $(addsuffix .asm,$(SRCS))
sjasm $<
%.tap : loader.bas %.out
mktap -b $(basename $(word 2,$^)) 10 <$(word 1,$^) >$@
mktap $(basename $(word 2,$^)) 32768 <$(word 2,$^) >>$@
FILES := Makefile loader.bas $(addsuffix .asm,$(PROGS)) $(addsuffix .asm, $(SRCS))
dist: all
ln -s .. $(PKG)
cp *.tap $(PKG)
zip ../$(PKG).zip $(addprefix $(PKG)/src/, $(FILES)) $(PKG)/*.txt $(PKG)/*.tap
rm $(PKG)/*.tap
rm $(PKG)
clean:
rm -rf *.out *.lst *.tap
tidy: clean
rm -rf $(PROGS)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,291 @@
; The Z80 tester.
;
; Copyright (C) 2012 Patrik Rak (patrik@raxoft.cz)
;
; This source code is released under the MIT license, see included license.txt.
opsize equ 4+postccf ; Size of the tested instruction sequence.
datasize equ 16 ; Size of the tested registers and data.
vecsize equ opsize+datasize ; Size of entire test vector.
test: ld (.spptr+1),sp
if maskflags ; Keep mask for official flags.
ld a,(hl)
ld (.flagptr+1),a
endif
inc hl
ld de,vector ; Init the test vector, counter and shifter.
ld bc,vecsize
call .copy
add hl,bc
call .copy
call .copy
add hl,bc
ld (.valptr+1),de
inc de
call .clear
ld (.maskptr+1),de
xor a
ld (de),a
inc de
call .copy
ld a,0x07 ; Make sure we get 0
out (0xfe),a ; on MIC bit when doing IN.
ld a,0xa9 ; Set I,R,AF' to known values.
ld i,a
ld r,a
or a
ex af,af
ld bc,65535 ; Init CRC.
ld d,b
ld e,c
exx
ld sp,data.regs
; Test vector sequence combinator.
.loop ld hl,counter
ld de,shifter+1
ld bc,vector
macro combine base,count,offset:0,last:1
repeat count
ld a,(bc)
xor (hl)
ex de,hl
xor (hl)
ld (base+offset+@#),a
if ( @# < count-1 ) | ! last
inc c
inc e
inc l
endif
endrepeat
endm
ld a,(bc)
xor (hl)
ex de,hl
xor (hl)
cp 0x76 ; Skip halt.
jp z,.next
ld (.opcode),a
inc c
inc e
inc l
ld a,(bc)
xor (hl)
ex de,hl
xor (hl)
ld (.opcode+1),a
cp 0x76 ; Skip halt...
jp nz,.ok
ld a,(.opcode)
and 0xdf ; ... with IX/IY prefix.
cp 0xdd
jp z,.next
.ok inc c
inc e
inc l
combine .opcode,opsize-2,2,0
combine data,datasize
; The test itself.
pop af
pop bc
pop de
pop hl
pop ix
pop iy
ld sp,(data.sp)
.opcode ds opsize
.continue
if memptr
ld hl,data
bit 0,(hl)
endif
ld (data.sp),sp
ld sp,data.regstop
push iy
push ix
push hl
push de
push bc
push af
ld hl,data
if maskflags
ld a,(hl)
.flagptr and 0xff
if ! onlyflags
ld (hl),a
endif
endif
; CRC update.
if ! onlyflags
ld b,datasize
endif
if ! ( onlyflags & maskflags )
.crcloop ld a,(hl)
endif
exx
xor e
ld l,a
ld h,crctable/256
ld a,(hl)
xor d
ld e,a
inc h
ld a,(hl)
xor c
ld d,a
inc h
ld a,(hl)
xor b
ld c,a
inc h
ld b,(hl)
exx
if ! onlyflags
inc hl
djnz .crcloop
endif
; Multibyte counter with arbitrary bit mask.
.next ld hl,countmask
ld de,counter
ld b,vecsize
.countloop ld a,(de)
or a
jr z,.countnext
dec a
and (hl)
ld (de),a
jp .loop
.countnext ld a,(hl)
ld (de),a
inc l
inc e
djnz .countloop
; Multibyte shifter with arbitrary bit mask.
.maskptr ld hl,shiftmask
.valptr ld de,shifter
ld a,(de)
add a,a
neg
add (hl)
xor (hl)
and (hl)
ld (de),a
jp nz,.loop
.shiftloop inc l
inc e
ld a,e
cp shiftend % 256
jr z,.exit
ld a,(hl)
dec a
xor (hl)
and (hl)
jr z,.shiftloop
ld (de),a
ld (.maskptr+1),hl
ld (.valptr+1),de
jp .loop
.exit exx
.spptr ld sp,0
ret
; Misc helper routines.
.copy push hl
push bc
ldir
pop bc
pop hl
ret
.clear push hl
push bc
ld h,d
ld l,e
ld (hl),0
inc de
dec bc
ldir
pop bc
pop hl
ret
align 256
include crctab.asm
; If this moves from 0x8800, all tests which use this address
; will need to have their CRCs updated, so don't move it.
align 256
data
.regs ds datasize-4
.regstop
.mem ds 2
.sp ds 2
.jump
if postccf
ccf
else
inc bc
endif
jp test.continue
; This entire workspace must be kept within single 256 byte page.
vector ds vecsize
counter ds vecsize
countmask ds vecsize
shifter ds 1+vecsize
shiftend
shiftmask ds 1+vecsize
; EOF ;

View File

@ -0,0 +1,2 @@
10 CLEAR 32767:LOAD "" CODE:CLS
20 RANDOMIZE USR 32768

View File

@ -0,0 +1,149 @@
; Main driver for the Z80 tester.
;
; Copyright (C) 2012 Patrik Rak (patrik@raxoft.cz)
;
; This source code is released under the MIT license, see included license.txt.
org 0x8000
main: di
push iy
exx
push hl
call printinit
call print
db "Z80 "
testname
db " test"
db 23,32-13,1,127," 2012 RAXOFT",13,13,0
ld bc,0
ld hl,testtable
jr .entry
.loop push hl
push bc
call .test
pop bc
pop hl
add a,b
ld b,a
inc c
.entry ld e,(hl)
inc hl
ld d,(hl)
inc hl
ld a,d
or e
jr nz,.loop
call print
db 13,"Result: ",0
ld a,b
or a
jr z,.ok
call printdeca
call print
db " of ",0
ld a,c
call printdeca
call print
db " tests failed.",13,0
jr .done
.ok call print
db "all tests passed.",13,0
.done pop hl
exx
pop iy
ei
ret
.test ld hl,1+3*vecsize
add hl,de
push hl
ld a,c
call printdeca
ld a,' '
call printchr
ld hl,1+3*vecsize+4
add hl,de
call printhl
ex de,hl
call test
ld hl,data+3
ld (hl),e
dec hl
ld (hl),d
dec hl
ld (hl),c
dec hl
ld (hl),b
pop de
ld b,4
call .cmp
jr nz,.mismatch
call print
db 23,32-2,1,"OK",13,0
ret
.mismatch call print
db 23,32-6,1,"FAILED",13
db "CRC:",0
call printcrc
call print
db " Expected:",0
ex de,hl
call printcrc
ld a,13
call printchr
ld a,1
ret
.cmp push hl
push de
.cmploop ld a,(de)
xor (hl)
jr nz,.exit
inc de
inc hl
djnz .cmploop
.exit pop de
pop hl
ret
include print.asm
include idea.asm
include tests.asm
; EOF ;

View File

@ -0,0 +1,82 @@
; Simple printing module.
;
; Copyright (C) 2012 Patrik Rak (patrik@raxoft.cz)
;
; This source code is released under the MIT license, see included license.txt.
printinit: ld a,2
jp 0x1601 ; CHAN-OPEN
print: ex (sp),hl
call printhl
ex (sp),hl
ret
printhl:
.loop ld a,(hl)
inc hl
or a
ret z
call printchr
jr .loop
printdeca: ld h,a
ld b,-100
call .digit
ld b,-10
call .digit
ld b,-1
.digit ld a,h
ld l,'0'-1
.loop inc l
add a,b
jr c,.loop
sub b
ld h,a
ld a,l
jr printchr
printcrc: ld b,4
printhexs:
.loop ld a,(hl)
inc hl
call printhexa
djnz .loop
ret
printhexa: push af
rrca
rrca
rrca
rrca
call .nibble
pop af
.nibble or 0xf0
daa
add a,0xa0
adc a,0x40
printchr: push iy
ld iy,0x5c3a ; ERR-NR
push de
push bc
exx
ei
; out (0xff),a
rst 0x10
di
exx
pop bc
pop de
pop iy
ret
; EOF ;

View File

@ -0,0 +1,103 @@
; Macros for defining the test vectors.
;
; Copyright (C) 2012 Patrik Rak (patrik@raxoft.cz)
;
; This source code is released under the MIT license, see included license.txt.
macro db8 b7,b6,b5,b4,b3,b2,b1,b0
db (b7<<7)|(b6<<6)|(b5<<5)|(b4<<4)|(b3<<3)|(b2<<2)|(b1<<1)|b0
endm
macro ddbe n
db (n>>24)&0xff
db (n>>16)&0xff
db (n>>8)&0xff
db n&0xff
endm
macro inst op1,op2,op3,op4,tail
; Unfortunately, elseifidn doesn't seem to work properly.
ifidn op4,stop
db op1,op2,op3,tail,0
else
ifidn op3,stop
db op1,op2,tail,op4,0
else
ifidn op2,stop
db op1,tail,op3,op4,0
else
db op1,op2,op3,op4,tail
endif
endif
endif
endm
macro flags sn,s,zn,z,f5n,f5,hcn,hc,f3n,f3,pvn,pv,nn,n,cn,c
if maskflags
db8 s,z,f5,hc,f3,pv,n,c
else
db 0xff
endif
endm
.veccount := 0
macro vec op1,op2,op3,op4,memn,mem,an,a,fn,f,bcn,bc,den,de,hln,hl,ixn,ix,iyn,iy,spn,sp
if postccf
if ( .@veccount % 3 ) == 0
inst op1,op2,op3,op4,tail
.@areg := 0
else
db op1,op2,op3,op4,0
.@areg := .@areg | a
endif
else
db op1,op2,op3,op4
endif
db f
if postccf & ( ( .veccount % 3 ) == 2 )
db a | ( ( ~ .@areg ) & 0x28 )
else
db a
endif
dw bc,de,hl,ix,iy
dw mem
dw sp
.@veccount := .@veccount+1
endm
macro crcs allflagsn,allflags,alln,all,docflagsn,docflags,docn,doc,ccfn,ccf,mptrn,mptr
if postccf
ddbe ccf
elseif memptr
ddbe mptr
else
if maskflags
if onlyflags
ddbe docflags
else
ddbe doc
endif
else
if onlyflags
ddbe allflags
else
ddbe all
endif
endif
endif
endm
macro name n
dz n
endm
; EOF ;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,18 @@
; Z80 test - post CCF version.
;
; Copyright (C) 2012 Patrik Rak (patrik@raxoft.cz)
;
; This source code is released under the MIT license, see included license.txt.
macro testname
db "CCF"
endm
maskflags equ 0
onlyflags equ 1
postccf equ 1
memptr equ 0
include main.asm
; EOF ;

View File

@ -0,0 +1,18 @@
; Z80 test - officially documented flags version.
;
; Copyright (C) 2012 Patrik Rak (patrik@raxoft.cz)
;
; This source code is released under the MIT license, see included license.txt.
macro testname
db "doc"
endm
maskflags equ 1
onlyflags equ 0
postccf equ 0
memptr equ 0
include main.asm
; EOF ;

View File

@ -0,0 +1,18 @@
; Z80 test - officially documented flags, flags only version.
;
; Copyright (C) 2012 Patrik Rak (patrik@raxoft.cz)
;
; This source code is released under the MIT license, see included license.txt.
macro testname
db "doc flags"
endm
maskflags equ 1
onlyflags equ 1
postccf equ 0
memptr equ 0
include main.asm
; EOF ;

View File

@ -0,0 +1,18 @@
; Z80 test - flags only version.
;
; Copyright (C) 2012 Patrik Rak (patrik@raxoft.cz)
;
; This source code is released under the MIT license, see included license.txt.
macro testname
db "flags"
endm
maskflags equ 0
onlyflags equ 1
postccf equ 0
memptr equ 0
include main.asm
; EOF ;

View File

@ -0,0 +1,18 @@
; Z80 test - the full version.
;
; Copyright (C) 2012 Patrik Rak (patrik@raxoft.cz)
;
; This source code is released under the MIT license, see included license.txt.
macro testname
db "full"
endm
maskflags equ 0
onlyflags equ 0
postccf equ 0
memptr equ 0
include main.asm
; EOF ;

View File

@ -0,0 +1,21 @@
; Z80 test - MEMPTR version.
;
; However note that the current set of tests was not designed to stress test MEMPTR
; particularly, so it doesn't detect much - I may eventually add such specific tests later.
;
; Copyright (C) 2012 Patrik Rak (patrik@raxoft.cz)
;
; This source code is released under the MIT license, see included license.txt.
macro testname
db "MEMPTR"
endm
maskflags equ 0
onlyflags equ 1
postccf equ 0
memptr equ 1
include main.asm
; EOF ;

View File

@ -0,0 +1,181 @@
//
// PatrikRakTests.swift
// Clock Signal
//
// Created by Thomas Harte on 22/02/2020.
// Copyright 2017 Thomas Harte. All rights reserved.
//
import XCTest
import Foundation
class PatrikRakTests: XCTestCase, CSTestMachineTrapHandler {
fileprivate var done = false
fileprivate var output = ""
private func runTest(_ name: String) {
if let filename = Bundle(for: type(of: self)).path(forResource: name, ofType: "tap") {
if let testData = try? Data(contentsOf: URL(fileURLWithPath: filename)) {
// Do a minor parsing of the TAP file to find the final file.
var dataPointer = 0
while dataPointer < testData.count {
let blockSize = Int(testData[dataPointer]) + Int(testData[dataPointer+1]) << 8
dataPointer += 2 + blockSize
break
}
// Create a machine.
let machine = CSTestMachineZ80()
machine.setData(testData, atAddress: 0x0100)
// Add a RET and a trap at 10h, this is the Spectrum's system call for outputting text.
machine.setValue(0xc9, atAddress: 0x0010)
machine.addTrapAddress(0x0010);
machine.trapHandler = self
// Add a call to $8000 and then an infinite loop; these tests load at $8000 and RET when done.
machine.setValue(0xcd, atAddress: 0x7000)
machine.setValue(0x00, atAddress: 0x7001)
machine.setValue(0x80, atAddress: 0x7002)
machine.setValue(0xc3, atAddress: 0x7003)
machine.setValue(0x03, atAddress: 0x7004)
machine.setValue(0x70, atAddress: 0x7005)
// seed execution at 0x7000
machine.setValue(0x7000, for: .programCounter)
// run!
let cyclesPerIteration: Int32 = 400_000_000
var cyclesToDate: TimeInterval = 0
let startDate = Date()
var printDate = Date()
let printMhz = false
while !done {
machine.runForNumber(ofCycles: cyclesPerIteration)
cyclesToDate += TimeInterval(cyclesPerIteration)
if printMhz && printDate.timeIntervalSinceNow < -5.0 {
print("\(cyclesToDate / -startDate.timeIntervalSinceNow) Mhz")
printDate = Date()
}
}
let targetOutput =
"Z80doc instruction exerciser\n\r" +
"<adc,sbc> hl,<bc,de,hl,sp>.... OK\n\r" +
"add hl,<bc,de,hl,sp>.......... OK\n\r" +
"add ix,<bc,de,ix,sp>.......... OK\n\r" +
"add iy,<bc,de,iy,sp>.......... OK\n\r" +
"aluop a,nn.................... OK\n\r" +
"aluop a,<b,c,d,e,h,l,(hl),a>.. OK\n\r" +
"aluop a,<ixh,ixl,iyh,iyl>..... OK\n\r" +
"aluop a,(<ix,iy>+1)........... OK\n\r" +
"bit n,(<ix,iy>+1)............. OK\n\r" +
"bit n,<b,c,d,e,h,l,(hl),a>.... OK\n\r" +
"cpd<r>........................ OK\n\r" +
"cpi<r>........................ OK\n\r" +
"<daa,cpl,scf,ccf>............. OK\n\r" +
"<inc,dec> a................... OK\n\r" +
"<inc,dec> b................... OK\n\r" +
"<inc,dec> bc.................. OK\n\r" +
"<inc,dec> c................... OK\n\r" +
"<inc,dec> d................... OK\n\r" +
"<inc,dec> de.................. OK\n\r" +
"<inc,dec> e................... OK\n\r" +
"<inc,dec> h................... OK\n\r" +
"<inc,dec> hl.................. OK\n\r" +
"<inc,dec> ix.................. OK\n\r" +
"<inc,dec> iy.................. OK\n\r" +
"<inc,dec> l................... OK\n\r" +
"<inc,dec> (hl)................ OK\n\r" +
"<inc,dec> sp.................. OK\n\r" +
"<inc,dec> (<ix,iy>+1)......... OK\n\r" +
"<inc,dec> ixh................. OK\n\r" +
"<inc,dec> ixl................. OK\n\r" +
"<inc,dec> iyh................. OK\n\r" +
"<inc,dec> iyl................. OK\n\r" +
"ld <bc,de>,(nnnn)............. OK\n\r" +
"ld hl,(nnnn).................. OK\n\r" +
"ld sp,(nnnn).................. OK\n\r" +
"ld <ix,iy>,(nnnn)............. OK\n\r" +
"ld (nnnn),<bc,de>............. OK\n\r" +
"ld (nnnn),hl.................. OK\n\r" +
"ld (nnnn),sp.................. OK\n\r" +
"ld (nnnn),<ix,iy>............. OK\n\r" +
"ld <bc,de,hl,sp>,nnnn......... OK\n\r" +
"ld <ix,iy>,nnnn............... OK\n\r" +
"ld a,<(bc),(de)>.............. OK\n\r" +
"ld <b,c,d,e,h,l,(hl),a>,nn.... OK\n\r" +
"ld (<ix,iy>+1),nn............. OK\n\r" +
"ld <b,c,d,e>,(<ix,iy>+1)...... OK\n\r" +
"ld <h,l>,(<ix,iy>+1).......... OK\n\r" +
"ld a,(<ix,iy>+1).............. OK\n\r" +
"ld <ixh,ixl,iyh,iyl>,nn....... OK\n\r" +
"ld <bcdehla>,<bcdehla>........ OK\n\r" +
"ld <bcdexya>,<bcdexya>........ OK\n\r" +
"ld a,(nnnn) / ld (nnnn),a..... OK\n\r" +
"ldd<r> (1).................... OK\n\r" +
"ldd<r> (2).................... OK\n\r" +
"ldi<r> (1).................... OK\n\r" +
"ldi<r> (2).................... OK\n\r" +
"neg........................... OK\n\r" +
"<rrd,rld>..................... OK\n\r" +
"<rlca,rrca,rla,rra>........... OK\n\r" +
"shf/rot (<ix,iy>+1)........... OK\n\r" +
"shf/rot <b,c,d,e,h,l,(hl),a>.. OK\n\r" +
"<set,res> n,<bcdehl(hl)a>..... OK\n\r" +
"<set,res> n,(<ix,iy>+1)....... OK\n\r" +
"ld (<ix,iy>+1),<b,c,d,e>...... OK\n\r" +
"ld (<ix,iy>+1),<h,l>.......... OK\n\r" +
"ld (<ix,iy>+1),a.............. OK\n\r" +
"ld (<bc,de>),a................ OK\n\r" +
"Tests complete\n\r"
XCTAssertEqual(targetOutput, output);
}
}
}
func testCCF() {
runTest("z80ccf")
}
func testMachine(_ testMachine: CSTestMachine, didTrapAtAddress address: UInt16) {
let testMachineZ80 = testMachine as! CSTestMachineZ80
switch address {
case 0x0010:
print("TODO")
let cRegister = testMachineZ80.value(for: .C)
var textToAppend = ""
switch cRegister {
case 9:
var address = testMachineZ80.value(for: .DE)
var character: Character = " "
while true {
character = Character(UnicodeScalar(testMachineZ80.value(atAddress: address)))
if character == "$" {
break
}
textToAppend += String(character)
address = address + 1
}
case 5:
textToAppend = String(describing: UnicodeScalar(testMachineZ80.value(for: .E)))
case 0:
done = true
default:
break
}
output += textToAppend
print(textToAppend)
case 0x7003:
done = true
default:
break
}
}
}