mirror of https://github.com/JorjBauer/aiie.git
testing threads
This commit is contained in:
parent
5db77a4765
commit
f5b7f19ebb
|
@ -1,7 +1,8 @@
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
#include <TimeLib.h>
|
#include <TimeLib.h>
|
||||||
#include <TimerOne.h>
|
#include <TeensyThreads.h>
|
||||||
|
|
||||||
#include "bios.h"
|
#include "bios.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "applevm.h"
|
#include "applevm.h"
|
||||||
|
@ -25,6 +26,8 @@ uint32_t startMicros;
|
||||||
|
|
||||||
BIOS bios;
|
BIOS bios;
|
||||||
|
|
||||||
|
int cpuThreadId = 0;
|
||||||
|
|
||||||
// How many microseconds per cycle
|
// How many microseconds per cycle
|
||||||
#define SPEEDCTL ((float)1000000/(float)g_speed)
|
#define SPEEDCTL ((float)1000000/(float)g_speed)
|
||||||
|
|
||||||
|
@ -133,9 +136,9 @@ void setup()
|
||||||
|
|
||||||
Serial.println("free-running");
|
Serial.println("free-running");
|
||||||
|
|
||||||
Timer1.initialize(3);
|
threads.setDefaultTimeSlice(1);
|
||||||
Timer1.attachInterrupt(runCPU);
|
threads.setSliceMicros(500);
|
||||||
Timer1.start();
|
cpuThreadId = threads.addThread(runCPU);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: move these memory-related functions elsewhere...
|
// FIXME: move these memory-related functions elsewhere...
|
||||||
|
@ -166,7 +169,7 @@ int heapSize(){
|
||||||
|
|
||||||
void biosInterrupt()
|
void biosInterrupt()
|
||||||
{
|
{
|
||||||
Timer1.stop();
|
threads.suspend(cpuThreadId);
|
||||||
|
|
||||||
// wait for the interrupt button to be released
|
// wait for the interrupt button to be released
|
||||||
while (digitalRead(RESETPIN) == LOW)
|
while (digitalRead(RESETPIN) == LOW)
|
||||||
|
@ -197,7 +200,7 @@ void biosInterrupt()
|
||||||
// Poll the keyboard before we start, so we can do selftest on startup
|
// Poll the keyboard before we start, so we can do selftest on startup
|
||||||
g_keyboard->maintainKeyboard();
|
g_keyboard->maintainKeyboard();
|
||||||
|
|
||||||
Timer1.start();
|
threads.restart(cpuThreadId);
|
||||||
}
|
}
|
||||||
|
|
||||||
//bool debugState = false;
|
//bool debugState = false;
|
||||||
|
@ -206,33 +209,32 @@ void biosInterrupt()
|
||||||
|
|
||||||
void runCPU()
|
void runCPU()
|
||||||
{
|
{
|
||||||
g_inInterrupt = true;
|
while (1) {
|
||||||
// Debugging: to watch when the speaker is triggered...
|
// Debugging: to watch when the speaker is triggered...
|
||||||
// static bool debugState = false;
|
// static bool debugState = false;
|
||||||
// debugState = !debugState;
|
// debugState = !debugState;
|
||||||
// digitalWrite(56, debugState);
|
// digitalWrite(56, debugState);
|
||||||
|
|
||||||
// Relatively critical timing: CPU needs to run ahead at least 4
|
|
||||||
// cycles, b/c we're calling this interrupt (runCPU, that is) just
|
|
||||||
// about 1/3 as fast as we should; and the speaker is updated
|
|
||||||
// directly from within it, so it needs to be real-ish time.
|
|
||||||
if (micros() > nextInstructionMicros) {
|
|
||||||
// Debugging: to watch when the CPU is triggered...
|
|
||||||
// static bool debugState = false;
|
|
||||||
// debugState = !debugState;
|
|
||||||
// digitalWrite(56, debugState);
|
|
||||||
|
|
||||||
uint8_t executed = g_cpu->Run(24);
|
// Relatively critical timing: CPU needs to run ahead at least 4
|
||||||
|
// cycles, b/c we're calling this interrupt (runCPU, that is) just
|
||||||
// The CPU of the Apple //e ran at 1.023 MHz. Adjust when we think
|
// about 1/3 as fast as we should; and the speaker is updated
|
||||||
// the next instruction should run based on how long the execution
|
// directly from within it, so it needs to be real-ish time.
|
||||||
// was ((1000/1023) * numberOfCycles) - which is about 97.8%.
|
if (micros() > nextInstructionMicros) {
|
||||||
nextInstructionMicros = startMicros + ((double)g_cpu->cycles * (double)SPEEDCTL);
|
// Debugging: to watch when the CPU is triggered...
|
||||||
|
// static bool debugState = false;
|
||||||
((AppleVM *)g_vm)->cpuMaintenance(g_cpu->cycles);
|
// debugState = !debugState;
|
||||||
|
// digitalWrite(56, debugState);
|
||||||
|
|
||||||
|
uint8_t executed = g_cpu->Run(24);
|
||||||
|
|
||||||
|
// The CPU of the Apple //e ran at 1.023 MHz. Adjust when we think
|
||||||
|
// the next instruction should run based on how long the execution
|
||||||
|
// was ((1000/1023) * numberOfCycles) - which is about 97.8%.
|
||||||
|
nextInstructionMicros = startMicros + ((double)g_cpu->cycles * (double)SPEEDCTL);
|
||||||
|
|
||||||
|
((AppleVM *)g_vm)->cpuMaintenance(g_cpu->cycles);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_inInterrupt = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
|
@ -259,14 +261,7 @@ void loop()
|
||||||
// display update, OR
|
// display update, OR
|
||||||
// - lock display updates so the CPU can update the memory, but we
|
// - lock display updates so the CPU can update the memory, but we
|
||||||
// keep drawing what was going to be displayed
|
// keep drawing what was going to be displayed
|
||||||
//
|
|
||||||
// The Timer1.stop()/start() is bad. Using it, the display doesn't
|
|
||||||
// tear; but the audio is also broken. Taking it out, audio is good
|
|
||||||
// but the display tears. So there's a global - g_prioritizeDisplay -
|
|
||||||
// which lets the user pick which they want.
|
|
||||||
|
|
||||||
if (g_prioritizeDisplay)
|
|
||||||
Timer1.stop();
|
|
||||||
g_ui->blit();
|
g_ui->blit();
|
||||||
g_vm->vmdisplay->lockDisplay();
|
g_vm->vmdisplay->lockDisplay();
|
||||||
if (g_vm->vmdisplay->needsRedraw()) {
|
if (g_vm->vmdisplay->needsRedraw()) {
|
||||||
|
@ -275,8 +270,6 @@ void loop()
|
||||||
g_display->blit(what);
|
g_display->blit(what);
|
||||||
}
|
}
|
||||||
g_vm->vmdisplay->unlockDisplay();
|
g_vm->vmdisplay->unlockDisplay();
|
||||||
if (g_prioritizeDisplay)
|
|
||||||
Timer1.start();
|
|
||||||
|
|
||||||
static unsigned long nextBattCheck = millis() + 30;// debugging
|
static unsigned long nextBattCheck = millis() + 30;// debugging
|
||||||
static int batteryLevel = 0; // static for debugging code! When done
|
static int batteryLevel = 0; // static for debugging code! When done
|
||||||
|
@ -374,7 +367,6 @@ void readPrefs()
|
||||||
g_volume = p.volume;
|
g_volume = p.volume;
|
||||||
g_displayType = p.displayType;
|
g_displayType = p.displayType;
|
||||||
g_debugMode = p.debug;
|
g_debugMode = p.debug;
|
||||||
g_prioritizeDisplay = p.priorityMode;
|
|
||||||
g_speed = (p.speed * (1023000/2)); // steps of half normal speed
|
g_speed = (p.speed * (1023000/2)); // steps of half normal speed
|
||||||
if (g_speed < (1023000/2))
|
if (g_speed < (1023000/2))
|
||||||
g_speed = (1023000/2);
|
g_speed = (1023000/2);
|
||||||
|
@ -411,14 +403,13 @@ void writePrefs()
|
||||||
p.volume = g_volume;
|
p.volume = g_volume;
|
||||||
p.displayType = g_displayType;
|
p.displayType = g_displayType;
|
||||||
p.debug = g_debugMode;
|
p.debug = g_debugMode;
|
||||||
p.priorityMode = g_prioritizeDisplay;
|
|
||||||
p.speed = g_speed / (1023000/2);
|
p.speed = g_speed / (1023000/2);
|
||||||
strcpy(p.disk1, ((AppleVM *)g_vm)->DiskName(0));
|
strcpy(p.disk1, ((AppleVM *)g_vm)->DiskName(0));
|
||||||
strcpy(p.disk2, ((AppleVM *)g_vm)->DiskName(1));
|
strcpy(p.disk2, ((AppleVM *)g_vm)->DiskName(1));
|
||||||
strcpy(p.hd1, ((AppleVM *)g_vm)->HDName(0));
|
strcpy(p.hd1, ((AppleVM *)g_vm)->HDName(0));
|
||||||
strcpy(p.hd2, ((AppleVM *)g_vm)->HDName(1));
|
strcpy(p.hd2, ((AppleVM *)g_vm)->HDName(1));
|
||||||
|
|
||||||
Timer1.stop();
|
threads.suspend(cpuThreadId);
|
||||||
bool ret = np.writePrefs(&p);
|
bool ret = np.writePrefs(&p);
|
||||||
Timer1.start();
|
threads.restart(cpuThreadId);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue