From 0468bf43c5d4f26412d9f1429066b6367b452a36 Mon Sep 17 00:00:00 2001 From: Jorj Bauer Date: Fri, 8 Jan 2021 19:25:08 -0500 Subject: [PATCH] more normalization and commenting --- apple/applemmu.cpp | 64 +++++++++------- apple/mouse.cpp | 181 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 218 insertions(+), 27 deletions(-) diff --git a/apple/applemmu.cpp b/apple/applemmu.cpp index 63f0464..2ba4005 100644 --- a/apple/applemmu.cpp +++ b/apple/applemmu.cpp @@ -61,8 +61,15 @@ Current write page table [512 bytes] in real ram */ -// This has a split memory model so more often addressed pages can be -// in internal memory, and an external memory can hold others. +// All the pages. Because we don't have enough RAM for both the +// display's DMA and the Apple's 148k (128k + ROM space), we're using +// an external SRAM for some of this. Anything that's accessed very +// often should be in the *low* pages, b/c those are in internal +// Teensy RAM. When we run out of preallocated RAM (cf. vmram.h), we +// fall over to an external 256kB SRAM (which is much slower). +// +// Zero page (and its alts) are the most used pages (the stack is in +// page 1). // // We want the video display pages in real RAM as much as possible, // since blits wind up touching so much of it. If we can keep that in @@ -79,20 +86,19 @@ enum { MP_ZP = 0, // page 0/1 * 2 page variants = 4; 0..3 MP_4 = 4, // 0x04 - 0x07 (text display pages) * 2 variants = 8; 4..11 MP_20 = 12, // 0x20 - 0x5F * 2 variants = 128; 12..139 - // Pages that can go to external RAM if needed: + // Pages that can go to external SRAM: MP_2 = 140, // 0x02 - 0x03 * 2 variants = 4; 140..143 MP_8 = 144, // 0x08 - 0x1F * 2 = 48; 144..191 MP_60 = 192, // 0x60 - 0xBF * 2 = 192; 192..383 - MP_C1 = 384, // start of 0xC1-0xCF * 2 page variants = 30; 384-413 - MP_C8 = 398, // 0xc8 - 0xcf, 3 page variants = 24; 398 - 421 + MP_C1 = 384, // start of 0xC1-0xC7 * 2 page variants = 14; 384-397 + 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 + MP_C0 = 598 // = 599 pages in all (149.75k) }; - static uint16_t _pageNumberForRam(uint8_t highByte, uint8_t variant) { if (highByte <= 1) { @@ -118,14 +124,13 @@ static uint16_t _pageNumberForRam(uint8_t highByte, uint8_t variant) return MP_C0; } if (highByte <= 0xC7) { - // 0xC1 - 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) return ((highByte - 0xD0) * 5 + variant + MP_D0); @@ -229,6 +234,8 @@ bool AppleMMU::Deserialize(int8_t fd) return true; } + + void AppleMMU::Reset() { resetRAM(); @@ -925,6 +932,7 @@ void AppleMMU::resetRAM() 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 @@ -932,28 +940,30 @@ void AppleMMU::resetRAM() #else uint8_t v = romData[idx]; #endif - // 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 + + // The space from 0xc1 through 0xcf is ROM image territory. We + // load the C3 ROM in to page 0, but not page 1; and then we + // load c800.CFFF to both 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 { - // C000..C2FF and C400..C7FF are main ROM - g_ram.writeByte((page1 << 8) | (k & 0xFF), v); - } - } else { - // Everything else goes in page 0. - g_ram.writeByte((page0 << 8) | (k & 0xFF), v); } + else if (i >= 0xc8) { + // C800..CFFF => built-in ROM and slot 3 extended ROM + g_ram.writeByte((page0 << 8) | (k & 0xFF), v); + g_ram.writeByte((page1 << 8) | (k & 0xFF), v); + } + else { + // C000..C2FF and C400..c7FF are main ROM + g_ram.writeByte((page1 << 8) | (k & 0xFF), v); + } + } else { + // Everything else goes in page 0. + g_ram.writeByte((page0 << 8) | (k & 0xFF), v); } } } @@ -1088,14 +1098,14 @@ void AppleMMU::updateMemoryPages() // for a given peripheral to C800..CFFF. if (slotLatch != -1) { // 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". + // 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++) { + for (int i=0xc8; i <= 0xcf; i++) { readPages[i] = _pageNumberForRam(i, 2); } } diff --git a/apple/mouse.cpp b/apple/mouse.cpp index aea25b3..9eacc91 100644 --- a/apple/mouse.cpp +++ b/apple/mouse.cpp @@ -36,6 +36,187 @@ void Mouse::writeSwitches(uint8_t s, uint8_t v) void Mouse::loadROM(uint8_t *toWhere) { + /* ROM Disassembly: +C400- 2C 58 FF BIT $FF58 ; test bits in FF58 w/ A +C403- 70 1B BVS $C420 ; V will contain bit 6 from $FF58, which should be $20 on boot-up +C405- 38 SEC +C406- 90 18 BCC $C420 ; no-op; unless called @ $C406 directly? + +C408- B8 CLV ; clear overflow +C409- 50 15 BVC $C420 ; always branches + +; unused... ? more lookup table... ? +C40B- 01 20 ORA ($20,X) +C40D- AE AE AE LDX $AEAE + +; This is the lookup table for entry addresses +C410- AE +C411- 00 +C412- 6D ;(setmouse @ c46d) +C413- 75 ;(servemouse @ C475) +C414- 8E ;(readmouse @ C48E) +C415- 9F ;(clearmouse @ C49F) +C416- A4 ;(posmouse @ C4A4) +C417- 86 ;(clampmouse @ C486) +C418- A9 ;(homemouse @ C4A9) +C419- 97 ;(initmouse @ C497) +C41A- AE +C41B- AE +C41C- AE ;(semi-documented: sets mouse frequency handler to 60 or 50 hz) +C41D- AE +C41E- AE +C41F- AE + +; Main +C420- 48 PHA ; push accumulator to stack +C421- 98 TYA +C422- 48 PHA ; push Y to stack +C423- 8A TXA +C424- 48 PHA ; push X to stack +C424- 48 PHA +C425- 08 PHP ; push status to stack +C426- 78 SEI ; disable interrupts + +; This JSR $FF58 is a trick to get the address we're calling from. By +; default, $FF58 contains a RTS (until patched as the DOS '&' vector, +; or ProDOS does something similar). As long as this executes before +; the DOS takes over, it's safe; but if we're doing this after ProDOS +; loads, a 64k machine might have garbage after the language card RAM +; is loaded here. A safer alternative would be something like +; LDA #$60 ; Write an RTS ($60) to a temporary memory +; STA WORK ; address, and then +; JSR WORK ; jump to it +; TSX +; LDA $100, X ; grab the return address off the stack + +C427- 20 58 FF JSR $FF58 +C42A- BA TSX +C42B- BD 00 01 LDA $0100,X +C42E- AA TAX +C42F- 0A ASL +C430- 0A ASL +C431- 0A ASL +C432- 0A ASL +C433- A8 TAY +C434- 28 PLP ; restore status from stack +C435- 50 0F BVC $C446 ; overflow is clear if ... ? +C437- A5 38 LDA $38 ; >> what's in $38? +C439- D0 0D BNE $C448 ; restore stack & return +C43B- 8A TXA +C43C- 45 39 EOR $39 ; >> what's in $39? +C43E- D0 08 BNE $C448 ; restore stack & return +C440- A9 05 LDA #$05 +C442- 85 38 STA $38 ; ($38) = $05 +C442- 85 38 STA $38 +C444- D0 0B BNE $C451 + +C446- B0 09 BCS $C451 ; carry set if ... ? +C448- 68 PLA ; pull X from stack +C449- AA TAX +C44A- 68 PLA ; pull Y from stack, but +C44B- EA NOP ; throw it away +C44C- 68 PLA ; pull A from stack +C44D- 99 80 C0 STA $C080,Y ; LC RAM bank2, read and wr-protect +C450- 60 RTS + +C451- 99 81 C0 STA $C081,Y ; LC RAM bank 2, read ROM +C454- 68 PLA ; +C455- BD 38 06 LDA $0638,X +C458- AA TAX +C459- 68 PLA +C45A- A8 TAY +C45B- 68 PLA +C45C- BD 00 02 LDA $0200,X ; keyboard character buffer? +C45F- 60 RTS + +C460- 00 BRK +C461- 00 BRK +C462- 00 BRK +C463- 00 BRK +C464- 00 BRK +C465- 00 BRK +C466- 00 BRK +C467- 00 BRK +C468- 00 BRK +C469- 00 BRK +C46A- 00 BRK +C46B- 00 BRK +C46C- 00 BRK + +; SetMouse +C46D- C9 10 CMP #$10 ; interrupt on VBL + interrupt on mouse move? +C46F- B0 3F BCS $C4B0 ; RTS if A >= 0x10 +C471- 99 82 C0 STA $C082,Y ; LC RAM bank 2, read ROM, wr-protect RAM +C474- 60 RTS +; ServeMouse +C475- 48 PHA +C476- 18 CLC +C477- 90 39 BCC $C4B2 ; always branches +; ServeMouse cleanup and exit +C479- 99 83 C0 STA $C083,Y ; LC RAM bank 2, read RAM +C47C- BD B8 06 LDA $06B8,X +C47F- 29 0E AND #$0E +C481- D0 01 BNE $C484 +C483- 38 SEC +C484- 68 PLA +C485- 60 RTS +; ClampMouse +C486- C9 02 CMP #$02 +C488- B0 26 BCS $C4B0 ; RTS if 2 <= the A register +C48A- 99 83 C0 STA $C083,Y ; LC RAM bank 2, read RAM +C48D- 60 RTS +; ReadMouse +C48E- A9 04 LDA #$04 +C490- 99 83 C0 STA $C083,Y ; LC RAM bank 2, read RAM +C493- 18 CLC +C494- EA NOP +C495- EA NOP +C496- 60 RTS +; InitMouse +C497- EA NOP +C498- A9 02 LDA #$02 +C49A- 99 83 C0 STA $C083,Y ; LC RAM bank 2, read RAM +C49D- 18 CLC +C49E- 60 RTS +; ClearMouse +C49F- EA NOP +C4A0- A9 05 LDA #$05 +C4A2- D0 F6 BNE $C49A +; PosMouse +C4A4- EA NOP +C4A5- A9 06 LDA #$06 +C4A7- D0 F1 BNE $C49A +; HomeMouse +C4A9- EA NOP +C4AA- A9 07 LDA #$07 +C4AC- D0 EC BNE $C49A +C4AE- A2 03 LDX #$03 +C4B0- 38 SEC +C4B1- 60 RTS +; ServeMouse main worker +C4B2- 08 PHP +C4B3- A5 00 LDA $00 +C4B5- 48 PHA +C4B6- A9 60 LDA #$60 +C4B8- 85 00 STA $00 +C4BA- 78 SEI +C4BB- 20 00 00 JSR $0000 +C4BE- BA TSX +C4BF- 68 PLA +C4C0- 85 00 STA $00 +C4C2- BD 00 01 LDA $0100,X +C4C5- 28 PLP +C4C6- AA TAX +C4C7- 0A ASL +C4C8- 0A ASL +C4C9- 0A ASL +C4CA- 0A ASL +C4CB- A8 TAY +C4CC- A9 03 LDA #$03 +C4CE- 18 CLC +C4CF- 90 A8 BCC $C479 ; always branches + + */ 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,