-
Notifications
You must be signed in to change notification settings - Fork 2
/
main.go
127 lines (117 loc) · 3.35 KB
/
main.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
123
124
125
126
127
/*
* Copyright (c) 2021 Pontus Rydin
*
* 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.
*/
package main
import (
"flag"
"github.com/beevik/go6502/asm"
"github.com/faiface/pixel"
"github.com/faiface/pixel/pixelgl"
"github.com/prydin/emu6502/computer"
"github.com/prydin/emu6502/screen"
vic_ii "github.com/prydin/emu6502/vic-ii"
"image"
"log"
"os"
"runtime/pprof"
"time"
)
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
var loadasm = flag.String("loadasm", "", "load assembly language file")
var PalFPS = 50.125
var PalFrameTime = time.Duration((1 / PalFPS) * 1e9)
func main() {
flag.Parse()
if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
if err != nil {
log.Fatal(err)
}
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
}
var code *asm.Assembly
var sourceMap *asm.SourceMap
if *loadasm != "" {
in, err := os.Open(*loadasm)
if err != nil {
panic(err)
}
code, sourceMap, err = asm.Assemble(in, *loadasm, os.Stderr, 0)
for _, parseErr := range code.Errors {
println(parseErr)
}
if err != nil {
panic(err)
}
}
pixelgl.Run(func() {
c64 := computer.Commodore64{}
cfg := pixelgl.WindowConfig{
Title: "Gommodore64",
Bounds: pixel.R(0, 0, 1024, 768),
VSync: true,
Resizable: true,
}
win, err := pixelgl.NewWindow(cfg)
if err != nil {
panic(err)
}
win.SetSmooth(true) // Gives a nice blurry retro look!
scr := screen.New(win, image.Rectangle{
Min: image.Point{},
Max: image.Point{vic_ii.PalVisibleWidth, vic_ii.PalVisibleHeight},
})
c64.Cpu.CrashOnInvalidInst = true // TODO: Make configurable
c64.Init(scr, vic_ii.PALDimensions)
c64.Keyboard.SetProvider(win)
//c64.cpu.Trace = true
c64.Cpu.Reset()
var lastVSynch time.Time
n := 0
for {
if c64.Vic.IsVSynch() {
now := time.Now()
frameTime := now.Sub(lastVSynch)
// Sleeping precision is too low, so we spin instead
if frameTime < PalFrameTime {
target := now.Add(PalFrameTime - frameTime)
for time.Now().Before(target) {
// Do nothing
}
}
lastVSynch = time.Now()
}
c64.Clock()
if code != nil && n > 10000000 {
for i := uint16(0); i < uint16(sourceMap.Size); i++ {
c64.Bus.WriteByte(i+sourceMap.Origin, code.Code[i])
}
code = nil
}
if n%1000000 == 0 {
if win.Closed() {
break
}
}
n++
}
})
}