mirror of
https://github.com/ivanizag/izapple2.git
synced 2024-12-22 09:30:19 +00:00
F6 to toggle mono/color modes
This commit is contained in:
parent
9247ae02af
commit
6fca02da6b
@ -20,6 +20,7 @@ type Apple2 struct {
|
||||
activeSlot int // Slot that has the addressing 0xc800 to 0ccfff
|
||||
commandChannel chan int
|
||||
cycleDurationNs float64 // Inverse of the cpu clock in Ghz
|
||||
isColor bool
|
||||
}
|
||||
|
||||
const (
|
||||
@ -29,7 +30,7 @@ const (
|
||||
)
|
||||
|
||||
// NewApple2 instantiates an apple2
|
||||
func NewApple2(romFile string, charRomFile string, clockMhz float64, panicSS bool) *Apple2 {
|
||||
func NewApple2(romFile string, charRomFile string, clockMhz float64, isColor bool, panicSS bool) *Apple2 {
|
||||
var a Apple2
|
||||
a.mmu = newMemoryManager(&a)
|
||||
a.cpu = core6502.NewNMOS6502(a.mmu)
|
||||
@ -39,6 +40,7 @@ func NewApple2(romFile string, charRomFile string, clockMhz float64, panicSS boo
|
||||
}
|
||||
a.mmu.resetRomPaging()
|
||||
a.commandChannel = make(chan int, 100)
|
||||
a.isColor = isColor
|
||||
a.panicSS = panicSS
|
||||
|
||||
if clockMhz <= 0 {
|
||||
@ -91,6 +93,8 @@ func (a *Apple2) SetKeyboardProvider(kb KeyboardProvider) {
|
||||
const (
|
||||
// CommandToggleSpeed toggles cpu speed between full speed and actual Apple II speed
|
||||
CommandToggleSpeed = iota + 1
|
||||
// CommandToggleColor toggles between NTSC color TV and Green phospor monitor
|
||||
CommandToggleColor
|
||||
)
|
||||
|
||||
// SendCommand enqueues a command to the emulator thread
|
||||
@ -108,6 +112,8 @@ func (a *Apple2) executeCommand(command int) {
|
||||
fmt.Println("Fast")
|
||||
a.cycleDurationNs = 0
|
||||
}
|
||||
case CommandToggleColor:
|
||||
a.isColor = !a.isColor
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ References:
|
||||
|
||||
// Snapshot the currently visible screen
|
||||
func Snapshot(a *Apple2) *image.RGBA {
|
||||
isColor := a.isColor
|
||||
isTextMode := a.io.isSoftSwitchActive(ioFlagText)
|
||||
isHiResMode := a.io.isSoftSwitchActive(ioFlagHiRes)
|
||||
isMixMode := a.io.isSoftSwitchActive(ioFlagMixed)
|
||||
@ -26,32 +27,36 @@ func Snapshot(a *Apple2) *image.RGBA {
|
||||
pageIndex = 1
|
||||
}
|
||||
|
||||
var lightColor color.Color
|
||||
if isColor {
|
||||
lightColor = color.White
|
||||
} else {
|
||||
// Color for typical Apple ][ period green P1 phosphor monitors
|
||||
// See: https://superuser.com/questions/361297/what-colour-is-the-dark-green-on-old-fashioned-green-screen-computer-displays
|
||||
lightColor = color.RGBA{65, 255, 0, 255}
|
||||
|
||||
}
|
||||
|
||||
var snap *image.RGBA
|
||||
if isTextMode {
|
||||
// Color for typical Apple ][ period green phosphor monitors
|
||||
// See: https://superuser.com/questions/361297/what-colour-is-the-dark-green-on-old-fashioned-green-screen-computer-displays
|
||||
p1GreenPhosphorColor := color.RGBA{65, 255, 0, 255}
|
||||
|
||||
snap = snapshotTextMode(a, pageIndex, false, p1GreenPhosphorColor)
|
||||
snap = linesSeparatedFilter(snap)
|
||||
snap = snapshotTextMode(a, pageIndex, false, lightColor)
|
||||
} else {
|
||||
if isHiResMode {
|
||||
//snap = snapshotHiResModeReferenceMono(a, pageIndex, isMixMode)
|
||||
//snap = snapshotHiResModeReferenceColor(a, pageIndex, isMixMode)
|
||||
//snap = snapshotHiResModeReferenceColorSolid(a, pageIndex, isMixMode)
|
||||
snap = snapshotHiResModeMonoShift(a, pageIndex, isMixMode)
|
||||
snap = snapshotHiResModeMonoShift(a, pageIndex, isMixMode, lightColor)
|
||||
} else {
|
||||
// Lo res mode not supported
|
||||
return nil
|
||||
}
|
||||
if isMixMode {
|
||||
snapText := snapshotTextMode(a, pageIndex, isHiResMode, color.White)
|
||||
snapText := snapshotTextMode(a, pageIndex, isHiResMode, lightColor)
|
||||
snap = mixSnapshots(snap, snapText)
|
||||
}
|
||||
//snap = filterNTSCColorStatic(snap)
|
||||
snap = filterNTSCColorMoving(false /*blacker*/, snap)
|
||||
snap = linesSeparatedFilter(snap)
|
||||
if isColor {
|
||||
snap = filterNTSCColor(false /*blacker*/, snap)
|
||||
}
|
||||
}
|
||||
|
||||
snap = linesSeparatedFilter(snap)
|
||||
return snap
|
||||
}
|
||||
|
||||
|
@ -37,37 +37,7 @@ func getGraphLine(a *Apple2, line int, page int) []uint8 {
|
||||
return memPage[lo : lo+40]
|
||||
}
|
||||
|
||||
func snapshotHiResModeReferenceMono(a *Apple2, page int, mixedMode bool) *image.RGBA {
|
||||
// As defined on "Apple II Reference Manual", page 19
|
||||
|
||||
height := graphHeight
|
||||
if mixedMode {
|
||||
height = graphHeightMixed
|
||||
}
|
||||
|
||||
size := image.Rect(0, 0, graphWidth, height)
|
||||
img := image.NewRGBA(size)
|
||||
|
||||
for y := 0; y < height; y++ {
|
||||
bytes := getGraphLine(a, y, page)
|
||||
x := 0
|
||||
for _, b := range bytes {
|
||||
for j := uint(0); j < 7; j++ {
|
||||
bit := (b >> j) & 1
|
||||
colour := color.Black
|
||||
if bit == 1 {
|
||||
colour = color.White
|
||||
}
|
||||
img.Set(x, y, colour)
|
||||
x++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return img
|
||||
}
|
||||
|
||||
func snapshotHiResModeMonoShift(a *Apple2, page int, mixedMode bool) *image.RGBA {
|
||||
func snapshotHiResModeMonoShift(a *Apple2, page int, mixedMode bool, light color.Color) *image.RGBA {
|
||||
// As described in "Undertanding the Apple II", with half pixel shifts
|
||||
|
||||
height := graphHeight
|
||||
@ -81,14 +51,14 @@ func snapshotHiResModeMonoShift(a *Apple2, page int, mixedMode bool) *image.RGBA
|
||||
for y := 0; y < height; y++ {
|
||||
bytes := getGraphLine(a, y, page)
|
||||
x := 0
|
||||
previousColour := color.Black
|
||||
var previousColour color.Color = color.Black
|
||||
for _, b := range bytes {
|
||||
shifted := b>>7 == 1
|
||||
for j := uint(0); j < 7; j++ {
|
||||
bit := (b >> j) & 1
|
||||
colour := color.Black
|
||||
if bit == 1 {
|
||||
colour = color.White
|
||||
colour := light
|
||||
if bit == 0 {
|
||||
colour = color.Black
|
||||
}
|
||||
|
||||
if shifted {
|
||||
|
@ -53,31 +53,7 @@ func getNTSCColorMap() []color.Color {
|
||||
return colorMap
|
||||
}
|
||||
|
||||
func filterNTSCColorStatic(in *image.RGBA) *image.RGBA {
|
||||
colorMap := getNTSCColorMap()
|
||||
|
||||
b := in.Bounds()
|
||||
size := image.Rect(0, 0, b.Dx()/4, b.Dy())
|
||||
out := image.NewRGBA(size)
|
||||
for y := b.Min.Y; y < b.Max.Y; y++ {
|
||||
for x := b.Min.X; x < b.Max.X; x += 4 {
|
||||
v := 0
|
||||
for i := 0; i < 4; i++ {
|
||||
cIn := in.At(x+i, y)
|
||||
r, _, _, _ := cIn.RGBA()
|
||||
v = v << 1
|
||||
if r != 0 {
|
||||
v++
|
||||
}
|
||||
}
|
||||
cOut := colorMap[v]
|
||||
out.Set(x/4, y, cOut)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func filterNTSCColorMoving(blacker bool, in *image.RGBA) *image.RGBA {
|
||||
func filterNTSCColor(blacker bool, in *image.RGBA) *image.RGBA {
|
||||
colorMap := getNTSCColorMap()
|
||||
|
||||
b := in.Bounds()
|
||||
|
@ -91,6 +91,8 @@ func (k *sdlKeyboard) putKey(keyEvent *sdl.KeyboardEvent) {
|
||||
// Control of the emulator
|
||||
case sdl.K_F5:
|
||||
k.a.SendCommand(apple2.CommandToggleSpeed)
|
||||
case sdl.K_F6:
|
||||
k.a.SendCommand(apple2.CommandToggleColor)
|
||||
}
|
||||
|
||||
// Missing values 91 to 95. Usually control for [\]^_
|
||||
|
9
main.go
9
main.go
@ -22,7 +22,7 @@ func main() {
|
||||
cpuClock := flag.Float64(
|
||||
"mhz",
|
||||
apple2.CpuClockMhz,
|
||||
"cpu speed in Mhz, use 0 for full speed")
|
||||
"cpu speed in Mhz, use 0 for full speed. Use F5 to toggle.")
|
||||
charRomFile := flag.String(
|
||||
"charRom",
|
||||
"apple2/romdumps/Apple2rev7CharGen.rom",
|
||||
@ -35,6 +35,11 @@ func main() {
|
||||
"stdout",
|
||||
false,
|
||||
"show the text screen on the standard output")
|
||||
mono := flag.Bool(
|
||||
"mono",
|
||||
false,
|
||||
"emulate a green phosphor monitor instead of a NTSC color TV. Use F6 to toggle.",
|
||||
)
|
||||
panicSS := flag.Bool(
|
||||
"panicss",
|
||||
false,
|
||||
@ -53,7 +58,7 @@ func main() {
|
||||
}
|
||||
|
||||
log := false
|
||||
a := apple2.NewApple2(*romFile, *charRomFile, *cpuClock, *panicSS)
|
||||
a := apple2.NewApple2(*romFile, *charRomFile, *cpuClock, !*mono, *panicSS)
|
||||
a.AddDisk2(*disk2RomFile, *diskImage)
|
||||
if *useSdl {
|
||||
a.ConfigureStdConsole(false, *stdoutScreen)
|
||||
|
Loading…
Reference in New Issue
Block a user