From fe46c4ab529054e1086d9134749f5e741160c7fc Mon Sep 17 00:00:00 2001 From: Jorj Bauer Date: Tue, 29 Dec 2020 09:12:33 -0500 Subject: [PATCH] importing old mouse work to new teensy 4.1 --- Makefile | 6 ++-- apple/applemmu.cpp | 88 ++++++++++++++++++++++++++++++---------------- apple/applevm.cpp | 3 ++ apple/applevm.h | 2 ++ apple/mouse.cpp | 86 ++++++++++++++++++++++++++++++++++++++++++++ apple/mouse.h | 31 ++++++++++++++++ apple/pia6821.cpp | 43 ++++++++++++++++++++++ apple/pia6821.h | 31 ++++++++++++++++ apple/slot.h | 3 ++ util/genrom.pl | 3 ++ vmram.cpp | 12 +++++-- vmram.h | 6 ++-- 12 files changed, 276 insertions(+), 38 deletions(-) create mode 100644 apple/mouse.cpp create mode 100644 apple/mouse.h create mode 100644 apple/pia6821.cpp create mode 100644 apple/pia6821.h diff --git a/Makefile b/Makefile index dcf8e35..886e889 100755 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ TSRC=cpu.cpp util/testharness.cpp COMMONSRCS=cpu.cpp apple/appledisplay.cpp apple/applekeyboard.cpp apple/applemmu.cpp apple/applevm.cpp apple/diskii.cpp apple/nibutil.cpp LRingBuffer.cpp globals.cpp apple/parallelcard.cpp apple/fx80.cpp lcg.cpp apple/hd32.cpp images.cpp apple/appleui.cpp vmram.cpp bios.cpp apple/noslotclock.cpp apple/woz.cpp apple/crc32.c apple/woz-serializer.cpp -COMMONOBJS=cpu.o apple/appledisplay.o apple/applekeyboard.o apple/applemmu.o apple/applevm.o apple/diskii.o apple/nibutil.o LRingBuffer.o globals.o apple/parallelcard.o apple/fx80.o lcg.o apple/hd32.o images.o apple/appleui.o vmram.o bios.o apple/noslotclock.o apple/woz.o apple/crc32.o apple/woz-serializer.o +COMMONOBJS=cpu.o apple/appledisplay.o apple/applekeyboard.o apple/applemmu.o apple/applevm.o apple/diskii.o apple/nibutil.o LRingBuffer.o globals.o apple/parallelcard.o apple/fx80.o lcg.o apple/hd32.o images.o apple/appleui.o vmram.o bios.o apple/noslotclock.o apple/woz.o apple/crc32.o apple/woz-serializer.o apple/mouse.o apple/pia6821.o FBSRCS=linuxfb/linux-speaker.cpp linuxfb/fb-display.cpp linuxfb/linux-keyboard.cpp linuxfb/fb-paddles.cpp nix/nix-filemanager.cpp linuxfb/aiie.cpp linuxfb/linux-printer.cpp nix/nix-clock.cpp nix/nix-prefs.cpp @@ -20,7 +20,7 @@ SDLSRCS=sdl/sdl-speaker.cpp sdl/sdl-display.cpp sdl/sdl-keyboard.cpp sdl/sdl-pad SDLOBJS=sdl/sdl-speaker.o sdl/sdl-display.o sdl/sdl-keyboard.o sdl/sdl-paddles.o nix/nix-filemanager.o sdl/aiie.o sdl/sdl-printer.o nix/nix-clock.o nix/nix-prefs.o nix/debugger.o nix/disassembler.o -ROMS=apple/applemmu-rom.h apple/diskii-rom.h apple/parallel-rom.h apple/hd32-rom.h +ROMS=apple/applemmu-rom.h apple/diskii-rom.h apple/parallel-rom.h apple/hd32-rom.h MouseInterface.rom .PHONY: roms clean @@ -40,7 +40,7 @@ test: $(TSRC) ./testharness -f tests/65c02-all.bin -s 0x200 roms: apple2e.rom disk.rom parallel.rom HDDRVR.BIN - ./util/genrom.pl apple2e.rom disk.rom parallel.rom HDDRVR.BIN + ./util/genrom.pl apple2e.rom disk.rom parallel.rom HDDRVR.BIN MouseInterface.rom apple/applemmu-rom.h: roms diff --git a/apple/applemmu.cpp b/apple/applemmu.cpp index 899cd3f..63f0464 100644 --- a/apple/applemmu.cpp +++ b/apple/applemmu.cpp @@ -52,8 +52,9 @@ page 0-1 4 pages (1k) [altzp] 0xC1-0xCF 15 * 2 pages = 30 pages (7.5k) [intcxrom, slotLatch] 0xD0 - 0xDF 16 * 5 pages = 80 pages (20k) [altzp, bank2, {r,w}bsr] 0xE0 - 0xFF 32 * 3 pages = 96 pages (24k) [altzp, {r,w}bsr] +... plus 8 additional pages for the mouse ROM -= 147.75k (591 pages) stored off-chip += 147.75k (591 pages) stored off-chip (+ 8 more) Current read page table [512 bytes] in real ram Current write page table [512 bytes] in real ram @@ -84,10 +85,11 @@ enum { MP_60 = 192, // 0x60 - 0xBF * 2 = 192; 192..383 MP_C1 = 384, // start of 0xC1-0xCF * 2 page variants = 30; 384-413 - MP_D0 = 414, // start of 0xD0-0xDF * 5 page variants = 80; 414-493 - MP_E0 = 493, // start of 0xE0-0xFF * 3 page variants = 96; 494-589 - MP_C0 = 590 - // = 591 pages in all (147.75k) + MP_C8 = 398, // 0xc8 - 0xcf, 3 page variants = 24; 398 - 421 + MP_D0 = 422, // start of 0xD0-0xDF * 5 page variants = 80; 422 - 501 + MP_E0 = 502, // start of 0xE0-0xFF * 3 page variants = 96; 502 - 597 + MP_C0 = 598 + // = 599 pages in all (149.75k) }; @@ -115,10 +117,14 @@ static uint16_t _pageNumberForRam(uint8_t highByte, uint8_t variant) if (highByte == 0xc0) { return MP_C0; } - if (highByte <= 0xCF) { - // 0xC1-0xCF 15 * 2 pages = 30 pages (7.5k) + if (highByte <= 0xC7) { + // 0xC1 - 0xC7 return ((highByte - 0xC1) * 2 + variant + MP_C1); } + if (highByte <= 0xCF) { + // bank-switched ROM. 0 = built-in; 1 = 80-column (slot 3); 2 = mouse (slot 4) + return ((highByte - 0xC8) * 3 + variant + MP_C8); + } if (highByte <= 0xDF) { // 0xD0 - 0xDF 16 * 5 pages = 80 pages (20k) @@ -917,6 +923,8 @@ void AppleMMU::resetRAM() // Load system ROM for (uint16_t i=0x80; i<=0xFF; i++) { + uint16_t page0 = _pageNumberForRam(i, 0); + uint16_t page1 = _pageNumberForRam(i, 1); for (uint16_t k=0; k<0x100; k++) { uint16_t idx = ((i-0x80) << 8) | k; #ifdef TEENSYDUINO @@ -924,30 +932,22 @@ void AppleMMU::resetRAM() #else uint8_t v = romData[idx]; #endif - for (int j=0; j<5; j++) { - // For the ROM section from 0xc100 .. 0xcfff, we load in to - // an alternate page space (INTCXROM). - - uint16_t page0 = _pageNumberForRam(i, 0); - - if (i >= 0xc1 && i <= 0xcf) { - // If we want to convince the VM we've got 128k of RAM, we - // need to load C3 ROM in page 0 (but not 1, meaning there's - // a board installed); and C800.CFFF in both page [0] and [1] - // (meaning there's an extended 80-column ROM available, - // that is also physically in the slot). - // Everything else goes in page [1]. - - uint16_t page1 = _pageNumberForRam(i, 1); - - if (i == 0xc3) { - g_ram.writeByte((page0 << 8) | (k & 0xFF), v); - } - else if (i >= 0xc8) { + // The space from 0xC1 through 0xCF is ROM image territory. We + // load the C3 ROM in to page 0, but not in page 1; and then we + // load C800.CFFF to both the main ROM (page 0) and the C3 aux ROM + // (page 1) to convince the VM that we've got 128k of RAM and an + // 80-column card. + if (i >= 0xc1 && i <= 0xcf) { + if (i == 0xc3) { + // C300..C3FF => built-in ROM + g_ram.writeByte((page0 << 8) | (k & 0xFF), v); + } else if (i >= 0xc8) { + // C800..CFFF => built-in ROM and slot 3 extended ROM + if (i >= 0xc1 && i <= 0xcf) { g_ram.writeByte((page0 << 8) | (k & 0xFF), v); g_ram.writeByte((page1 << 8) | (k & 0xFF), v); - } - else { + } else { + // C000..C2FF and C400..C7FF are main ROM g_ram.writeByte((page1 << 8) | (k & 0xFF), v); } } else { @@ -962,12 +962,33 @@ void AppleMMU::resetRAM() for (uint8_t slotnum = 1; slotnum <= 7; slotnum++) { uint16_t page0 = _pageNumberForRam(0xC0 + slotnum, 0); if (slots[slotnum]) { + // Load the primary ROM for this peripheral (0xCsXX..0xCsFF) uint8_t tmpBuf[256]; memset(tmpBuf, 0, sizeof(tmpBuf)); slots[slotnum]->loadROM(tmpBuf); for (int i=0; i<256; i++) { g_ram.writeByte( (page0 << 8) + i, tmpBuf[i] ); } + + // See if there's an extended 2k ROM for this peripheral (0xC800..0xCFFF) + if (slots[slotnum]->hasExtendedRom()) { + for (int j=0; j<8; j++) { + // Load each of the 256 byte chunks separately to its own VMRam page + uint16_t slotPage = 0; + if (slotnum == 4) { + slotPage = _pageNumberForRam(0xC8 + j, 2); + } else { +#ifndef TEENSYDUINO + fprintf(stderr, "ERROR: unsupported extended ROM peripheral in slot %d\n", slotnum); + exit(1); +#endif + } + if (slotPage) { + uint8_t *p = g_ram.memPtr(slotPage << 8); + slots[slotnum]->loadExtendedRom(p, j * 256); + } + } + } } } @@ -1066,12 +1087,17 @@ void AppleMMU::updateMemoryPages() // If slotLatch is set (!= -1), then we are mapping 2k of ROM // for a given peripheral to C800..CFFF. if (slotLatch != -1) { - // FIXME: the only peripheral we support this with right now is - // the 80-column card. + // FIXME: this is a hacky mess. Slot 3 (the 80-col card) is + // supported as "page 1"; and Slot 4 (the mouse card) is + // supported as "page 2". if (slotLatch == 3) { for (int i=0xc8; i <= 0xcf; i++) { readPages[i] = _pageNumberForRam(i, 1); } + } else if (slotLatch == 4) { + for (int i=0xc8; i<=0xcf; i++) { + readPages[i] = _pageNumberForRam(i, 2); + } } } diff --git a/apple/applevm.cpp b/apple/applevm.cpp index b925d2b..b0c822c 100644 --- a/apple/applevm.cpp +++ b/apple/applevm.cpp @@ -32,6 +32,9 @@ AppleVM::AppleVM() hd32 = new HD32((AppleMMU *)mmu); ((AppleMMU *)mmu)->setSlot(7, hd32); + + mouse = new Mouse(); + ((AppleMMU *)mmu)->setSlot(4, mouse); } AppleVM::~AppleVM() diff --git a/apple/applevm.h b/apple/applevm.h index a595d7a..65e02f4 100644 --- a/apple/applevm.h +++ b/apple/applevm.h @@ -7,6 +7,7 @@ #include "hd32.h" #include "vmkeyboard.h" #include "parallelcard.h" +#include "mouse.h" #include "vm.h" class AppleVM : public VM { @@ -39,6 +40,7 @@ class AppleVM : public VM { protected: VMKeyboard *keyboard; ParallelCard *parallel; + Mouse *mouse; }; diff --git a/apple/mouse.cpp b/apple/mouse.cpp new file mode 100644 index 0000000..aea25b3 --- /dev/null +++ b/apple/mouse.cpp @@ -0,0 +1,86 @@ +#include "mouse.h" +#include +#include "mouse-rom.h" + +Mouse::Mouse() +{ +} + +Mouse::~Mouse() +{ +} + +bool Mouse::Serialize(int8_t fd) +{ + return true; +} + +bool Mouse::Deserialize(int8_t fd) +{ + return true; +} + +void Mouse::Reset() +{ +} + +uint8_t Mouse::readSwitches(uint8_t s) +{ + return 0xFF; +} + +void Mouse::writeSwitches(uint8_t s, uint8_t v) +{ + printf("unknown switch 0x%X\n", s); +} + +void Mouse::loadROM(uint8_t *toWhere) +{ + uint8_t rom[256] = { 0x2c, 0x58, 0xff, 0x70, 0x1B, 0x38, 0x90, 0x18, + 0xb8, 0x50, 0x15, 0x01, 0x20, 0xae, 0xae, 0xae, + 0xae, 0x00, 0x6d, 0x75, 0x8e, 0x9f, 0xa4, 0x86, + 0xa9, 0x97, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, + 0x48, 0x98, 0x48, 0x8a, 0x48, 0x08, 0x78, 0x20, + 0x58, 0xFF, 0xBA, 0xBD, 0x00, 0x01, 0xAA, 0x0A, + 0x0A, 0x0A, 0x0A, 0xA8, 0x28, 0x50, 0x0F, 0xA5, + 0x38, 0xd0, 0x0d, 0x8a, 0x45, 0x39, 0xd0, 0x08, + 0xa9, 0x05, 0x85, 0x38, 0xd0, 0x0b, 0xb0, 0x09, + 0x68, 0xaa, 0x68, 0xea, 0x68, 0x99, 0x80, 0xc0, + 0x60, 0x99, 0x81, 0xc0, 0x68, 0xbd, 0x38, 0x06, + 0xaa, 0x68, 0xa8, 0x68, 0xbd, 0x00, 0x02, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc9, 0x10, 0xb0, + 0x3f, 0x99, 0x82, 0xc0, 0x60, 0x48, 0x18, 0x90, + 0x39, 0x99, 0x83, 0xc0, 0xbd, 0xb8, 0x06, 0x29, + + 0x0E, 0xD0, 0x01, 0x38, 0x68, 0x60, 0xc9, 0x02, + 0xb0, 0x26, 0x99, 0x83, 0xc0, 0x60, 0xa9, 0x04, + 0x99, 0x83, 0xc0, 0x18, 0xea, 0xea, 0x60, 0xea, + 0xa9, 0x02, 0x99, 0x83, 0xc0, 0x18, 0x60, 0xea, + 0xa9, 0x05, 0xd0, 0xf6, 0xea, 0xa9, 0x06, 0xd0, + 0xf1, 0xea, 0xa9, 0x07, 0xd0, 0xec, 0xa2, 0x03, + 0x38, 0x60, 0x08, 0xa5, 0x00, 0x48, 0xa9, 0x60, + 0x85, 0x00, 0x78, 0x20, 0x00, 0x00, 0xba, 0x68, + 0x85, 0x00, 0xbd, 0x00, 0x01, 0x28, 0xaa, 0x0a, + 0x0a, 0x0a, 0x0a, 0xa8, 0xa9, 0x03, 0x18, 0x90, + 0xa8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xd6, 0xff, 0xff, 0xff, 0x01 }; + memcpy(toWhere, rom, 256); +} + +bool Mouse::hasExtendedRom() +{ + return true; +} + +void Mouse::loadExtendedRom(uint8_t *toWhere, uint16_t byteOffset) +{ + printf("loading extended rom for the mouse\n"); + for (int i=0; i<256; i++) { + toWhere[i] = romData[i + byteOffset]; + } +} diff --git a/apple/mouse.h b/apple/mouse.h new file mode 100644 index 0000000..fcc330b --- /dev/null +++ b/apple/mouse.h @@ -0,0 +1,31 @@ +#ifndef __APPLEMOUSE_H +#define __APPLEMOUSE_H + +#ifdef TEENSYDUINO +#include +#else +#include +#include +#endif + +#include "applemmu.h" +#include "slot.h" + +class Mouse : public Slot { + public: + Mouse(); + virtual ~Mouse(); + + virtual bool Serialize(int8_t fd); + virtual bool Deserialize(int8_t fd); + + virtual void Reset(); // used by BIOS cold-boot + virtual uint8_t readSwitches(uint8_t s); + virtual void writeSwitches(uint8_t s, uint8_t v); + virtual void loadROM(uint8_t *toWhere); + + virtual bool hasExtendedRom(); + virtual void loadExtendedRom(uint8_t *toWhere, uint16_t byteOffset); +}; + +#endif diff --git a/apple/pia6821.cpp b/apple/pia6821.cpp new file mode 100644 index 0000000..bb26c53 --- /dev/null +++ b/apple/pia6821.cpp @@ -0,0 +1,43 @@ +#include "pia6821.h" + +PIA6821::PIA6821() +{ +} + +PIA6821::~PIA6821() +{ +} + +uint8_t PIA6821::read(uint8_t addr) +{ + uint8_t rv; + + switch (addr) { + case DDRA: + if (cra & 0x04) { // DDR or Peripherial Interface access control + // peripheral + // rv = readPeripheralA(); + // FIXME continue here + } else { + rv = ddra; + } + break; + case CTLA: + rv = cra; + break; + case DDRB: + if (crb & 0x04) { + // rv = readPeripheralB(); + // FIXME continue here + } else { + rv = ddrb; + } + break; + case CTLB: + rv = crb; + break; + } + + return rv; +} + diff --git a/apple/pia6821.h b/apple/pia6821.h new file mode 100644 index 0000000..9317d63 --- /dev/null +++ b/apple/pia6821.h @@ -0,0 +1,31 @@ +#ifndef _PIA6821_H +#define _PIA6821_H + +#include + +// http://webpages.charter.net/coinopcauldron/piaarticle.html + +#define DDRA 0 +#define CTLA 1 +#define DDRB 2 +#define CTLB 3 + +class PIA6821 { + public: + PIA6821(); + ~PIA6821(); + + uint8_t read(uint8_t addr); + + + private: + uint8_t porta, portb; + uint8_t ddra, ddrb; + uint8_t cra, crb; // control registers + /* + 2 ports - porta, portb + */ + +}; + +#endif diff --git a/apple/slot.h b/apple/slot.h index e394e06..fedf709 100644 --- a/apple/slot.h +++ b/apple/slot.h @@ -22,6 +22,9 @@ class Slot { virtual void writeSwitches(uint8_t s, uint8_t v) = 0; virtual void loadROM(uint8_t *toWhere) = 0; + + virtual bool hasExtendedRom() { return false; }; + virtual void loadExtendedRom(uint8_t *toWhere, uint16_t byteOffset) {}; }; #endif diff --git a/util/genrom.pl b/util/genrom.pl index 867f2b0..b5ecaf2 100755 --- a/util/genrom.pl +++ b/util/genrom.pl @@ -7,16 +7,19 @@ my $romfile = shift || die "Must provide the path to an Apple //e ROM image"; my $diskrom = shift || die "Must also provide the path to an Apple //e Disk II ROM image"; my $parallelrom = shift || die "Must also provide the path to an Apple // parallel card ROM image"; my $hdrom = shift || die "Must also provide the path to the AppleWin HDDRVR.BIN"; +my $mouserom = shift || die "Also need the path to the 2k Mouse rom"; validate($romfile, 32768, "an Apple //e ROM image"); validate($diskrom, 256, "a DiskII ROM image"); validate($parallelrom, 256, "a parallel card ROM image"); validate($hdrom, 256, "HDDRVR.BIN from AppleWin"); +validate($mouserom, 2048, "2k Mouse extended ROM image"); dumpRom($romfile, "apple/applemmu-rom.h", "romData", 32768); dumpRom($diskrom, "apple/diskii-rom.h", "romData", 256); dumpRom($parallelrom, "apple/parallel-rom.h", "romData", 256); dumpRom($hdrom, "apple/hd32-rom.h", "romData", 256); +dumpRom($hdrom, "apple/mouse-rom.h", "romData", 2048); exit 0; sub validate { diff --git a/vmram.cpp b/vmram.cpp index a4f99d8..cb07178 100644 --- a/vmram.cpp +++ b/vmram.cpp @@ -8,9 +8,10 @@ #include "globals.h" #ifdef TEENSYDUINO -EXTMEM uint8_t preallocatedRam[591*256]; +EXTMEM uint8_t preallocatedRam[599*256]; #else -uint8_t preallocatedRam[591*256]; +#include +uint8_t preallocatedRam[599*256]; #endif #ifndef TEENSYDUINO @@ -44,6 +45,13 @@ void VMRam::writeByte(uint32_t addr, uint8_t value) preallocatedRam[addr] = value; } +uint8_t *VMRam::memPtr(uint32_t addr) +{ + printf("Asked for preallocated RAM pointer at 0x%X\n", addr); + printf("Base is 0x%llX\n", (unsigned long long) preallocatedRam); + return &preallocatedRam[addr]; +} + bool VMRam::Serialize(int8_t fd) { uint32_t size = sizeof(preallocatedRam); diff --git a/vmram.h b/vmram.h index 1d3e158..38af993 100644 --- a/vmram.h +++ b/vmram.h @@ -15,13 +15,15 @@ class VMRam { uint8_t readByte(uint32_t addr); void writeByte(uint32_t addr, uint8_t value); + uint8_t *memPtr(uint32_t addr); + bool Serialize(int8_t fd); bool Deserialize(int8_t fd); bool Test(); private: - // We need 591 pages of 256 bytes for the //e. + // We need 599 pages of 256 bytes for the //e. // // This previously used a split memory model where some of this was // in internal ram and some was external - and while that's not true @@ -37,7 +39,7 @@ class VMRam { // Pages 4-7 are 0x200 - 0x3FF. We want those in RAM too (text pages). // Has to be static if we're using the EXTMEM sectioning, so it's now in vmram.cpp :/ - //EXTMEM uint8_t preallocatedRam[591*256]; + //EXTMEM uint8_t preallocatedRam[599*256]; };