-
-
Notifications
You must be signed in to change notification settings - Fork 50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Apple II/II+/IIe floating bus problems #1180
Comments
ryandesign
added a commit
to ryandesign/CLK
that referenced
this issue
Oct 25, 2023
ryandesign
added a commit
to ryandesign/CLK
that referenced
this issue
Oct 25, 2023
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I've found some bugs in the way that Clock Signal implemented the Apple II floating bus in #425.
Here is the 2012 "rainbow" sample program that uses the floating bus to synchronize lores / hires mode switches between scan lines to produce hires rainbow-colored lines:
https://web.archive.org/web/20151021120119/http://hoop-la.ca/apple2/2011/rainbow/
You can load it into memory by starting a new Apple II+/IIe emulator, pressing F12 to reset and go to the Applesoft BASIC prompt, and pasting this in:
Run it with:
The original longer and less-obfuscated version of this program is here:
https://macgui.com/usenet/?group=2&id=22342#msg
Here is what it looks like on my real unenhanced Apple //e connected to a Toshiba CRT TV:
The CRT makes it a little hard to see but there are six solid bands of color in red, orange, yellow, green, blue, and violet. There is no flickering.
It also looks correct in OpenEmulator 1.1.1-202203110628 and Virtual ][ 11.4.
Here is what it looks like in Clock Signal 2023-09-10:
The red and blue lines are totally missing and the yellow line is flickering. Something is amiss!
(The problem that the lines are slanted instead of horizontal is #1173.)
The machine language program that the rainbow BASIC program pokes into memory starting at $300 is as follows:
It relies on the fact that the hires screen it sets up doesn't contain any zero bytes except for where it wants to switch to lores mode.
Bob Bishop's 1982 article Have an Apple Split presents BASIC programs that prepare the hires screen with special bytes and generate a machine language program that samples the floating bus as fast as possible (one sample every eight cycles), recording the results in memory for later analysis. The preparation program puts $00 into every byte of hires page 1's 0th row, $01 into every byte of the 1st row, all the way down to $BF in the 191st row, and puts $C0 through $FF into every byte of the rows of screen holes.
I rewrote the two programs in assembly and combined them and made the sampling portion wait until the vertical blanking interval begins when running on a //e so that the sampled data always begins in approximately the same place (but not exactly; there's a seven-cycle jitter in my naive VBL detection method so since we sample every eight cycles results on repeated runs may be positioned one location off).
Here is the source code of my program.
You can poke it into memory by entering the monitor with:
and then pasting this in:
Run it with:
In my version, data is stored starting at $1000. I'll show some output from running this program on Virtual ][ 11.4 (this output matches my real unenhanced //e) and on Clock Signal emulating an unenhanced //e.
Let's start with the first few displayed scanlines. That data starts 70 * 65 / 8 cycles after the start of data, around memory location $1238, and can be displayed by running:
Here's output from Virtual ][:
We start at $1238 with three bytes (80 80 C0) of horizontal blanking preceding line $0. $80 $80 comes from the end of visible scanline $80 (($0 - $40 + $C0) % $C0) followed by $C0 from the eight holes that follow that scanline (so the 25 bytes for horizontal blanking are indeed from consecutive memory locations, specifically these were from between $2068 and $207F). Next, five bytes (00 00 00 00 00) from the displayed portion of line $0 (from memory locations between $2000 and $2027). Then three (81 81 C1) from the next horizontal blanking period from the end of visible scanline $81 (($1 - $40 + $C0) % $C0) and the holes that follow it, and so on.
Compare this with output from Clock Signal 2023-09-10:
The horizontal blanking period period for line $0 begins at $1237 here instead of $1238 due to my imprecise detection of the VBL, so that difference is fine, but the three bytes that start line $0's HBL here (59 08 A8) appear to be nonsense, and they are -- Clock Signal is returning values from the memory locations that literally precede line $0's visible component in memory, in other words it is taking them from memory locations outside of (preceding) hires page 1 (specifically from $1FE8 to $1FFF). Clock Signal's behavior matches the italicized conclusion in Bishop's article, quoted in the code:
CLK/Machines/Apple/AppleII/Video.hpp
Lines 132 to 133 in 14851f4
but that's not correct for scan lines < 64. What he wrote in the preceding paragraph is more accurate:
Clock Signal appears to initialize Apple II RAM to random values so the values it returns for the horizontal blanking period preceding the first 64 rows are literally random. They could contain any value, including the zero that the rainbow program is looking for as its signal, which could account for it switching modes at the wrong times. We can make Clock Signal's behavior more obvious by writing a specific value to those memory locations before running the test program, e.g. $42 with these monitor commands:
Then we get:
In this run we see a minor difference from the previous one: we get four garbage $42s here instead of three garbage values because that'll happen once every eight scanlines since we're sampling every eight cycles and the horizontal blanking period is 25 cycles long.
Following the five $00 bytes for scanline $0, the horizontal blanking bytes for line $1 (B8 B8 F8) are again from the wrong row. At least they're from within hires page 1 this time but again they're taken from the 24 bytes that precede row $1 (row $1 starts at $2080; these bytes are from row $B8 (which starts at $2050) and the holes that follow it rather than from the correct row $81 (which starts at $20D0). Returning data from the wrong row like this could also definitely account for a program switching modes at the wrong time, since it would see its signal bytes at the wrong times.
The second problem is specific to the vertical blanking period whose data was recorded starting at $1000:
With Virtual ][:
With Clock Signal:
Clock Signal is following what Bob Bishop wrote and which is quoted in the code:
CLK/Machines/Apple/AppleII/Video.hpp
Lines 134 to 137 in 14851f4
But again Bishop wasn't precise enough. Although the output he published from his sampling program shows it, his text didn't mention that the data returned by the bus during vertical blanking is pulled from memory locations eight bytes earlier than during the visible portion. Looking at the correct output from Virtual ][, during the non-VBL scan of line $0 we got five $00 bytes preceded by three (or, 1 in 8 times, four) bytes:
But during VBL we got only four $00 bytes preceded by four (or, 1 in 8 times, five) bytes:
Clock Signal isn't implementing that difference. During non-VBL, we got the correct five $00's:
But during VBL we also got five $00's when we should have gotten four:
All of this is investigated much more thoroughly and explained much more precisely in Jim Sather's book Understanding the Apple II. Once I read the relevant passages there, I discovered one more issue with Clock Signal's implementation which Bishop must not have realized because his sample program was not designed to detect it: There are not 25 consecutive bytes during the horizontal blanking period. There are 24 consecutive bytes and the first byte is read twice.
After fixing these issues (I'll submit a pull request shortly), the rainbow program works:
The text was updated successfully, but these errors were encountered: