• Re: How does IIgs register $C035 bit 6 affect $e000+?

    From kegs@kegs@provalid.com (Kent Dickey) to comp.sys.apple2 on Wednesday, October 21, 2020 14:52:31
    From Newsgroup: comp.sys.apple2

    In article <2c5f5cc6-18c8-4902-bb27-0d6ea4e45e1cn@googlegroups.com>,
    Thomas Harte <thomas.harte@gmail.com> wrote:
    On Tuesday, 20 October 2020 at 15:27:25 UTC-4, Kent Dickey wrote:
    When $C035 bit 6 is 0, memory from $c000-$ffff in banks 0 and 1 work like >> an Apple //e, with all the language card, ROM, and IO space soft switches >> (built-in and peripherals) behaving as you would expect on a //e affecting >> accessing to banks 0 and 1.

    When $C035 bit 6 is 1, memory from $c000-$ffff in bank 0 is the DRAM from >> $c000-$ffff--there is no LC bank switching, no ROM, and no IO space soft
    switches. And similarly in bank 1 (but it points to bank 1 DRAM).

    [snip]

    Standard Apple //e memory mapping is complex, and I think that is your
    actual question. What is it you're trying to do?

    Just research; writing emulators is one of my hobbies and reading up as >though I were going to write one even more so. But this feels like a day >one-type question — the documentation didn't feel particularly
    explicit as to how the reset vector ends up being sourced from ROM and >therefore how the system even starts up.

    The IIgs documentation is not as complete as the previous generation.
    That's partly because they basically don't document things that don't
    affect people writing normal software. I'm not sure where the vector
    pull always coming from ROM is documented.

    As well as the Hardware Reference and the Firmware Guide, I also checked
    the Fischer book; I'm grateful for your answer indicating that bit 6
    does affect the entire range from $c000 to the end of each bank, which
    both explains how appropriate vectors are visible straight from the
    power-on reset and how they can point to useful code.

    I think I'm actually fine with //e mapping; I wrote >https://github.com/TomHarte/CLK/wiki/Apple-IIe-Memory-Paging to
    summarise it for myself back when I wrote an emulator of that. I hope
    it's accurate (and, indeed, comprehensible). So if I've fully understood
    then I guess the main difference on a IIgs with bit 6 = 0 versus a IIe
    is that VPB also factors in? I can't imagine that they changed the rules
    for regular memory accesses.

    There are other differences around shadowing. The actual video buffers
    are not in banks $00 or $01, but rather in $e0 and $e1, and writes to
    banks $00 and $01 are shadowed to also be done to banks $e0 and $e1.
    Note that the shadowing is done at the true bank level--so if RAMWRT is
    set so that writes to address $1000 really go to bank 1, then those writes
    are shadowed to bank $e1.


    I'm also taking it from the documentation and your commentary that with
    bit 6 = 0, banks $00 and $01 have exactly the same contents. Presumably >that's a safeguard against those addressing modes, like abs, x, that can
    now cross bank boundaries?

    Banks $00 and $01 combine to make 128KB of memory that look like an Apple
    //e's 128KB of memory (except these are not the actual video buffers). The
    way to think of it is generating accesses to bank $00 addresses may actually reference bank $00 or bank $01, and may shadow writes to bank $e0 (or $e1), depending on the //e softswitches. But, directly access bank $01 using the 65816 long addressing modes will always access bank $01 (although again,
    writes can be shadowed to bank $e1). Accessing other banks just accesses the indicated bank, and there's no shadowing.

    Banks $e0 and $e1 have the actual video memory (main and aux), which you can directly access if you want. This memory is all running at 1MHz. It's not that useful, so the ROM uses most of bank $e0 and $e1 that are not video
    memory as storage for things like the Memory Manager, etc.

    All of my knowledge about IIgs addressing is in my emulator, KEGS,
    at http://kegs.sourceforge.net/ (Old version from 15 years ago), with an
    alpha update at: https://sourceforge.net/projects/kegs/ which is cleaned up
    a bit. KEGS 1.00+ is intended for Mac OS X and Linux. The memory mapping is handled in moremem.c. KEGS has a table of 65536 remap entries for
    every page of $100 bytes (so it covers the entire 16MB of addressing), so
    KEGS just has to fiddle with these pointers when the softswitches are
    touched. moremem.c has "fixup" routines which handle each softswitch.
    Actual emulation is basically a lookup of this pointer, then add the offset onto the page, and then access that location.

    I will look into your emulator, I'm interested in using Metal on Mac OS X
    in KEGS. I'm pretty disappointed in the Mac programming documentation.

    Kent
    --- Synchronet 3.18b-Win32 NewsLink 1.113
  • From Thomas Harte@thomas.harte@gmail.com to comp.sys.apple2 on Wednesday, October 21, 2020 13:06:49
    From Newsgroup: comp.sys.apple2

    On Tuesday, 20 October 2020 at 15:59:38 UTC-4, Thomas Harte wrote:
    Just research; writing emulators is one of my hobbies and reading up as though I were going to write one even more so. But this feels like a day one-type question — the documentation didn't feel particularly explicit as to how the reset vector ends up being sourced from ROM and therefore how the system even starts up.

    As well as the Hardware Reference and the Firmware Guide, I also checked the Fischer book; I'm grateful for your answer indicating that bit 6 does affect the entire range from $c000 to the end of each bank, which both explains how appropriate vectors are visible straight from the power-on reset and how they can point to useful code.

    I think I'm actually fine with //e mapping; I wrote https://github.com/TomHarte/CLK/wiki/Apple-IIe-Memory-Paging to summarise it for myself back when I wrote an emulator of that. I hope it's accurate (and, indeed, comprehensible). So if I've fully understood then I guess the main difference on a IIgs with bit 6 = 0 versus a IIe is that VPB also factors in? I can't imagine that they changed the rules for regular memory accesses.

    I'm also taking it from the documentation and your commentary that with bit 6 = 0, banks $00 and $01 have exactly the same contents. Presumably that's a safeguard against those addressing modes, like abs, x, that can now cross bank boundaries?
    Actually, I withdraw the questions above having already improved my understanding of how shadowing and banking are distinct, as is much of the $00/$01 and $e0/$e1 banking state, so a 256kb machine isn't in practice just a 128kb machine with an additional 128kb write-through cache.
    Anyway, clearly I've still yet to get a full handle on things and the members of this group don't need to be bothered by my slow and annunciated comprehension. So thanks again for helping me with the first question, I think it's helped a lot to break my initial mental ice.
    --- Synchronet 3.18b-Win32 NewsLink 1.113
  • From Thomas Harte@thomas.harte@gmail.com to comp.sys.apple2 on Thursday, October 22, 2020 12:01:40
    From Newsgroup: comp.sys.apple2

    On Wednesday, 21 October 2020 at 15:52:39 UTC-4, Kent Dickey wrote:
    Banks $00 and $01 combine to make 128KB of memory that look like an Apple //e's 128KB of memory (except these are not the actual video buffers). The way to think of it is generating accesses to bank $00 addresses may actually reference bank $00 or bank $01, and may shadow writes to bank $e0 (or $e1), depending on the //e softswitches. But, directly access bank $01 using the 65816 long addressing modes will always access bank $01 (although again, writes can be shadowed to bank $e1). Accessing other banks just accesses the indicated bank, and there's no shadowing.
    Thanks for the additional information; I can see now that part of my problem has been conflating the language card and auxiliary memory, and another was making a false assumption about what would be strictly logically behind the Mega II. I think I have a much better handle on it now, thanks to you.
    I may still be way off, of course, but it looks like the language card switches affect the top of all four banks (being shown on Page 34 and 42 for banks $00 and $01, and Page 46 for banks $e0 and $e1), and the auxiliary switches as you say merely permit some substitution of bank $01 into bank $00. And then shadowing optionally adds a synchronise-and-write-through step to any writes.
    All of my knowledge about IIgs addressing is in my emulator, KEGS,
    at http://kegs.sourceforge.net/ (Old version from 15 years ago), with an alpha update at: https://sourceforge.net/projects/kegs/ which is cleaned up a bit. KEGS 1.00+ is intended for Mac OS X and Linux. The memory mapping is handled in moremem.c. KEGS has a table of 65536 remap entries for
    every page of $100 bytes (so it covers the entire 16MB of addressing), so KEGS just has to fiddle with these pointers when the softswitches are touched. moremem.c has "fixup" routines which handle each softswitch.
    Actual emulation is basically a lookup of this pointer, then add the offset onto the page, and then access that location.
    Cool, I somehow failed to spot that I was talking to royalty! I generally avoid looking at the source code of other emulators for a bunch of pragmatic reasons — primarily that the emulation problem is solved at this point, so it's no disaster if I can't figure something out — and at least one ethical (and technically legal): mine is MIT licensed so there's a delicate line at play if I read GPL code.
    That said, you may not be surprised to learn that I did essentially the same thing for the 8-bit Apple IIs, albeit with only the 256 pairs of pointers necessary and, of course, no need to flag potential shadowing. In the abstract I'm actually perfectly happy to include switch and if chains in my cycle-by-cycle address decoding if they're neater, because modern computers are very fast and my time is finite, but when I made the step up to the IIe that was no longer the case.
    I will look into your emulator, I'm interested in using Metal on Mac OS X
    in KEGS. I'm pretty disappointed in the Mac programming documentation.
    Yeah, I tend to think that Apple's documentation in general was really good about a decade ago but nowadays it's a bit of a disaster. My emulator is a little atypical in terms of what it pushes to the GPU — it's always linear one-dimensional diagonal scans, an internal PLL having been fed a one-dimensional video signal and extracted them, and for the Apple II the pixel format is monochrome with any NTSC decoding done in a generic fashion over on the GPU.
    But even with those things being the case, the addition of Metal was only about a month of hobby-time work as it fits very neatly with the rest of the OS — it's just a serial queue and the shading language is very close to C++11. There are still some rough edges in my implementation but I'm happy enough with it to file those mentally into the backlog. It also has quite a few performance advantages over Apple's almost-decade-old version of OpenGL, most obviously because you can be overt about where buffers live and when/whether they actually need to go into the GPU cache. E.g. my Mac has only embedded graphics but for this sort of program where all content is streamed that's an advantage as you can just put your intermediate pixel buffers in shared memory.
    If there's anything I can do to help, let me know.
    --- Synchronet 3.18b-Win32 NewsLink 1.113