Wednesday, April 12, 2017

Apple II - Double Hi-Res From The Ground Up
Part 2: How DHR works

Check out part one here!

Bank switched memory:


One limitation that 8 bit machines hit early on was memory. If you haven't noticed by now all of the addresses we've referenced here use two bytes $2000,$4000,etc... This is because the 6502 internally stores addresses using no more than two bytes. Two bytes is sixteen bits which means 216 possible memory locations. In other words 65536 bytes or 64 Kilobytes.

To get around this, many systems used a technique called bank switching. This involves having circuitry which allows you to take some part of the memory in the computer and switch it with another piece of memory of the same size. Effectively you can take what's stored at say memory location $3000-$3FFF - flip a switch - and now those same memory locations point to a completely different block of memory. Flip the switch again and you've got your original memory block back.

With the release of the Apple //e and the Extended 80 Column Card users now owned machines with 128K of memory primarily existing as two bank switched blocks of 64K. The memory that the Apple II uses when turned on is called the MAIN bank and the other 64K is referred to as the auxiliary bank or simply AUX memory.

Double hi-res works by having the Apple //e video circuitry read the memory in both the MAIN and AUX banks at the same time. This extra memory doubles the number of pixels available in monochrome hi-res and doubles the number of bits per pixel on a colour screen.  There's no documentation that I can find on who decided to make this change but evidence suggests it was an afterthought and possibly done by someone who worked on the Apple /// or understood it's video circuitry. As this function replicates the Apple ///'s graphic modes almost exactly.  In any case once this was realized, Apple made this change to their production line resulting in the Revision B motherboard.

Under DHR, pixels are read first from AUX memory and then from MAIN memory. So the screen layout for the first eight lines of DHR PAGE1 looks something like this



Let's take a closer look at just the first four bytes. Again we will use letters to represent pixels.



As you can see, we have seven pixels spread across four bytes of memory BUT using only two addresses $2000 (8192) and $2001 (8193). Some of these pixels reside in a single byte and others are split between two bytes - one in MAIN and the other in AUX.

Perhaps you've noticed that the palette bit is still there. Does that mean we can use it to get even more colours? Nope! When DHR is active the palette bit simply gets ignored (in the vast majority of cases).

So how do we activate this magical mode? You guessed it! Softswitches! You need FIVE - in no particular order. Here they are:

$C050 (49232) - Graphics $C057 (49239) - Hires $C052 (49234) - Fullscreen $C05E (49246) - DHR $C00D (49165) - 80 Column mode

POKE something into each one of those locations and you will be on the DHR screen. At this point  you usually see a kind of stripe pattern. This is due to the fact that the main hi-res page is, on power up filled with garbage and the AUX page gets cleared.

Drawing on the DHR screen


Ok let's put together everything we've learned and get some pixels up on the DHR screen. If you recall our diagram...



...and keeping in mind that currently we don't yet know how to access the AUX memory. The first memory location we have access to is 8192 in MAIN memory. As you can see, it has one bit from pixel B, all four from pixel C and two from pixel D. So the only pixel we can fully draw by changing this byte alone is C! In order to know what to put in this byte we need to decide what colour pixel we are going to draw. Here is full list of DHR colours and their associated bit patterns:



Lets say we want to colour pixel C yellow. The bit pattern for yellow is 1110 and putting that into the spot where pixel C is in our diagram we get PDD1110B.  For now lets assume that all the other pixels around this are black so we can set all the other bits in this byte to zero and the result is 00011100 or 28! There's probably a lot of junk on the screen so let's write a simple program to flicker the pixel between yellow and black which as you can see from the chart above the bit pattern is 0000.
10 POKE 8192,0 20 POKE 8192,28 30 GOTO 10

Accessing AUX memory


The last thing we need in order to have complete control of every pixel on the DHR screen is to figure out how to write to AUX memory. To help with that the Apple II provides a special softswitch called 80STOREON $C001 (49153). When invoked it changes the behavior of the PAGE1 and PAGE2 softswitches. Instead of switching which page is displayed. The PAGE2 softswitch now swaps the MAIN hi-res page 1 ($2000-$3FFF) with the hi-res page in in AUX memory and the PAGE1 softswitch swaps them back.

Looking back at our diagram again to the first byte of PAGE1 in aux memory. We see: PBBBAAAA and we recall the bit pattern for yellow is 1110. To set pixel A to yellow we again insert it into our diagram PBBB1110 and zero the other bits 00001110 which gives us 14. So starting from the beginning our program for writing looks like this:
10 POKE 49232,100: REM TURN ON GRAPHICS 20 POKE 49239,100: REM TURN ON HIRES 30 POKE 49234,100: REM TURN ON FULLSCREEN 40 POKE 49246,100: REM TURN ON DHR 50 POKE 49165,100: REM TURN ON 80COLUMNS 60 POKE 49153,100:POKE 49237,100:POKE 8192,14: REM TURN ON 80STORE, TURN ON PAGE2, WRITE YELLOW PIXEL RUN
As this is probably the last bit of BASIC code in this series. Here is that same program in assembly code:
 STA $C050 ;TURN ON GRAPHICS
 STA $C057 ;TURN ON HIRES
 STA FULLSCREEN ;TURN ON FULLSCREEN
 STA $C05E ;TURN ON DHR
 STA $C00D ;TURN ON 80 COLUMNS
 STA $C001 ;TURN ON 80STORE
 STA $C055 ;TURN ON PAGE2
 LDA #$0E  ;LOAD 14
 STA $2000 ;Put in first location on HIRES PAGE 1 in AUX RAM.
...and here's a binary output that you can paste into any Apple II emulator.

CALL -151 6000:8d 50 c0 8d 57 c0 8d 52 c0 8d 5e c0 8d 0d c0 8d 01 c0 8d 55 c0 a9 0e 8d 00 20 60 6000g

Now you have everything you need to activate the DHR screen and turn on any DHR pixel in any DHR colour. Next up we'll talk more about bank switched memory and how to access DHR PAGE2 and after that we will begin a two part post on writing a fast machine language program to plot a pixel of any colour anywhere on the DHR screen.

2 comments:

Michaelangel007 said...


Excellent write-up.

Minor pet peeve / spelling:

Pallet vs Palette vs Palate :-)
https://literatureandlibation.files.wordpress.com/2013/12/ppp.jpg

Michael
AppleWin Developer

Axon Punch said...

Thanks for the feedback. Just shows how lazy we get with spellcheckers. :-)

Apple II - Double Hi-Res From The Ground Up - Part 9: An API and a demo!

A better interface Perhaps you've noticed that all these drawing routines we've developed require a fair amount of memory to do an...