MCUME/MCUME_teensy41/teensyaiie/wrapemu.cpp

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
}