Egyptian Meme – Bmp2DHR DHGR conversion using Buckels Dithering |
Cat “walking on water” – Bmp2DHR DHGR conversion using Buckels Dithering |
Displaying BSAVE Double Hi-Res Graphics (DHGR) Image
Files in AppleSoft BASIC
Rebranding BSAVE for “The
Great Unwashed”
Loading Binary Files In
Apple$oft BASIC
BLOAD and BSAVE - DOS 3.3 and
ProDOS 8 Differences
Converting from ProDOS A2FC
to DOS 3.3 AUX, BIN
ProDOS 8 AppleSoft BASIC DHGR
Slideshow Example One
Example One Compared to the C
Programming Language
Example Two - Adding a Script
to Example One
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.
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.
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):
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.
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
“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. |
|||||
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).
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.
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.
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:
Unlatch - 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 |
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.
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 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 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 |
|||
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 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!
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 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 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 |
|||
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.
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
February 4, 2014