kopia lustrzana https://github.com/Jean-MarcHarvengt/MCUME
246 wiersze
5.8 KiB
C++
246 wiersze
5.8 KiB
C++
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
extern "C" {
|
|
#include "emuapi.h"
|
|
#include "platform_config.h"
|
|
}
|
|
|
|
#include <Arduino.h>
|
|
|
|
// Apple2 2 emulation includes
|
|
#include "bios.h"
|
|
#include "cpu.h"
|
|
#include "applevm.h"
|
|
#include "plf-display.h"
|
|
#include "plf-keyboard.h"
|
|
#include "plf-speaker.h"
|
|
#include "plf-paddles.h"
|
|
#include "plf-filemanager.h"
|
|
#include "globals.h"
|
|
|
|
|
|
uint32_t nextInstructionMicros;
|
|
uint32_t startMicros;
|
|
|
|
|
|
static int ik; // joypad key
|
|
static int pik=0;
|
|
|
|
static int ihk; // I2C keyboard key
|
|
static int iusbhk;// USB keyboard key
|
|
static int prevhk;
|
|
|
|
void aiie_Input(int bClick) {
|
|
ik = emu_GetPad();
|
|
ihk = emu_ReadI2CKeyboard();
|
|
}
|
|
|
|
void emu_KeyboardOnDown(int keymodifer, int key) {
|
|
int keyCode = -1; //INV_KEY;
|
|
if ((key >=0xc0) && (key <=0xdf)) {
|
|
keyCode = ((key-0xc0) & 0x1f) + 0x7f;
|
|
}
|
|
else {
|
|
keyCode = key & 0x7f;
|
|
}
|
|
|
|
//Serial.println(keyCode);
|
|
|
|
if (keyCode != -1) {
|
|
iusbhk = keyCode;
|
|
}
|
|
}
|
|
|
|
void emu_KeyboardOnUp(int keymodifer, int key) {
|
|
iusbhk = 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void aiie_Init(void)
|
|
{
|
|
g_speaker = new PlfSpeaker(0);
|
|
|
|
// First create the filemanager - the interface to the host file system.
|
|
g_filemanager = new PlfFileManager();
|
|
|
|
// Construct the interface to the host display. This will need the
|
|
// VM's video buffer in order to draw the VM, but we don't have that
|
|
// yet.
|
|
g_display = new PlfDisplay();
|
|
|
|
// Next create the virtual CPU. This needs the VM's MMU in order to
|
|
// run, but we don't have that yet.
|
|
g_cpu = new Cpu();
|
|
|
|
// Create the virtual machine. This may read from g_filemanager to
|
|
// get ROMs if necessary. (The actual Apple VM we've built has them
|
|
// compiled in, though.) It will create its virutal hardware (MMU,
|
|
// video driver, floppy, paddles, whatever).
|
|
g_vm = new AppleVM();
|
|
|
|
// Now that the VM exists and it has created an MMU, we tell the CPU
|
|
// how to access memory through the MMU.
|
|
g_cpu->SetMMU(g_vm->getMMU());
|
|
|
|
// And the physical keyboard needs hooks in to the virtual keyboard...
|
|
g_keyboard = new PlfKeyboard(g_vm->getKeyboard());
|
|
|
|
g_paddles = new PlfPaddles(1, 1);
|
|
|
|
// Now that all the virtual hardware is glued together, reset the VM
|
|
g_vm->Reset();
|
|
|
|
g_display->redraw();
|
|
|
|
g_cpu->cycles = 0;
|
|
startMicros = nextInstructionMicros = micros();
|
|
startMicros = 0;
|
|
nextInstructionMicros = micros();
|
|
|
|
#ifdef HAS_SND
|
|
emu_sndInit();
|
|
#endif
|
|
}
|
|
|
|
|
|
void aiie_Start(char * filename)
|
|
{
|
|
emu_printf("emu starting");
|
|
|
|
((AppleVM *)g_vm)->insertDisk(0, filename, false);
|
|
|
|
emu_printf("emu started");
|
|
}
|
|
|
|
static int padx = 128;
|
|
static int pady = 128;
|
|
static int padxinc = 0;
|
|
static int padyinc = 0;
|
|
|
|
void aiie_Step(void)
|
|
{
|
|
int n = 1000;
|
|
while (n-- > 0) {
|
|
//if (micros() >= nextInstructionMicros) {
|
|
g_cpu->Run(24);
|
|
//g_speaker->beginMixing();
|
|
((AppleVM *)g_vm)->cpuMaintenance(g_cpu->cycles);
|
|
//g_speaker->maintainSpeaker(g_cpu->cycles);
|
|
// 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 * 0.978d);
|
|
//}
|
|
}
|
|
|
|
((AppleVM*)g_vm)->disk6->fillDiskBuffer();
|
|
g_keyboard->maintainKeyboard();
|
|
g_vm->vmdisplay->needsRedraw();
|
|
AiieRect what = g_vm->vmdisplay->getDirtyRect();
|
|
g_vm->vmdisplay->didRedraw();
|
|
g_display->blit(what);
|
|
|
|
emu_DrawVsync();
|
|
|
|
int hk=ihk;
|
|
if (iusbhk) hk = iusbhk;
|
|
|
|
if ( (hk) && (hk != prevhk) ) {
|
|
if (hk == 10) hk=RET;
|
|
else if (hk == 153) hk=UARR; //U L R D
|
|
else if (hk == 151) hk=LARR;
|
|
else if (hk == 150) hk=RARR;
|
|
else if (hk == 152) hk=DARR;
|
|
else if (hk == 127) hk=DEL;
|
|
prevhk = hk;
|
|
g_keyboard->onPress(hk);
|
|
// Serial.println(hk);
|
|
}
|
|
else if ( (prevhk) && (!hk) ) {
|
|
g_keyboard->onRelease(prevhk);
|
|
// Serial.println("release");
|
|
prevhk = 0;
|
|
}
|
|
|
|
|
|
int k=ik;
|
|
#ifdef TEECOMPUTER
|
|
// Ignore joypad if shift/fn is pressed!!!
|
|
if ( !(k & MASK_KEY_USER1) && !(k & MASK_KEY_USER2) )
|
|
#endif
|
|
{
|
|
if ( !(pik & MASK_JOY2_BTN) && (k & MASK_JOY2_BTN) ) {
|
|
g_keyboard->onPress(RA);
|
|
g_keyboard->onPress(LA);
|
|
}
|
|
else if ( (pik & MASK_JOY2_BTN) && !(k & MASK_JOY2_BTN) ) {
|
|
g_keyboard->onRelease(RA);
|
|
g_keyboard->onRelease(LA);
|
|
}
|
|
|
|
if ( !(pik & MASK_JOY1_BTN) && (k & MASK_JOY1_BTN) ) {
|
|
g_keyboard->onPress(RA);
|
|
g_keyboard->onPress(LA);
|
|
|
|
}
|
|
else if ( (pik & MASK_JOY1_BTN) && !(k & MASK_JOY1_BTN) ) {
|
|
g_keyboard->onRelease(RA);
|
|
g_keyboard->onRelease(LA);
|
|
}
|
|
|
|
if ( (k & MASK_JOY2_LEFT) || (k & MASK_JOY1_LEFT) ) {
|
|
if (padxinc < 0) padxinc = 0;
|
|
if (padxinc != +1) padxinc += 1;
|
|
if (padx != 255) padx += padxinc;
|
|
g_paddles->setPaddle0(padx);
|
|
}
|
|
else if ( (k & MASK_JOY2_RIGHT) || (k & MASK_JOY1_RIGHT) ) {
|
|
if (padxinc > 0) padxinc = 0;
|
|
if (padxinc != -1) padxinc -= 1;
|
|
if (padx != 0) padx += padxinc;
|
|
g_paddles->setPaddle0(padx);
|
|
}
|
|
|
|
if ( (k & MASK_JOY2_UP) || (k & MASK_JOY1_UP) ) {
|
|
if (padyinc < 0) padyinc = 0;
|
|
if (padyinc != 1) padyinc += 1;
|
|
if (pady != 255) pady += padyinc;
|
|
g_paddles->setPaddle1(pady);
|
|
}
|
|
else if ( (k & MASK_JOY2_DOWN) || (k & MASK_JOY1_DOWN) ) {
|
|
if (padyinc > 0) padyinc = 0;
|
|
if (padyinc != -1) padyinc -= 1;
|
|
if (pady != 0) pady += padyinc;
|
|
g_paddles->setPaddle1(pady);
|
|
}
|
|
}
|
|
|
|
#ifndef TEECOMPUTER
|
|
if ( !(pik & MASK_KEY_USER1) && (k & MASK_KEY_USER1) ) {
|
|
g_keyboard->onPress('a');
|
|
}
|
|
else if ( (pik & MASK_KEY_USER1) && !(k & MASK_KEY_USER1) ) {
|
|
g_keyboard->onRelease('a');
|
|
}
|
|
|
|
if ( !(pik & MASK_KEY_USER2) && (k & MASK_KEY_USER2) ) {
|
|
g_keyboard->onPress('b');
|
|
}
|
|
else if ( (pik & MASK_KEY_USER2) && !(k & MASK_KEY_USER2) ) {
|
|
g_keyboard->onRelease('b');
|
|
}
|
|
#endif
|
|
pik = k;
|
|
|
|
|
|
#ifdef HAS_SND
|
|
#endif
|
|
}
|
|
|
|
|
|
|