-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathscreen.cpp
More file actions
135 lines (108 loc) · 2.94 KB
/
Copy pathscreen.cpp
File metadata and controls
135 lines (108 loc) · 2.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include <stdint.h>
#include <machine.h>
#include <memory.h>
#include <display.h>
#include <hardware.h>
#include "config.h"
#include "screen.h"
#include CHARSET_ROM
static struct resolution {
const char *name;
const unsigned cw, ch;
} resolutions[] = {
{"40x25", 8, 8},
};
void screen::begin() {
struct resolution &r = resolutions[_resolution];
Display::begin(BG_COLOUR, FG_COLOUR, ORIENT, CHARS_PER_LINE*r.cw, SCREEN_LINES*r.ch);
Display::clear();
memset(_mem, ' ', sizeof(_mem));
}
void screen::set_upper(bool u) {
if (u != _upr) {
_upr = u;
_redraw();
}
}
void screen::_redraw() {
struct resolution &r = resolutions[_resolution];
for (Memory::address a = 0; a < CHARS_PER_LINE * SCREEN_LINES; a++) {
uint8_t c = _mem[a];
unsigned x = r.cw * (a % CHARS_PER_LINE);
unsigned y = r.ch * (a / CHARS_PER_LINE);
uint8_t ch = (c & 0x7f);
bool invert = (c & 0x80);
if (_upr)
ch |= 0x80;
for (unsigned j = 0; j < r.ch; j++) {
uint8_t b = pgm_read_byte(&charset[ch][j]);
if (invert)
b = ~b;
for (unsigned bit = 0; bit < 8; bit++)
drawPixel(x + (7 - bit), y + j, (b & (1 << bit)) ? FG_COLOUR : BG_COLOUR);
}
}
}
/*
* c is "nearly" the character to be written at address a:
* bit 7 of c indicates whether it should be inverted (reverse video)
* bit 1 of VIA register CA2 indicates whether the displayed character
* should be taken from the lower- or upper-half of the character set;
* this bit is set by POKE 59468, 14 and reset by POKE 59468, 12.
*/
void screen::_set(Memory::address a, uint8_t c)
{
a %= (CHARS_PER_LINE * SCREEN_LINES);
uint8_t cm = _mem[a];
if (c == cm)
return;
struct resolution &r = resolutions[_resolution];
unsigned x = r.cw * (a % CHARS_PER_LINE);
unsigned y = r.ch * (a / CHARS_PER_LINE);
uint8_t ch = (c & 0x7f);
bool invert = (c & 0x80), inverted = (cm & 0x80);
cm &= 0x7f;
if (_upr) {
ch |= 0x80;
cm |= 0x80;
}
for (unsigned j = 0; j < r.ch; j++) {
uint8_t b = pgm_read_byte(&charset[ch][j]);
if (invert)
b = ~b;
uint8_t m = pgm_read_byte(&charset[cm][j]);
if (inverted)
m = ~m;
if (b != m) {
uint8_t d = (b ^ m);
if (d & 1)
drawPixel(x + 7, y + j, (b & 1)? FG_COLOUR: BG_COLOUR);
if (d & 2)
drawPixel(x + 6, y + j, (b & 2)? FG_COLOUR: BG_COLOUR);
if (d & 4)
drawPixel(x + 5, y + j, (b & 4)? FG_COLOUR: BG_COLOUR);
if (d & 8)
drawPixel(x + 4, y + j, (b & 8)? FG_COLOUR: BG_COLOUR);
if (d & 16)
drawPixel(x + 3, y + j, (b & 16)? FG_COLOUR: BG_COLOUR);
if (d & 32)
drawPixel(x + 2, y + j, (b & 32)? FG_COLOUR: BG_COLOUR);
if (d & 64)
drawPixel(x + 1, y + j, (b & 64)? FG_COLOUR: BG_COLOUR);
if (d & 128)
drawPixel(x + 0, y + j, (b & 128)? FG_COLOUR: BG_COLOUR);
}
}
_mem[a] = c;
}
void screen::checkpoint(Checkpoint &s) {
s.write(_resolution);
s.write(_upr);
s.write(_mem, sizeof(_mem));
}
void screen::restore(Checkpoint &s) {
s.read(_resolution);
s.read(_upr);
s.read(_mem, sizeof(_mem));
_redraw();
}