From 577b01e80b8082c7046250d7b0d213fd9cdd639d Mon Sep 17 00:00:00 2001 From: Ryan Schmidt <git@ryandesign.com> Date: Sun, 22 Oct 2023 04:38:52 -0500 Subject: [PATCH 1/5] Fix Apple II/II+/IIe vbl rows read addresses See #1180 --- Machines/Apple/AppleII/Video.hpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Machines/Apple/AppleII/Video.hpp b/Machines/Apple/AppleII/Video.hpp index 1e84d2c04..79dad3c2b 100644 --- a/Machines/Apple/AppleII/Video.hpp +++ b/Machines/Apple/AppleII/Video.hpp @@ -147,8 +147,13 @@ template <class BusHandler, bool is_iie> class Video: public VideoBase { // Apply carry into the row counter. int mapped_row = row_ + (mapped_column / 65); - mapped_column %= 65; mapped_row %= 262; + mapped_column %= 65; + + // Vertical blanking rows read eight bytes earlier. + if(mapped_row >= 192) { + mapped_column -= 8; + } // Apple out-of-bounds row logic. if(mapped_row >= 256) { @@ -168,20 +173,20 @@ template <class BusHandler, bool is_iie> class Video: public VideoBase { @returns @c true if the display will be within vertical blank at now + @c offset; @c false otherwise. */ bool get_is_vertical_blank(Cycles offset) { - // Map that backwards from the internal pixels-at-start generation to pixels-at-end - // (so what was column 0 is now column 25). + // Determine column at offset. int mapped_column = column_ + int(offset.as_integral()); // Map that backwards from the internal pixels-at-start generation to pixels-at-end // (so what was column 0 is now column 25). mapped_column += 25; - // Apply carry into the row counter and test it for location. + // Apply carry into the row counter. int mapped_row = row_ + (mapped_column / 65); + mapped_row %= 262; // Per http://www.1000bit.it/support/manuali/apple/technotes/iigs/tn.iigs.040.html // "on the IIe, the screen is blanked when the bit is low". - return (mapped_row % 262) < 192; + return mapped_row < 192; } private: From c272632b5a255a3073ad87758da178eea266dfc7 Mon Sep 17 00:00:00 2001 From: Ryan Schmidt <git@ryandesign.com> Date: Mon, 23 Oct 2023 05:18:13 -0500 Subject: [PATCH 2/5] Fix Apple II/II+/IIe hbl row < 64 read addresses See #1180 --- Machines/Apple/AppleII/Video.hpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Machines/Apple/AppleII/Video.hpp b/Machines/Apple/AppleII/Video.hpp index 79dad3c2b..0beea0828 100644 --- a/Machines/Apple/AppleII/Video.hpp +++ b/Machines/Apple/AppleII/Video.hpp @@ -150,6 +150,9 @@ template <class BusHandler, bool is_iie> class Video: public VideoBase { mapped_row %= 262; mapped_column %= 65; + // Remember if we're in a horizontal blanking interval. + int hbl = mapped_column < 25; + // Vertical blanking rows read eight bytes earlier. if(mapped_row >= 192) { mapped_column -= 8; @@ -162,8 +165,17 @@ template <class BusHandler, bool is_iie> class Video: public VideoBase { mapped_row %= 192; } - // Calculate the address and return the value. + // Calculate the address. uint16_t read_address = uint16_t(get_row_address(mapped_row) + mapped_column - 25); + + if(hbl) { + // Wraparound addressing within 128 byte sections. + if(mapped_row < 64) { + read_address += 128; + } + } + + // Read the address and return the value. uint8_t value, aux_value; bus_handler_.perform_read(read_address, 1, &value, &aux_value); return value; From 98730f1f904d582ecad40a59bfb1dee50f47e973 Mon Sep 17 00:00:00 2001 From: Ryan Schmidt <git@ryandesign.com> Date: Wed, 25 Oct 2023 00:27:18 -0500 Subject: [PATCH 3/5] Fix Apple II/II+/IIe first hbl byte read addresses Closes #1180 --- Machines/Apple/AppleII/Video.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Machines/Apple/AppleII/Video.hpp b/Machines/Apple/AppleII/Video.hpp index 0beea0828..72245c22e 100644 --- a/Machines/Apple/AppleII/Video.hpp +++ b/Machines/Apple/AppleII/Video.hpp @@ -153,6 +153,11 @@ template <class BusHandler, bool is_iie> class Video: public VideoBase { // Remember if we're in a horizontal blanking interval. int hbl = mapped_column < 25; + // The first column is read twice. + if(mapped_column == 0) { + mapped_column = 1; + } + // Vertical blanking rows read eight bytes earlier. if(mapped_row >= 192) { mapped_column -= 8; From c206c7e2cbcad7e4ebba71e3163428bc4266c3b2 Mon Sep 17 00:00:00 2001 From: Ryan Schmidt <git@ryandesign.com> Date: Wed, 25 Oct 2023 01:44:48 -0500 Subject: [PATCH 4/5] Fix Apple II/II+ text/lores hbl read addresses Closes #1181 --- Machines/Apple/AppleII/Video.hpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Machines/Apple/AppleII/Video.hpp b/Machines/Apple/AppleII/Video.hpp index 72245c22e..c2e947a3a 100644 --- a/Machines/Apple/AppleII/Video.hpp +++ b/Machines/Apple/AppleII/Video.hpp @@ -178,6 +178,13 @@ template <class BusHandler, bool is_iie> class Video: public VideoBase { if(mapped_row < 64) { read_address += 128; } + + // On Apple II and II+ (not IIe or later) in text/lores mode (not hires), horizontal + // blanking bytes read from $1000 higher. + const GraphicsMode pixel_mode = graphics_mode(mapped_row); + if(!is_iie_ && ((pixel_mode == GraphicsMode::Text) || (pixel_mode == GraphicsMode::LowRes))) { + read_address += 0x1000; + } } // Read the address and return the value. From 18ed36d09010b80d627dc595374f00a58833ee9e Mon Sep 17 00:00:00 2001 From: Ryan Schmidt <git@ryandesign.com> Date: Tue, 24 Oct 2023 19:50:02 -0500 Subject: [PATCH 5/5] Update get_last_read_value source documentation --- Machines/Apple/AppleII/Video.hpp | 56 ++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/Machines/Apple/AppleII/Video.hpp b/Machines/Apple/AppleII/Video.hpp index c2e947a3a..1af8620ad 100644 --- a/Machines/Apple/AppleII/Video.hpp +++ b/Machines/Apple/AppleII/Video.hpp @@ -129,14 +129,56 @@ template <class BusHandler, bool is_iie> class Video: public VideoBase { */ uint8_t get_last_read_value(Cycles offset) { // Rules of generation: - // (1) a complete sixty-five-cycle scan line consists of sixty-five consecutive bytes of - // display buffer memory that starts twenty-five bytes prior to the actual data to be displayed. - // (2) During VBL the data acts just as if it were starting a whole new frame from the beginning, but - // it never finishes this pseudo-frame. After getting one third of the way through the frame (to - // scan line $3F), it suddenly repeats the previous six scan lines ($3A through $3F) before aborting - // to begin the next true frame. + + // FOR ALL MODELS IN ALL MODES: // - // Source: Have an Apple Split by Bob Bishop; http://rich12345.tripod.com/aiivideo/softalk.html + // - "Screen memory is divided into 128-byte segments. Each segment is divided into the FIRST 40, the + // SECOND 40, the THIRD 40, and eight bytes of no man's memory (UNUSED 8)." (5-8*) + // + // - "The VBL base addresses are equal to the FIRST 40 base addresses minus eight bytes using 128-byte + // wraparound subtraction. Example: $400 minus $8 gives $478; not $3F8." (5-11*) + // + // - "The memory locations scanned during HBL prior to a displayed line are the 24 bytes just below the + // displayed area, using 128-byte wraparound addressing." (5-13*) + // + // - "The first address of HBL is always addressed twice consecutively" (5-11*) + // + // - "Memory scanned by lines 256 through 261 is identical to memory scanned by lines 250 through 255, + // so those six 64-byte sections are scanned twice" (5-13*) + + // FOR II AND II+ ONLY (NOT IIE OR LATER) IN TEXT/LORES MODE ONLY (NOT HIRES): + // + // - "HBL scanned memory begins $18 bytes before display scanned memory plus $1000." (5-11*) + // + // - "Horizontal scanning wraps around at the 128-byte segment boundaries. Example: the address scanned + // before address $400 is $47F during VBL. The address scanned before $400 when VBL is false is + // $147F." (5-11*) + // + // - "the memory scanned during HBL is completely separate from the memory scanned during HBL´." (5-11*) + // + // - "HBL scanned memory is in an area normally taken up by Applesoft programs or Integer BASIC + // variables" (5-37*) + // + // - Figure 5.17 Screen Memory Scanning (5-37*) + + // FOR IIE AND LATER IN ALL MODES AND II AND II+ IN HIRES MODE: + // + // - "HBL scanned memory begins $18 bytes before display scanned memory." (5-10**) + // + // - "Horizontal scanning wraps around at the 128-byte segment boundaries. Example: the address scanned + // before address $400 is $47F." (5-11**) + // + // - "during HBL, the memory locations that are scanned are in the displayed memory area." (5-13*) + // + // - "Programs written for the Apple II may well not perform correctly on the Apple IIe because of + // differences in scanning during HBL. In the Apple II, HBL scanned memory was separate from other + // display memory in TEXT/LORES scanning. In the Apple IIe, HBL scanned memory overlaps other scanned + // memory in TEXT/LORES scanning in similar fashion to HIRES scanning." (5-43**) + // + // - Figure 5.17 Display Memory Scanning (5-41**) + + // Source: * Understanding the Apple II by Jim Sather + // Source: ** Understanding the Apple IIe by Jim Sather // Determine column at offset. int mapped_column = column_ + int(offset.as_integral());