Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Is there a way to access DHR on the Apple 2 from Applesoft Basic

80 views
Skip to first unread message

wayne a arthurton

unread,
Aug 2, 2010, 4:54:02 PM8/2/10
to
When using Applesoft Basic on the Apple 2 with an 80 column card, is
there a way to create DHR graphics using only POKE?

I have found a number of solutions using third party extensions such
as Beagle Graphics, but I really want to implement it myself. I've
searched my Nibble magazine collection, and basic books, but have been
unable to find any detailed information.

Wikipedia:

Double High-Resolution The composition of the Double Hi-Res screen is
very complicated. In addition to the 64:1 interleaving, the pixels in
the individual rows are stored in an unusual way: each pixel was half
its usual width and each byte of pixels alternated between the first
and second bank of 64KB memory. Where three consecutive on pixels were
white, six were now required in double high-resolution. Effectively,
all pixel patterns used to make color in Lo-Res graphics blocks could
be reproduced in Double Hi-Res graphics. The ProDOS implementation of
its RAM disk made access to the Double Hi-Res screen easier by making
the first 8 KB file saved to /RAM store its data at 0x012000 to
0x013fff by design. Also, a second page was possible, and a second
file (or a larger first file) would store its data at 0x014000 to
0x015fff. However, access via the ProDOS file system was slow and not
well suited to page-flipping animation in Double Hi-Res, beyond the
memory requirements.

Wikipedia says that DHR uses 64:1 interlacing, but gives no reference
to the implementation. Additionally Wikipedia says you can use the /
RAM disk to access, but again gives no reference to the
implementation.

I am working an small program that plots a simple version of Connet's
Circle Pattern. Speed isn't really as important as resolution.

rich12345

unread,
Aug 2, 2010, 5:41:18 PM8/2/10
to
On Aug 2, 1:54 pm, wayne a arthurton <warthur...@gmail.com> wrote:
> When using Applesoft Basic on the Apple 2 with an 80 column card, is
> there a way to create DHR graphics using only POKE?
>
> I have found a number of solutions using third party extensions such
> as Beagle Graphics, but I really want to implement it myself. I've
> searched my Nibble magazine collection,

You need to search harder in Nibble. They had several articles on how
to access DHR with BASIC...

Oliver Schmidt

unread,
Aug 3, 2010, 7:27:19 AM8/3/10
to
Hi,

>When using Applesoft Basic on the Apple 2 with an 80 column card, is
>there a way to create DHR graphics using only POKE?

Certainly.

There are basically two things to figure out:

1. Which bytes you want to POKE to which address in order to produce
the pixels you want. Therefore you need to understand the DHR screen
layout - which is well documented.

2. How to access AUX memory from BASIC.

If you are fine with using only the first DHR page then things are
fortunately quite easy: Check out the 80COLSTORE soft switch. It
allows to map only $400-$800 and $2000-$4000 to AUX and keep all other
addresses mapped to MAIN.

If you need access to both DHR pages then you'll most probably end up
POKEing a little assembler routing and CALLing it then...

Regards,
Oliver

BluPhoenyx

unread,
Aug 3, 2010, 7:26:39 AM8/3/10
to
To: wayne a arthurton

On 08/02/2010 03:54 PM, wayne a arthurton wrote:
>
> Wikipedia says that DHR uses 64:1 interlacing, but gives no reference
> to the implementation. Additionally Wikipedia says you can use the /
> RAM disk to access, but again gives no reference to the
> implementation.

When ProDOS first starts it creates /RAM. From this point the first file
you create @ 8kb will be stored in AUX ram location $2000-3fff. This
area will hold the alternate portion of the DHR screen. You could bsave
the HGR space from BASIC.SYSTEM to reserve this space which is useful if
you want to save other data to the /RAM drive.

How you load DHR from floppy or HD depends on the format you saved the
graphics screen with. Some programs use one large file while others use
one file for each 8 kb area. The latter is loaded from BASIC.SYSTEM by
first bloading the ALT page into main memory like a normal graphics page
then bsaving this page into /RAM. The full file load could be loaded
using the bsave parameters to load 1/2 of the file at a time.

Cheers,
Mike T

David Empson

unread,
Aug 3, 2010, 9:14:35 AM8/3/10
to
wayne a arthurton <warth...@gmail.com> wrote:

> When using Applesoft Basic on the Apple 2 with an 80 column card, is
> there a way to create DHR graphics using only POKE?

Yes. Nibble magazine is a good source. It has been too long since I
looked at it, but I recall one program I typed in which included a
reasonably good set of drawing primitives.

(I wrote a hi-res graphics drawing program in high school, originally in
BASIC, then I rewrote it in assembly language. I never got around to
porting it to ProDOS or taking advantage of double hi-res.)

[...]

> Wikipedia says that DHR uses 64:1 interlacing, but gives no reference
> to the implementation.

This refers to the interleaved memory pattern of rows on the hi-res and
double hi-res screens, which are arranged in three groups of 64 lines.

Looking at standard hi-res for starters...

If you address consecutive memory locations, the row pattern starts like
this:

$2000 - $2027: row 0
$2028 - $205F: row 64
$2060 - $2077: row 128
$2078 - $207F: screen holes (not displayed)

For each subequent group of 128 bytes, the pattern of lines repeats,
eight lines below the previous group of 128 bytes, e.g. $2080 is row 8,
$2100 is row 16, etc.

When you get to $2400, the entire pattern repeats again, starting at row
1. This repeats eight times in total, giving a total of $2000 (8192)
bytes of memory and 192 rows.

Within each byte, standard hi-res defines 7 bits containing pixels and 1
bit (MSB) which affects the colour. If you have a monochrome screen you
effectively get 280x192 resolution, with bit 7 in each byte having a
subtle effect (it shifts the pixels in that byte half a pixel to the
right).

If you have a colour screen, you effectively get 140x192 resolution,
with pairs of pixels forming black, green, violet or white if bit 7 is
clear, or black, orange, blue or white if bit 7 is set. (There are some
fringing effects at the transition between bytes.)

Double hi-res is much more complicated. It has twice as many bytes per
row, but they are interleaved between main memory and auxiliary memory
(with auxiliary memory first).

With a monochrome display you get 560x192 resolution. With a colour
display you get 140x192 resolution with 16 colours instead of 6. In both
cases, bit 7 in each byte has no effect (except with some RGB cards,
where it was used to control whether to generate colour or monochrome).

I never experimented enough with DHR to fully understand the colour
mapping. It gets ugly due to needing to work with groups of 4 bits which
straddle byte boundaries, skipping bit 7 and interleaving banks.

When the IIgs came along with its linearly addressable super hi-res
display, it was a godsend. As a result, I never bothered to deal with
DHR.

--
David Empson
dem...@actrix.gen.nz

David Empson

unread,
Aug 3, 2010, 9:27:20 AM8/3/10
to
David Empson <dem...@actrix.gen.nz> wrote:

> Looking at standard hi-res for starters...
>
> If you address consecutive memory locations, the row pattern starts like
> this:
>
> $2000 - $2027: row 0
> $2028 - $205F: row 64
> $2060 - $2077: row 128
> $2078 - $207F: screen holes (not displayed)

Oops, second boundary should have been $204F and $2050. I thought
something looked wrong as I was writing that.

> For each subequent group of 128 bytes, the pattern of lines repeats,
> eight lines below the previous group of 128 bytes, e.g. $2080 is row 8,
> $2100 is row 16, etc.
>
> When you get to $2400, the entire pattern repeats again, starting at row
> 1. This repeats eight times in total, giving a total of $2000 (8192)
> bytes of memory and 192 rows.

[...]

--
David Empson
dem...@actrix.gen.nz

ict@ccess

unread,
Aug 8, 2010, 12:16:38 AM8/8/10
to


I wrote this routine a while back because I wanted to see if I could
write a DHR plotting program strictly with applesoft without using
ampersand help routines and this is what I came up with.

5 HGR : POKE 49237,0 : CALL 62450 : REM clear hires then hires.aux
6 POKE 49246,0 : PG = 49236
7 HCOLOR=7
9 GOTO 100
10 X2 = X * 4: CL = CO: FOR I = 3 TO 0 STEP -1: BIT = CL >= 2 ^ I: CL
= CL - BIT * (2 ^ I)
20 X1 = X + I: HCOLOR= 7 * BIT
30 XX = INT (X1 / 7): H = XX / 2: POKE PG + (H+ INT (H)),0
40 XX = INT (( INT (H) + (( X1 / 7) - XX)) * 7 + .5)
50 HPLOT XX,Y: POKE PG, 0: NEXT : RETURN
100 FOR CO = 0 TO 15
110 FOR X = CO * 8 TO CO * 8 + 7: FOR Y = 0 TO 10 : GOSUB 10 : NEXT :
NEXT
120 NEXT
130 REM color is 0 to 15
140 REM X coordinate is from 0 to 139
150 REM Y coordinate is from 0 to 191

Set the color CO and X and Y variables and GOSUB to the routine at
LINE 10.

Rob

sicklittlemonkey

unread,
Aug 8, 2010, 8:23:02 AM8/8/10
to
On Aug 8, 4:16 pm, "ict@ccess" <gids...@sasktel.net> wrote:
> I wrote this routine a while back because I wanted to see if I could
> write a DHR plotting program strictly with applesoft without using
> ampersand help routines and this is what I came up with.

Good start - but this doesn't work for me in DOS on AppleWin. What
platform (//e, //c, emulator, OS) did you run this on?

Also ...

> 6 POKE 49246,0 : PG = 49236

You seem to be assuming that the 80-column firmware is active so that
80STORE (write to C001) is enabled, but I find the //e firmware gets
in the way of using it from Applesoft.

> 10 X2 = X * 4 ...

X2 is never used again.
Also the program eventually accesses C058 instead of C054/55.

> 30 XX = INT (X1 / 7): H = XX / 2: POKE PG + (H+ INT (H)),0

Maybe you want (H - INT (H)) + 0.5 or similar?
(Wish I had time to investigate.)

In any case the original poster probably just needs a 560-res
monochrome plot routine, which as your code (almost!) shows can be
done with 80STORE and Applesoft's HPLOT.

Cheers,
Nick.

ict@ccess

unread,
Aug 9, 2010, 1:09:37 AM8/9/10
to


Many apologies for the speliing mistakes. Late nights are catching up
to me and not the drinking kind. :)

Works on a IIGS, and all emulators. Have not verified an enchanced
IIe.
Yes I am taking for granted that the 80 col firmware is active. I
deal only in 80 columns so had programmed Basic.system to always turn
on the 80 column card when started.

The corrections to the listing will make a big difference. X2 is used
twice now and the boolean expression has been fixed.

5 HGR : POKE 49237,0 : CALL 62450 : REM clear hires then hires.aux

6 POKE 49246,0 : PG = 49236

7 HCOLOR=7
9 GOTO 100
10 X2 = X * 4: CL = CO: FOR I = 3 TO 0 STEP -1: BIT = CL >= 2 ^ I: CL
= CL - BIT * (2 ^ I)

20 X1 = X2 + I: HCOLOR= 7 * BIT
30 XX = INT (X1 / 7): H = XX / 2: POKE PG + (H= INT (H)),0

Michael J. Mahon

unread,
Aug 9, 2010, 8:01:05 PM8/9/10
to

Clever idea, but I must be something. I still see X2 only used once.

And computing 2^I twice instead of just multiplying by 0.5 inside the
loop seems costly. Same for dividing by constants, when a multiply
would be cheaper. In the same vein, CO * 8 could be computed as
C8 = C8 + 8 before the 110 FOR loop to save 30 multiplies. (Of course,
efficiency can't really be what motivates doing DHR with Applesoft. ;-)

-michael

NadaNet 3.1 for Apple II parallel computing!
Home page: http://home.comcast.net/~mjmahon/

"The wastebasket is our most important design
tool--and it's seriously underused."

bloomer_au

unread,
Aug 10, 2010, 2:18:06 AM8/10/10
to
Something ancillary that might be of use to you Michael,

The Dazzle Draw manual came with a little routine that would let you
load a DHR pic you made with it (an uncompressed pic file, 33 blocks
in size) from a basic program. However I've noticed the routine
doesn't work right in emulators (where it gives weird, distorted
results), only on real Apple IIs. Nevertheless I thought you might
want to see the routine.

The following disk image is an incomplete game of mine from the 90s.
The disk boots to a catalog. To start the game you do '-STARTU' (yes,
no P on the end of that)

This file EXECs the text file GO, which enters the DHR assembly
routine, then runs START, which loads the raw image file P1, then CALL
768s to make it appear, before wiping the routine at $300 with the
sound one for the elec duet music.

http://home.iprimus.com.au/bloomer/warlords.zip

dsk image inside.

- Wade

BLuRry

unread,
Aug 10, 2010, 5:07:49 PM8/10/10
to

Wade, is your disk not supposed to work in emulators? If I type "exec
go" then only half the screen is loaded. However if I type "- startu"
as you mentioned it loads just fine in my local build of Jace.

Hey, nice title music!

-Brendan

Bill Garber

unread,
Aug 10, 2010, 7:10:02 PM8/10/10
to

"BLuRry" <brendan...@gmail.com> wrote in message news:71d0fe27-4e81-4387...@c10g2000yqi.googlegroups.com...

Hence the following contents of the file "STARTU".

5 TEXT : HOME : HGR : HGR2 : PRINT CHR$ (4);"EXEC GO"
=========
=====
Bill


bloomer_au

unread,
Aug 10, 2010, 7:14:12 PM8/10/10
to

Hey Brendan, thanks for prompting me to retry my own game! Last time I
tried it on the Mac Ap2 emulators I had (which was probably a few
years ago..), the title page didn't work. I tried it again last night,
and it still doesn't work in Sweet16, but it now works fine in
VirtualII. Are you running a PC emulator? If so, that's good news that
it works there. Thanks also for the props on the music :)

- Wade
- Wade

Toinet

unread,
Aug 11, 2010, 1:33:21 AM8/11/10
to

Hi Wade,
The image is displayed correctly if you PR#3 before launching/running
your startup program,
antoine

bloomer_au

unread,
Aug 11, 2010, 3:17:30 AM8/11/10
to
On Aug 11, 3:33 pm, Toinet <antoine.vig...@laposte.net> wrote:

> Hi Wade,
> The image is displayed correctly if you PR#3 before launching/running
> your startup program,
> antoine

That's even better news... and good for future reference, though I
guarantee I will never complete this particular game!

- Wade

BLuRry

unread,
Aug 11, 2010, 2:57:32 PM8/11/10
to
> Hey Brendan, thanks for prompting me to retry my own game! Last time I
> tried it on the Mac Ap2 emulators I had (which was probably a few
> years ago..), the title page didn't work. I tried it again last night,
> and it still doesn't work in Sweet16, but it now works fine in
> VirtualII. Are you running a PC emulator? If so, that's good news that
> it works there. Thanks also for the props on the music :)
>
> - Wade

Jace is java-based. So it should (in theory) work on Windows, *nix,
Mac all the same. With one exception that OS X 32-bit users have an
interesting time getting Java 6 support, if any at all. But as such
Jace is missing some features that would make it suitable for gaming,
in particular it needs better NTSC emulation and joystick support.

http://sourceforge.net/projects/java-ace/

-Brendan

ict@ccess

unread,
Aug 12, 2010, 12:53:06 AM8/12/10
to
> Clever idea, but I must be something.  I still see X2 only used once.

You really are something :)

>
> And computing 2^I twice instead of just multiplying by 0.5 inside the
> loop seems costly.  Same for dividing by constants, when a multiply
> would be cheaper.  In the same vein, CO * 8 could be computed as
> C8 = C8 + 8 before the 110 FOR loop to save 30 multiplies.  (Of course,
> efficiency can't really be what motivates doing DHR with Applesoft.  ;-)
>
> -michael
>
> NadaNet 3.1 for Apple II parallel computing!
> Home page:  http://home.comcast.net/~mjmahon/
>

I put the X2 before the loop to speed up the calculation so X times 4
does not get calculated each time within the loop. Thus the use of
booleans, also. I am always looking for ways to speed up applesoft.
But I don't see how multiplying by .5 takes the place of the 2^I since
the I variable is decrementing.

Care to elaborate or provide a replacement code for that line,
Michael.

Also, line 100 to 120 is just a demo, and was not really meant to be
used in a regular program.


Rob

Michael J. Mahon

unread,
Aug 12, 2010, 4:54:01 AM8/12/10
to
On 8/11/2010 9:53 PM, ict@ccess wrote:
>> Clever idea, but I must be something. I still see X2 only used once.
>
> You really are something :)

;-)

Ironic that what was missing was "missing". ;-)

>>
>> And computing 2^I twice instead of just multiplying by 0.5 inside the
>> loop seems costly. Same for dividing by constants, when a multiply
>> would be cheaper. In the same vein, CO * 8 could be computed as
>> C8 = C8 + 8 before the 110 FOR loop to save 30 multiplies. (Of course,
>> efficiency can't really be what motivates doing DHR with Applesoft. ;-)
>>
>> -michael
>

> I put the X2 before the loop to speed up the calculation so X times 4
> does not get calculated each time within the loop.

Well done--and shame on me for writing that line before looking
at the loop structure.

> Thus the use of
> booleans, also. I am always looking for ways to speed up applesoft.
> But I don't see how multiplying by .5 takes the place of the 2^I since
> the I variable is decrementing.
>
> Care to elaborate or provide a replacement code for that line,
> Michael.

If you start an auxiliary variable at 8, and multiply it by 0.5
each time through the loop, it will replace 2^I. Applesoft does
not special case powers of two, so that will avoid taking a LOG.

> Also, line 100 to 120 is just a demo, and was not really meant to be
> used in a regular program.

<sheepishly> Fair enough. ;-)

-michael

NadaNet 3.1 for Apple II parallel computing!
Home page: http://home.comcast.net/~mjmahon/

"The wastebasket is our most important design

ict@ccess

unread,
Aug 12, 2010, 11:41:36 AM8/12/10
to
Ah! (light bulb turns on)

replacement for line 10 and ever so slightly faster

10 X2 = X * 4 : CL = CO : TMP = 8 : FOR I = 3 TO 0 STEP -1 : BIT = CL
>= TMP: CL
= CL - BIT * TMP : TMP = TMP * .5

APPLESOFT : where every nanosecond counts

ict@ccess

unread,
Aug 12, 2010, 12:15:51 PM8/12/10
to
I'd better state that all numbers used in any math equations should be
declared in variables before entering the subroutine for a speed boost
before I get corrected on that point as well.


5 HGR : POKE 49237,0 : CALL 62450 : REM clear hires then hires.aux
6 POKE 49246,0 : PG = 49236

7 SVN = 7 : HCOLOR= SVN : P5 = .5
9 GOTO 100


10 X2 = X * 4 : CL = CO : TMP = 8 : FOR I = 3 TO 0 STEP -1 : BIT = CL
>= TMP: CL

= CL - BIT * TMP : TMP = TMP * P5
20 X1 = X + I: HCOLOR= SVN * BIT
30 XX = INT (X1 / SVN): H = XX * P5: POKE PG + (H= INT (H)),0
40 XX = INT (( INT (H) + (( X1 / SVN) - XX)) * SVN + P5)


50 HPLOT XX,Y: POKE PG, 0: NEXT : RETURN

100 FOR CO = 0 TO 15 : C8 = CO * 8
110 FOR X = C8 TO C8 + SVN: FOR Y = 0 TO 10 : GOSUB 10 : NEXT :


NEXT
120 NEXT
130 REM color is 0 to 15
140 REM X coordinate is from 0 to 139
150 REM Y coordinate is from 0 to 191


Does this satisfy you, late night, applesoft programmers to make the
most efficient code to try to get close to the machine language hyper
speed?

Michael J. Mahon

unread,
Aug 12, 2010, 1:51:40 PM8/12/10
to

;-)

John B. Matthews

unread,
Aug 12, 2010, 8:55:54 PM8/12/10
to
In article
<312bc274-6f5d-44dd...@z28g2000yqh.googlegroups.com>,
"ict@ccess" <gid...@sasktel.net> wrote:

The admiral approves: <http://en.wikipedia.org/wiki/Grace_Hopper>

--
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>

Jerry

unread,
Aug 12, 2010, 11:57:07 PM8/12/10
to


Line 20 should read:

20 X1 = X2 + I: HCOLOR= SVN * BIT

--
Jerry awanderin at yahoo dot ca

--- news://freenews.netfront.net/ - complaints: ne...@netfront.net ---

Jerry

unread,
Aug 13, 2010, 12:05:30 AM8/13/10
to
"Michael J. Mahon" <mjm...@aol.com> writes:


Another idea (albeit, a less general solution), is to do a vertical line
in line 50 rather than loop Y in line 110. This will run much faster
since the vertical line will be drawn at machine language speed by HPLOT
x,y1 TO x,y2.

That is:

50 HPLOT XX,Y to XX,Y2: POKE PG,0: NEXT : RETURN

110 Y = 0: Y2 = 10: FOR X = C8 TO C8 + SVN: GOSUB 10: NEXT

--

Peter Watson

unread,
Aug 15, 2010, 8:06:26 AM8/15/10
to
"ict@ccess" <gid...@sasktel.net> wrote in message
news:312bc274-6f5d-44dd...@z28g2000yqh.googlegroups.com...


Other suggestions to consider if you're truly feeling pedantic about shaving
nanoseconds... ;-)

- Only use a single setup line (eg. 5 GOTO 100) at the start of the program.
Every line before the gosub target costs you!
- In line 10 consider using X2 = X + X + X + X since addition is faster than
multiplication. I remember doing tests *many* years ago, and I'm fairly sure
you win for * 2 and * 3, but I can't remember where the break-even point is
for higher multipliers.
- Alternatively try X2 = X + X : X2 = X2 + X2 (I'm assuming an assignment is
faster than an addition).
- Even in the subroutine, the fewer the lines and the smaller the variables
(single character FTW), the better! Those 3-character variables are pure
parsing overhead!

--
Peter Watson
-- Write to MS-DOS disks on the Apple IIgs?
-- Impossible! ;-)


ict@ccess

unread,
Aug 15, 2010, 11:11:33 PM8/15/10
to
On Aug 2, 2:54 pm, wayne a arthurton <warthur...@gmail.com> wrote:

> I am working an small program that plots a simple version of Connet's
> Circle Pattern. Speed isn't really as important as resolution.

There is also a cool little ampersand routine in one of the nibble
magazines that effectively doubles the resolution of the regular hires
screen as well which effectively gives you 560 horizontal dots.
Connets Circle Pattern will show up on screen with smoother lines for
the circle and a more rounded circle as well. This routine works on
all Apple II's and also on Hires Page 1 and Page 2. This might be a
better alternative than using the complicated Double Hires screen
since all that is needed is the pixel count for higher resolution.

Rob

Michael J. Mahon

unread,
Aug 16, 2010, 5:31:33 PM8/16/10
to

I agree. I've used the "white 3/white 7" approach in the past, and
it works quite well as long as lines do not (often) come within 7
(14) pixels of each other, since that clobbers the "color set" bit
and shifts the preexisting line(s) in that byte by 1/2 (1) pixel.

For relatively sparse, non-crossing drawings, it works quite acceptably.
One of the things I used it for was plotting orbits which seldom cross.

It does mean plotting dots instead of lines, but for orbits, which are
always dots, it worked perfectly.

-michael

NadaNet and AppleCrate II: parallel computing for Apple II computers!
Home page: http://home.comcast.net/~mjmahon

wayne a arthurton

unread,
Aug 25, 2010, 10:17:15 AM8/25/10
to
Thanks everyone.

I don't yet have a full run of Nibble, so having this great collective
knowledge is wonderful.

I am investigating your suggestions and solutions and will summarize
my results in the future.

I appreciate all the responses.

0 new messages