180 lines
4.3 KiB
Go
180 lines
4.3 KiB
Go
package optimizer
|
|
|
|
import (
|
|
"testing"
|
|
"c65gm/internal/preproc"
|
|
)
|
|
|
|
func TestNewConfigWithAll(t *testing.T) {
|
|
ps := preproc.NewPragmaSet(map[string]string{
|
|
"_P_OPT_ALL": "1",
|
|
"_P_OPT_DEBUG": "1",
|
|
})
|
|
cfg := NewConfig(ps)
|
|
if !cfg.Any() {
|
|
t.Error("expected Any()=true")
|
|
}
|
|
if !cfg.EnableLoad {
|
|
t.Error("expected EnableLoad=true from _P_OPT_ALL")
|
|
}
|
|
if !cfg.EnableImm {
|
|
t.Error("expected EnableImm=true from _P_OPT_ALL")
|
|
}
|
|
if !cfg.Debug {
|
|
t.Error("expected Debug=true")
|
|
}
|
|
}
|
|
|
|
func TestParseExcludeRange(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input string
|
|
wantOk bool
|
|
wantS uint16
|
|
wantE uint16
|
|
}{
|
|
{"hex", "0xD000:0xDFFF", true, 0xD000, 0xDFFF},
|
|
{"hex lowercase", "0xd000:0xdfff", true, 0xD000, 0xDFFF},
|
|
{"hex mixed case", "0XD000:0XdFfF", true, 0xD000, 0xDFFF},
|
|
{"decimal", "53248:57343", true, 53248, 57343},
|
|
{"single address", "0xD020:0xD020", true, 0xD020, 0xD020},
|
|
{"invalid range", "0xFFFF:0x0000", false, 0, 0},
|
|
{"bad format", "garbage", false, 0, 0},
|
|
{"bad hex", "0xGGGG:0x0000", false, 0, 0},
|
|
{"too many colons", "0xD000:0xDFFF:extra", false, 0, 0},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
r, err := ParseExcludeRange(tt.input)
|
|
if tt.wantOk {
|
|
if err != nil {
|
|
t.Errorf("unexpected error: %v", err)
|
|
}
|
|
if r.Start != tt.wantS || r.End != tt.wantE {
|
|
t.Errorf("got %04X:%04X, want %04X:%04X", r.Start, r.End, tt.wantS, tt.wantE)
|
|
}
|
|
} else {
|
|
if err == nil {
|
|
t.Errorf("expected error, got %04X:%04X", r.Start, r.End)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAddIORegions(t *testing.T) {
|
|
cfg := &Config{}
|
|
cfg.AddIORegions([]IORegion{
|
|
{Start: 0xD000, End: 0xDFFF},
|
|
})
|
|
|
|
if !cfg.IOMap[0xD000] {
|
|
t.Error("expected 0xD000 to be marked I/O")
|
|
}
|
|
if !cfg.IOMap[0xDFFF] {
|
|
t.Error("expected 0xDFFF to be marked I/O")
|
|
}
|
|
if cfg.IOMap[0xCFFF] {
|
|
t.Error("expected 0xCFFF to NOT be marked I/O")
|
|
}
|
|
if cfg.IOMap[0xE000] {
|
|
t.Error("expected 0xE000 to NOT be marked I/O")
|
|
}
|
|
}
|
|
|
|
func TestAddIORegionsMultiple(t *testing.T) {
|
|
cfg := &Config{}
|
|
cfg.AddIORegions([]IORegion{
|
|
{Start: 0xD000, End: 0xDFFF},
|
|
{Start: 0xDC00, End: 0xDC0F}, // overlaps — still correct
|
|
})
|
|
|
|
if !cfg.IOMap[0xD000] {
|
|
t.Error("expected 0xD000 I/O")
|
|
}
|
|
if !cfg.IOMap[0xDC00] {
|
|
t.Error("expected 0xDC00 I/O")
|
|
}
|
|
if !cfg.IOMap[0xDC0F] {
|
|
t.Error("expected 0xDC0F I/O")
|
|
}
|
|
}
|
|
|
|
func TestBuildIOMap(t *testing.T) {
|
|
p := preproc.NewPragma()
|
|
p.AddPragma("_P_OPT_IO", "$D000 $DFFF")
|
|
|
|
// Last pragma set should have _P_OPT_IO
|
|
ps := p.GetPragmaSetByIndex(p.GetCurrentPragmaSetIndex())
|
|
cfg := NewConfig(ps)
|
|
cfg.BuildIOMap(p)
|
|
|
|
if !cfg.IOMap[0xD000] {
|
|
t.Error("expected $D000 I/O from pragma")
|
|
}
|
|
if !cfg.IOMap[0xDFFF] {
|
|
t.Error("expected $DFFF I/O from pragma")
|
|
}
|
|
}
|
|
|
|
func TestBuildIOMapMultiple(t *testing.T) {
|
|
// Simulate two _P_OPT_IO pragmas
|
|
p := preproc.NewPragma()
|
|
p.AddPragma("_P_OPT_IO", "$D000 $DFFF")
|
|
p.AddPragma("_P_OPT_IO", "$DC00 $DC0F")
|
|
p.AddPragma("_P_SOMETHING_ELSE", "1")
|
|
|
|
// BuildIOMap scans ALL sets, finding _P_OPT_IO at index 1 and 2
|
|
ps := p.GetPragmaSetByIndex(p.GetCurrentPragmaSetIndex())
|
|
cfg := NewConfig(ps)
|
|
cfg.BuildIOMap(p)
|
|
|
|
if !cfg.IOMap[0xD000] {
|
|
t.Error("expected $D000 I/O")
|
|
}
|
|
if !cfg.IOMap[0xDC00] {
|
|
t.Error("expected $DC00 I/O")
|
|
}
|
|
}
|
|
|
|
func TestBuildIOMapEmpty(t *testing.T) {
|
|
p := preproc.NewPragma()
|
|
ps := p.GetPragmaSetByIndex(p.GetCurrentPragmaSetIndex())
|
|
cfg := NewConfig(ps)
|
|
cfg.BuildIOMap(p)
|
|
|
|
for _, addr := range []uint16{0, 0xD000, 0xFFFF} {
|
|
if cfg.IOMap[addr] {
|
|
t.Errorf("address %04X should not be I/O", addr)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestNewConfigPragmasAccumulate(t *testing.T) {
|
|
// Pragma sets COPY previous values — so last set has ALL pragmas
|
|
p := preproc.NewPragma()
|
|
p.AddPragma("_P_OPT_ALL", "1")
|
|
p.AddPragma("_P_OPT_DEBUG", "1")
|
|
p.AddPragma("_P_SOMETHING_ELSE", "1")
|
|
|
|
// Last set should have all three
|
|
ps := p.GetPragmaSetByIndex(p.GetCurrentPragmaSetIndex())
|
|
if v := ps.GetPragma("_P_OPT_ALL"); v != "1" {
|
|
t.Errorf("expected _P_OPT_ALL=1, got %q", v)
|
|
}
|
|
if v := ps.GetPragma("_P_OPT_DEBUG"); v != "1" {
|
|
t.Errorf("expected _P_OPT_DEBUG=1, got %q", v)
|
|
}
|
|
if v := ps.GetPragma("_P_SOMETHING_ELSE"); v != "1" {
|
|
t.Errorf("expected _P_SOMETHING_ELSE=1, got %q", v)
|
|
}
|
|
|
|
cfg := NewConfig(ps)
|
|
if !cfg.Any() {
|
|
t.Error("expected Any()=true")
|
|
}
|
|
if !cfg.Debug {
|
|
t.Error("expected Debug=true")
|
|
}
|
|
}
|