Displaying BSAVE Double Hi-Res Graphics (DHGR) Image Files in AppleSoft BASIC

 

More DHGR Mischief!

 

Egyptian Meme Bmp2DHR DHGR conversion using Buckels Dithering

Cat “walking on waterBmp2DHR DHGR conversion using Buckels Dithering

 

Displaying BSAVE Double Hi-Res Graphics (DHGR) Image Files in AppleSoft BASIC.. 1

More DHGR Mischief! 1

Forward. 1

The BSAVE Graphics Image File. 1

Why BSAVE?. 2

The Wrong Basket of Eggs. 3

Rebranding BSAVE for “The Great Unwashed”. 5

Loading Binary Files In Apple$oft BASIC.. 6

BLOAD and BSAVE - DOS 3.3 and ProDOS 8 Differences. 6

Converting from ProDOS A2FC to DOS 3.3 AUX, BIN.. 7

Forbidden Areas. 7

ProDOS 8 AppleSoft BASIC DHGR Slideshow Example One. 7

Example One Compared to the C Programming Language. 8

Example Two - Adding a Script to Example One. 9

Closing Remarks. 10

Downloads. 11

 

Forward

 

Jobs “Evangelizes”Bmp2DHR DHGR conversion using Buckels Dithering

 

Woz “looks on”Bmp2DHR DHGR conversion using Buckels Dithering

 

This article is about loading and displaying Apple II DHGR BSAVE graphics files in Apple II AppleSoft BASIC programs and includes programming examples and background information. It is “written in English”; that is to say that I want “everyone” to generally understand what I am saying. For example, when I say “bitmap” I am referring to a bit array somewhere; it could be in a computer file or in computer memory. I am not referring to Microsoft’s BMP file format. When I say “device independent bitmap”, I am using the term “generically; I am not referring to Microsoft’s DIB memory structure that can be saved to a Windows DIB file.  When I describe the BSAVE graphics file format as being “standard device dependent” I am using the word “standard” in the principle sense (not necessarily based on something that Apple Computer once wrote) and the “device” that I refer to is screen memory (a graphics device). I’m sure you get the idea.

 

In this article I also continue some previous themes from my other retro-computing articles, remaining convinced that experiencing computing history and “getting a little carried away” by trying to improve on history by “clever programming” is a goal totally worthy of any retro-computing enthusiast. It is left as an exercise for the reader to decide whether I am right or not.

 

The BSAVE Graphics Image File

 

 

Well, a lot has happened since 1964 when the BASIC programming language first appeared. In contrast, development of the C programming language would not even start until 5 years later; by 1973 when Dennis Ritchie finally completed C to the point where it could begin to be used for structured System programming and Application development, BASIC programming was already well established. With BASIC being widely used throughout the period as a command interpreter on mini-computers as well as main-frames, the average user knew BASIC. Since BASIC promotes non-structured programming and spaghetti-code, writing simple application programs in BASIC was a very “short-leap” for programmers and non-programmers alike! It wasn’t very long before computer games written in BASIC began to “show-up”. Tom Mayfield (author of one of the first BASIC games called “Star Trek”) first published his book “101 BASIC Computer Games” in 1973, the same year that the C programming language was “born”.

 

Depending on the platform, it could have been several years before the C programming language enjoyed some use either as an application development language or  as a system programming language especially on “smaller computers”. Originally systems programmers wrote in assembly language, and this practice continued as micro-computers like the Apple II came along, as did the practice of providing a BASIC interpreter. Later higher-end 16-bit “personal computers” like the PC with their more capable hardware and expanding user-base finally saw the use of the C programming language become more wide-spread in that market. Almost invariably, applications for microcomputers like the Apple II were not written in C, but in BASIC or assembly language or both, with other programming languages like Pascal enjoying some use as well.    

 

 

In 2007, I “officially” documented the BSAVE graphics file format as a Wikipedia Article, providing code and examples for the IBM-PC, the Apple II and the Commodore 64/128 “classic” micro-computers. My BSAVE Wikipedia Article barely “scratched the surface” as far as the Apple II is concerned, especially considering BSAVE graphics files of “one sort or another” were used for all the Apple II graphics modes, including DHGR (and Super Hi-Res (SHR) on the Apple IIgs). This Wikipedia Article of mine soon found its way into many Internet knowledge bases. Until that time, I had never seen a general reference of BSAVE as a standard device dependent graphics file format despite the fact that BSAVE was historically the most widely available micro-computer graphics file format from the time of the Apple II until over a decade later when (“so-called’) device-independent formats like gif, PCX, and BMP took over (in “lamestream computing”), followed by formats like jpeg and PNG.  

 

Why BSAVE?

 

What’s in a name? When it comes to graphics file formats a name is required to identify the format independently from the other named formats that are “out there”. From the time I began serious graphics programming in the 1980’s I have always called this unstructured format  “BSAVE” no matter what kind of computer I worked on, so for my Wikipedia Article I stayed with the name I had always used. This is not to say that you won’t hear BSAVE graphics files referred to by other names; the VGACad program on the IBM-PC called them “Bloadable Pictures”. Microsoft’s BSAVE documentation for GW-BASIC simply calls BSAVE files “images”; a consistent naming convention for all the variations of BSAVE was never established even on the same platform. Microsoft provided most of the BASIC  for 8 bit microcomputers beginning with the Altair 8800, and with the introduction of 16 bit microcomputers like the PC, for them as well. In many of their BASICs of that era Microsoft includes a BSAVE command to save reloadable memory images including images of video memory. On the Apple II computer, the BSAVE command is part of the disk operating system and not a BASIC command, but BSAVE is “callable” from AppleSoft BASIC and saves Apple II video memory to a BSAVE graphics file.

 

In 1988 in his “][gif” version 1.0 documentation, Jason Harper says that that his graphics file converter will “save the converted pictures in standard Apple graphics formats for use with other programs” and “Allows you to view a HiRes or DoubleHiRes picture saved in standard Apple format”. Jason also says “There's no question about the format of HiRes graphics files, however some programs use a nonstandard two-file format for DoubleHiRes”. Jason never does say what this format is, nor why one DHGR variation is standard, and another DHGR variation is not standard when both can be saved and loaded equivalently to Apple II screen memory using AppleSoft BASIC, nor why there can be no question about the HGR file (although the reason there is no question is because these were invariably created in BASIC as a single BSAVE file).  Apple Computer also anonymously call these “standard” files in their File Type Notes and provide “format” specifications but they later anonymously called the Super Hi-Res equivalent a “graphics screen image” and an “unpacked picture image”.

 

A BSAVE format file can be created by processes other than a BSAVE command, so one cannot, instead, inclusively call a file format a BSAVED file format since other creation processes don’t necessarily use a BSAVE command to save a BSAVE format file; they may just save it! On some systems, header information is needed for loader commands like BLOAD; Apple DOS 3.3 and MS-DOS GW-BASIC both require header info in their BSAVE files. The ProDOS 8 BSAVE command uses the ProDOS 8 (SOS) filing system instead of headers, so BSAVE images have no headers in ProDOS 8.

 

My criteria for calling something a BSAVE graphics image is as follows (they are not nameless images or standard files alone):

 

  • Regardless of the differences in the way BASICs and the systems they run-on in “wrap” these video memory images to make them work with their loader commands, they are all the same format; they are all reloadable video memory images of “native” video hardware. This is the format qualifier; device dependent graphics images.

 

  • On systems that have a BSAVE command or equivalent and have a complementary “BLOAD” command or equivalent, they are BLOAD compatible.

 

  • The systems that these are natively used with have both a BSAVE and a BLOAD command or equivalent that is available from BASIC.

 

The primary reason that BSAVE was historically the most widely available micro-computer graphics file format during the early years is that computers like the Apple II, Commodore 64/128 and IBM-PC shipped with BASIC, providing the capability to create graphics screen images of video memory, and to easily load and save these BSAVE graphics screens in the BASIC programming language without additional software. Many (if not most) of the users of the day were, out of necessity, more “hands-on” when it came to doing BASIC programming and understanding their hardware, including their video hardware. This understanding in turn eventually provided a desire and market for “productivity tools” like Paint Programs and Graphics Utilities, many which initially supported the BSAVE graphics format in some way thereby providing additional graphics capabilities to the BASIC programmers of the day.

 

“Almost universally, home computers had a BASIC interpreter which one could use to type in BASIC programs. The BASIC interpreter was also used as the user interface; the concept of a computer platform was still forming, with most companies considering BASIC language sufficient. A common marketing tactic was emphasizing the computer's greater ability by showing it running user-created programs. Books of type-in program listings were available for most models of computer (Before the Internet, and before most computer owners had a modem, books served a role in familiarizing new computer owners with the concepts of programming). Modifying software to be compatible with one's system or writing a utility program to fit one's needs was a skill every advanced computer owner was expected to have.  The declining cost of IBM compatibles and abilities of video game consoles combined to cause the market segment for home computers to vanish by the early 1990s.” - (“condensed” quotation )  - http://en.wikipedia.org/wiki/Home_computer

 

At the end of the “Home Computer Era”, “The computers that were bought for use in the family room were either forgotten in closets or relegated to basements and children's bedrooms to be used exclusively for games and the occasional book report. Home computers of the 1980s have been called 'a technology in search of a use’” - http://en.wikipedia.org/wiki/Home_computer#The_Home_Computer_.22Revolution.22

 

By 1987 only 15% of American homes owned a computer.  Just exactly how many BASIC programs were written and how many BSAVE graphics files as opposed to graphics file in other formats were actually created by the average user, or even just how much “meaningful use” a “productivity tool” like a Paint Program really saw “back in the day” remains a mystery; today relatively few old computer graphics seem to exist, other than professionally created graphics like game screens and the sample images that came with those Paint Programs and Graphics Utilities.  And other than a handful of “sample images”, most of the graphics files of “the day” that persist today (in Internet archives and the like) are, in a word, pretty “crappy” even by “yesterday’s standards”. Anyone can usually do much better today simply by converting a modern graphics image to a BSAVE image like those converted by Bmp2DHR and shown in the document you are now reading.

 

The Wrong Basket of Eggs

 

 

DHGR “came out” in 1984, the same year that Apple Computer released the Apple II Mouse (a re-packaged Macintosh mouse), bundled with Bill Budge’s MousePaint. But MousePaint was capable only of producing HGR BSAVE graphics images of hand-drawn pixel graphics; DHGR BSAVE graphics images were not supported! By that time the “domain” of the Apple II BSAVE graphics image format (arguably) did not “belong” to Apple Computer, but to the AppleSoft BASIC command interpreter licenced from Micro$oft. Also in 1984 Apple Computer cancelled Macintosh BASIC and sold it to Bill Gates, Microsoft’s co-founder, for a dollar, as part of a renewal contract for Microsoft’s AppleSoft BASIC for the Apple II. As part of the same deal Gates obtained perpetual rights to provide BASIC for the Macintosh. (Through licencing agreements for their BASIC, Microsoft also offered the BSAVE graphics image format on the IBM-PC and Commodore computers. Like the device-independent BMP format that followed, Microsoft established the device-dependent BSAVE graphics image format as an indisputable standard.)     

 

 

The interface design of MousePaint was based on MacPaint by Bill Atkinson, who developed Atkinson Error Diffusion Dithering (by modifyingFloyd-Steinberg dithering) that same year (while helping to write the ThunderScan scanner interface for the Macintosh). The ThunderScan interface for the Macintosh included Atkinson’s dithering, and by that time error diffusion dithering which was developed in 1977(when the Apple II was first introduced) was already “old news”. Also in 1984 the ThunderScan scanner was introduced to the Apple II, but the Apple II was never provided with the same interface offered on the Macintosh, and so was deprived of Atkinson error diffusion dithering (for one thing the Apple II was considered too slow for the ThunderScan when compared to the Macintosh, and for another Steve Jobs, Apple’s co-founder, was convinced that the Apple II would be gone in a few years so instead focused on the Macintosh).

 

Apple Computer already had access to the technology required to convert scanned files to error-diffused DHGR graphics files and with a little real effort could likely have aspired to something similar (in monochrome) to the same quality of display rendering provided today by Bmp2DHR (seen throughout this document) when MousePaint was released, but selectively introduced or withheld this technology from Apple II users. Instead (and generally speaking), with their mouse “bundle” Apple Computer offered Apple II users only the “entry level”  “trailing –edge” capability of “hand-built” HGR pixel-graphics saved to BSAVE files; functionality that had  been around(at least programmatically) since the Apple II Plus was introduced in 1979; 5 year old technology. But at that same time the “Digital Image Revolution” was just getting started, and after all, the Apple II would be gone in a few years…

 

From “Pictures to Pixels” by Gord McComb - MacWorld April 1985

Original Image – 8 x 10 Photo

ThunderScan using Atkinson Dithering

 

“Some of the best minds that worked on the Mac have worked on the software for a new genre of products – digitizers.”  ThunderScan has excellent resolution and produced the most detailed image in the test.”

Bmp2DHR conversion to DHGR Monochrome 560 x 192 BSAVE Image

Using Buckels Dithering with 25% Color Bleed Reduction

 

Apparently the software written by one average mind that worked on the IBM-PC around the same time produces at least comparative results on a TV set to what we see from the best minds on the Mac for this “new genre of products” reviewed in 1985 by MacWorld.

 

It’s also made obvious by the images in the document you are currently reading just what the old “genre” of the Apple II display with 15 colors and BSAVE images can do. Rendering specifically for the Apple II NTSC display’s capabilities to capitalize its potential rather than for a display that mimics a piece of paper was not Apple Computer’s “vision” of the day; software was evidently viewed as a necessary evil to sell hardware, and improving the Apple II’s “status-quo” by providing similar innovation wasn’t “on the radar”.  But the technology and supporting research to produce the output below including the Psycho-Visual color model was available and well understood even back then. Apple’s later rendering efforts were targeted at the RGB display on the Apple IIgs and also did not capitalize on the capabilities of the Apple II’s NTSC display (Home computers of the 1980s have been called 'a technology in search of a use’.)

 

Bmp2DHR compiles and runs under MS-DOS as well as on most modern computers including Windows, Mac OSX, and Linux; the 1987 MS-DOS Turbo C compiler version 2.0 is used to build the MS-DOS executable binary. Therefore Bmp2DHR could have provided the DHGR output below when the Apple II was still in wide use, so surely if one old PC guy can write such a thing in his spare time spanning a couple of months, and make it work on computers from before the time of the Apple IIgs, the “best minds on the Mac” could have provided equal or better capabilities to Apple II users with a little real effort. There is no question in my mind that the Mac Team was capable! Even the dithering that I developed (with reduced color bleed similar to Atkinson dithering for monochrome and full color bleed like Floyd-Steinberg for the color display) has a pattern similar to Apple’s Atkinson dithering, with weighting better suited for DHGR’s NTSC display!  

 

But it is left as an exercise for the reader to decide whether I am being wildly speculative or if history agrees, and my argument is conclusive and my results speak for themselves.

 

 

Rebranding BSAVE for “The Great Unwashed”

 

The fact of the Apple II BSAVE file format standard on the Apple II family of computers is (obviously) indisputable. Before DHGR the BSAVE binary graphics file format was used to save and load Hi-Res Graphics (HGR) screens; before ProDOS 8, DOS 3.3 supported HGR BSAVE binary files. But selling Computers and Computer Software depends on the same marketing strategies as selling refrigerators and color TVs and everything else.

 

 

Towards the end of 1988, Apple Computer attempted to re-brand and up-market the BSAVE graphics file format used on the Apple II in “their own image” in their ProDOS File Type $08 specifications, as part of their File Type Notes. However this was analogous to calling a CAT a DOG; by the time Apple Computer re-branded BSAVE, two Apple II DHGR variations of BSAVE were already in wide use; Beagle Graphics AUX, BIN 8192 byte file pairs for both DOS 3.3 and ProDOS (since August 1984), and Dazzle Draw’s A2FC 16384 byte single file variation of BSAVE for ProDOS 8 (also since 1984). These are also the two DHGR BSAVE formats created by my Bmp2DHR utility. And as mentioned earlier, in 1984 when the DHGR “ship was sailing” with the BEAGLEs and Broderbund “on-board”, Apple Computer did not seem as interested in developing some new DHGR standard for BSAVE graphics images as selling Macintosh mice bundled with a Paint Program that only aspired to saving in AppleSoft BASIC compatible HGR BSAVE format as ProDOS Binary File Type $06. Having yet another standard for the same “standard” file makes no sense to me at all.

 

 

In 1988, the same year as Apple’s re-branding, Jason Harper released “][gif” Version 1.0 which saved gif files to the DHGR A2FC single file variation of BSAVE as ProDOS Binary File Type $06. In his documentation Jason says “some programs use a nonstandard two-file format for DoubleHiRes.” Jason’s later effort for the Apple IIgs, Super Convert 4 (1992 to 1997), still opened A2FC files (and HGR BSAVE graphics files as well) as ProDOS Binary File Type $06. While history disagrees with Jason’s statement that AUX, BIN file pairs are not a standard (they are very much as standard in DOS 3.3 simply due to the limitations of the DOS 3.3 BSAVE command), Apple Computer’s re-assignment of their ProDOS File Type $08 to include the BSAVE image format with some other files that were not BSAVE format does not constitute a standard and is simply up-marketing, like Bill Atkinson’s re-branded Floyd-Steinberg dithering which also found its way into Apple Computer’s Desktop programming libraries (Bmp2DHR’s Buckels Dithering and user-definable dithering are both more innovative and better suited to Apple II graphics, and like Atkinson are simply Floyd-Steinberg variations). History agrees with Jason Harper’s statement that A2FC is one of the two BSAVE standards for Apple II DHGR graphics images.     

 

Although not always as formal and “up-marketed” as Apple Computer’s “official” re-branding of the BSAVE format, the transition from device-dependent screen images to the device-independent graphics file formats of today was already similarly well represented on other micro-computers; by 1984, inspired by MacPaint, John Bridges had already changed the IBM-PC BSAVE graphics file format to suit his own needs in the programming of PCPaint, the first Paint Program for the PC while he evolved his Pictor file format, the first widely accepted MS-DOS imaging standard (all covered in a series of Wikipedia articles that I wrote in 2007 which led to my Wikipedia BSAVE article).

 

 

Loading Binary Files In Apple$oft BASIC

 

 

The following is just a synopsis. For additional info about Apple II DOS 3.3 and ProDOS 8, The Apple DOS & Commands Frequently Asked Questions (FAQ) is a good starting point. For AppleSoft BASIC, read the manual.

 

BLOAD and BSAVE - DOS 3.3 and ProDOS 8 Differences

 

In 1983 when Apple Computer released the Apple IIe, the ProDOS 8 disk operating system, and Double-Hi Res Graphics, the Apple DOS 3.3 disk operating system was in wide use. ProDOS 8 offers many advantages over DOS 3.3 including support for disk volumes up to 32 MB in size; DOS 3.3 was designed to support disk media only in 140K floppy-drive format. But Apple II users who decided they had no need for the improvements of ProDOS (or who did not like its higher memory footprint or who had a significant investment in DOS 3.3 programs and games) continued using DOS 3.3 long after 1983. DOS 3.3 and ProDOS 8 both shipped with AppleSoft BASIC licenced from Micro$oft.  AppleSoft BASIC does not come with any built-in commands for dealing with files or disks, other than a feature to save programs to, and load programs from, cassette tape. DOS 3.3 and ProDOS 8 augment AppleSoft BASIC by providing commands for dealing with disks, and files on disk. These commands can be used from the BASIC prompt in immediate mode or called from a BASIC program (in program mode) by using the BASIC PRINT statement followed by CHR$(4).

 

DOS 3.3 “boots” into BASIC and all programs are executed from there. ProDOS 8 does not necessarily boot into BASIC; when ProDOS 8 boots-up, it will run the first SYS program with a “.SYSTEM” file extension on the boot volume… if BASIC.SYSTEM is the first, ProDOS 8 runs BASIC.SYSTEM. In ProDOS 8, BASIC is optional and lives in a SYS program called “BASIC.SYSTEM”. ProDOS 8 is also a SYS program and is also optional.

 

In DOS 3.3 there are only 8 File Types, stored in the filing system according to a very limited and “low-level” scheme. ProDOS 8 both changed and expanded the use of File Types; DOS 3.3 and ProDOS 8 are entirely different filing systems. ProDOS 8 has 256 File Types and essentially all files are stored on disks the same way, regardless if they are composed of text or binary data.

 

In general, all executable 6502 machine code programs in DOS 3.3 are stored as binary files. The BRUN command can be used to load and execute binary files as 6502 machine code programs in both DOS 3.3 and ProDOS 8 from the BASIC command prompt or in a BASIC program. ProDOS 8 also executes system (SYS) programs (ProDOS File Type $FF) with or without BASIC but DOS 3.3 has no equivalent to a ProDOS SYS program.

 

In addition to BRUN, both disk operating systems provide a complementary binary save command called “BSAVE” that can be used to save the Apple II’s memory to binary disk files, and a complementary binary load command called “BLOAD” that can be used to load these binary disk files back to the Apple II’s memory.  BLOAD and BSAVE are not used exclusively for 6502 machine code programs; these commands provide the only way that BASIC can read and write binary files in either DOS 3.3 or ProDOS 8.  

 

BSAVE can be used to save the Apple II’s DHGR screen memory to binary disk files, and BLOAD can be used to load these binary disk files back to the Apple II’s DHGR screen memory. But the BSAVE and BLOAD command options and parameters differ between DOS 3.3 and ProDOS.

 

Because of the difference in the way ProDOS 8 and DOS 3.3 reference disk files, the DOS 3.3 BSAVE and BLOAD commands provide options for specifying filenames followed by Slot, Drive, and Volume. In ProDOS 8 filenames are usually used alone (with or without prefix) but the ProDOS BSAVE and BLOAD commands provide options for specifying filenames followed by Slot, and Drive (Volume is DOS 3.3 only). 

 

The ProDOS 8 BLOAD and BSAVE commands have options for saving and loading memory ranges from a file, and are not limited to binary files so can be used to load any ProDOS File Type. In DOS 3.3 the BSAVE and BLOAD commands work only with binary files, and do not accept memory range parameters; DOS 3.3 BSAVES an entire file or BLOADS an entire file contiguously.

 

Regardless of the differences between DOS 3.3 and ProDOS 8, the BSAVE and BLOAD commands can be used for respectively saving and loading DHGR files in both operating systems from the BASIC prompt or in a BASIC program. However, because of the DOS 3.3 BSAVE and BLOAD commands do not support loading and saving memory ranges, only the AUX, BIN file pair variation of the DHGR BSAVE file can be (practically) used in DOS 3.3 BASIC without extending DOS 3.3 BASIC with 6502 machine code routines.

 

Converting from ProDOS A2FC to DOS 3.3 AUX, BIN

 

If you use Bmp2DHR you can specify AUX, BIN output for your conversions rather than the A2FC default. However if you use a utility like Sheldon Simms tohgr which does not support AUX, BIN file pair output (A2FC format is also tohgr’s default) or if you already have A2FC files created in a program like Dazzle Draw, you have at least two conversion options:

 

  • Use my unlatch command line utility to convert to AUX, BIN file pairs on your modern computer.
  • Use AppleSoft BASIC to convert from A2FC to AUX, BIN format on your Apple II or emulator (see the code from Jason Harper below).

 

Unlatch - Split 'DHRPIC.A2FC' into file pair 'DHRPIC.BIN' & 'DHRPIC.AUX':

 

BLOAD DHRPIC.A2FC,A$2000

BSAVE DHRPIC.AUX,A$2000,L$2000

BSAVE DHRPIC.BIN,A$4000,L$2000

Latch - Concatenate file pair 'DHRPIC.BIN' & 'DHRPIC.AUX'  to file 'DHRPIC.A2FC':

 

BLOAD DHRPIC.AUX,A$2000

BLOAD DHRPIC.BIN,A$4000

BSAVE DHRPIC.A2FC,A$2000,L$4000

 

Forbidden Areas

 

One important difference between the ProDOS 8 and DOS 3.3 BLOAD command which does not apply to DHGR mode but applies to “BLOADing” of Lo-Res and Double Lo-Res graphics is because memory was scarce on the Apple II, and the text screen “memory holes” were used to store hardware information for disk controllers, ProDOS 8 is protected from “BLOADing” to this memory area. Another consideration is ProDOS comes with a RAM disk that uses Auxiliary Memory in the same memory area as the Apple II double-resolution graphics modes.  So it’s a good idea when using the text screen area in any Apple II program, to address only the normally visible memory area, and when using double-res graphics, do not use the RAM disk.

 

 

It should probably be noted again that the use of BSAVE and BLOAD is not limited to graphics files; any binary file can be loaded from disk using BLOAD, and changed in memory, and saved back to disk using BSAVE. And in ProDOS 8, any File Type can be used with BLOAD and BSAVE. So BSAVE and BLOAD provide AppleSoft BASIC with relatively powerful disk file commands, in addition to providing AppleSoft BASIC with “built-in” Apple II graphics file formats by facilitating the saving and loading of the Apple II Screen Memory in a standard format.

 

ProDOS 8 AppleSoft BASIC DHGR Slideshow Example One

 

 

This Slideshow was cobbled together with bits and pieces from the Beagle Graphics Slideshow which contains a 6502 assembly module. But because I wanted a simple and “generic” demo written entirely in AppleSoft BASIC, I removed those parts, and replaced them with the “more or less” equivalent BASIC routines.

 

In order to use Double-Res, 80-column text-mode must be on, so right at the beginning on LINE 3 I tell ProDOS to initialize the language card in Slot 3. Then I show a little menu since this program is also used as a STARTUP program for my demo disks, and I wanted to provide the user with the option of exiting to BASIC without running the Slideshow; otherwise the menu would not be necessary.

 

LINES 24 to 28 turn-on DHGR. Now that DHGR is on, the PAGE ONE switch will “window” Main DHGR Memory at $2000 and the PAGE TWO switch will “window” Auxiliary DHGR Memory at $2000. The idea here is to switch to Auxiliary Memory, load and display the first half of the A2FC file, then switch back to Main Memory and load the second half of the A2FC file. If we are loading file pairs, then the AUX file is loaded first, then the BIN file using the same technique.

 

So after initializing DHGR the Slideshow is capable of loading up to 20 images, so on LINE 33 I create a couple of string arrays to store the files’ base-names and extensions, and an integer array to store the delay times for each file, and set an ONERR condition to GOTO LINE 40 if an error occurs.

 

Then on LINE 34 while looping, I populate up to 20 subscripts in the arrays by READING DATA statements that start at LINE 150. When I run-out of DATA an error occurs and sends me to LINE 40. I use the loop counter to tell me how many image names I was able to read successfully, and I then go into an endless loop at LINE 50. It is time to load some slides.

 

LINES 51 to 56 check the extension to see what kind of file I want to load. I stay within a known naming convention just to “keep it simple”. Since I am loading only two different formats, I provide a loader branch to LINE 60 for file pairs, and a loader branch to LINE 70 for A2FC files.

 

Both the loaders work the same way and “window” AUX MEM and load 8192 bytes of DHGR picture data, then “window” MAIN MEM and load 8192 bytes of DHGR picture data.

 

The Length Parameter L$2000 is not required for BLOAD for the AUX, BIN file pair loader at LINE 60 since the files are only 8192 bytes each so L$2000 is optional. But for the A2FC single-file loader at LINE 70, the Length Parameter L$2000 is required for the first half of the file, and I just left it in place for the second-half of the file (it does no harm). I also add the optional Byte-offset Parameter B$2000 for the second-half of the file; this tells BLOAD to seek to 8192 bytes before reading the next 8192 bytes.

 

The timing loop is a FOR-NEXT loop between LINE 85 and LINE 125. This timing loop is set-up for an Apple IIe running at 1MHZ.

 

Any key press or paddle button press will break this loop and load another image, except if the ESC key is pressed, at which point the loop is exited with a GOTO LINE 700. If no keys or paddle buttons are pressed the timing loop will expire naturally and GOTO LINE 50 from LINE 140 to load another image.

 

The keyboard buffer is read directly and reset when a key-press is waiting. The paddle buttons are also read. Before entering the loop a BACKWARDS directional flag was set to FALSE on LINE 80. If this flag is set in the loop the slide counter will run backwards from LINE 130 and if not the slide counter will run forwards from LINE 140. In either case both LINE 130 and LINE 140 both GOTO LINE 50 at the top of the MAIN loop to load another image.

 

Before the Slideshow exits text-mode is turned back-on and DHGR is turned-off, starting at LINE 700.

 

When the Slideshow exits a catalog of the files in the current directory is displayed and the user is at the BASIC prompt in immediate mode. The program has been cleared from memory.

 

It is left as an exercise for the reader to “fill-in” the blanks here. The code is fairly self-explanatory so that’s probably a good place to start.

 

 1  REM Double Hi-Res Slideshow in Applesoft BASIC for ProDOS 8

 2  REM By Bill Buckels January 2015

 3  D$ =  CHR$ (4): PRINT D$;"PR#3": PRINT : REM ENABLE 80 COL

 5  TEXT

 6  HOME

 7   PRINT "****************************************************"

 8   PRINT "*                                                  *"

 9   PRINT "*  DHGR Slideshow, Bill Buckels, 2015              *"

 10  PRINT "*  Loosely Based on The Beagle Graphics Slideshow  *"

 11  PRINT "*  And a Slideshow by Andrew and Ivan Hogan        *"

 12  PRINT "*                                                  *"

 13  PRINT "*            1 -   Run Slideshow                   *"

 14  PRINT "*            ESC - Exit to AppleSoft               *"

 15  PRINT "*                                                  *"

 16  PRINT "* Slideshow: ESC - Quit and Exit to AppleSoft      *"

 17  PRINT "*            Left Arrow, Up Arrow - Previous Slide *"

 18  PRINT "*            Other Keys - Next Slide               *"

 19  PRINT "****************************************************"

 20 GET A$

 21  IF A$ =  CHR$ (27) THEN  GOTO 800

 22  IF A$ = "1" THEN  GOTO 24

 23 GOTO 5

 24 POKE 49232,0: REM GRAPHICS

 25 POKE 49234,0: REM FULL GRAPHICS

 26 POKE 49236,0: REM PAGE ONE

 27 POKE 49239,0: REM HI-RES ON

 28 POKE 49246,0: REM DOUBLE HI-RES ON

 33 DIM NAME$(20),EXT$(20),TIME(20): ONERR  GOTO 40

 34 FOR I = 1 TO 20: READ NAME$(I),EXT$(I),TIME(I): NEXT

 40 NUMBER = I - 1:I = 1: POKE 216,0: REM SET ONERR FLAG

 50 REM MAIN LOOP

 51 IF EXT$(I) = "BIN" GOTO 60: REM AUX,BIN FILE PAIRS

 52 IF EXT$(I) = "AUX" GOTO 60: REM AUX,BIN FILE PAIRS

 53 IF EXT$(I) = "2FC" GOTO 70: REM 2FC Single File created by BmpA2FC 

 54 IF EXT$(I) = "A2FC" GOTO 70:REM A2FC Color created by Bmp2DHR

 55 IF EXT$(I) = "A2FM" GOTO 70:REM A2FM Mono created by Bmp2DHR

 56 IF EXT$(I) = "DHGR" GOTO 70:REM DHGR created by Sheldon Simms tohgr

 59 GOTO 70

 60 TEMP$ = NAME$(I) + "."

 61  POKE 49237,0: PRINT D$;"BLOAD ";TEMP$;"AUX, A$2000": PRINT

 62  POKE 49236,0: PRINT D$;"BLOAD ";TEMP$;"BIN, A$2000": PRINT

 63 GOTO 80

 70 TEMP$ = NAME$(I) + "." + EXT$(I) + ", A$2000, L$2000"

 71  POKE 49237,0: PRINT D$;"BLOAD ";TEMP$: PRINT

 72  POKE 49236,0: PRINT D$;"BLOAD ";TEMP$; ", B$2000": PRINT

 80 B = 0

 85  FOR J = 1 TO TIME(I) * 30

 86   REM PADDLE BUTTONS

 90   IF  PEEK ( - 16286) > 127 THEN J = TIME(I) * 44

 100  IF  PEEK ( - 16287) > 127 THEN J = TIME(I) * 44:B = 1

 101  K =  PEEK ( - 16384)

 105  REM ESCAPE KEY, ANY KEY, LEFT ARROW, UP ARROW

 110  IF K = 155 THEN  POKE  - 16368,0: GOTO 700

 115  IF K > 127 THEN  POKE  - 16368,0:J = TIME(I) * 44: REM ANY KEY

 120  IF K = 136 THEN B = 1: REM LEFT ARROW - BACK

 121  IF K = 139 THEN B = 1: REM UP ARROW - BACK

 125 NEXT J

 130  IF B THEN I = I + NUMBER * (I = 1) - 1: GOTO 50

 140 I = I - I * (I = NUMBER) + 1: GOTO 50

 141  REM BASENAMES,EXTENSIONS, AND SECONDS TO DISPLAY ARE ADDED HERE

 150  DATA BEER,A2FC,10

 170  DATA FLCAT,A2FC,10

 180  DATA CATFACE,A2FC,10

 200  DATA CATEYE,BIN,10

 210  DATA ACAT,A2FC,10

 700  REM EXIT SLIDESHOW

 710  POKE 49233,0: REM TEXT MODE

 720  POKE 49247,0: REM DOUBLE HI-RES OFF

 730  POKE 49236,0: REM PAGE ONE

 800  TEXT

 810  HOME

 820  CALL  - 1184: CALL 42350

 830  REM THIS IS THE END

 840  NEW

 

Example One Compared to the C Programming Language

 

The C language code snippets below are from the source code of my cc65 DHGR Slideshow demo: http://www.appleoldies.ca/cc65/programs/dhgr/dhishow.zip

 

 

/* initialize 80 column card */

videomode(VIDEOMODE_80COL);

clrscr();

 

/* turn-on double hi-res and clear the dhgr screen */

dhireson();

dhiresclear();

 

 

 

/* load picture */

if (dlodehi(picname) < 0) continue;

 

/* clear the dhgr screen and turn-off double hi-res */

dhiresclear();

dhiresoff();

videomode(VIDEOMODE_80COL);

clrscr();

 

3  D$ =  CHR$ (4): PRINT D$;"PR#3": PRINT : REM ENABLE 80 COL

5  TEXT

6  HOME

 

24 POKE 49232,0: REM GRAPHICS

25 POKE 49234,0: REM FULL GRAPHICS

26 POKE 49236,0: REM PAGE ONE

27 POKE 49239,0: REM HI-RES ON

28 POKE 49246,0: REM DOUBLE HI-RES ON

 

61  POKE 49237,0: PRINT D$;"BLOAD ";TEMP$;"AUX, A$2000":PRINT

62  POKE 49236,0: PRINT D$;"BLOAD ";TEMP$;"BIN, A$2000":PRINT

 

710  POKE 49233,0: REM TEXT MODE

720  POKE 49247,0: REM DOUBLE HI-RES OFF

730  POKE 49236,0: REM PAGE ONE

800  TEXT

810  HOME

 

Needless to say, the cc65 C code above was not modeled after the Beagle Slideshow. It is hard to compare old interpreted BASIC with the readability and language features, or performance of the C programming language; C compiles to 6502 machine code and runs much more quickly on the Apple II without the need for a BASIC interpreter. Outside the retro-computing community, the very thinking required to write in old BASIC like AppleSoft probably does not really exist in “the wild” anymore. Today the closest thing we generally have are the various scripting languages, but many have become very “C-like” and aren’t really very “low-level” anyway. Today’s compiled BASIC resembles C more than it resembles AppleSoft BASIC. Needless to say it is much easier and probably a lot more productive for today’s programmer to write Apple II DHGR programs in cc65 than in AppleSoft BASIC. But it may not be more fun!

 

Example Two - Adding a Script to Example One

 

The C language Slideshow mentioned above uses a list of DHGR images in ProDOS Apple II sequential text file format called “PICLIST” as a script. We are going to change the BASIC “Beagle-like” Slideshow above to be more like the C language Slideshow so they can share the same script. We are also going to remove the menu. Here’s what we end-up with:

 

 

When the program starts, on LINE 126 it tries to BLOAD 6 bytes from a sequential text file called “PICLIST”. This represents the shortest filename that we want to accept (5 bytes for a name like “1.BIN” and 1 byte for a carriage-return).  If “PICLIST” doesn’t exist or is empty, then an error is generated and the program ends. This is a “quick and dirty” use for BLOAD’s capability of loading all file types in ProDOS; to avoid AppleSoft’s “feature” of creating empty text files during the opening of a file that doesn’t exist.   

 

If “PICLIST” seems valid, we open it, and on LINE 150, we read up to 40 file names for our Slideshow, before closing “PICLIST”.

 

On LINE 300 we initialize DHGR then jump past our error handler at LINE 400 to LINE 500 and our main program loop.

 

On LINE 125 at the start of our program we assigned LINE 400 to handle our errors. Using the variable “EL”, we also set some internal error-levels for various activities throughout our program to help us decide what to do with our errors at different states.

 

David Finnigan’s New Apple II User’s Guide (everyone should have a copy) has a detailed section on handling file errors. Sorry David… I didn’t want to go through the overkill of all the possible misfortunes that AppleSoft might encounter so I used this local approach in my example instead. It’s good enough for my purposes and my codes are easier to remember than Apple’s. It’s left as an exercise for the reader to thoughtfully compare my code to David’s published approach and to reach your own conclusions.

 

In our main loop starting a LINE 500, we are using file extensions to drive our choice of our two loaders like in Example One. But our logic is a little different. We just assume that every file in the “PICLIST” that does not meet our naming convention for file pairs or for image fragments is an A2FC file.

 

Our loader for AUX, BIN file pairs is at LINE 560 and our A2FC loader is at LINE 570.

 

Our timing loop is between LINE 581 and LINE 592. This is essentially identical to the timing loop in our Example One Slideshow.

 

Our Slideshow can go backwards as well as forwards just like Example One. This is why we are using an array of filenames rather than just reading them in directly from the “PICLIST” one at a time.

 

Unlike Example One, we are just using a shared timing value between all slides. It’s hardly worth the extra programming to have a bunch of different values for our purposes here.

 

The Slideshow ends on an ESC (escape) key press, just like in Example One.

 

Before exiting to the AppleSoft prompt, we turn-off DHGR but we don’t do anything much else. 

 

So now we have a relatively simple script-driven DHGR Slideshow “driver” written entirely in AppleSoft BASIC for ProDOS 8.

 

 100 REM Double Hi-Res Slideshow in Applesoft BASIC for ProDOS 8

 110 REM By Bill Buckels January 2015

 120 Z$ = "PICLIST": DIM NAME$(40): TIME = 10: D$ = CHR$(4)

 125 ONERR GOTO 400

 126 EL = 666: PRINT D$;"BLOAD ";Z$;", A$2000, L6, T4": PRINT

 130 EL = 999: PRINT D$;"OPEN ";Z$

 140 EL = 411: PRINT D$;"READ ";Z$

 145 EL = 0

 150 FOR I = 1 TO 40: INPUT NAME$(I): NEXT

 160 PRINT D$;"CLOSE ";Z$

 170 NUMBER = I - 1: I = 1

 300 PRINT D$;"PR#3": PRINT: REM ENABLE 80 COL

 310 POKE 49232,0: REM GRAPHICS

 320 POKE 49234,0: REM FULL GRAPHICS

 330 POKE 49236,0: REM PAGE ONE

 340 POKE 49239,0: REM HI-RES ON

 350 POKE 49246,0: REM DOUBLE HI-RES ON

 360 GOTO 500

 400 IF EL = 911 THEN GOTO 600

 405 IF EL = 666 THEN PRINT Z$; " NOT FOUND! EXITING!": GOTO 840

 410 IF EL = 999 THEN PRINT "UNABLE TO OPEN "; Z$; " EXITING!": GOTO 840

 420 IF EL = 411 THEN PRINT D$;"CLOSE ";Z$: GOTO 840

 430 GOTO 160

 500 REM MAIN LOOP

 505 EL = 911

 510 EXT$ = RIGHT$ (NAME$(I),4) 

 520   IF EXT$ = ".BIN" GOTO 560: REM AUX,BIN FILE PAIRS

 530   IF EXT$ = ".AUX" GOTO 560: REM AUX,BIN FILE PAIRS

 540   IF EXT$ = ".DHR" GOTO 600: REM SKIP DHR IMAGE FRAGMENTS

 550 GOTO 570

 560   TEMP$ =  LEFT$ (NAME$(I),( LEN (NAME$(I)) - 3))

 561   POKE 49237,0: PRINT D$;"BLOAD ";TEMP$;"AUX, A$2000": PRINT

 562   POKE 49236,0: PRINT D$;"BLOAD ";TEMP$;"BIN, A$2000": PRINT

 563 GOTO 580

 570   TEMP$ =  NAME$(I) + ", A$2000, L$2000"

 571   POKE 49237,0: PRINT D$;"BLOAD ";TEMP$: PRINT

 572   POKE 49236,0: PRINT D$;"BLOAD ";TEMP$; ", B$2000": PRINT

 580 B = 0

 581 FOR J = 1 TO TIME * 30

 582   REM PADDLE BUTTONS

 583   IF  PEEK ( - 16286) > 127 THEN J = TIME * 44

 584   IF  PEEK ( - 16287) > 127 THEN J = TIME * 44:B = 1

 585   REM KEYBOARD

 586   K =  PEEK ( - 16384)

 587   REM ESCAPE KEY, ANY KEY, LEFT ARROW, UP ARROW

 588   IF K = 155 THEN  POKE  - 16368,0: GOTO 700

 589   IF K > 127 THEN  POKE  - 16368,0:J = TIME * 44: REM ANY KEY

 590   IF K = 136 THEN B = 1: REM LEFT ARROW - BACK

 591   IF K = 139 THEN B = 1: REM UP ARROW - BACK

 592 NEXT J

 600 IF B THEN I = I + NUMBER * (I = 1) - 1: GOTO 500

 610 I = I - I * (I = NUMBER) + 1: GOTO 500

 700 REM EXIT SLIDESHOW

 710 POKE 49233,0: REM TEXT MODE

 720 POKE 49247,0: REM DOUBLE HI-RES OFF

 730 POKE 49236,0: REM PAGE ONE

 800 TEXT

 810 HOME

 840 NEW

 

Closing Remarks

 

 

Well, I certainly hope that I have provided you with enough information to understand how just about anyone can write a DHGR Slideshow in AppleSoft BASIC, even a C language programmer like me. You also likely understand that the Apple II’s DHGR mode was historically underutilized by comparison to what we can do with it today. Just about anyone can do better than what they did back then; provided that one uses modern tools and standard parts which from my view include a proper Apple II C compiler like cc65, and provided one cobbles a tool or two like Bmp2DHR together to help things along. Good quality continuous tone graphics are everywhere waiting to be converted to Apple II DHGR BSAVE files, so apparently there is no excuse not to enjoy art for art’s sake, whether the art of your choice is the art of retro-programming or some other creative force that has brought you here today.

 

When I wrote my Bmp2DHR Apple II graphics conversion utility I initially said that I would not be providing AppleSoft BASIC examples. There are several “practical” reasons for not wanting to do so. For one thing, BASIC is too slow for DHGR especially in DOS 3.3.  Bmp2DHR was written primarily to provide DHGR bitmapped graphics support for Apple II ProDOS 8 cc65 C language programs. Cc65 is a modern C cross-compiler, writes small quick code, and supports 6502 assembly language inline and in separate modules (it comes with an assembler) and runs on a modern computer. For programming the Apple II, I believe ones time is better spent using modern cross-development tools like cc65 and writing in the C programming language..

 

But in the interest of providing my perspective on this whole matter of the BSAVE image format and how it came to be, listing some BASIC programming examples for this article seems the right thing to do to illustrate the relationship between AppleSoft BASIC and the DHGR BSAVE format.

 

Downloads

 

Download the Disk Images of the Examples and DHGR BSAVE Graphics Images from this document:

 

http://www.appleoldies.ca/bmp2dhr/basicdhgr.zip

 

Download Bmp2DHR at the following links:

 

Win32 and latest version complete with source: http://www.appleoldies.ca/cc65/programs/dhgr/bmp2dhr.zip

MS-DOS: http://www.appleoldies.ca/cc65/programs/dhgr/bmp2dhrMSDOS.zip

Other: (Linux, OSX): http://hoop-la.ca/apple2/appleoldies/bmp2dhr/

 

All the best,

 

Bill Buckels

bbuckels@mts.net

 

February 4, 2014