Help loading GR, HGR, DGR AND DHGR image files in the Apple II

Genjoke

Tinkerer
Oct 31, 2021
70
42
18
Brazil - Rio de Janeiro - Flamengo
Hi folks.

Programs to encode modern images into Apple II-savvy formats are not new.

Digarok released a nifty utility to do so: Buckshot. I recently came to know about it in a YouTube video by @Javmast3r .

The application lets you convert images into 4 modes:
  • Low Resolution
  • Double Low Resolution
  • High Resolution
  • Double High Resolution
I was able to load the high-resolution ones.

High resolution:

Code:
 ? CHR$(4);"BLOADARCHIVE,A$2000 (or 4000 depending on the page)

Screenshot 2024-04-27 at 11.36.18.jpg
Screenshot 2024-04-27 at 11.33.02.jpg



For double high resolution it's a little bit trickier, but I managed to dig the net for the solution:

Code:
PR#3

POKE 49232,0: REM GRAPHICS
POKE 49234,0: REM FULL GRAPHICS
POKE 49236,0: REM PAGE ONE
POKE 49239,0: REM HI-RES ON
POKE 49246,0: REM DOUBLE HI-RES ON

POKE 49237,0: PRINT CHR$(4);"BLOADARCHIVE,A$2000,L$2000
POKE 49236,0: PRINT CHR$(4);"BLOADARCHIVE,A$2000,L$2000,B$2000


Screenshot 2024-04-27 at 11.40.20.jpg
Screenshot 2024-04-27 at 12.01.19.jpg



The problem begins when I try to load low-resolution images! Looking at the memory allocation map for the Apple II, it says that low-res graphics are allocated in the same place as text: 0400.

I tried BLOADARCHIVE,A$400 but I got nothing… I didn't even try to tap into Double Low Resolution!!!

Does anyone know the answer to this??

As always, Thank You!!!!
 
Last edited:
  • Like
  • Love
Reactions: JDW and Javmast3r

joevt

Tinkerer
Mar 5, 2023
73
32
18
There's some info at https://en.wikipedia.org/wiki/Apple_II_graphics

Basically, the graphics pages have screen holes between some rows. The screen holes for HGR aren't used for anything so you can overwrite them without issue with a BLOAD.

The screen holes for GR are used by various things including the disk driver so you should not try to BLOAD there. Instead, BLOAD to some free memory space (maybe HGR space) then copy the bytes to GR space but skip the screen holes.

Below is some notes for translating line numbers in HGR or GR or TEXT to addresses. Basically, it uses some bit shifting or multiplying of parts of the line number to get the address.
Code:
Line addresses:                       reference COMPUTE! August 1983 pp. 172-177

Brief explanation of line number (eg 0-191) to line start address conversion
(eg $2000-$4000):

For text mode, the display is divided in 3 and each third is split in 8 rows. A row is a
character's vertical position. For HR and DHR, these are split into 8 character lines (the
height of a character is 8 pixels or hi-res lines).

                          vv-third (00,01,10)
text line # bits (0..23): ABCDE
                            ^^^-row in third 000..111

  LR line # bits (0..47): ABCDEF
                               ^-even/odd row in lo/hi nibble of byte

  HR line # bits (0.191): ABCDEFGH
                               ^^^-character line (0..7)

                                    111111 000 0000 000
                              bit#: 543210 987 6543 210
text or LR line start address bits: 0000pp CDE ABAB 000
        HR line start address bits: 0ppFGH CDE ABAB 000

pp = 01 for page 1, 10 for page 2.


For LR, if F is 0 then top even line of row, low nibble $0x for byte, else bottom odd line
of row, high nibble $x0 for byte.

The pattern ABAB 000 means each third is multiplied by 101000 = 40 which is the exact
number of bytes per row. It also means there are screen holes for the unused third (where
AB=11). The screen holes have addresses with pattern 0ppxxxxxx1111xxx for HR and
0000ppxxx1111xxx for LR. That's 512 bytes for HR and 64 for LR.

  1010000 last third (%10) start
+  100111 last byte of character line (39,$27)
= 1110111 last byte of last third (%10)
+       1
  1111000 first byte of unused third (%11)
+  100111 last byte of character line (39,$27)
=10011111 overflows into other address lines
- 1111111 max allowed in unused third (%11)
=  100000 amount of overflow (32)
          The unused third only has 40-32=8 bytes. Each third has 8 rows of characters.
          For HR, each character row has 8 character lines.
          8*8=64 unused bytes for text and LR. 8*8*8=512 unused bytes for HR.
[code]
 
Last edited:
  • Like
Reactions: Genjoke

joevt

Tinkerer
Mar 5, 2023
73
32
18
If you load the GR image to $2000, then this should be able to copy it to $400 (if my math is correct):
Code:
10 FOR Y = 0 TO 23
20 AB = INT(Y / 8)
30 CDE = Y - AB * 8
40 OFFSET = CDE * 128 + AB * 40
50 FOR X = 0 to 39 : POKE 1024+OFFSET+X,PEEK(8192+OFFSET+X) : NEXT
60 NEXT
But it's really slow because Applesoft BASIC uses floating point numbers and doesn't have integer arithmetic or bitwise operands.

https://www.calormen.com/jsbasic/reference.html
https://www.calormen.com/jsbasic/
https://www.scullinsteel.com/apple2/
 
  • Like
Reactions: Genjoke

joevt

Tinkerer
Mar 5, 2023
73
32
18
The COMPUTE! magazine issue I referenced is at internet archive and contains machine language for calculating HGR line address.
 
  • Like
Reactions: Genjoke

Genjoke

Tinkerer
Oct 31, 2021
70
42
18
Brazil - Rio de Janeiro - Flamengo
I think the problem is the Buckshot output.

I converted that heart image to a low-res image file.

Screenshot 2024-04-28 at 00.19.56.jpg


I then used the load at HGR and then transfering it to GR approach.

Using an assambly routine I got this:

Screenshot 2024-04-28 at 00.19.42.jpg


Using your BASIC program I got this:

Screenshot 2024-04-28 at 00.22.05.jpg


I think your program has some wrong value, but one can notice that both results suggest that the original file is saved in a different "order" as the horizontal lines are not loaded on the correct Y position.
 

joevt

Tinkerer
Mar 5, 2023
73
32
18
Using your BASIC program I got this:

I think your program has some wrong value, but one can notice that both results suggest that the original file is saved in a different "order" as the horizontal lines are not loaded on the correct Y position.

My program is correct. Change line 50 to write the line number as a character between A and X (1 to 24)
Code:
50 FOR X = 0 to 39 : POKE 1024+OFFSET+X,Y+1 : NEXT

What is the size of the binary created by buckshot? If it's 24 * 40 = 960 then it's not including screen holes. It might be saving the file with the lines in order (except with the lores pixels of the odd row numbers 1-39 mixed into the bytes of the even row numbers 0-38). If both are true, then line 50 should maybe be like this:

Code:
50 FOR X = 0 to 39 : POKE 1024+OFFSET+X, PEEK(8192+Y*40+X) : NEXT
 
  • Love
Reactions: Genjoke

Genjoke

Tinkerer
Oct 31, 2021
70
42
18
Brazil - Rio de Janeiro - Flamengo
50 FOR X = 0 to 39 : POKE 1024+OFFSET+X, PEEK(8192+Y*40+X) : NEXT

THIS ONE WORKED!!!!

I will now dig into the theory and try to understand it!

Thanks a lot!

The file created by Bucksot is indeed 960 bytes long.

Now the only one that I have to figure out is the Double Lo-Res! The binary is exactly the double: 1920 bytes.
 
Last edited:

joevt

Tinkerer
Mar 5, 2023
73
32
18
Seems like Buckshot is not saving DLO images correctly. In my source test image, the diagonal line reaches the bottom line. In the DLO result, the diagonal line doesn't reach the bottom line. It seems the image was stretched horizontally so that only 40 of the 80 pixels are represented. It looks like the first 40 bytes are for main memory and the next 40 bytes are for auxiliary memory.

Is the file saved to ProDOS image the same as the file saved as local binary?

Buckshut DLO test.png
 

Genjoke

Tinkerer
Oct 31, 2021
70
42
18
Brazil - Rio de Janeiro - Flamengo
Seems like Buckshot is not saving DLO images correctly. In my source test image, the diagonal line reaches the bottom line. In the DLO result, the diagonal line doesn't reach the bottom line. It seems the image was stretched horizontally so that only 40 of the 80 pixels are represented. It looks like the first 40 bytes are for main memory and the next 40 bytes are for auxiliary memory.

Is the file saved to ProDOS image the same as the file saved as local binary?

View attachment 16372
That explan the odd results I was getting in PRODOS!

indeed I got a stretched image, but both horizontally and vertically. I could only fill the screen with the upper left quadrant of the image.
 
Last edited:

JDW

Administrator
Staff member
Founder
Sep 2, 2021
1,577
1,373
113
53
Japan
youtube.com
I was playing around with Buckshot today, even before I discovered this thread. I was Googling about how to get the exported graphics to display, and it was then I found this thread. Funny that I missed seeing it back in April.

Anyway, I am finding A2Desktop to be the drop-dead easiest means of getting the graphics to display. I am using Virtual ][ right now, and here's how one file I created as HGR (from a bitmap I had on my Mac) looks when I merely double-click it within A2D:

1723194642061.png



1723194666995.png


It displays DHGR graphics equally as well, by a mere double-click!

HGR export from Buckshot
1723195812115.png



DHGR export from Buckshot
1723195771705.png



MONO export from Buckshot
1723195991646.png


SOURCE IMAGE:
1723196046255.png
 

joevt

Tinkerer
Mar 5, 2023
73
32
18
MONO is meant to be a 280x192 black & white image instead of 140x192 color image.
The MONO and HGR and DHR examples are using a naive bits to color conversion method which is not what real hardware would do.

A single 25% brightness DHGR pixel should be half the width of a HGR color pixel and a quarter the width of a white pixel.
A single 75% brightness DHGR pixel should be 75% the width of a white pixel.
A single 50% brightness DHGR gray pixel is probably also 75% the width of a white pixel.

There are 560 possible positions for HGR and DHGR pixels. All 560 positions are usable by white and gray. Other colors have only 140 possible positions.
A single 50% brightness HGR green pixel can't exist in the same column as a single 50% brightness HGR violet pixel.
A single 50% brightness HGR orange pixel can't exist in the same column as a single 50% brightness HGR blue pixel.

HGR usually has 4 colors besides white and black, but you can get some of the DHGR colors at the byte boundaries in HGR.

Are there any conversion programs that emulate a color composite display's NTSC interpretation of the Apple II's 14MHz square wave by emulating the analog circuitry or at least performing the same signal transformations?
https://codeandlife.com/2012/10/09/composite-video-decoding-theory-and-practice/
http://www.kreativekorp.com/miscpages/a2info/munafo.shtml
 

JDW

Administrator
Staff member
Founder
Sep 2, 2021
1,577
1,373
113
53
Japan
youtube.com
MONO is meant to be a 280x192 black & white image instead of 140x192 color image.
The MONO and HGR and DHR examples are using a naive bits to color conversion method which is not what real hardware would do.
Have you used the Virtual ][ emulator?

I ask because I have a real Apple IIc and whatever I see in Virtual ][ (when using IIc emulation) always very closely matches what I see on my Apple IIc when connected to my DELL 17” display connected via Apple IIc to VGA adapter. That adapter is super neat because there’s a push button switch on the adapter itself which let you flip between color and monochrome most. There are two monochrome modes, one of which is green and the other white. Being able to switch to monochrome on the fly is critically important for A2D because it’s barely useable when viewed in color.

I realize there are some differences between setup I have an a genuine CRT. Many purists would maybe prefer to have a CRT. The tiny monochrome one for the IIc looks especially cute! Would love to have one one day. But for those of us living outside the US, CRTs are sometimes hard to find or expensive when we find them, not to mention problem-ridden; and if it’s not an authentic Apple or period-correct CRT, it may not look all that aesthetic pleasing either.

I realize that some graphics are indeed intended to be properly displayed on a monochrome monitor, but the Virtual ][ emulator allows you to conveniently switch between a monochrome and color display. In my previous post I deliberately showed what the Virtual ][ color display would show when viewing that monochrome graphics file because my Apple IIc to VGA adapter works well to display what I see in Virtual ][.

You did not comment on A2D, but for casual viewing of different image types, it’s hard to beat. With that said, I do think it would be neat if I could throw a few HGR and DHGR image files on a 140kb boot floppy and have the graphics automatically display, either as an automatic slideshow or by key press to switch to the ext graphic. Something easy to use that would show off the graphics capability of a given Apple II without needing A2D would be fabulous.
 

joevt

Tinkerer
Mar 5, 2023
73
32
18
You did not comment on A2D, but for casual viewing of different image types, it’s hard to beat.
A2D is interesting. Does it load everything as DHGR or does it switch graphics mode to match the input file? Certainly DHGR can display anything that GR, DGR, and HGR can since it allows explicit control over all 560 horizontal displayable bits and you shouldn't be able to tell the difference except there might be a shift in pixels affecting the left or right edge of an image depending on the first displayable bit's relationship to the color burst which might be different between DHR and the source graphics mode.

With that said, I do think it would be neat if I could throw a few HGR and DHGR image files on a 140kb boot floppy and have the graphics automatically display, either as an automatic slideshow or by key press to switch to the next graphic. Something easy to use that would show off the graphics capability of a given Apple II without needing A2D would be fabulous.
I remember DOS 3.3 disks had a HELLO file that would run. It would show a menu of files that you can choose from. I suppose such a program could be converted to a slide show app.

Have you used the Virtual ][ emulator?
Last time I tried Virtual ][ was 2012 when it was version 6.4.1. I see the've made some improvements since then.
The version history is at https://www.virtualii.com/VirtualIIHelp/virtual_II_help.html

1) The monochrome mode now faithfully reproduces the half pixel shift that occurs when setting the MSB of a HGR byte (HCOLOR 4,5,6,7). In 6.4.1, you could not see a difference between HCOLOR 1,2,3 and HCOLOR 5,6,7.

2) An NTSC color mode was added to more faithfully reproduce the NTSC artifact colouring. I believe the new RGB color mode matches the old behaviour of 6.4.1? Not sure why it's named RGB. It's not like the RGB of the Apple IIGS. It would be nice if you could switch between NTSC and RGB without rebooting.

I've attached a test program called HRTEST.txt which produces two HGR images. Set Virtual ][ to max speed and paste the text. Type PR#3 to switch to 80 column mode, then type RUN. Press Return to show the second test image. "Toggle B&W" only works on the IIGS. For Virtual ][, use the Color/Mono buttons.

You could put the text file on a disk and use EXEC to input it. And then SAVE it as an AppleSoft binary.

The attachment includes screenshots from various emulators.

The pixel shift feature you see in "A Virtual ][ 9.3.1 NTSC/RGB mono.png" is missing in "A Virtual ][ 6.4.1 mono.png".

If you look at the "Virtual ][ 9.3.1 NTSC color" images, you can see many more colors than the usual 6 of HGR (compare with the Virtual ][ 9.3.1 RGB color or Virtual ][ 6.4.1 color screenshots). There's more color fringing than I expected. Compare with my experimental joevtKEGSMAC color screenshots. I don't have a real Apple ][ and composite display to compare with so I don't know how accurate anything is.

In "A Virtual ][ 9.3.1 NTSC color.png", I think there's something strange with the rightmost column of colors (the OBc and the BOc columns).
P=Purple/Violet, G=GReen, O=Orange, B=Blue, c=MSB clear, s=MSB set.

In the OBc column, OB together makes white but c in the next byte truncates the last dot so that the total is only 75% the width of a white pixel which should be Pink/Beige. Similarly, the BOc column should be Aqua. In "A Virtual ][ 9.3.1 NTSC color.png", the columns show two colors: OBc is Orange then Blue; BOc is Light Blue then Brown.

The Dazzle Draw test images (D) include some MIXED Mode examples. Dazzle Draw sets the unused MSB bit of bytes that it wants to display as monochrome. This is only useable for non-composite output (RGB and possibly S-Video). https://github.com/AppleWin/AppleWin/issues/523
 

Attachments

  • HRTEST.zip
    12.3 MB · Views: 32
  • Like
Reactions: JDW

JDW

Administrator
Staff member
Founder
Sep 2, 2021
1,577
1,373
113
53
Japan
youtube.com
A2D is interesting. Does it load everything as DHGR or does it switch graphics mode to match the input file? Certainly DHGR can display anything that GR, DGR, and HGR can...
I am by no means an expert on A2D, but based on the text description of it here, A2D appears to use DHGR graphics. Even so, it is not clear if A2D is switching graphics mode depending on the graphic you double-click within the A2D environment.

Because I was unable to get the Virtual ][ emulator to display graphics mode info, I sent an email to Gerard Putter to ask if there was some way I could get Virtual ][ to tell me that. I am currently waiting for his reply.
 

joevt

Tinkerer
Mar 5, 2023
73
32
18
I tried A2D using Apple //jse. I don't think A2D supports loading lores or double lores images?

A2D loads HR as DHGR. You can tell by moving the mouse which makes the cursor visible. The cursor is definitely using DHR pixels.
The HGR image is loaded into the main column of DHGR immediately. You can see this as loading 7 pixels every 14 pixels. Then those main bytes are used to generate DHGR main and aux bytes. You can see this loading and conversion process as it's happening (because it's slow enough to see the pixels load and update). I think the load is done by address order and the conversion process is done by line order.

There is source code for the HR to DHR conversion routine at https://github.com/a2stuff/a2d/blob...a1171a799b7a4/desk.acc/show.image.file.s#L525
I'm not sure if it's totally accurate. It uses lookup tables for address calculation and for HR to DHR bit conversion. Neither are necessary but might speed up the conversion process. I'm not sure what it's doing with hibitset and spill bits. It works from right to left which is opposite from the way I would do it.

The loading process for a DHGR image is simpler. It loads main first. Copies that to aux? Then loads aux. Both are by address order. Maybe that's for one type of DHGR image (the butterfly sample). Probably need to slow it down to be sure. Or try to decipher that assembly source file.

Apple //jse doesn't show correct color fringing unless you enable the GL Renderer which also adds a slight CRT curvature and disables the ability of A2D to switch between mono and color mode with the space bar (but you can still enable a mono mode using the Apple //jse settings).
 

JDW

Administrator
Staff member
Founder
Sep 2, 2021
1,577
1,373
113
53
Japan
youtube.com
Gerard Putter (creator of the Virtual ][ emulator) wrote me back to say this:

What could help is using the inspector. Double resolution involves 0xC05E (to switch it on) and 0xC05F (switch off). By setting an I/O breakpoints on those addresses you can determine whether they are triggered.

So based on that advice, I enabled those two breakpoints in the Inspector:

1724215412656.png


I then booted from an A2D v1.3 disk. Early in the boot sequence, it halted at C05F (switch OFF double resolution):

1724215530000.png


Then just before it loads A2D, it halted at C05E (switch ON double resolution):

1724215671839.png



1724215724706.png


Then it halted at C05F (switch ON):

1724215759073.png


It halted several more times as it switch back and forth at C05E and C05F.

Then after I double-clicked a graphic, just as it starts to display, it halted at C05F. But as you can see from the addresses below, it halts several more times, flipping between C05F & C05E.

1724215912868.png
 

joevt

Tinkerer
Mar 5, 2023
73
32
18
The Apple //jse GL Renderer seems to do color fringing more accurately than Virtual ][ (at least according to my expectations for my test image A - the pink and aqua columns on the right side are mostly a single color).
 

joevt

Tinkerer
Mar 5, 2023
73
32
18
Apple II question:
Does it draw even and odd fields of an NTSC frame?
Can VBL be detected?

If yes to both, then wouldn't it be possible to create a 280x384 interlaced mode by switching between HGR and HGR2 at 60Hz?
Then you could have a 560x384 mode by switching between DHGR page 1 and DHGR page 2.
It would flicker a lot but a convolver connected to composite output would improve that.
This works only if the even and odd fields are offset from each other. The discussion at https://rich12345.tripod.com/aiivideo/softalk.html suggests that is not the case :( (search for "objectionable flicker"). Custom hardware in the convolver could add the offset if it's missing.

Here's a page describing mode switching per scan line (much more than 60Hz):
http://www.deater.net/weave/vmwprod/megademo/
They show a 40x96 lores mode. I wonder if they could get 80x96 double lores?