mirror of
https://github.com/jscrane/r65emu.git
synced 2025-01-02 13:30:53 +00:00
38 simpletimer (#39)
* SimpleTimer * handlers * use std::function for handlers * ... * add optional USE_OWN_DISPLAY
This commit is contained in:
parent
70d63487bc
commit
7625e1613a
@ -4,6 +4,8 @@
|
||||
#include "memory.h"
|
||||
#include "display.h"
|
||||
|
||||
#if !defined(USE_OWN_DISPLAY)
|
||||
|
||||
#if defined(USE_UTFT)
|
||||
#pragma message "UTFT configured"
|
||||
#include <UTFT.h>
|
||||
@ -373,3 +375,4 @@ void Display::drawString(const char *s, unsigned x, unsigned y, colour_t c) {
|
||||
dvi.print(s);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <Arduino.h>
|
||||
#include <SimpleTimer.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "memory.h"
|
||||
@ -26,6 +27,7 @@ spiram sram(SPIRAM_SIZE);
|
||||
#endif
|
||||
|
||||
static CPU *_cpu;
|
||||
static SimpleTimer timers;
|
||||
|
||||
bool hardware_reset() {
|
||||
bool success = false;
|
||||
@ -105,6 +107,8 @@ bool hardware_debug_cpu() {
|
||||
|
||||
bool hardware_run(unsigned instructions) {
|
||||
|
||||
timers.run();
|
||||
|
||||
#if defined(CPU_DEBUG)
|
||||
if (cpu_debug) {
|
||||
char buf[256];
|
||||
@ -119,6 +123,14 @@ bool hardware_run(unsigned instructions) {
|
||||
return !_cpu->halted();
|
||||
}
|
||||
|
||||
int hardware_interval_timer(uint32_t interval, std::function<void(void)> cb) {
|
||||
return timers.setInterval(interval, cb);
|
||||
}
|
||||
|
||||
int hardware_oneshot_timer(uint32_t interval, std::function<void(void)> cb) {
|
||||
return timers.setTimeout(interval, cb);
|
||||
}
|
||||
|
||||
#if !defined(NO_CHECKPOINT)
|
||||
void hardware_checkpoint(Stream &s) {
|
||||
unsigned ds = 0;
|
||||
|
@ -11,7 +11,7 @@
|
||||
#endif
|
||||
|
||||
#if !defined(CPU_INSTRUCTIONS)
|
||||
#define CPU_INSTRUCTIONS 1000
|
||||
#define CPU_INSTRUCTIONS 500
|
||||
#endif
|
||||
|
||||
#if !defined(TERMINAL_SPEED)
|
||||
@ -24,6 +24,8 @@ void hardware_checkpoint(class Stream &);
|
||||
void hardware_restore(class Stream &);
|
||||
bool hardware_run(unsigned instructions = CPU_INSTRUCTIONS);
|
||||
bool hardware_debug_cpu();
|
||||
int hardware_interval_timer(uint32_t ms, std::function<void(void)> cb);
|
||||
int hardware_oneshot_timer(uint32_t ms, std::function<void(void)> cb);
|
||||
|
||||
#if defined(__SPIRAM_H__) && defined(USE_SPIRAM)
|
||||
extern class spiram sram;
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
// Display
|
||||
// https://cdn-learn.adafruit.com/downloads/pdf/picodvi-arduino-library-video-out-for-rp2040-boards.pdf
|
||||
#if !defined(USE_OWN_DISPLAY)
|
||||
#define USE_DVI
|
||||
#define DVI_CONFIG adafruit_feather_dvi_cfg
|
||||
|
||||
@ -52,6 +53,7 @@
|
||||
#if !defined(DVI_DEFAULT_FONT)
|
||||
#define DVI_DEFAULT_FONT 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// 64kB RAM
|
||||
#define RAM_SIZE 0x10000u
|
||||
|
@ -1,6 +1,7 @@
|
||||
#define RAM_SIZE 0x10000u
|
||||
|
||||
// TFT display...
|
||||
#if !defined(USE_OWN_DISPLAY)
|
||||
#define USE_ESPI
|
||||
// must be configured in uC-Makefile, or platformio, or TFT_eSPI's User_Setup.h
|
||||
//#define USER_SETUP_LOADED
|
||||
@ -26,6 +27,7 @@
|
||||
//#define TFT_WR 33
|
||||
//#define TFT_CS 27
|
||||
//#define TFT_RST 26
|
||||
#endif
|
||||
|
||||
// PS/2 keyboard
|
||||
#if !defined(USE_OWN_KBD)
|
||||
|
@ -4,6 +4,7 @@
|
||||
#define RAM_SIZE 0x8000u
|
||||
|
||||
// TFT display...
|
||||
#if !defined(USE_OWN_DISPLAY)
|
||||
#define USE_ESPI
|
||||
//must define these in Makefile (or platformio)
|
||||
//#define USER_SETUP_LOADED
|
||||
@ -19,6 +20,7 @@
|
||||
#if !defined(ESPI_DEFAULT_FONT)
|
||||
#define ESPI_DEFAULT_FONT 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// PS/2 keyboard
|
||||
#if !defined(USE_OWN_KBD)
|
||||
|
@ -30,6 +30,7 @@
|
||||
// TFT display...
|
||||
// NOTE: edit memorysaver.h to select the correct chip for your display!
|
||||
// Daniel Rebollo's boosterpack
|
||||
#if !defined(USE_OWN_DISPLAY)
|
||||
#define USE_UTFT
|
||||
#define TFT_BACKLIGHT PD_6
|
||||
#define TFT_MODEL SSD1289
|
||||
@ -37,4 +38,4 @@
|
||||
#define TFT_WR PC_5
|
||||
#define TFT_CS PC_7
|
||||
#define TFT_RST PC_4
|
||||
|
||||
#endif
|
||||
|
@ -2,6 +2,7 @@
|
||||
// https://www.tinytronics.nl/shop/en/development-boards/microcontroller-boards/with-wi-fi/lilygo-ttgo-vga32-esp32
|
||||
|
||||
// Display
|
||||
#if !defined(USE_OWN_DISPLAY)
|
||||
#define USE_VGA
|
||||
#if !defined(VGA_RESOLUTION)
|
||||
#define VGA_RESOLUTION VGA_480x300_75Hz
|
||||
@ -10,6 +11,7 @@
|
||||
#if !defined(VGA_DEFAULT_FONT)
|
||||
#define VGA_DEFAULT_FONT &fabgl::FONT_6x10
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// PS/2 Keyboard
|
||||
#if !defined(USE_OWN_KBD)
|
||||
|
24
src/pia.cpp
24
src/pia.cpp
@ -100,6 +100,22 @@ void PIA::restore(Stream &s) {
|
||||
ca2 = s.read();
|
||||
}
|
||||
|
||||
void PIA::write_porta(uint8_t b) {
|
||||
|
||||
outa = b;
|
||||
|
||||
if (porta_write_handler)
|
||||
porta_write_handler(b);
|
||||
}
|
||||
|
||||
void PIA::write_portb(uint8_t b) {
|
||||
|
||||
outb = b;
|
||||
|
||||
if (portb_write_handler)
|
||||
portb_write_handler(b);
|
||||
}
|
||||
|
||||
void PIA::write_ca1(bool state) {
|
||||
|
||||
if (ca1 == state)
|
||||
@ -169,11 +185,19 @@ uint8_t PIA::read_crb() {
|
||||
}
|
||||
|
||||
uint8_t PIA::read_porta() {
|
||||
|
||||
if (porta_read_handler)
|
||||
ina = porta_read_handler();
|
||||
|
||||
irq_a1 = irq_a2 = false;
|
||||
return (ina & ~ddra) | (outa & ddra);
|
||||
}
|
||||
|
||||
uint8_t PIA::read_portb() {
|
||||
|
||||
if (portb_read_handler)
|
||||
inb = portb_read_handler();
|
||||
|
||||
irq_b1 = irq_b2 = false;
|
||||
return (inb & ~ddrb) | (outb & ddrb);
|
||||
}
|
||||
|
56
src/pia.h
56
src/pia.h
@ -1,5 +1,4 @@
|
||||
#ifndef __PIA_H__
|
||||
#define __PIA_H__
|
||||
#pragma once
|
||||
|
||||
// Motorola 6820 / 6821 PIA
|
||||
// https://en.wikipedia.org/wiki/Peripheral_Interface_Adapter
|
||||
@ -34,26 +33,49 @@ public:
|
||||
static const uint8_t IRQ1 = 0x80;
|
||||
static const uint8_t IRQ2 = 0x40;
|
||||
|
||||
protected:
|
||||
// overrideable device memory interface
|
||||
virtual uint8_t read_ddra() { return ddra; }
|
||||
virtual uint8_t read_porta();
|
||||
virtual uint8_t read_cra();
|
||||
virtual uint8_t read_ddrb() { return ddrb; }
|
||||
virtual uint8_t read_portb();
|
||||
virtual uint8_t read_crb();
|
||||
void register_porta_write_handler(std::function<void(uint8_t)> fn) {
|
||||
porta_write_handler = fn;
|
||||
}
|
||||
|
||||
virtual void write_ddra(uint8_t b) { ddra = b; }
|
||||
virtual void write_porta(uint8_t b) { outa = b; }
|
||||
virtual void write_cra(uint8_t b) { cra = (b & 0x3f); }
|
||||
virtual void write_ddrb(uint8_t b) { ddrb = b; }
|
||||
virtual void write_portb(uint8_t b) { outb = b; }
|
||||
virtual void write_crb(uint8_t b) { crb = (b & 0x3f); }
|
||||
void register_portb_write_handler(std::function<void(uint8_t)> fn) {
|
||||
portb_write_handler = fn;
|
||||
}
|
||||
|
||||
void register_porta_read_handler(std::function<uint8_t(void)> fn) {
|
||||
porta_read_handler = fn;
|
||||
}
|
||||
|
||||
void register_portb_read_handler(std::function<uint8_t(void)> fn) {
|
||||
portb_read_handler = fn;
|
||||
}
|
||||
|
||||
protected:
|
||||
// FIXME: overrideable device memory interface
|
||||
// should be non-virtual and private
|
||||
virtual uint8_t read_porta();
|
||||
virtual uint8_t read_portb();
|
||||
virtual void write_portb(uint8_t b);
|
||||
|
||||
private:
|
||||
void write_ddra(uint8_t b) { ddra = b; }
|
||||
void write_ddrb(uint8_t b) { ddrb = b; }
|
||||
uint8_t read_ddra() { return ddra; }
|
||||
uint8_t read_ddrb() { return ddrb; }
|
||||
|
||||
void write_cra(uint8_t b) { cra = (b & 0x3f); }
|
||||
void write_crb(uint8_t b) { crb = (b & 0x3f); }
|
||||
uint8_t read_cra();
|
||||
uint8_t read_crb();
|
||||
|
||||
void write_porta(uint8_t b);
|
||||
|
||||
std::function<void(uint8_t)> porta_write_handler;
|
||||
std::function<void(uint8_t)> portb_write_handler;
|
||||
std::function<uint8_t(void)> porta_read_handler;
|
||||
std::function<uint8_t(void)> portb_read_handler;
|
||||
|
||||
uint8_t cra, ina, outa, ddra;
|
||||
uint8_t crb, inb, outb, ddrb;
|
||||
bool ca1, ca2, irq_a1, irq_a2;
|
||||
bool cb1, cb2, irq_b1, irq_b2;
|
||||
};
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include <stdint.h>
|
||||
#include <Arduino.h>
|
||||
#include "hardware.h"
|
||||
|
||||
#if defined(USE_PS2_KBD)
|
||||
|
@ -1,5 +1,4 @@
|
||||
#if !defined(__PS2_KBD_H__)
|
||||
#define __PS2_KBD_H__
|
||||
#pragma once
|
||||
|
||||
class matrix_keyboard {
|
||||
public:
|
||||
@ -12,13 +11,11 @@ inline bool is_ps2_shift(uint16_t scan) { return scan == 0x12 || scan == 0x59; }
|
||||
|
||||
inline bool is_ps2_ctrl(uint16_t scan) { return scan == 0x14; }
|
||||
|
||||
typedef void (*fnkey_handler)(uint8_t);
|
||||
|
||||
class ps2_raw_kbd {
|
||||
public:
|
||||
ps2_raw_kbd(matrix_keyboard &m): _m(m) {}
|
||||
|
||||
void register_fnkey_handler(fnkey_handler f) { _f = f; }
|
||||
void register_fnkey_handler(std::function<void(uint8_t)> f) { _f = f; }
|
||||
void poll();
|
||||
void reset();
|
||||
|
||||
@ -29,8 +26,6 @@ private:
|
||||
uint16_t read();
|
||||
bool available();
|
||||
|
||||
fnkey_handler _f;
|
||||
std::function<void(uint8_t)> _f;
|
||||
matrix_keyboard &_m;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "flash_filer.h"
|
||||
#include "serial_filer.h"
|
||||
#include "socket_filer.h"
|
||||
#include "timed.h"
|
||||
#include "hardware.h"
|
||||
#include "sound_dac.h"
|
||||
#include "ps2_raw_kbd.h"
|
||||
|
@ -1,20 +1,15 @@
|
||||
#if !defined(__SERIAL_KBD_H__)
|
||||
#define __SERIAL_KBD_H__
|
||||
|
||||
typedef void (*fnkey_handler)(uint8_t);
|
||||
#pragma once
|
||||
|
||||
class serial_kbd {
|
||||
public:
|
||||
virtual int read() = 0;
|
||||
virtual bool available() = 0;
|
||||
virtual void reset() {}
|
||||
virtual void register_fnkey_handler(fnkey_handler f) { _f = f; }
|
||||
virtual void register_fnkey_handler(std::function<void(uint8_t)> f) { _f = f; }
|
||||
|
||||
protected:
|
||||
void fnkey(uint8_t k) { if (_f) _f(k); }
|
||||
|
||||
private:
|
||||
fnkey_handler _f;
|
||||
std::function<void(uint8_t)> _f;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,6 +1,8 @@
|
||||
// FIXME: does this really belong in the core library?
|
||||
// it only works on esp32 and is only used by invaders
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <hardware.h>
|
||||
#include "timed.h"
|
||||
#include "sound_dac.h"
|
||||
|
||||
#if defined(DAC_SOUND) && defined(ESP_PLATFORM)
|
||||
@ -15,6 +17,15 @@ void IRAM_ATTR timer_callback() {
|
||||
s->on_tick();
|
||||
}
|
||||
|
||||
typedef void (*handler_t)(void);
|
||||
|
||||
static void timer_create(unsigned freq, handler_t handler) {
|
||||
hw_timer_t *timer = timerBegin(3, 80, true); // prescaler of 80
|
||||
timerAttachInterrupt(timer, handler, true);
|
||||
timerAlarmWrite(timer, 1000000 / freq, true);
|
||||
timerAlarmEnable(timer);
|
||||
}
|
||||
|
||||
void IRAM_ATTR DAC::on_tick() {
|
||||
portENTER_CRITICAL_ISR(&mux);
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include <Arduino.h>
|
||||
#include "hardware.h"
|
||||
|
||||
#if defined(USE_SPIRAM)
|
||||
|
@ -1,65 +0,0 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
#if defined(__LM4F120H5QR__)
|
||||
#include <inc/hw_ints.h>
|
||||
#include <driverlib/interrupt.h>
|
||||
#include <driverlib/sysctl.h>
|
||||
#include <driverlib/timer.h>
|
||||
|
||||
#elif defined(ESP8266)
|
||||
#include <ets_sys.h>
|
||||
#include <osapi.h>
|
||||
#include <os_type.h>
|
||||
#endif
|
||||
|
||||
#include "timed.h"
|
||||
|
||||
#if defined(__LM4F120H5QR__)
|
||||
static handler_t client_handler;
|
||||
|
||||
static void timer0isr(void) {
|
||||
ROM_TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
|
||||
client_handler();
|
||||
}
|
||||
|
||||
void timer_create(unsigned freq, handler_t handler) {
|
||||
client_handler = handler;
|
||||
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
|
||||
ROM_TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
|
||||
TimerIntRegister(TIMER0_BASE, TIMER_A, timer0isr);
|
||||
ROM_TimerEnable(TIMER0_BASE, TIMER_A);
|
||||
ROM_IntEnable(INT_TIMER0A);
|
||||
ROM_TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
|
||||
ROM_TimerLoadSet(TIMER0_BASE, TIMER_A, ROM_SysCtlClockGet() / freq);
|
||||
}
|
||||
#elif defined(ESP_PLATFORM)
|
||||
|
||||
void timer_create(unsigned freq, handler_t handler) {
|
||||
hw_timer_t *timer = timerBegin(3, 80, true); // prescaler of 80
|
||||
timerAttachInterrupt(timer, handler, true);
|
||||
timerAlarmWrite(timer, 1000000 / freq, true);
|
||||
timerAlarmEnable(timer);
|
||||
}
|
||||
#elif defined(ESP8266)
|
||||
|
||||
void timer_create(unsigned freq, handler_t handler) {
|
||||
static os_timer_t t;
|
||||
os_timer_setfn(&t, (os_timer_func_t *)handler, 0);
|
||||
os_timer_arm(&t, 1000 / freq, true);
|
||||
}
|
||||
#elif defined(ARDUINO_ARCH_rp2040)
|
||||
|
||||
static handler_t client_handler;
|
||||
static int64_t period;
|
||||
|
||||
int64_t alarm_callback(alarm_id_t, void *) {
|
||||
client_handler();
|
||||
return -period;
|
||||
}
|
||||
|
||||
void timer_create(unsigned freq, handler_t handler) {
|
||||
period = 1000000 / freq;
|
||||
client_handler = handler;
|
||||
add_alarm_in_us(period, alarm_callback, 0, false);
|
||||
}
|
||||
#endif
|
12
src/timed.h
12
src/timed.h
@ -1,12 +0,0 @@
|
||||
#ifndef __TIMED_H__
|
||||
#define __TIMED_H__
|
||||
|
||||
typedef void (*handler_t)(void);
|
||||
|
||||
void timer_create(unsigned freq, handler_t handler);
|
||||
|
||||
#if !defined(ESP32) && !defined(ESP8266)
|
||||
#define IRAM_ATTR
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user