diff --git a/Makefile b/Makefile index 3adf838..78772eb 100755 --- a/Makefile +++ b/Makefile @@ -1,30 +1,24 @@ LDFLAGS=-L/usr/local/lib -OPENCVLIBS=-lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_features2d -lopencv_calib3d - SDLLIBS=-lSDL2 -CXXFLAGS=-Wall -I .. -I . -I apple -I opencv -I sdl -I/usr/local/include/SDL2 -O3 -g +CXXFLAGS=-Wall -I .. -I . -I apple -I sdl -I/usr/local/include/SDL2 -O3 -g TSRC=cpu.cpp util/testharness.cpp COMMONOBJS=cpu.o apple/appledisplay.o apple/applekeyboard.o apple/applemmu.o apple/applevm.o apple/diskii.o apple/nibutil.o RingBuffer.o globals.o apple/parallelcard.o apple/fx80.o apple/mockingboard.o apple/sy6522.o apple/ay8910.o -OPENCVOBJS=opencv/dummy-speaker.o opencv/opencv-display.o opencv/opencv-keyboard.o opencv/opencv-paddles.o opencv/opencv-filemanager.o opencv/aiie.o opencv/opencv-printer.o SDLOBJS=sdl/sdl-speaker.o sdl/sdl-display.o sdl/sdl-keyboard.o sdl/sdl-paddles.o sdl/sdl-filemanager.o sdl/aiie.o sdl/sdl-printer.o ROMS=apple/applemmu-rom.h apple/diskii-rom.h apple/parallel-rom.h all: sdl -opencv: roms $(COMMONOBJS) $(OPENCVOBJS) - g++ $(LDFLAGS) $(OPENCVLIBS) -o aiie-opencv $(COMMONOBJS) $(OPENCVOBJS) - sdl: roms $(COMMONOBJS) $(SDLOBJS) - g++ $(LDFLAGS) $(SDLLIBS) $(OPENCVLIBS) -o aiie-sdl $(COMMONOBJS) $(SDLOBJS) + g++ $(LDFLAGS) $(SDLLIBS) -o aiie-sdl $(COMMONOBJS) $(SDLOBJS) clean: - rm -f *.o *~ */*.o */*~ testharness.basic testharness.verbose testharness.extended aiie-opencv apple/diskii-rom.h apple/applemmu-rom.h apple/parallel-rom.h aiie-sdl + rm -f *.o *~ */*.o */*~ testharness.basic testharness.verbose testharness.extended apple/diskii-rom.h apple/applemmu-rom.h apple/parallel-rom.h aiie-sdl test: $(TSRC) g++ $(CXXFLAGS) -DBASICTEST $(TSRC) -o testharness.basic diff --git a/opencv/aiie.cpp b/opencv/aiie.cpp deleted file mode 100644 index a6960d7..0000000 --- a/opencv/aiie.cpp +++ /dev/null @@ -1,299 +0,0 @@ -#include -#include -#include -#include -#include - -#include "applevm.h" -#include "opencv-display.h" -#include "opencv-keyboard.h" -#include "dummy-speaker.h" -#include "opencv-paddles.h" -#include "opencv-filemanager.h" -#include "opencv-printer.h" - -#include "globals.h" - -#include "timeutil.h" - -//#define SHOWFPS -//#define SHOWPC -//#define DEBUGCPU -//#define SHOWMEMPAGE - -static struct timespec nextInstructionTime, startTime; -uint64_t hitcount = 0; -uint64_t misscount = 0; - -#define NB_ENABLE 1 -#define NB_DISABLE 0 - -int send_rst = 0; - -pthread_t cpuThreadID; - -void sigint_handler(int n) -{ - send_rst = 1; -} - -void nonblock(int state) -{ - struct termios ttystate; - - //get the terminal state - tcgetattr(STDIN_FILENO, &ttystate); - - if (state==NB_ENABLE) - { - //turn off canonical mode - ttystate.c_lflag &= ~ICANON; - //minimum of number input read. - ttystate.c_cc[VMIN] = 1; - } - else if (state==NB_DISABLE) - { - //turn on canonical mode - ttystate.c_lflag |= ICANON; - } - //set the terminal attributes. - tcsetattr(STDIN_FILENO, TCSANOW, &ttystate); - -} - -uint8_t read(void *arg, uint16_t address) -{ - // no action; this is a dummy function until we've finished initializing... - return 0x00; -} - -void write(void *arg, uint16_t address, uint8_t v) -{ - // no action; this is a dummy function until we've finished initializing... -} - -static void *cpu_thread(void *dummyptr) { - struct timespec currentTime; - -#if 0 - int policy; - struct sched_param param; - pthread_getschedparam(pthread_self(), &policy, ¶m); - param.sched_priority = sched_get_priority_max(policy); - pthread_setschedparam(pthread_self(), policy, ¶m); -#endif - - _init_darwin_shim(); - do_gettime(&startTime); - do_gettime(&nextInstructionTime); - - printf("free-running\n"); - while (1) { - // cycle down the CPU... - do_gettime(¤tTime); - struct timespec diff = tsSubtract(nextInstructionTime, currentTime); - if (diff.tv_sec >= 0 && diff.tv_nsec >= 0) { - hitcount++; - nanosleep(&diff, NULL); - } else { - misscount++; - } - -#ifdef DEBUGCPU - uint8_t executed = g_cpu->Run(1); -#else - uint8_t executed = g_cpu->Run(24); -#endif - timespec_add_cycles(&startTime, g_cpu->cycles + executed, &nextInstructionTime); - - g_speaker->beginMixing(); - - // The paddles need to be triggered in real-time on the CPU - // clock. That happens from the VM's CPU maintenance poller. - ((AppleVM *)g_vm)->cpuMaintenance(g_cpu->cycles); - - // cpuMaintenance also maintained the sound card; update the speaker after - g_speaker->maintainSpeaker(g_cpu->cycles); - -#ifdef DEBUGCPU - { - uint8_t p = g_cpu->flags; - printf("OP: $%02x A: %02x X: %02x Y: %02x PC: $%04x SP: %02x Flags: %c%cx%c%c%c%c%c\n", - g_vm->getMMU()->read(g_cpu->pc), - g_cpu->a, g_cpu->x, g_cpu->y, g_cpu->pc, g_cpu->sp, - p & (1<<7) ? 'N':' ', - p & (1<<6) ? 'V':' ', - p & (1<<4) ? 'B':' ', - p & (1<<3) ? 'D':' ', - p & (1<<2) ? 'I':' ', - p & (1<<1) ? 'Z':' ', - p & (1<<0) ? 'C':' ' - ); - } -#endif - - if (send_rst) { -#if 1 - printf("Sending reset\n"); - g_cpu->Reset(); - - // testing startup keyboard presses - perform Apple //e self-test - //g_vm->getKeyboard()->keyDepressed(RA); - //g_vm->Reset(); - //g_cpu->Reset(); - //((AppleVM *)g_vm)->insertDisk(0, "disks/DIAGS.DSK"); - -#else - MMU *mmu = g_vm->getMMU(); - - printf("PC: 0x%X\n", g_cpu->pc); - for (int i=g_cpu->pc; ipc + 0x100; i++) { - printf("0x%X ", mmu->read(i)); - } - printf("\n"); - - - printf("Dropping to monitor\n"); - // drop directly to monitor. - g_cpu->pc = 0xff69; // "call -151" - mmu->read(0xC054); // make sure we're in page 1 - mmu->read(0xC056); // and that hires is off - mmu->read(0xC051); // and text mode is on - mmu->read(0xC08A); // and we have proper rom in place - mmu->read(0xc008); // main zero-page - mmu->read(0xc006); // rom from cards - mmu->write(0xc002 + mmu->read(0xc014)? 1 : 0, 0xff); // make sure aux ram read and write match - mmu->write(0x20, 0); // text window - mmu->write(0x21, 40); - mmu->write(0x22, 0); - mmu->write(0x23, 24); - mmu->write(0x33, '>'); - mmu->write(0x48, 0); // from 0xfb2f: part of text init -#endif - - send_rst = 0; - } - } -} - -int main(int argc, char *argv[]) -{ - g_speaker = new DummySpeaker(); - g_printer = new OpenCVPrinter(); - - // create the filemanager - the interface to the host file system. - g_filemanager = new OpenCVFileManager(); - - // 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. (The OpenCV display looks it up dynamically every blit() call, which - // we'll probably change as we get the Teensy version working.) - g_display = new OpenCVDisplay(); - - // paddles have to be created after g_display created the window - g_paddles = new OpenCVPaddles(); - - // 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(); - - g_keyboard = new OpenCVKeyboard(g_vm->getKeyboard()); - - // 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()); - - // Now that all the virtual hardware is glued together, reset the VM - g_vm->Reset(); - g_cpu->rst(); - - // g_display->blit(); - g_display->redraw(); - - if (argc >= 2) { - printf("Inserting disk %s\n", argv[1]); - ((AppleVM *)g_vm)->insertDisk(0, argv[1]); - } - - if (argc == 3) { - printf("Inserting disk %s\n", argv[2]); - ((AppleVM *)g_vm)->insertDisk(1, argv[2]); - } - - nonblock(NB_ENABLE); - - signal(SIGINT, sigint_handler); - - printf("creating CPU thread\n"); - if (!pthread_create(&cpuThreadID, NULL, &cpu_thread, (void *)NULL)) { - printf("thread created\n"); - // pthread_setschedparam(cpuThreadID, SCHED_RR, PTHREAD_MAX_PRIORITY); - } - - while (1) { - static uint8_t ctr = 0; - if (++ctr == 0) { - printf("hit: %llu; miss: %llu; pct: %f\n", hitcount, misscount, (double)misscount / (double)(misscount + hitcount)); - } - - // Make this a little friendlier, and the expense of some framerate? - // usleep(10000); - if (g_vm->vmdisplay->needsRedraw()) { - AiieRect what = g_vm->vmdisplay->getDirtyRect(); - // make sure to clear the flag before drawing; there's no lock - // on didRedraw, so the other thread might update it - g_vm->vmdisplay->didRedraw(); - g_display->blit(what); - } - - g_keyboard->maintainKeyboard(); - - g_display->drawBatteryStatus(100); - -#ifdef SHOWFPS - static time_t startAt = time(NULL); - static uint32_t loopCount = 0; - loopCount++; - - time_t lenSecs = time(NULL) - startAt; - if (lenSecs >= 10) { - char buf[25]; - sprintf(buf, "%lu FPS", loopCount / lenSecs); - g_display->debugMsg(buf); - if (lenSecs >= 60) { - startAt = time(NULL); - loopCount = 0; - } - } -#endif -#ifdef SHOWPC - { - char buf[25]; - sprintf(buf, "%X", g_cpu->pc); - g_display->debugMsg(buf); - } -#endif -#ifdef SHOWMEMPAGE - { - char buf[40]; - sprintf(buf, "AUX %c/%c BNK %d BSR %c/%c ZP %c 80 %c INT %c", - g_vm->auxRamRead?'R':'_', - g_vm->auxRamWrite?'W':'_', - g_vm->bank1, - g_vm->readbsr ? 'R':'_', - g_vm->writebsr ? 'W':'_', - g_vm->altzp ? 'Y':'_', - g_vm->_80store ? 'Y' : '_', - g_vm->intcxrom ? 'Y' : '_'); - g_display->debugMsg(buf); - } - -#endif - - - } -} - diff --git a/opencv/dummy-speaker.cpp b/opencv/dummy-speaker.cpp deleted file mode 100644 index 6a3b32e..0000000 --- a/opencv/dummy-speaker.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "dummy-speaker.h" -#include - -DummySpeaker::DummySpeaker() -{ -} - -DummySpeaker::~DummySpeaker() -{ -} - -void DummySpeaker::toggle() -{ -} - -void DummySpeaker::maintainSpeaker(uint32_t c) -{ -} - -void DummySpeaker::beginMixing() -{ -} - -void DummySpeaker::mixOutput(uint8_t v) -{ -} diff --git a/opencv/dummy-speaker.h b/opencv/dummy-speaker.h deleted file mode 100644 index 9d7b1b1..0000000 --- a/opencv/dummy-speaker.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef __DUMMYSPEAKER_H -#define __DUMMYSPEAKER_H - -#include -#include -#include "physicalspeaker.h" - -class DummySpeaker : public PhysicalSpeaker { - public: - DummySpeaker(); - virtual ~DummySpeaker(); - - virtual void toggle(); - virtual void maintainSpeaker(uint32_t c); - virtual void beginMixing(); - virtual void mixOutput(uint8_t v); -}; - -#endif diff --git a/opencv/opencv-display.cpp b/opencv/opencv-display.cpp deleted file mode 100644 index deb603e..0000000 --- a/opencv/opencv-display.cpp +++ /dev/null @@ -1,269 +0,0 @@ -#include // isgraph -#include "opencv-display.h" - -#include "opencv2/core/core.hpp" -#include "opencv2/imgproc/imgproc.hpp" -#include "opencv2/highgui/highgui.hpp" -#include "opencv2/calib3d/calib3d.hpp" -#include "opencv2/features2d/features2d.hpp" - -using namespace cv; -using namespace std; - -#define WINDOWNAME "Aiie!" - -#include "bios-font.h" -#include "display-bg.h" - -#include "globals.h" -#include "applevm.h" - -// RGB map of each of the lowres colors -const uint8_t loresPixelColors[16][3] = { { 0, 0, 0 }, // black - { 195, 0, 48 }, // magenta - { 0, 0, 130 }, // dark blue - { 166, 52, 170 }, // purple - { 0, 146, 0 }, // dark green - { 105, 105, 105 }, // drak grey - { 24, 113, 255 }, // medium blue - { 12, 190, 235 }, // light blue - { 150, 85, 40 }, // brown - { 255, 24, 44 }, // orange - { 150, 170, 170 }, // light gray - { 255, 158, 150 }, // pink - { 0, 255, 0 }, // green - { 255, 255, 0 }, // yellow - { 130, 255, 130 }, // aqua - { 255, 255, 255 } // white -}; - -OpenCVDisplay::OpenCVDisplay() -{ - pixels = new Mat(240*2, 320*2, CV_8UC3); - - namedWindow(WINDOWNAME, CV_WINDOW_AUTOSIZE); -} - -OpenCVDisplay::~OpenCVDisplay() -{ - delete pixels; pixels = NULL; -} - -void OpenCVDisplay::redraw() -{ - // primarily for the device, where it's in and out of the - // bios. Draws the background image. - - for (int y=0; y<240; y++) { - for (int x=0; x<320; x++) { - uint8_t *p = &displayBitmap[(y * 320 + x)*3]; - drawPixel(x, y, p[0], p[1], p[2]); - } - } - - if (g_vm) { - drawDriveDoor(0, ((AppleVM *)g_vm)->DiskName(0)[0] == '\0'); - drawDriveDoor(1, ((AppleVM *)g_vm)->DiskName(1)[0] == '\0'); - } -} - -void OpenCVDisplay::drawDriveStatus(uint8_t which, bool isRunning) -{ - // location of status indicator for left drive - uint16_t xoff = 125; - uint16_t yoff = 213; - - // and right drive - if (which == 1) - xoff += 135; - - for (int y=0; y<1; y++) { - for (int x=0; x<6; x++) { - drawPixel(x + xoff, y + yoff, isRunning ? 0xF800 : 0x8AA9); - } - } - -} - -void OpenCVDisplay::drawDriveDoor(uint8_t which, bool isOpen) -{ - // location of drive door for left drive - uint16_t xoff = 55; - uint16_t yoff = 216; - - // location for right drive - if (which == 1) { - xoff += 134; - } - - for (int y=0; y<20; y++) { - for (int x=0; x<43; x++) { - uint8_t *p = &driveLatch[(y * 43 + x)*3]; - if (isOpen) { - p = &driveLatchOpen[(y * 43 + x)*3]; - } - drawPixel(x+xoff, y+yoff, p[0], p[1], p[2]); - } - } -} - -void OpenCVDisplay::drawBatteryStatus(uint8_t percent) -{ - uint16_t xoff = 300; - uint16_t yoff = 222; - - // the area around the apple is 12 wide - // it's exactly 11 high - // the color is 210/202/159 - - float watermark = ((float)percent / 100.0) * 11; - - for (int y=0; y<11; y++) { - uint8_t bgr = 210; - uint8_t bgg = 202; - uint8_t bgb = 159; - - if (11-y > watermark) { - // black... - bgr = bgg = bgb = 0; - } - - for (int x=0; x<11; x++) { - uint8_t *p = &appleBitmap[(y * 10 + (x-1))*4]; - // It's RGBA; blend w/ background color - - uint8_t r,g,b; - float alpha = (float)p[3] / 255.0; - r = (float)p[0] * alpha + (bgr * (1.0 - alpha)); - g = (float)p[1] * alpha + (bgg * (1.0 - alpha)); - b = (float)p[2] * alpha + (bgb * (1.0 - alpha)); - drawPixel(x+xoff, y+yoff, r, g, b); - } - } -} - - -#define BASEX 36 -#define BASEY 26 - -void OpenCVDisplay::blit(AiieRect r) -{ - uint8_t *videoBuffer = g_vm->videoBuffer; // FIXME: poking deep - for (uint8_t y=r.top; y<=r.bottom; y++) { - for (uint16_t x=r.left; x<=r.right; x++) { - uint16_t pixel = (y*320+x)/2; - uint8_t colorIdx; - if (x & 1) { - colorIdx = videoBuffer[pixel] & 0x0F; - } else { - colorIdx = videoBuffer[pixel] >> 4; - } - - // OpenCV is using BGR. This pixel-doubles both axes. - for (uint8_t xoff=0; xoff<2; xoff++) { - for (uint8_t yoff=0; yoff<2; yoff++) { - pixels->at(y*2+yoff+BASEY, (x*2+xoff+BASEX)*3 + 0) = (loresPixelColors[colorIdx][2]) & 0xFF; - pixels->at(y*2+yoff+BASEY, (x*2+xoff+BASEX)*3 + 1) = (loresPixelColors[colorIdx][1]) & 0xFF; - pixels->at(y*2+yoff+BASEY, (x*2+xoff+BASEX)*3 + 2) = (loresPixelColors[colorIdx][0]) & 0xFF; - } - } - } - } - - if (overlayMessage[0]) { - drawString(M_SELECTDISABLED, 1, 240 - 16 - 12, overlayMessage); - } - - - imshow(WINDOWNAME, *pixels); -} - -void OpenCVDisplay::drawPixel(uint16_t x, uint8_t y, uint16_t color) -{ - uint8_t - r = (color & 0xF800) >> 8, - g = (color & 0x7E0) >> 3, - b = (color & 0x1F) << 3; - - // Pixel-doubling - for (int yoff=0; yoff<2; yoff++) { - for (int xoff=0; xoff<2; xoff++) { - pixels->at(y*2+yoff, (x*2+xoff)*3 + 0) = b; - pixels->at(y*2+yoff, (x*2+xoff)*3 + 1) = g; - pixels->at(y*2+yoff, (x*2+xoff)*3 + 2) = r; - } - } -} - -void OpenCVDisplay::drawPixel(uint16_t x, uint8_t y, uint8_t r, uint8_t g, uint8_t b) -{ - // Pixel-doubling - for (int yoff=0; yoff<2; yoff++) { - for (int xoff=0; xoff<2; xoff++) { - pixels->at(y*2+yoff, (x*2+xoff)*3 + 0) = b; - pixels->at(y*2+yoff, (x*2+xoff)*3 + 1) = g; - pixels->at(y*2+yoff, (x*2+xoff)*3 + 2) = r; - } - } -} - -void OpenCVDisplay::drawCharacter(uint8_t mode, uint16_t x, uint8_t y, char c) -{ - int8_t xsize = 8, - ysize = 0x0C, - offset = 0x20; - uint16_t temp; - - c -= offset;// font starts with a space - - uint16_t offPixel, onPixel; - switch (mode) { - case M_NORMAL: - onPixel = 0xFFFF; - offPixel = 0x0010; - break; - case M_SELECTED: - onPixel = 0x0000; - offPixel = 0xFFFF; - break; - case M_DISABLED: - default: - onPixel = 0x7BEF; - offPixel = 0x0000; - break; - case M_SELECTDISABLED: - onPixel = 0x7BEF; - offPixel = 0xFFE0; - break; - } - - temp=(c*ysize); - for (int8_t y_off = 0; y_off <= ysize; y_off++) { - uint8_t ch = BiosFont[temp]; - for (int8_t x_off = 0; x_off <= xsize; x_off++) { - if (ch & (1 << (7-x_off))) { - drawPixel(x + x_off, y + y_off, onPixel); - } else { - drawPixel(x + x_off, y + y_off, offPixel); - } - } - temp++; - } - -} - -void OpenCVDisplay::drawString(uint8_t mode, uint16_t x, uint8_t y, const char *str) -{ - int8_t xsize = 8; // width of a char in this font - - for (int8_t i=0; i - -#include "opencv2/core/core.hpp" -#include "opencv2/imgproc/imgproc.hpp" -#include "opencv2/highgui/highgui.hpp" -#include "opencv2/calib3d/calib3d.hpp" -#include "opencv2/features2d/features2d.hpp" - -#include "physicaldisplay.h" - -enum { - M_NORMAL = 0, - M_SELECTED = 1, - M_DISABLED = 2, - M_SELECTDISABLED = 3 -}; - -class OpenCVDisplay : public PhysicalDisplay { - public: - OpenCVDisplay(); - virtual ~OpenCVDisplay(); - - virtual void blit(AiieRect r); - virtual void redraw(); - - virtual void drawDriveDoor(uint8_t which, bool isOpen); - virtual void drawDriveStatus(uint8_t which, bool isRunning); - virtual void drawBatteryStatus(uint8_t percent); - - void drawPixel(uint16_t x, uint8_t y, uint16_t color); - void drawPixel(uint16_t x, uint8_t y, uint8_t r, uint8_t g, uint8_t b); - virtual void drawCharacter(uint8_t mode, uint16_t x, uint8_t y, char c); - virtual void drawString(uint8_t mode, uint16_t x, uint8_t y, const char *str); - virtual void debugMsg(const char *msg); - - private: - - cv::Mat *pixels; -}; - -#endif diff --git a/opencv/opencv-filemanager.cpp b/opencv/opencv-filemanager.cpp deleted file mode 100644 index c966551..0000000 --- a/opencv/opencv-filemanager.cpp +++ /dev/null @@ -1,189 +0,0 @@ -#include // strcpy -#include -#include -#include -#include -#include - -#include "opencv-filemanager.h" - - -OpenCVFileManager::OpenCVFileManager() -{ - numCached = 0; -} - -OpenCVFileManager::~OpenCVFileManager() -{ -} - -int8_t OpenCVFileManager::openFile(const char *name) -{ - // See if there's a hole to re-use... - for (int i=0; i= MAXFILES) - return -1; - - - // No, so we'll add it to the end - strncpy(cachedNames[numCached], name, MAXPATH-1); - cachedNames[numCached][MAXPATH-1] = '\0'; // safety: ensure string terminator - fileSeekPositions[numCached] = 0; - - numCached++; - return numCached-1; -} - -void OpenCVFileManager::closeFile(int8_t fd) -{ - // invalid fd provided? - if (fd < 0 || fd >= numCached) - return; - - // clear the name - cachedNames[fd][0] = '\0'; -} - -const char *OpenCVFileManager::fileName(int8_t fd) -{ - if (fd < 0 || fd >= numCached) - return NULL; - - return cachedNames[fd]; -} - -int8_t OpenCVFileManager::readDir(const char *where, const char *suffix, char *outputFN, int8_t startIdx, uint16_t maxlen) -{ - // not used in this version - return -1; -} - -void OpenCVFileManager::seekBlock(int8_t fd, uint16_t block, bool isNib) -{ - if (fd < 0 || fd >= numCached) - return; - - if (isNib) { - fileSeekPositions[fd] = block * 416; - } else { - fileSeekPositions[fd] = block * 256; - } -} - - -bool OpenCVFileManager::readTrack(int8_t fd, uint8_t *toWhere, bool isNib) -{ - if (fd < 0 || fd >= numCached) - return false; - - if (cachedNames[fd][0] == 0) - return false; - - // open, seek, read, close. - bool ret = false; - int ffd = open(cachedNames[fd], O_RDONLY); - if (ffd) { - lseek(ffd, fileSeekPositions[fd], SEEK_SET); - if (isNib) { - ret = (read(ffd, toWhere, 0x1A00) == 0x1A00); - } else { - ret = (read(ffd, toWhere, 256 * 16) == 256 * 16); - } - close(ffd); - } - - return ret; -} - -bool OpenCVFileManager::readBlock(int8_t fd, uint8_t *toWhere, bool isNib) -{ - // open, seek, read, close. - if (fd < 0 || fd >= numCached) - return false; - - if (cachedNames[fd][0] == 0) - return false; - - // open, seek, read, close. - bool ret = false; - int ffd = open(cachedNames[fd], O_RDONLY); - if (ffd) { - lseek(ffd, fileSeekPositions[fd], SEEK_SET); - if (isNib) { - ret = (read(ffd, toWhere, 416) == 416); - } else { - ret = (read(ffd, toWhere, 256) == 256); - } - close(ffd); - } - - return ret; -} - -bool OpenCVFileManager::writeBlock(int8_t fd, uint8_t *fromWhere, bool isNib) -{ - // open, seek, write, close. - if (fd < 0 || fd >= numCached) - return false; - - if (cachedNames[fd][0] == 0) - return false; - - // don't know how to do this without seeking through the nibblized - // track data, so just give up for now - if (isNib) - return false; - - // open, seek, write, close. - int ffd = open(cachedNames[fd], O_WRONLY); - if (ffd) { - if (lseek(ffd, fileSeekPositions[fd], SEEK_SET) != fileSeekPositions[fd]) { - printf("ERROR: failed to seek to %lu\n", fileSeekPositions[fd]); - return false; - } - if (write(ffd, fromWhere, 256) != 256) { - printf("ERROR: failed to write 256 bytes\n"); - return false; - } - close(ffd); - } - return true; -} - -bool OpenCVFileManager::writeTrack(int8_t fd, uint8_t *fromWhere, bool isNib) -{ - // open, seek, write, close. - if (fd < 0 || fd >= numCached) - return false; - - if (cachedNames[fd][0] == 0) - return false; - - // open, seek, write, close. - int ffd = open(cachedNames[fd], O_WRONLY); - if (ffd) { - if (lseek(ffd, fileSeekPositions[fd], SEEK_SET) != fileSeekPositions[fd]) { - printf("ERROR: failed to seek to %lu\n", fileSeekPositions[fd]); - return false; - } - int16_t wrsize = 256 * 16; - if (isNib) - wrsize = 0x1A00; - - if (write(ffd, fromWhere, wrsize) != wrsize) { - printf("ERROR: failed to write bytes\n"); - return false; - } - close(ffd); - } - return true; -} diff --git a/opencv/opencv-filemanager.h b/opencv/opencv-filemanager.h deleted file mode 100644 index 82133d0..0000000 --- a/opencv/opencv-filemanager.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef __OPENCV_FILEMANAGER_H -#define __OPENCV_FILEMANAGER_H - -#include "filemanager.h" -#include - -class OpenCVFileManager : public FileManager { - public: - OpenCVFileManager(); - virtual ~OpenCVFileManager(); - - virtual int8_t openFile(const char *name); - virtual void closeFile(int8_t fd); - - virtual const char *fileName(int8_t fd); - - virtual int8_t readDir(const char *where, const char *suffix, char *outputFN, int8_t startIdx, uint16_t maxlen); - virtual void seekBlock(int8_t fd, uint16_t block, bool isNib = false); - virtual bool readTrack(int8_t fd, uint8_t *toWhere, bool isNib = false); - virtual bool readBlock(int8_t fd, uint8_t *toWhere, bool isNib = false); - virtual bool writeBlock(int8_t fd, uint8_t *fromWhere, bool isNib = false); - virtual bool writeTrack(int8_t fd, uint8_t *fromWhere, bool isNib = false); - - private: - int8_t numCached; - char cachedNames[MAXFILES][MAXPATH]; - unsigned long fileSeekPositions[MAXFILES]; - -}; - -#endif diff --git a/opencv/opencv-keyboard.cpp b/opencv/opencv-keyboard.cpp deleted file mode 100644 index 867ba0c..0000000 --- a/opencv/opencv-keyboard.cpp +++ /dev/null @@ -1,223 +0,0 @@ -#include "opencv-keyboard.h" - -/* - * OpenCV doesn't support very sophisticated keyboard interaction. - * You can't query modifier keys; you don't get up-and-down - * events. There's just a simple "has any key been pressed" method. - */ - -#include "opencv2/core/core.hpp" -#include "opencv2/imgproc/imgproc.hpp" -#include "opencv2/highgui/highgui.hpp" -#include "opencv2/calib3d/calib3d.hpp" -#include "opencv2/features2d/features2d.hpp" - -using namespace cv; -using namespace std; - -OpenCVKeyboard::OpenCVKeyboard(VMKeyboard *k) : PhysicalKeyboard(k) -{ -} - -OpenCVKeyboard::~OpenCVKeyboard() -{ -} - -typedef struct { - int8_t actualKey; - bool shifted; -} keymapChar; - -// keymap starts at space (32), ends at delete (127). -// Note that this maps them based on what the Apple //e expects. It's the -// same as a modern US keyboard. -const keymapChar keymap[96] = - { { ' ', false }, // space - { '1', true }, // ! - { '\'', true }, // " - { '3', true }, // # - { '4', true }, // $ - { '5', true }, // % - { '7', true }, // & - { '\'', false}, // ' - { '9', true }, // ( - { '0', true }, // ) - { '8', true }, // * - { '=', true }, // + - { ',', false }, // , - { '-', false }, // - - { '.', false }, // . - { '/', false }, // / - { '0', false }, // 0 - { '1', false }, // 1 - { '2', false }, // 2 - { '3', false }, // 3 - { '4', false }, // 4 - { '5', false }, // 5 - { '6', false }, // 6 - { '7', false }, // 7 - { '8', false }, // 8 - { '9', false }, // 9 - { ':', true }, // : - { ';', false }, // ; - { ',', true }, // < - { '=', false }, // = - { '.', true }, // > - { '/', true }, // ? - { '2', true }, // @ - { 'A', true }, // A - { 'B', true }, // B - { 'C', true }, // C - { 'D', true }, // D - { 'E', true }, // E - { 'F', true }, // F - { 'G', true }, // G - { 'H', true }, // H - { 'I', true }, // I - { 'J', true }, // J - { 'K', true }, // K - { 'L', true }, // L - { 'M', true }, // M - { 'N', true }, // N - { 'O', true }, // O - { 'P', true }, // P - { 'Q', true }, // Q - { 'R', true }, // R - { 'S', true }, // S - { 'T', true }, // T - { 'U', true }, // U - { 'V', true }, // V - { 'W', true }, // W - { 'X', true }, // X - { 'Y', true }, // Y - { 'Z', true }, // Z -#ifndef TEENSYDUINO - { LA, false }, // [ -#else - { '[', false }, // [ -#endif - { '\\', false}, // \ ... -#ifndef TEENSYDUINO - { RA, false }, // ] -#else - { ']', false }, // ] -#endif - { '6', true }, // ^ - { '-', true }, // _ - { '`', false }, // ` - { 'A', false }, // a - { 'B', false }, // b - { 'C', false }, // c - { 'D', false }, // d - { 'E', false }, // e - { 'F', false }, // f - { 'G', false }, // g - { 'H', false }, // h - { 'I', false }, // i - { 'J', false }, // j - { 'K', false }, // k - { 'L', false }, // l - { 'M', false }, // m - { 'N', false }, // n - { 'O', false }, // o - { 'P', false }, // p - { 'Q', false }, // q - { 'R', false }, // r - { 'S', false }, // s - { 'T', false }, // t - { 'U', false }, // u - { 'V', false }, // v - { 'W', false }, // w - { 'X', false }, // x - { 'Y', false }, // y - { 'Z', false }, // z - { '[', true }, // { - { '\\', true }, // | - { ']', true }, // } - { '`', true }, // ~ - { DEL, false } // delete - }; - -void OpenCVKeyboard::maintainKeyboard() -{ - static int invalidCount = 0; - int c = cv::waitKey(1); - // OpenCV relies on KeyRepeat to deliver individual presses. We want - // to guess about "it's still down": so, unless we get > 3 invalid - // "-1" values in a row, we're gonna assume it's still pressed. - if (c == -1) { - invalidCount++; - if (invalidCount < 4) { - return; - } - } else { - invalidCount = 0; - } - - if (c == -1) { - if (lastKey >= ' ' && lastKey <= 127) { - vmkeyboard->keyReleased(keymap[lastKey-' '].actualKey); - if (keymap[lastKey-' '].shifted) { - vmkeyboard->keyReleased(LSHFT); - } - } else { - vmkeyboard->keyReleased(lastKey); - } - - lastKey = -1; - return; - } - - - if (c == 0xF700) { - c = UARR; // up - } else if (c == 0xF701) { - c = DARR; // down - } else if (c == 0xF702) { - c = LARR; // left - } else if (c == 0xF703) { - c = RARR; // right - } - - // If we're already repeating this key, do nothing - if (lastKey != -1 && - lastKey == c) { - return; - } - - // If it's a different key, then do a key up - if (lastKey != -1) { - if (lastKey >= ' ' && lastKey <= 127) { - vmkeyboard->keyReleased(keymap[lastKey-' '].actualKey); - if (keymap[lastKey-' '].shifted) { - vmkeyboard->keyReleased(LSHFT); - } - } else { - vmkeyboard->keyReleased(lastKey); - } - - lastKey = -1; - } - - // Now it's a new keypress - do a key down - - if (c >= ' ' && c <= 127) { - if (keymap[c-' '].shifted) { - vmkeyboard->keyDepressed(LSHFT); - } - vmkeyboard->keyDepressed(keymap[c-' '].actualKey); - - lastKey = c; - return; - } - - // Any other key that could have been reported: - // ESC RET TAB LA RA LARR RARR DARR UARR - vmkeyboard->keyDepressed(c); - - // anything else isn't reported by OpenCV, so we can't report it - // specifically. So these are ignored: - // _CTRL LSHFT RSHFT LOCK LA RA - - lastKey = c; -} diff --git a/opencv/opencv-keyboard.h b/opencv/opencv-keyboard.h deleted file mode 100644 index b87386e..0000000 --- a/opencv/opencv-keyboard.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __OPENCV_KEYBOARD_H -#define __OPENCV_KEYBOARD_H - -#include "physicalkeyboard.h" -#include "vmkeyboard.h" - -class OpenCVKeyboard : public PhysicalKeyboard { - public: - OpenCVKeyboard(VMKeyboard *k); - virtual ~OpenCVKeyboard(); - - virtual void maintainKeyboard(); - private: - int lastKey; -}; - -#endif diff --git a/opencv/opencv-paddles.cpp b/opencv/opencv-paddles.cpp deleted file mode 100644 index dc2f16e..0000000 --- a/opencv/opencv-paddles.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include - -#include "opencv-paddles.h" - -#include "opencv2/core/core.hpp" -#include "opencv2/imgproc/imgproc.hpp" -#include "opencv2/highgui/highgui.hpp" -#include "opencv2/calib3d/calib3d.hpp" -#include "opencv2/features2d/features2d.hpp" - -using namespace cv; -using namespace std; - -// FIXME: abstract this somewhere -#define WINDOWNAME "6502core" -#define WINDOWHEIGHT (240*2) -#define WINDOWWIDTH (320*2) - -#include "globals.h" - -static void mouseCallback(int event, int x, int y, int flags, void* userdata) -{ - OpenCVPaddles *a = (OpenCVPaddles *)userdata; - - if (event == EVENT_MOUSEMOVE) { - a->p0 = ((float) x / (float)WINDOWWIDTH) * 255.0; - a->p1 = ((float) y / (float)WINDOWHEIGHT) * 255.0; - } -} - -OpenCVPaddles::OpenCVPaddles() -{ - p0 = p1 = 127; - setMouseCallback(WINDOWNAME, mouseCallback, this); -} - -OpenCVPaddles::~OpenCVPaddles() -{ -} - -void OpenCVPaddles::startReading() -{ - g_vm->triggerPaddleInCycles(0, 12 * p0); - g_vm->triggerPaddleInCycles(1, 12 * p1); -} - -uint8_t OpenCVPaddles::paddle0() -{ - return p0; -} - -uint8_t OpenCVPaddles::paddle1() -{ - return p1; -} diff --git a/opencv/opencv-paddles.h b/opencv/opencv-paddles.h deleted file mode 100644 index da3e352..0000000 --- a/opencv/opencv-paddles.h +++ /dev/null @@ -1,17 +0,0 @@ -#include - -#include "physicalpaddles.h" - -class OpenCVPaddles : public PhysicalPaddles { - public: - OpenCVPaddles(); - virtual ~OpenCVPaddles(); - - virtual void startReading(); - virtual uint8_t paddle0(); - virtual uint8_t paddle1(); - - public: - uint8_t p0; - uint8_t p1; -}; diff --git a/opencv/opencv-printer.cpp b/opencv/opencv-printer.cpp deleted file mode 100644 index ccde95b..0000000 --- a/opencv/opencv-printer.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "opencv-printer.h" - -#include "opencv2/core/core.hpp" -#include "opencv2/imgproc/imgproc.hpp" -#include "opencv2/highgui/highgui.hpp" -#include "opencv2/calib3d/calib3d.hpp" -#include "opencv2/features2d/features2d.hpp" - -using namespace cv; -using namespace std; - -#define WINDOWNAME "printer" - -#define HEIGHT 800 -#define NATIVEWIDTH 960 // FIXME: printer can change density... - - -//#define WIDTH 384 // emulating the teeny printer I've got -#define WIDTH 960 - -OpenCVPrinter::OpenCVPrinter() -{ - pixels = new Mat(HEIGHT, WIDTH, CV_8U); - *pixels = cv::Scalar(0xFF); - ypos = 0; - isDirty = false; - namedWindow(WINDOWNAME, CV_WINDOW_AUTOSIZE); -} - -OpenCVPrinter::~OpenCVPrinter() -{ - delete pixels; pixels = NULL; -} - -void OpenCVPrinter::update() -{ - if (isDirty) { - imshow(WINDOWNAME, *pixels); - isDirty = false; - } -} - -void OpenCVPrinter::addLine(uint8_t *rowOfBits) -{ - isDirty = true; - for (int yoff=0; yoff<9; yoff++) { - // 960 pixels == 120 bytes -- FIXME - for (int i=0; i<(NATIVEWIDTH/8); i++) { - uint8_t bv = rowOfBits[yoff*120+i]; - for (int xoff=0; xoff<8; xoff++) { - // scale X from "actual FX80" coordinates to "real printer" coordinates - uint16_t actualX = (uint16_t)(((float)(i*8+xoff) * (float)WIDTH) / (float)NATIVEWIDTH); - - uint8_t oldPixel = pixels->at((ypos + yoff)%HEIGHT, actualX); - uint8_t pixelColor = (bv & (1 << (7-xoff))) ? 0x00 : 0xFF; - // Make sure to preserve any pixels we've already drawn - pixels->at((ypos + yoff)%HEIGHT, actualX) = ~(~oldPixel | ~pixelColor); - } - } - } - - if (ypos >= HEIGHT) { - ypos = 0; - } -} - -void OpenCVPrinter::moveDownPixels(uint8_t p) -{ - ypos+= p; - if (ypos >= HEIGHT) { - // clear page & restart - *pixels = cv::Scalar(0xFF); - ypos = 0; - } -} diff --git a/opencv/opencv-printer.h b/opencv/opencv-printer.h deleted file mode 100644 index cbf1d70..0000000 --- a/opencv/opencv-printer.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef __OPENCV_PRINTER_H -#define __OPENCV_PRINTER_H - -#include - -#include "opencv2/core/core.hpp" -#include "opencv2/imgproc/imgproc.hpp" -#include "opencv2/highgui/highgui.hpp" -#include "opencv2/calib3d/calib3d.hpp" -#include "opencv2/features2d/features2d.hpp" - -#include "physicalprinter.h" - -class OpenCVPrinter : public PhysicalPrinter { - public: - OpenCVPrinter(); - virtual ~OpenCVPrinter(); - - virtual void addLine(uint8_t *rowOfBits); // must be 960 pixels wide (120 bytes) - - virtual void update(); - - virtual void moveDownPixels(uint8_t p); - - private: - bool isDirty; - uint16_t ypos; - cv::Mat *pixels; -}; - -#endif diff --git a/opencv/timeutil.h b/opencv/timeutil.h deleted file mode 100644 index d5edb94..0000000 --- a/opencv/timeutil.h +++ /dev/null @@ -1,143 +0,0 @@ -#include -#include -// Derived from -// http://stackoverflow.com/questions/5167269/clock-gettime-alternative-in-mac-os-x - -#define ORWL_NANO (+1.0E-9) -#define ORWL_GIGA UINT64_C(1000000000) -#define NANOSECONDS_PER_SECOND 1000000000UL -#define CYCLES_PER_SECOND 1023000UL -#define NANOSECONDS_PER_CYCLE (NANOSECONDS_PER_SECOND / CYCLES_PER_SECOND) - -static double orwl_timebase = 0.0; -static uint64_t orwl_timestart = 0; -static void _init_darwin_shim(void) { - mach_timebase_info_data_t tb = { 0 }; - mach_timebase_info(&tb); - orwl_timebase = tb.numer; - orwl_timebase /= tb.denom; - orwl_timestart = mach_absolute_time(); -} - -static int do_gettime(struct timespec *tp) { - double diff = (mach_absolute_time() - orwl_timestart) * orwl_timebase; - tp->tv_sec = diff * ORWL_NANO; - tp->tv_nsec = diff - (tp->tv_sec * ORWL_GIGA); - return 0; -} - -// adds the number of microseconds that 'cycles' takes to *start and -// returns it in *out -static void timespec_add_cycles(struct timespec *start, - uint32_t cycles, - struct timespec *out) -{ - out->tv_sec = start->tv_sec; - out->tv_nsec = start->tv_nsec; - - uint64_t nanosToAdd = NANOSECONDS_PER_CYCLE * cycles; - out->tv_sec += (nanosToAdd / NANOSECONDS_PER_SECOND); - out->tv_nsec += (nanosToAdd % NANOSECONDS_PER_SECOND); - - if (out->tv_nsec >= 1000000000L) { - out->tv_sec++ ; - out->tv_nsec -= 1000000000L; - } -} - -// adds the number of microseconds given to *start and -// returns it in *out -static void timespec_add_us(struct timespec *start, - uint64_t micros, - struct timespec *out) -{ - out->tv_sec = start->tv_sec; - out->tv_nsec = start->tv_nsec; - - uint64_t nanosToAdd = micros * 1000L; - out->tv_sec += (nanosToAdd / NANOSECONDS_PER_SECOND); - out->tv_nsec += (nanosToAdd % NANOSECONDS_PER_SECOND); - - if (out->tv_nsec >= 1000000000L) { - out->tv_sec++ ; - out->tv_nsec -= 1000000000L; - } -} - -static void timespec_diff(struct timespec *start, - struct timespec *end, - struct timespec *diff, - bool *negative) { - struct timespec t; - - if (negative) - { - *negative = false; - } - - // if start > end, swizzle... - if ( (start->tv_sec > end->tv_sec) || ((start->tv_sec == end->tv_sec) && (start->tv_nsec > end->tv_nsec)) ) - { - t=*start; - *start=*end; - *end=t; - if (negative) - { - *negative = true; - } - } - - // assuming time_t is signed ... - if (end->tv_nsec < start->tv_nsec) - { - t.tv_sec = end->tv_sec - start->tv_sec - 1; - t.tv_nsec = 1000000000 + end->tv_nsec - start->tv_nsec; - } - else - { - t.tv_sec = end->tv_sec - start->tv_sec; - t.tv_nsec = end->tv_nsec - start->tv_nsec; - } - - diff->tv_sec = t.tv_sec; - diff->tv_nsec = t.tv_nsec; -} - -// tsCompare: return -1, 0, 1 for (a < b), (a == b), (a > b) -static int8_t tsCompare(struct timespec *A, struct timespec *B) -{ - if (A->tv_sec < B->tv_sec) - return -1; - - if (A->tv_sec > B->tv_sec) - return 1; - - if (A->tv_nsec < B->tv_nsec) - return -1; - - if (A->tv_nsec > B->tv_nsec) - return 1; - - return 0; -} - -static struct timespec tsSubtract(struct timespec time1, struct timespec time2) -{ - struct timespec result; - if ((time1.tv_sec < time2.tv_sec) || - ((time1.tv_sec == time2.tv_sec) && - (time1.tv_nsec <= time2.tv_nsec))) {/* TIME1 <= TIME2? */ - result.tv_sec = result.tv_nsec = 0 ; - } else {/* TIME1 > TIME2 */ - result.tv_sec = time1.tv_sec - time2.tv_sec ; - if (time1.tv_nsec < time2.tv_nsec) { - result.tv_nsec = time1.tv_nsec + 1000000000L - time2.tv_nsec ; - result.tv_sec-- ;/* Borrow a second. */ - } else { - result.tv_nsec = time1.tv_nsec - time2.tv_nsec ; - } - } - - return (result) ; -} -