-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathapple2Tester.go
122 lines (101 loc) · 2.83 KB
/
apple2Tester.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package izapple2
import (
"strings"
"github.com/ivanizag/izapple2/screen"
)
type terminateConditionFunc func(a *Apple2) bool
type apple2Tester struct {
a *Apple2
terminateCondition terminateConditionFunc
}
func makeApple2Tester(model string, overrides *configuration) (*apple2Tester, error) {
models, _, err := loadConfigurationModelsAndDefault()
if err != nil {
return nil, err
}
config, err := models.getWithOverrides(model, overrides)
if err != nil {
return nil, err
}
config.set(confSpeed, "full")
a, err := configure(config)
if err != nil {
return nil, err
}
var at apple2Tester
a.addTracer(&at)
return &at, nil
}
func (at *apple2Tester) connect(a *Apple2) {
at.a = a
}
func (at *apple2Tester) inspect() {
if at.terminateCondition(at.a) {
at.a.SendCommand(CommandKill)
}
}
func (at *apple2Tester) run() {
at.a.Run()
}
type testTextModeFunc func(a *Apple2) string
var testTextMode40 testTextModeFunc = func(a *Apple2) string {
return screen.RenderTextModeString(a.video, false, false, false, a.hasLowerCase, false)
}
var testTextMode80 testTextModeFunc = func(a *Apple2) string {
return screen.RenderTextModeString(a.video, true, false, false, a.hasLowerCase, false)
}
var testTextMode80AltOrder testTextModeFunc = func(a *Apple2) string {
return screen.RenderTextModeString(a.video, true, false, false, a.hasLowerCase, true)
}
func (at *apple2Tester) getText(textMode testTextModeFunc) string {
return textMode(at.a)
}
func (at *apple2Tester) getTextBest() string {
videxMaybe := at.a.cards[3]
if videxMaybe != nil {
if videx, ok := videxMaybe.(*CardVidexVideoterm); ok {
return videx.getText()
}
if videxUltraterm, ok := videxMaybe.(*CardVidexUltraterm); ok {
return videxUltraterm.getText()
}
}
videoMode := at.a.video.GetCurrentVideoMode()
if videoMode&screen.VideoBaseMask == screen.VideoText80 {
return at.getText(testTextMode80)
}
return at.getText(testTextMode40)
}
/*
func buildTerminateConditionCycles(cycles uint64) terminateConditionFunc {
return func(a *Apple2) bool {
return a.cycles() > cycles
}
}
*/
const textCheckInterval = uint64(100_000)
func buildTerminateConditionText(needle string, textMode testTextModeFunc, timeoutCycles uint64) terminateConditionFunc {
needles := []string{needle}
return buildTerminateConditionTexts(needles, textMode, timeoutCycles)
}
func buildTerminateConditionTexts(needles []string, textMode testTextModeFunc, timeoutCycles uint64) terminateConditionFunc {
lastCheck := uint64(0)
found := false
return func(a *Apple2) bool {
cycles := a.GetCycles()
if cycles > timeoutCycles {
return true
}
if cycles-lastCheck > textCheckInterval {
lastCheck = cycles
text := textMode(a)
for _, needle := range needles {
if !strings.Contains(text, needle) {
return false
}
}
found = true
}
return found
}
}