F6 to toggle mono/color modes

This commit is contained in:
Ivan Izaguirre 2019-05-05 13:25:45 +02:00
parent 9247ae02af
commit 6fca02da6b
6 changed files with 41 additions and 77 deletions

View File

@ -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
}
}

View File

@ -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
}

View File

@ -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 {

View File

@ -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()

View File

@ -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 [\]^_

View File

@ -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)