MC6845 Cursor modes
This commit is contained in:
parent
f15a7bb9d2
commit
c390be1ced
20
cardVidex.go
20
cardVidex.go
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
"image/color"
|
"image/color"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ivanizag/izapple2/component"
|
"github.com/ivanizag/izapple2/component"
|
||||||
"github.com/ivanizag/izapple2/storage"
|
"github.com/ivanizag/izapple2/storage"
|
||||||
|
@ -125,22 +126,37 @@ func (c *CardVidex) buildImage(light color.Color) *image.RGBA {
|
||||||
img.Set(1, 1, color.White)
|
img.Set(1, 1, color.White)
|
||||||
return img
|
return img
|
||||||
}
|
}
|
||||||
|
ms := time.Now().Nanosecond() / (1000 * 1000) // Host time, used for the cursoR blink
|
||||||
|
|
||||||
size := image.Rect(0, 0, width, height)
|
size := image.Rect(0, 0, width, height)
|
||||||
img := image.NewRGBA(size)
|
img := image.NewRGBA(size)
|
||||||
|
|
||||||
params.IterateScreen(func(address uint16, charLine uint8,
|
params.IterateScreen(func(address uint16, charLine uint8,
|
||||||
cursor bool, displayEnable bool,
|
cursorMode uint8, displayEnable bool,
|
||||||
column uint8, y int) {
|
column uint8, y int) {
|
||||||
|
|
||||||
bits := uint8(0)
|
bits := uint8(0)
|
||||||
if displayEnable {
|
if displayEnable {
|
||||||
char := c.sram[address&0x7ff]
|
char := c.sram[address&0x7ff]
|
||||||
bits = c.charGen[(uint16(char&0x7f)<<4)+uint16(charLine)]
|
bits = c.charGen[(uint16(char&0x7f)<<4)+uint16(charLine)]
|
||||||
if cursor {
|
isCursor := false
|
||||||
|
switch cursorMode {
|
||||||
|
case component.MC6845CursorFixed:
|
||||||
|
isCursor = true
|
||||||
|
case component.MC6845CursorSlow:
|
||||||
|
// It should be 533ms (32/60, 32 screen refreshes)
|
||||||
|
// Let's make a 2 blinks per second
|
||||||
|
isCursor = ms/2 > 1000/4
|
||||||
|
case component.MC6845CursorFast:
|
||||||
|
// It should be 266ms (32/60, 16 screen refreshes)
|
||||||
|
// Let's make a 4 blinks per second
|
||||||
|
isCursor = ms/4 > 1000/8
|
||||||
|
}
|
||||||
|
if isCursor {
|
||||||
bits = ^bits
|
bits = ^bits
|
||||||
}
|
}
|
||||||
if char >= 128 {
|
if char >= 128 {
|
||||||
|
// Inverse
|
||||||
bits = ^bits
|
bits = ^bits
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,10 +51,17 @@ func (m *MC6845) ImageData() MC6845ImageData {
|
||||||
data.cursorPos = uint16(m.reg[14]&0x3f)<<8 + uint16(m.reg[15])
|
data.cursorPos = uint16(m.reg[14]&0x3f)<<8 + uint16(m.reg[15])
|
||||||
data.cursorStart = m.reg[10] & 0x1f
|
data.cursorStart = m.reg[10] & 0x1f
|
||||||
data.cursorEnd = m.reg[11] & 0x1f
|
data.cursorEnd = m.reg[11] & 0x1f
|
||||||
// cursor mode is on bits 6 and 5 of R10
|
data.cursorMode = (m.reg[10] >> 5) & 0x03 // Bit 6 and 5
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
MC6845CursorFixed = uint8(0)
|
||||||
|
MC6845CursorNone = uint8(1)
|
||||||
|
MC6845CursorFast = uint8(2)
|
||||||
|
MC6845CursorSlow = uint8(3)
|
||||||
|
)
|
||||||
|
|
||||||
type MC6845ImageData struct {
|
type MC6845ImageData struct {
|
||||||
firstChar uint16 // 14 bits, address of the firt char on the first line
|
firstChar uint16 // 14 bits, address of the firt char on the first line
|
||||||
charLines uint8 // 5 bits, lines par character
|
charLines uint8 // 5 bits, lines par character
|
||||||
|
@ -64,8 +71,8 @@ type MC6845ImageData struct {
|
||||||
|
|
||||||
cursorPos uint16 // 14 bits, address? of the cursor position
|
cursorPos uint16 // 14 bits, address? of the cursor position
|
||||||
cursorStart uint8 // 5 bits, cursor starting char row
|
cursorStart uint8 // 5 bits, cursor starting char row
|
||||||
cursorEnd uint8 // 5 bits, cursos ending char row
|
cursorEnd uint8 // 5 bits, cursor ending char row
|
||||||
// cursor mode
|
cursorMode uint8 // 2 bits, cursor mode
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +82,7 @@ func (data *MC6845ImageData) DisplayedWidthHeight(charWidth uint8) (int, int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type MC6845RasterCallBack func(address uint16, charLine uint8, // Lookup in char ROM
|
type MC6845RasterCallBack func(address uint16, charLine uint8, // Lookup in char ROM
|
||||||
cursor bool, displayEnable bool, // Modifiers
|
cursorMode uint8, displayEnable bool, // Modifiers
|
||||||
column uint8, y int) // Position in screen
|
column uint8, y int) // Position in screen
|
||||||
|
|
||||||
func (data *MC6845ImageData) IterateScreen(callBack MC6845RasterCallBack) {
|
func (data *MC6845ImageData) IterateScreen(callBack MC6845RasterCallBack) {
|
||||||
|
@ -86,10 +93,15 @@ func (data *MC6845ImageData) IterateScreen(callBack MC6845RasterCallBack) {
|
||||||
for charLine := uint8(0); charLine < data.charLines; charLine++ {
|
for charLine := uint8(0); charLine < data.charLines; charLine++ {
|
||||||
address = lineAddress // Back to the first char of the line
|
address = lineAddress // Back to the first char of the line
|
||||||
for column := uint8(0); column < data.columns; column++ {
|
for column := uint8(0); column < data.columns; column++ {
|
||||||
|
cursorMode := MC6845CursorNone
|
||||||
isCursor := (address == data.cursorPos) &&
|
isCursor := (address == data.cursorPos) &&
|
||||||
(charLine >= data.cursorStart) &&
|
(charLine >= data.cursorStart) &&
|
||||||
(charLine <= data.cursorEnd)
|
(charLine <= data.cursorEnd)
|
||||||
callBack(address, charLine, isCursor, true, column, y)
|
if isCursor {
|
||||||
|
cursorMode = data.cursorMode
|
||||||
|
}
|
||||||
|
|
||||||
|
callBack(address, charLine, cursorMode, true, column, y)
|
||||||
address = (address + 1) & 0x3fff // 14 bits
|
address = (address + 1) & 0x3fff // 14 bits
|
||||||
}
|
}
|
||||||
y++
|
y++
|
||||||
|
@ -98,7 +110,7 @@ func (data *MC6845ImageData) IterateScreen(callBack MC6845RasterCallBack) {
|
||||||
}
|
}
|
||||||
for adjust := uint8(0); adjust <= data.adjustLines; adjust++ {
|
for adjust := uint8(0); adjust <= data.adjustLines; adjust++ {
|
||||||
for column := uint8(0); column < data.columns; column++ {
|
for column := uint8(0); column < data.columns; column++ {
|
||||||
callBack(0, 0, false, false, column, y) // lines with display not enabled
|
callBack(0, 0, MC6845CursorNone, false, column, y) // lines with display not enabled
|
||||||
}
|
}
|
||||||
y++
|
y++
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue