mirror of
https://github.com/jscrane/Apple1.git
synced 2024-12-22 03:30:09 +00:00
Serial display (#11)
* extract disp from io * extract screen_disp * working * ... * working * refactor * config
This commit is contained in:
parent
c7db5b18b4
commit
05f50a18fd
28
Apple1.ino
28
Apple1.ino
@ -7,6 +7,9 @@
|
||||
#include <sd_filer.h>
|
||||
|
||||
#include "io.h"
|
||||
#include "disp.h"
|
||||
#include "screen_disp.h"
|
||||
#include "terminal_disp.h"
|
||||
#include "config.h"
|
||||
|
||||
#if defined(KRUSADER)
|
||||
@ -29,15 +32,16 @@ flash_filer files(PROGRAMS);
|
||||
|
||||
#if defined(PS2_SERIAL_KBD)
|
||||
ps2_serial_kbd kbd;
|
||||
|
||||
#elif defined(HW_SERIAL_KBD)
|
||||
hw_serial_kbd kbd(Serial);
|
||||
|
||||
#else
|
||||
#error "No keyboard defined!"
|
||||
hw_serial_kbd kbd(Serial);
|
||||
#endif
|
||||
|
||||
io io(files, kbd);
|
||||
#if defined(SCREEN_SERIAL_DSP)
|
||||
screen_disp dsp;
|
||||
#else
|
||||
terminal_disp dsp(Serial);
|
||||
#endif
|
||||
io io(files, kbd, dsp);
|
||||
|
||||
r6502 cpu(memory);
|
||||
|
||||
@ -46,14 +50,14 @@ void reset() {
|
||||
|
||||
io.reset();
|
||||
if (!ok) {
|
||||
io.status("Reset failed");
|
||||
dsp.status("Reset failed");
|
||||
return;
|
||||
}
|
||||
io.start();
|
||||
#if defined(KRUSADER)
|
||||
io.status("Krusader: F000R / Basic: E000R");
|
||||
dsp.status("Krusader: F000R / Basic: E000R");
|
||||
#else
|
||||
io.status("Basic: E000R");
|
||||
dsp.status("Basic: E000R");
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -66,17 +70,17 @@ void function_key(uint8_t fn) {
|
||||
break;
|
||||
case 2:
|
||||
filename = io.files.advance();
|
||||
io.status(filename);
|
||||
dsp.status(filename);
|
||||
break;
|
||||
case 3:
|
||||
filename = io.files.rewind();
|
||||
io.status(filename);
|
||||
dsp.status(filename);
|
||||
break;
|
||||
case 4:
|
||||
io.load();
|
||||
break;
|
||||
case 6:
|
||||
io.status(io.files.checkpoint());
|
||||
dsp.status(io.files.checkpoint());
|
||||
break;
|
||||
case 7:
|
||||
if (filename)
|
||||
|
4
Makefile
4
Makefile
@ -1,8 +1,8 @@
|
||||
t ?= esp32
|
||||
|
||||
TERMINAL_SPEED := 115200
|
||||
CPPFLAGS = -DDEBUGGING -DCPU_DEBUG=false -DTERMINAL_SPEED=$(TERMINAL_SPEED) -DUSE_OWN_KBD -DPS2_SERIAL_KBD=\"UK\"
|
||||
#CPPFLAGS = -DDEBUGGING -DCPU_DEBUG -DTERMINAL_SPEED=$(TERMINAL_SPEED) -DUSE_OWN_KBD -DHW_SERIAL_KBD
|
||||
#CPPFLAGS = -DDEBUGGING -DCPU_DEBUG=false -DTERMINAL_SPEED=$(TERMINAL_SPEED) -DUSE_OWN_KBD -DPS2_SERIAL_KBD=\"UK\"
|
||||
CPPFLAGS = -DDEBUGGING -DCPU_DEBUG=false -DTERMINAL_SPEED=$(TERMINAL_SPEED) -DUSE_OWN_KBD -DUSE_SERIAL
|
||||
LIBRARIES = PS2KeyAdvanced PS2KeyMap
|
||||
|
||||
ifeq ($t, esp8266)
|
||||
|
4
config.h
4
config.h
@ -16,6 +16,10 @@
|
||||
|
||||
#endif
|
||||
|
||||
// uncomment to use TFT / VGA display
|
||||
// otherwise serial terminal is used
|
||||
//#define SCREEN_SERIAL_DSP
|
||||
|
||||
#define FG_COLOUR GREEN
|
||||
#define BG_COLOUR BLACK
|
||||
|
||||
|
12
disp.h
Normal file
12
disp.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef _DISP_H
|
||||
#define _DISP_H
|
||||
|
||||
class disp: public serial_dsp {
|
||||
public:
|
||||
virtual void checkpoint(Stream &) =0;
|
||||
virtual void restore(Stream &) =0;
|
||||
|
||||
virtual void status(const char *) =0;
|
||||
};
|
||||
|
||||
#endif
|
91
io.cpp
91
io.cpp
@ -4,51 +4,28 @@
|
||||
#include <serialio.h>
|
||||
#include <filer.h>
|
||||
#include <serial_kbd.h>
|
||||
#include <serial_dsp.h>
|
||||
#include <pia.h>
|
||||
#include <timed.h>
|
||||
|
||||
#include "io.h"
|
||||
#include "disp.h"
|
||||
#include "hardware.h"
|
||||
#include "config.h"
|
||||
|
||||
void io::reset() {
|
||||
Display::begin(BG_COLOUR, FG_COLOUR, ORIENT);
|
||||
clear();
|
||||
_cy += 2;
|
||||
|
||||
r = c = 0;
|
||||
for (int j = 0; j < ROWS; j++)
|
||||
for (int i = 0; i < COLS; i++)
|
||||
screen[j][i] = ' ';
|
||||
|
||||
_dsp.reset();
|
||||
_kbd.reset();
|
||||
|
||||
_loading = false;
|
||||
PIA::reset();
|
||||
}
|
||||
|
||||
static io *i;
|
||||
|
||||
const int TICK_FREQ = 2;
|
||||
|
||||
bool io::start() {
|
||||
|
||||
i = this;
|
||||
timer_create(TICK_FREQ, io::on_tick);
|
||||
return files.start();
|
||||
}
|
||||
|
||||
void IRAM_ATTR io::on_tick() {
|
||||
|
||||
static int tick = 0;
|
||||
tick = ++tick % 3;
|
||||
i->cursor(tick < 2);
|
||||
}
|
||||
|
||||
void io::cursor(bool on) {
|
||||
draw(on? '_': ' ', c, r);
|
||||
}
|
||||
|
||||
void io::load() {
|
||||
if (files.more()) {
|
||||
_loading = true;
|
||||
@ -62,53 +39,9 @@ void io::enter(uint8_t key) {
|
||||
PIA::write_ca1(true);
|
||||
}
|
||||
|
||||
void io::draw(char ch, int i, int j) {
|
||||
if (screen[j][i] != ch) {
|
||||
screen[j][i] = ch;
|
||||
char c[2] = { ch, 0 };
|
||||
drawString(c, i*_cx, j*_cy);
|
||||
}
|
||||
}
|
||||
|
||||
void io::display(uint8_t b) {
|
||||
char ch = (char)b;
|
||||
switch(ch) {
|
||||
case 0x5f:
|
||||
draw(' ', c, r);
|
||||
if (c-- == 0) {
|
||||
r--;
|
||||
c = COLS-1;
|
||||
}
|
||||
break;
|
||||
case 0x0d:
|
||||
draw(' ', c, r);
|
||||
c = 0;
|
||||
r++;
|
||||
break;
|
||||
default:
|
||||
if (ch >= 0x20 && ch < 0x7f) {
|
||||
draw(ch, c, r);
|
||||
if (++c == COLS) {
|
||||
c = 0;
|
||||
r++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (r == ROWS) {
|
||||
// scroll
|
||||
r--;
|
||||
for (int j = 0; j < (ROWS-1); j++)
|
||||
for (int i = 0; i < COLS; i++)
|
||||
draw(screen[j+1][i], i, j);
|
||||
for (int i = 0; i < COLS; i++)
|
||||
draw(' ', i, ROWS-1);
|
||||
}
|
||||
draw('_', c, r);
|
||||
}
|
||||
|
||||
void io::write_portb(uint8_t b) {
|
||||
b &= 0x7f;
|
||||
display(b);
|
||||
_dsp.write(b);
|
||||
PIA::write_portb(b);
|
||||
}
|
||||
|
||||
@ -129,22 +62,10 @@ uint8_t io::read_cra() {
|
||||
|
||||
void io::checkpoint(Stream &s) {
|
||||
PIA::checkpoint(s);
|
||||
s.write(r);
|
||||
s.write(c);
|
||||
for (int j = 0; j < ROWS; j++)
|
||||
for (int i = 0; i < COLS; i++)
|
||||
s.write(screen[j][i]);
|
||||
_dsp.checkpoint(s);
|
||||
}
|
||||
|
||||
void io::restore(Stream &s) {
|
||||
PIA::restore(s);
|
||||
r = s.read();
|
||||
c = s.read();
|
||||
for (int j = 0; j < ROWS; j++)
|
||||
for (int i = 0; i < COLS; i++) {
|
||||
char c = s.read();
|
||||
screen[j][i] = c;
|
||||
draw(c, i, j);
|
||||
}
|
||||
draw('_', c, r);
|
||||
_dsp.restore(s);
|
||||
}
|
||||
|
20
io.h
20
io.h
@ -2,16 +2,16 @@
|
||||
#define _IO_H
|
||||
|
||||
class serial_kbd;
|
||||
class disp;
|
||||
|
||||
class io: public Memory::Device, public Display, public PIA {
|
||||
class io: public Memory::Device, public PIA {
|
||||
public:
|
||||
io(filer &files, serial_kbd &kbd): Memory::Device(Memory::page_size), files(files), _kbd(kbd) {}
|
||||
io(filer &files, serial_kbd &kbd, disp &dsp):
|
||||
Memory::Device(Memory::page_size), files(files), _kbd(kbd), _dsp(dsp) {}
|
||||
|
||||
void reset();
|
||||
bool start();
|
||||
|
||||
static void on_tick();
|
||||
|
||||
void operator=(uint8_t b) { PIA::write(_acc, b); }
|
||||
operator uint8_t() { return PIA::read(_acc); }
|
||||
|
||||
@ -24,20 +24,12 @@ public:
|
||||
void load();
|
||||
filer &files;
|
||||
|
||||
static const uint8_t ROWS = 24;
|
||||
static const uint8_t COLS = 40;
|
||||
|
||||
private:
|
||||
serial_kbd &_kbd;
|
||||
disp &_dsp;
|
||||
|
||||
void cursor(bool on);
|
||||
void display(uint8_t);
|
||||
void draw(char, int, int);
|
||||
void enter(uint8_t);
|
||||
|
||||
bool _shift, _loading;
|
||||
uint8_t r, c;
|
||||
char screen[ROWS][COLS];
|
||||
bool _loading;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
106
screen_disp.cpp
Normal file
106
screen_disp.cpp
Normal file
@ -0,0 +1,106 @@
|
||||
#include <Arduino.h>
|
||||
#include <memory.h>
|
||||
#include <display.h>
|
||||
#include <serial_dsp.h>
|
||||
#include <timed.h>
|
||||
#include <hardware.h>
|
||||
|
||||
#include "disp.h"
|
||||
#include "screen_disp.h"
|
||||
#include "config.h"
|
||||
|
||||
static screen_disp *i;
|
||||
|
||||
const int TICK_FREQ = 2;
|
||||
|
||||
void IRAM_ATTR screen_disp::on_tick() {
|
||||
|
||||
static int tick = 0;
|
||||
tick = ++tick % 3;
|
||||
i->cursor(tick < 2);
|
||||
}
|
||||
|
||||
void screen_disp::reset() {
|
||||
|
||||
if (!i) {
|
||||
i = this;
|
||||
timer_create(TICK_FREQ, on_tick);
|
||||
}
|
||||
|
||||
Display::begin(BG_COLOUR, FG_COLOUR, ORIENT);
|
||||
Display::clear();
|
||||
_cy += 2;
|
||||
|
||||
r = c = 0;
|
||||
for (int j = 0; j < ROWS; j++)
|
||||
for (int i = 0; i < COLS; i++)
|
||||
screen[j][i] = ' ';
|
||||
}
|
||||
|
||||
void screen_disp::cursor(bool on) {
|
||||
draw(on? '_': ' ', c, r);
|
||||
}
|
||||
|
||||
void screen_disp::draw(char ch, int i, int j) {
|
||||
if (screen[j][i] != ch) {
|
||||
screen[j][i] = ch;
|
||||
char c[2] = { ch, 0 };
|
||||
drawString(c, i*_cx, j*_cy);
|
||||
}
|
||||
}
|
||||
|
||||
void screen_disp::write(uint8_t b) {
|
||||
char ch = (char)b;
|
||||
switch(ch) {
|
||||
case '_':
|
||||
draw(' ', c, r);
|
||||
if (c-- == 0) {
|
||||
r--;
|
||||
c = COLS-1;
|
||||
}
|
||||
break;
|
||||
case 0x0d:
|
||||
draw(' ', c, r);
|
||||
c = 0;
|
||||
r++;
|
||||
break;
|
||||
default:
|
||||
if (ch >= 0x20 && ch < 0x7f) {
|
||||
draw(ch, c, r);
|
||||
if (++c == COLS) {
|
||||
c = 0;
|
||||
r++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (r == ROWS) {
|
||||
// scroll
|
||||
r--;
|
||||
for (int j = 0; j < (ROWS-1); j++)
|
||||
for (int i = 0; i < COLS; i++)
|
||||
draw(screen[j+1][i], i, j);
|
||||
for (int i = 0; i < COLS; i++)
|
||||
draw(' ', i, ROWS-1);
|
||||
}
|
||||
draw('_', c, r);
|
||||
}
|
||||
|
||||
void screen_disp::checkpoint(Stream &s) {
|
||||
s.write(r);
|
||||
s.write(c);
|
||||
for (int j = 0; j < ROWS; j++)
|
||||
for (int i = 0; i < COLS; i++)
|
||||
s.write(screen[j][i]);
|
||||
}
|
||||
|
||||
void screen_disp::restore(Stream &s) {
|
||||
r = s.read();
|
||||
c = s.read();
|
||||
for (int j = 0; j < ROWS; j++)
|
||||
for (int i = 0; i < COLS; i++) {
|
||||
char c = s.read();
|
||||
screen[j][i] = c;
|
||||
draw(c, i, j);
|
||||
}
|
||||
draw('_', c, r);
|
||||
}
|
29
screen_disp.h
Normal file
29
screen_disp.h
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef __SCREEN_DISP_H__
|
||||
#define __SCREEN_DISP_H__
|
||||
|
||||
class screen_disp: public Display, public disp {
|
||||
public:
|
||||
void reset();
|
||||
|
||||
void checkpoint(Stream &);
|
||||
void restore(Stream &);
|
||||
|
||||
void write(uint8_t);
|
||||
void status(const char *s) { Display::status(s); }
|
||||
|
||||
protected:
|
||||
static void on_tick();
|
||||
|
||||
void cursor(bool on);
|
||||
|
||||
private:
|
||||
void draw(char, int, int);
|
||||
|
||||
static const uint8_t ROWS = 24;
|
||||
static const uint8_t COLS = 40;
|
||||
|
||||
uint8_t r, c;
|
||||
char screen[ROWS][COLS];
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user