added SDL clock for testing

This commit is contained in:
Jorj Bauer 2017-02-28 23:44:03 -05:00
parent 609e5456b2
commit e033f6e039
5 changed files with 167 additions and 1 deletions

View File

@ -8,7 +8,7 @@ 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 lcg.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
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 sdl/sdl-clock.o
ROMS=apple/applemmu-rom.h apple/diskii-rom.h apple/parallel-rom.h

View File

@ -29,6 +29,9 @@ AppleVM::AppleVM()
#ifdef TEENSYDUINO
teensyClock = new TeensyClock((AppleMMU *)mmu);
((AppleMMU *)mmu)->setSlot(7, teensyClock);
#else
sdlClock = new SDLClock((AppleMMU *)mmu);
((AppleMMU *)mmu)->setSlot(7, sdlClock);
#endif
}
@ -36,6 +39,8 @@ AppleVM::~AppleVM()
{
#ifdef TEENSYDUINO
delete teensyClock;
#else
delete sdlClock;
#endif
delete disk6;
delete parallel;

View File

@ -9,6 +9,8 @@
#include "mockingboard.h"
#ifdef TEENSYDUINO
#include "teensy-clock.h"
#else
#include "sdl-clock.h"
#endif
#include "vm.h"
@ -37,6 +39,8 @@ class AppleVM : public VM {
Mockingboard *mockingboard;
#ifdef TEENSYDUINO
TeensyClock *teensyClock;
#else
SDLClock *sdlClock;
#endif
};

131
sdl/sdl-clock.cpp Normal file
View File

@ -0,0 +1,131 @@
#include <string.h> // memset
#include <time.h>
#include "sdl-clock.h"
#include "applemmu.h" // for FLOATING
/*
* http://apple2online.com/web_documents/prodos_technical_notes.pdf
*
* When ProDOS calls a clock card, the card deposits an ASCII string
* in the GETLN input buffer in the form: 07,04,14,22,46,57. The
* string translates as the following:
*
* 07 = the month, July
* 04 = the day of the week (00 = Sun)
* 14 = the date (00 to 31)
* 22 = the hour (00 to 23)
* 46 = the minute (00 to 59)
* 57 = the second (00 to 59)
*/
static void timeToProDOS(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute,
uint8_t proDOStimeOut[4])
{
proDOStimeOut[0] = ((year % 100) << 1) | (month >> 3);
proDOStimeOut[1] = ((month & 0x0F) << 5) | (day & 0x1F);
proDOStimeOut[2] = hour & 0x1F;
proDOStimeOut[3] = minute & 0x3F;
}
SDLClock::SDLClock(AppleMMU *mmu)
{
this->mmu = mmu;
}
SDLClock::~SDLClock()
{
}
void SDLClock::Reset()
{
}
uint8_t SDLClock::readSwitches(uint8_t s)
{
// When any switch is read, we'll put the current time in the prodos time buffer
time_t lt;
time(&lt);
struct tm *ct = localtime(&lt);
// Put the date/time in the official ProDOS buffer
uint8_t prodosOut[4];
timeToProDOS(ct->tm_year+1900,
ct->tm_mon,
ct->tm_mday,
ct->tm_hour,
ct->tm_min,
prodosOut);
mmu->write(0xBF90, prodosOut[0]);
mmu->write(0xBF91, prodosOut[1]);
mmu->write(0xBF92, prodosOut[2]);
mmu->write(0xBF93, prodosOut[3]);
// and also generate a date/time that contains seconds, but not a
// year, which it also consumes
char ts[18];
sprintf(ts, "%.2d,%.2d,%.2d,%.2d,%.2d,%.2d",
ct->tm_mon,
ct->tm_wday,
ct->tm_mday,
ct->tm_hour,
ct->tm_min,
ct->tm_sec);
uint8_t i = 0;
while (ts[i]) {
mmu->write(0x200 + i, ts[i] | 0x80);
i++;
}
return FLOATING;
}
void SDLClock::writeSwitches(uint8_t s, uint8_t v)
{
// printf("unimplemented write to the clock - 0x%X\n", v);
}
// FIXME: this assumes slot #7
void SDLClock::loadROM(uint8_t *toWhere)
{
memset(toWhere, 0xEA, 256); // fill the page with NOPs
// ProDOS only needs these 4 bytes to recognize that a clock is present
toWhere[0x00] = 0x08; // PHP
toWhere[0x02] = 0x28; // PLP
toWhere[0x04] = 0x58; // CLI
toWhere[0x06] = 0x70; // BVS
// Pad out those bytes so they will return control well. The program
// at c700 becomes
//
// C700: PHP ; push to stack
// NOP ; filler (filled in by memory clear)
// PLP ; pop from stack
// RTS ; return
// CLI ; required to detect driver, but not used
// NOP ; filled in by memory clear
// BVS ; required to detect driver, but not used
toWhere[0x03] = 0x60; // RTS
// And it needs a small routing here to read/write it:
// 0x08: read
toWhere[0x08] = 0x4C; // JMP $C710
toWhere[0x09] = 0x10;
toWhere[0x0A] = 0xC7;
// 0x0b: write
toWhere[0x0B] = 0x8D; // STA $C0F0 (slot 7's first switch)
toWhere[0x0C] = 0xF0;
toWhere[0x0D] = 0xC0;
toWhere[0x0E] = 0x60; // RTS
// simple read
toWhere[0x10] = 0xAD; // LDA $C0F0 (slot 7's first switch)
toWhere[0x11] = 0xF0;
toWhere[0x12] = 0xC0;
toWhere[0x13] = 0x60; // RTS
}

26
sdl/sdl-clock.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef __SDLCLOCK_H
#define __SDLCLOCK_H
#include <stdint.h>
#include <stdio.h>
#include "slot.h"
#include "applemmu.h"
class SDLClock : public Slot {
public:
SDLClock(AppleMMU *mmu);
virtual ~SDLClock();
virtual void Reset();
virtual uint8_t readSwitches(uint8_t s);
virtual void writeSwitches(uint8_t s, uint8_t v);
virtual void loadROM(uint8_t *toWhere);
private:
AppleMMU *mmu;
};
#endif