izapple2/characterGenerator.go

108 lines
2.4 KiB
Go
Raw Permalink Normal View History

2020-10-03 21:38:26 +00:00
package izapple2
2019-04-21 16:18:43 +00:00
import (
2019-10-05 23:26:00 +00:00
"errors"
2024-01-06 20:48:23 +00:00
"fmt"
2019-04-21 16:18:43 +00:00
)
/*
See:
2019-10-12 19:37:37 +00:00
https://mirrors.apple2.org.za/Apple%20II%20Documentation%20Project/Companies/Apple/Documentation/Apple%20Technical%20Information%20Library/a2til041.txt
2019-04-21 16:18:43 +00:00
*/
// CharacterGenerator represents the ROM wth the characters bitmaps
type CharacterGenerator struct {
data []uint8
columnMap charColumnMap
page int
2021-10-12 10:26:40 +00:00
pageSize int
2019-04-21 16:18:43 +00:00
}
type charColumnMap func(column int) int
2019-10-12 19:37:37 +00:00
func charGenColumnsMap2Plus(column int) int {
return 6 - column
}
func charGenColumnsMap2e(column int) int {
return column
}
2019-04-21 16:18:43 +00:00
const (
2021-10-12 10:26:40 +00:00
charGenPageSize2Plus = 2048
charGenPageSize2E = 2048 * 2
2019-04-21 16:18:43 +00:00
)
// NewCharacterGenerator instantiates a new Character Generator with the rom on the file given
2024-01-06 20:48:23 +00:00
func newCharacterGenerator(filename string, order charColumnMap, pageSize int) (*CharacterGenerator, error) {
2019-04-21 16:18:43 +00:00
var cg CharacterGenerator
2021-10-12 10:26:40 +00:00
cg.columnMap = order
2024-01-06 20:48:23 +00:00
cg.pageSize = pageSize
2019-10-05 23:26:00 +00:00
err := cg.load(filename)
if err != nil {
return nil, err
}
2021-10-12 10:26:40 +00:00
2019-10-05 23:26:00 +00:00
return &cg, nil
2019-04-21 16:18:43 +00:00
}
2019-10-05 23:26:00 +00:00
func (cg *CharacterGenerator) load(filename string) error {
2022-01-28 18:25:52 +00:00
bytes, _, err := LoadResource(filename)
2019-10-05 23:26:00 +00:00
if err != nil {
return err
}
2019-05-15 14:01:04 +00:00
size := len(bytes)
2021-10-12 10:26:40 +00:00
if size < cg.pageSize {
2021-08-05 19:12:52 +00:00
return errors.New("character ROM size not supported")
2019-04-21 16:18:43 +00:00
}
2019-05-15 14:01:04 +00:00
cg.data = bytes
2019-10-05 23:26:00 +00:00
return nil
2019-04-21 16:18:43 +00:00
}
func (cg *CharacterGenerator) setPage(page int) {
// Some clones had a switch to change codepage with extra characters
2021-10-12 10:26:40 +00:00
pages := len(cg.data) / cg.pageSize
cg.page = page % pages
}
2021-10-12 10:26:40 +00:00
func (cg *CharacterGenerator) getPage() int {
return cg.page
}
func (cg *CharacterGenerator) nextPage() {
cg.setPage(cg.page + 1)
}
2019-04-21 19:04:02 +00:00
func (cg *CharacterGenerator) getPixel(char uint8, row int, column int) bool {
2021-10-12 10:26:40 +00:00
bits := cg.data[int(char)*8+row+cg.page*cg.pageSize]
2019-10-12 19:37:37 +00:00
bit := cg.columnMap(column)
value := bits >> uint(bit) & 1
return value == 1
2019-04-21 19:04:02 +00:00
}
2024-01-06 20:48:23 +00:00
func setupCharactedGenerator(a *Apple2, board string, charRomFile string) error {
var charGenMap charColumnMap
initialCharGenPage := 0
pageSize := charGenPageSize2Plus
switch board {
case "2plus":
charGenMap = charGenColumnsMap2Plus
case "2e":
charGenMap = charGenColumnsMap2e
pageSize = charGenPageSize2E
case "base64a":
charGenMap = charGenColumnsMapBase64a
initialCharGenPage = 1
default:
return fmt.Errorf("board %s not supported it must be '2plus', '2e' or 'base64a'", board)
}
cg, err := newCharacterGenerator(charRomFile, charGenMap, pageSize)
if err != nil {
return err
}
cg.setPage(initialCharGenPage)
a.cg = cg
return nil
}