Skip to content

Commit 8526e78

Browse files
committed
better savekey debugging windows
1 parent b76abf6 commit 8526e78

File tree

9 files changed

+804
-277
lines changed

9 files changed

+804
-277
lines changed

gui/sdlimgui/colors.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,13 @@ type imguiColors struct {
8989
// chip registers window
9090
RegisterBit imgui.Vec4
9191

92+
// savekey i2c/eeprom window
93+
SaveKeyBit imgui.Vec4
94+
SaveKeyOscBG imgui.Vec4
95+
SaveKeyOscSCL imgui.Vec4
96+
SaveKeyOscSDA imgui.Vec4
97+
SaveKeyBitPointer imgui.Vec4
98+
9299
// terminal
93100
TermBackground imgui.Vec4
94101
TermStyleEcho imgui.Vec4
@@ -166,6 +173,13 @@ func newColors() *imguiColors {
166173

167174
// deferring chip registers window RegisterBit
168175

176+
// deferring savekey i2c/eeprom window RegisterBit
177+
178+
SaveKeyOscBG: imgui.Vec4{0.21, 0.29, 0.23, 1.0},
179+
SaveKeyOscSCL: imgui.Vec4{0.10, 0.97, 0.29, 1.0},
180+
SaveKeyOscSDA: imgui.Vec4{0.97, 0.10, 0.29, 1.0},
181+
SaveKeyBitPointer: imgui.Vec4{0.8, 0.8, 0.8, 1.0},
182+
169183
// terminal
170184
TermBackground: imgui.Vec4{0.1, 0.1, 0.2, 0.9},
171185
TermStyleEcho: imgui.Vec4{0.8, 0.8, 0.8, 1.0},
@@ -196,6 +210,7 @@ func newColors() *imguiColors {
196210
cols.DisasmBreakOther = cols.DisasmMnemonic
197211
cols.CollisionBit = imgui.CurrentStyle().Color(imgui.StyleColorButton)
198212
cols.RegisterBit = imgui.CurrentStyle().Color(imgui.StyleColorButton)
213+
cols.SaveKeyBit = imgui.CurrentStyle().Color(imgui.StyleColorButton)
199214

200215
// convert 2600 colours to format usable by imgui
201216

gui/sdlimgui/lazyvalues/savekey.go

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,29 @@ import (
2525
type LazySaveKey struct {
2626
val *Lazy
2727

28-
SaveKeyActive bool
28+
atomicSaveKeyActive atomic.Value // bool
29+
SaveKeyActive bool
2930

30-
atomicSDA atomic.Value // []float32
31-
atomicSCL atomic.Value // []float32
32-
SDA []float32
33-
SCL []float32
31+
atomicSDA atomic.Value // []float32
32+
atomicSCL atomic.Value // []float32
33+
atomicState atomic.Value // savekey.MessageState
34+
atomicDir atomic.Value // savekey.DataDirection
35+
atomicAck atomic.Value // bool
36+
atomicBits atomic.Value // uint8
37+
atomicBitsCt atomic.Value // int
38+
atomicAddress atomic.Value // uint16
39+
atomicEEPROMdata atomic.Value // []uint8
40+
atomicDirty atomic.Value // bool
41+
SDA []float32
42+
SCL []float32
43+
State savekey.MessageState
44+
Dir savekey.DataDirection
45+
Ack bool
46+
Bits uint8
47+
BitsCt int
48+
Address uint16
49+
EEPROMdata []uint8
50+
Dirty bool
3451
}
3552

3653
func newLazySaveKey(val *Lazy) *LazySaveKey {
@@ -39,19 +56,48 @@ func newLazySaveKey(val *Lazy) *LazySaveKey {
3956

4057
func (lz *LazySaveKey) update() {
4158
lz.val.Dbg.PushRawEvent(func() {
42-
if l, ok := lz.val.Dbg.VCS.RIOT.Ports.Player1.(*savekey.SaveKey); ok {
43-
lz.atomicSDA.Store(l.SDA.Copy())
44-
lz.atomicSCL.Store(l.SCL.Copy())
59+
if sk, ok := lz.val.Dbg.VCS.RIOT.Ports.Player1.(*savekey.SaveKey); ok {
60+
lz.atomicSaveKeyActive.Store(true)
61+
lz.atomicSDA.Store(sk.SDA.Copy())
62+
lz.atomicSCL.Store(sk.SCL.Copy())
63+
lz.atomicState.Store(sk.State)
64+
lz.atomicDir.Store(sk.Dir)
65+
lz.atomicAck.Store(sk.Ack)
66+
lz.atomicBits.Store(sk.Bits)
67+
lz.atomicBitsCt.Store(sk.BitsCt)
68+
lz.atomicAddress.Store(sk.EEPROM.Address)
69+
lz.atomicEEPROMdata.Store(sk.EEPROM.Copy())
70+
lz.atomicDirty.Store(sk.EEPROM.Dirty)
71+
} else {
72+
lz.atomicSaveKeyActive.Store(false)
4573
}
4674
})
4775

76+
if l, ok := lz.atomicSaveKeyActive.Load().(bool); l && ok {
77+
lz.SaveKeyActive = true
78+
} else {
79+
lz.SaveKeyActive = false
80+
return
81+
}
82+
4883
if l, ok := lz.atomicSDA.Load().([]float32); ok {
49-
lz.SaveKeyActive = ok
5084
lz.SDA = l
5185
}
5286

5387
if l, ok := lz.atomicSCL.Load().([]float32); ok {
54-
lz.SaveKeyActive = ok
5588
lz.SCL = l
5689
}
90+
91+
lz.State = lz.atomicState.Load().(savekey.MessageState)
92+
lz.Dir = lz.atomicDir.Load().(savekey.DataDirection)
93+
lz.Ack = lz.atomicAck.Load().(bool)
94+
lz.Bits = lz.atomicBits.Load().(uint8)
95+
lz.BitsCt = lz.atomicBitsCt.Load().(int)
96+
lz.Address = lz.atomicAddress.Load().(uint16)
97+
98+
if l, ok := lz.atomicEEPROMdata.Load().([]uint8); ok {
99+
lz.EEPROMdata = l
100+
}
101+
102+
lz.Dirty = lz.atomicDirty.Load().(bool)
57103
}

gui/sdlimgui/win_chip_registers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ type winChipRegisters struct {
3131

3232
img *SdlImgui
3333

34-
// ready flag colors
34+
// color of bit indicator
3535
regBit imgui.PackedColor
3636
}
3737

gui/sdlimgui/win_savekey.go

Lines changed: 0 additions & 71 deletions
This file was deleted.

gui/sdlimgui/win_savekey_eeprom.go

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
// This file is part of Gopher2600.
2+
//
3+
// Gopher2600 is free software: you can redistribute it and/or modify
4+
// it under the terms of the GNU General Public License as published by
5+
// the Free Software Foundation, either version 3 of the License, or
6+
// (at your option) any later version.
7+
//
8+
// Gopher2600 is distributed in the hope that it will be useful,
9+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
// GNU General Public License for more details.
12+
//
13+
// You should have received a copy of the GNU General Public License
14+
// along with Gopher2600. If not, see <https://www.gnu.org/licenses/>.
15+
16+
package sdlimgui
17+
18+
import (
19+
"fmt"
20+
"strconv"
21+
22+
"github.com/inkyblackness/imgui-go/v2"
23+
"github.com/jetsetilly/gopher2600/hardware/riot/ports/savekey"
24+
)
25+
26+
const winSaveKeyEEPROMTitle = "SaveKey EEPROM"
27+
const menuSaveKeyEEPROMTitle = "EEPROM"
28+
29+
type winSaveKeyEEPROM struct {
30+
windowManagement
31+
widgetDimensions
32+
33+
img *SdlImgui
34+
35+
// height of status line at bottom of window. valid after first frame
36+
statusHeight float32
37+
38+
// the X position of the grid header. based on the width of the column
39+
// headers (we know this value after the first pass)
40+
xPos float32
41+
}
42+
43+
func newWinSaveKeyEEPROM(img *SdlImgui) (managedWindow, error) {
44+
win := &winSaveKeyEEPROM{img: img}
45+
return win, nil
46+
}
47+
48+
func (win *winSaveKeyEEPROM) init() {
49+
win.widgetDimensions.init()
50+
}
51+
52+
func (win *winSaveKeyEEPROM) destroy() {
53+
}
54+
55+
func (win *winSaveKeyEEPROM) id() string {
56+
return winSaveKeyEEPROMTitle
57+
}
58+
59+
func (win *winSaveKeyEEPROM) draw() {
60+
if !win.open {
61+
return
62+
}
63+
64+
if !win.img.lz.SaveKey.SaveKeyActive {
65+
return
66+
}
67+
68+
imgui.SetNextWindowPosV(imgui.Vec2{469, 285}, imgui.ConditionFirstUseEver, imgui.Vec2{0, 0})
69+
imgui.SetNextWindowSizeV(imgui.Vec2{394, 356}, imgui.ConditionFirstUseEver)
70+
imgui.BeginV(winSaveKeyEEPROMTitle, &win.open, 0)
71+
72+
win.drawGrid(winSaveKeyEEPROMTitle, win.img.lz.SaveKey.EEPROMdata)
73+
win.drawStatusLine()
74+
75+
imgui.End()
76+
}
77+
78+
func (win *winSaveKeyEEPROM) drawStatusLine() {
79+
statusHeight := imgui.CursorPosY()
80+
81+
imgui.Spacing()
82+
83+
if imgui.Button("Save to disk") {
84+
win.img.lz.Dbg.PushRawEvent(func() {
85+
if sk, ok := win.img.lz.Dbg.VCS.RIOT.Ports.Player1.(*savekey.SaveKey); ok {
86+
sk.EEPROM.Write()
87+
}
88+
})
89+
}
90+
imgui.SameLine()
91+
92+
imgui.AlignTextToFramePadding()
93+
if win.img.lz.SaveKey.Dirty {
94+
imgui.Text("Data is NOT saved")
95+
} else {
96+
imgui.Text("Data is saved")
97+
}
98+
99+
win.statusHeight = imgui.CursorPosY() - statusHeight
100+
}
101+
102+
func (win *winSaveKeyEEPROM) drawGrid(tag string, a []byte) {
103+
const numberOfColumns = 16
104+
105+
height := imguiRemainingWinHeight() - win.statusHeight
106+
imgui.BeginChildV(tag, imgui.Vec2{X: 0, Y: height}, false, 0)
107+
108+
// no spacing between any of the drawEditByte() objects
109+
imgui.PushStyleVarVec2(imgui.StyleVarItemSpacing, imgui.Vec2{})
110+
111+
// draw headers for each column. this relies on win.xPos, which requires
112+
// one frame before it is accurate.
113+
headerDim := imgui.Vec2{X: win.xPos, Y: imgui.CursorPosY()}
114+
for i := 0; i < numberOfColumns; i++ {
115+
imgui.SetCursorPos(headerDim)
116+
headerDim.X += win.twoDigitDim.X
117+
imgui.AlignTextToFramePadding()
118+
imgui.Text(fmt.Sprintf("-%x", i))
119+
}
120+
121+
// draw rows
122+
var clipper imgui.ListClipper
123+
clipper.Begin(len(a) / numberOfColumns)
124+
for clipper.Step() {
125+
for i := clipper.DisplayStart; i < clipper.DisplayEnd; i++ {
126+
offset := (i * numberOfColumns)
127+
imgui.AlignTextToFramePadding()
128+
imgui.Text(fmt.Sprintf("%03x- ", i))
129+
imgui.SameLine()
130+
win.xPos = imgui.CursorPosX()
131+
132+
imgui.PushItemWidth(win.twoDigitDim.X)
133+
for j := 0; j < numberOfColumns; j++ {
134+
imgui.SameLine()
135+
win.drawEditByte(tag, uint16(offset+j), a[offset+j])
136+
}
137+
imgui.PopItemWidth()
138+
}
139+
}
140+
141+
// finished with spacing setting
142+
imgui.PopStyleVar()
143+
144+
imgui.EndChild()
145+
}
146+
147+
func (win *winSaveKeyEEPROM) drawEditByte(tag string, address uint16, data byte) {
148+
l := fmt.Sprintf("##%d", address)
149+
content := fmt.Sprintf("%02x", data)
150+
151+
if imguiHexInput(l, !win.img.paused, 2, &content) {
152+
if v, err := strconv.ParseUint(content, 16, 8); err == nil {
153+
win.img.lz.Dbg.PushRawEvent(func() {
154+
if sk, ok := win.img.lz.Dbg.VCS.RIOT.Ports.Player1.(*savekey.SaveKey); ok {
155+
sk.EEPROM.Poke(address, uint8(v))
156+
}
157+
})
158+
}
159+
}
160+
}

0 commit comments

Comments
 (0)