Discussion:
How would you save and load images?
Add Reply
Chris Tobar
2017-07-19 00:48:53 UTC
Reply
Permalink
Raw Message
I've been writing some simple BASIC programs to get my Apple II+ to draw pictures. I just use GR and have it draw pictures line by line with code. I was wondering, is there a way I could then save the drawn image on the screen to file on a floppy disk? And another way to load images and display them back on the screen? I'm sure there has to be a way, but I'm clueless.

I've done a lot of programming in Visual Basic for modern (ish) computers running Windows, and it's a piece of cake to work with graphics using that. But I'm fairly new to programming with vintage computers like the Apple II. Things that are super easy to do with modern computers are a lot more challenging with these old computers!
Anthony Ortiz
2017-07-19 01:45:05 UTC
Reply
Permalink
Raw Message
You need to boot up using some OS, perhaps DOS or PRODOS, and then use the BSAVE command to save the range of memory you want. Read up on the location of memory your GR picture resides in and read up on BSAVE for your flavor of DOS.
James Davis
2017-07-19 02:03:39 UTC
Reply
Permalink
Raw Message
Chris,
Post by Anthony Ortiz
You need to boot up using some OS, perhaps DOS or PRODOS, and then use the BSAVE command to save the range of memory you want. Read up on the location of memory your GR picture resides in and read up on BSAVE for your flavor of DOS.
For what Anthony suggests, you will need some Apple II Technical Manuals. Here is a list of sources for ProDOS TMs:

ftp://public.asimov.net/pub/apple_II/documentation/misc/
ftp://public.asimov.net/pub/apple_II/documentation/misc/Apple 2 ProDOS Info BSC.pdf

ftp://public.asimov.net/pub/apple_II/documentation/os/prodos/
ftp://public.asimov.net/pub/apple_II/documentation/os/prodos/Apple II Prodos User's Manual_HiRes.pdf
ftp://public.asimov.net/pub/apple_II/documentation/os/prodos/Apple IIe ProDOS Supplement to the Apple IIe Owner's Manual.pdf
ftp://public.asimov.net/pub/apple_II/documentation/os/prodos/Apple IIgs ProDOS 16 Reference.pdf
ftp://public.asimov.net/pub/apple_II/documentation/os/prodos/Apple ProDOS 8 Technical Reference Manual.pdf
ftp://public.asimov.net/pub/apple_II/documentation/os/prodos/Beginning with ProDOS 8 & 16.pdf
ftp://public.asimov.net/pub/apple_II/documentation/os/prodos/Beneath Apple ProDOS (1985).pdf
ftp://public.asimov.net/pub/apple_II/documentation/os/prodos/Beneath Apple ProDOS 101 Supplement.pdf
ftp://public.asimov.net/pub/apple_II/documentation/os/prodos/Beneath Apple ProDOS 111 Supplement.pdf
ftp://public.asimov.net/pub/apple_II/documentation/os/prodos/Beneath Apple ProDOS 120 and 130 Supplement.pdf
ftp://public.asimov.net/pub/apple_II/documentation/os/prodos/Beneath Apple ProDOS_Alt.pdf
ftp://public.asimov.net/pub/apple_II/documentation/os/prodos/ProDOS Pathnames Primer.pdf
ftp://public.asimov.net/pub/apple_II/documentation/os/prodos/ProDOS.File.Types.v2.0.txt

You may also want to search Asimov's Index for Integer BASIC, Applesoft BASIC, and Apple DOS, Tech Manuals.

James Dais
Michael 'AppleWin Debugger Dev'
2017-07-19 01:52:16 UTC
Reply
Permalink
Raw Message
Post by Chris Tobar
just use GR and have it draw pictures line by line with code. I was wondering, is there a way I could then save the drawn image on the screen to file on a floppy disk?
Yes, all frame buffers on the Apple 2 are memory mapped.

GR shares the same memory location as the text screen.

For Page 1, $400..$7F8.
For Page 2, $800..$BF8

BSAVE GR.PIC,A$400,L$3F8

One minor complication is that there "screen holes" since the framebuffers are NOT linear.

Row Text Address | Screen Hole
0 $400 $427 | n/a
1 $480 $4A7 | n/a
2 $500 $527 | n/a
3 $580 $5A7 | n/a
4 $600 $627 | n/a
5 $600 $6A7 | n/a
6 $700 $727 | n/a
7 $780 $7A7 | n/a

8 $428 $44F | n/a
9 $4A8 $4CF | n/a
10 $528 $54F | n/a
11 $5A8 $5CF | n/a
12 $628 $64F | n/a
13 $6A8 $6CF | n/a
14 $728 $74F | n/a
15 $7A8 $7CF | n/a

16 $450 $477 | $478 .. $47F
17 $4D0 $4F7 | $4F8 .. $4FF
18 $550 $577 | $578 .. $57F
19 $5D0 $5F7 | $5F8 .. $5FF
20 $650 $677 | $678 .. $67F
21 $6D0 $6F7 | $6F8 .. $6FF
22 $750 $777 | $778 .. $77F
23 $7D0 $7F7 | $7F8 .. $7FF

Hope this helps.
Nick Westgate
2017-07-19 02:55:09 UTC
Reply
Permalink
Raw Message
Post by Michael 'AppleWin Debugger Dev'
One minor complication is that there "screen holes" since the framebuffers are NOT linear.
In terms of saving it that's only a complication if you want to write a program to save the graphics and avoid the screen holes.

Of course, the important point is that TEXT1 screen holes (and some others) are reserved for use by peripheral cards, so BSAVEing and BLOADing the whole screen might cause problems - though it's usually benign in practice.

Here's some more info:
https://retrocomputing.stackexchange.com/questions/2534/what-are-the-screen-holes-in-apple-ii-graphics/2541#2541

Cheers,
Nick.
Michael 'AppleWin Debugger Dev'
2017-07-19 04:15:37 UTC
Reply
Permalink
Raw Message
Post by Nick Westgate
In terms of saving it that's only a complication if you want to write a program to save the graphics and avoid the screen holes.
Of course, the important point is that TEXT1 screen holes (and some others) are reserved for use by peripheral cards, so BSAVEing and BLOADing the whole screen might cause problems - though it's usually benign in practice.
It is probably best if a "safe save" and "save load" assembly programs were used. That way the screen holes are left alone for DOS3.3 / ProDOS.

CALL-151
0300:A2 77 BD 00 04 9D 00 20
0308:BD 80 04 9D 78 20 BD 00
0310:05 9D F0 20 BD 80 05 9D
0318:68 21 BD 00 06 9D E0 21
0320:BD 80 06 9D 58 22 BD 00
0328:07 9D D0 22 BD 80 07 9D
0330:48 23 CA 10 CD 60 A2 77
0338:BD 00 20 9D 00 04 BD 78
0340:20 9D 80 04 BD F0 20 9D
0348:00 05 BD 68 21 9D 80 05
0350:BD E0 21 9D 00 06 BD 58
0358:22 9D 80 06 BD D0 22 9D
0360:00 07 BD 48 23 9D 80 07
0368:CA 10 CD 60
BSAVE GR_LOAD_SAVE.BIN,A$300,L$6C

Then to use:

5 D$=CHR$(4)
10 PRINT D$;"BLOAD GR_LOAD_SAVE.BIN"
20 GR
30 REM PLOT SOME STUFF
40 COLOR=2:HLIN 0,39 AT 20
50 COLOR=3:VLIN 0,39 AT 20
60 COLOR=1:FOR I=0 TO 23:PLOT I,I:NEXT
70 CALL 768: REM MOVE GR TO HGR
80 ? D$;"BSAVE DEMO.GR,A$2000,L$3C0"
90 GR
100 CALL 822: REM MOVE HGR TO GR

Assembly source, and gr_demo.dsk available on GitHub:
https://github.com/Michaelangel007/apple2_gr_load_save
Chris Tobar
2017-07-19 06:49:40 UTC
Reply
Permalink
Raw Message
Ok, if understand this right, the image you plotted would be saved on the disk as a file named "DEMO.GR" at line 80? But how would I then load the file to display it back on the screen later? Would I just use "LOAD DEMO.GR" or "BRUN DEMO.GR"?

Thanks for the help so far, everyone! I hope I can figure this out eventually!
Michael 'AppleWin Debugger Dev'
2017-07-19 07:02:30 UTC
Reply
Permalink
Raw Message
For a binary file that was BSAVE'd you need to use a corresponding BLOAD. The bload address is optional -- DOS will default to the memory address it was initially saved at.

The commands SAVE and LOAD are only used to save Basic programs.
Michael 'AppleWin Debugger Dev'
2017-07-19 07:10:31 UTC
Reply
Permalink
Raw Message
Post by Chris Tobar
the image you plotted would be saved on the disk as a file named "DEMO.GR"
Correct!
Post by Chris Tobar
Would I just use "LOAD DEMO.GR" or "BRUN DEMO.GR"?
BRUN is to _execute_ binary code. Since (low-resolution) GR data is NOT executable code we need to BLOAD the binary _data._
i.e.

95 PRINT D$;"BLOAD DEMO.GR"

This will allow you to load one image at a time.

If you want to have multiple GR images in memory at one time -- say for multiple "flip book" animation, the ASM mover would need to be modified to use a different buffer address. (Right now it is hard-coded to $2000).

Other advanced techniques would be to set LOMEM so that Applesoft programs start at $6000 (just above HGR page 2) instead of the default $801, which happens to be the GR page 2 framebuffer.

See the Beagle Bros Peek's and Pokes Chart for details:
http://beagle.applearchives.com/Posters/Poster%202.pdf
Chris Tobar
2017-07-19 07:51:25 UTC
Reply
Permalink
Raw Message
Ok, cool! This is great! I can't wait to try it out.

I'll admit I'm still pretty lost with the terminology about memory though. I never had to work directly with memory like this before. When I make programs with Visual Basic, displaying and manipulating images and even sprites is really simple, by just using functions built into VB and using the Windows API. The operating system aitomatically handles all the stuff with memory. But I like doing this just to know if I CAN do it. I definitely have a lot of respect for people who were writing programs back in the early 1980's! It looks like it definitely wasn't easy!
Michael 'AppleWin Debugger Dev'
2017-07-19 15:30:53 UTC
Reply
Permalink
Raw Message
Post by Chris Tobar
I'll admit I'm still pretty lost with the terminology about memory though.
There is a LOT of terminology with the Apple 2 -- you'll pick it up over time.

I'm assuming you are referring to the phrase "memory mapped non-linear framebuffer with screen holes" ?

Let's break this down in byte-sized chunks that more digestable:


= Memory Mapped =

The text and graphics screens are basically an array of bytes. From BASIC we can "POKE" (set) values and they will show up as characters (text screen) or pixels (graphics screen)

In C this would look like:

char TextScreen1[ 24 ][ 40 ];


For example

TEXT:HOME

Will set text mode (40x24) and clear it.

POKE 1024,1

Will show an "inverse" A.

POKE 1025,65

Will show an "flashing" A and

POKE 1026,65+128

will show a normal A.

You could think of a POKE is directly doing this:

C:

TextScreen1[ 0 ] = 'A';

Applesoft:

POKE 1024,65

You can find a list of ASCII values and a memory map with the famous "Beagle Bros Peeks, Pokes, and Pointers" side B poster:
Loading Image...

Now this probably begs the question: Why are the values:

* 1 inverse,
* 65 flashing, and
* 193 normal?

That has to do with the "character set" built into the Apple. Here is an example:
Loading Image...

Woz decided to have the hardware support different "text styles" based on what values the characters were.

* $00..$3F Inverse
* $40..$7F Flashing
* $80..$FF Normal

Setting values in specific memory locations, $400 .. $7FF corresponds to the Text Page 1 area.

In case you aren't familiar with the $ prefix -- that is the character most Apple 2 programmers use to refer to hex values. In VB6 it is the &H.

i.e. The "A" character is 65 decimal or 41 in hex:

Apple 2 notation:

$41

Basic notation:

&H41

C notation:

0x41


= Page Flipping =

There are also two "pages" of which only 1 is visible. This means we can do smooth "page flipping" animation.
I.e. We can show the 1st, draw on the 2nd, then "flip" to showing the 2nd, draw on the 1st, repeat.

For example:

CALL-151
C055
C054
E003G

When you typed C055 <RETURN> it shows a screen full of "Junk".
What you were looking at was Text Page 2 -- which normally contains your Applesoft program.


= Framebuffer =

This just means that of the 64K (65,536 bytes) in an Apple 2 that there are:

* 1,024 are reserved for the Text Page 1
* 1,024 are reserved for the Text Page 2
* 8,192 are reserved for the High Resolution Graphics Page 1 (280x192)
* 8,192 are reserved for the High Resolution Graphics Page 2 (280x192)

Now you may be asking -- what happened to the Low Resolution Graphics (GR) memory areas? They are _shared_ with the Text Page.

For example:

GR:POKE 1024,65:POKE 2000,65


Will plot TWO vertical pixels -- red and green respectively AND a flashing A in the bottom left.

Then if we type:

TEXT

Notice how the text screen is filled with inverse '@' ? This is because in GR mode the value $00 are two black pixels, but in TEXT mode shows up as an inverse '@'.

This value $A0 shows up BLACK on top of GREY in GR mode but as a space in TEXT mode.

i.e.

TEXT:CALL-151
C050
FC58G
E003G
TEXT


= Non-Linear =

In any modern system we would normally have something like this for a 40x24 screen:

char TextScreen1[ 24 ][ 40 ];

This is called a "linear" layout, because ALL the memory is contiguous.

When Woz designed the Apple he decided to break the screen layout into triads. What we really have is this layout:

struct Text40x24
{
char rows00_08_16[ 40 ];
char pad0[ 8 ];

char rows01_09_17[ 40 ];
char pad1[ 8 ];

char rows02_10_18[ 40 ];
char pad2[ 8 ];

char rows03_11_19[ 40 ];
char pad3[ 8 ];

char rows04_12_20[ 40 ];
char pad4[ 8 ];

char rows05_13_21[ 40 ];
char pad5[ 8 ];

char rows06_14_22[ 40 ];
char pad6[ 8 ];

char rows07_15_23[ 40 ];
char pad7[ 8 ];
};

This is called "non-linear" because _inbetween_ each "row" are 8 bytes of padding.


= Screen Holes =

The "pad" section are also called "screen holes" because they are NEVER displayed. To prove this:

TEXT:HOME:POKE 1143,255:POKE 1144,255

There are a total of ...

$478 .. $47F
$4F8 .. $4FF
$578 .. $57F
$5F8 .. $5FF
$678 .. $67F
$6F8 .. $6FF
$778 .. $77F
$7F8 .. $7FF

... 8x8 = 64 memory locations that are NOT used. You can "POKE" whatever values you want into them and they will never show up.

The operatoring sytem (DOS3.3, ProDOS, etc.) and the Peripherals are free to use these values as "scratch" memory locations.


= Saving / Loading =

Normally we would just "BSAVE" the entire 1,024 chunks of of the TEXT (or GR) memory via:

BSAVE DRAWING1.GR,A$400,L$400

But due to a "fluke "of DOS3.3 dumb design and the Text memory layout -- the last 8 bytes of $7F8 .. $7FF are never displayed -- we can (b)save the TEXT (or GR) screen via:

BSAVE DRAWING1.GR,A$400,L$3F8

to take up 1 less sector on disk.

Similarly, to load a TEXT (or GR) screen that had been previously saved:

BLOAD DRAWING1.GR,A$400

On disk our graphics file has this layout ...

+--------------+
| rows00_08_16 |
| pad0 |
| rows01_09_17 |
| pad1 |
| rows02_10_18 |
| pad2 |
| rows03_11_19 |
| pad3 |
| rows04_12_20 |
| pad4 |
| rows05_13_21 |
| pad5 |
| rows06_14_22 |
| pad6 |
| rows07_15_23 |
| pad7 |
+--------------+

Since we _don't_ want to touch the screen holes AND don't want to waste space storing them we really want to (b)save this layout:

+--------------+
| rows00_08_16 |
| rows01_09_17 |
| rows02_10_18 |
| rows03_11_19 |
| rows04_12_20 |
| rows05_13_21 |
| rows06_14_22 |
| rows07_15_23 |
+--------------+

This means we need TWO areas:

1) The non-linear TEXT (or GR) region
2) A linear BUFFER

The "Pack" and "Unpack" mentioned into the earlier emails do this:

* "Pack" (Copy) the TEXT (or GR) framebuffer to a buffer located in the HGR region
* "Unpack" (Copy) the HGR region back into the TEXT (or GR) framebuffer.

Hope this helps clear up how the GR memory is layed out in the Apple 2.

Michael
Chris Tobar
2017-07-20 01:20:40 UTC
Reply
Permalink
Raw Message
Wow! Thank you Michael, for your time and work in writing that! I really appreciate it. It's a lot to digest, so I'm going to have to read through it carefully.

I'm planning to set up my Apple II tonight and experiment with the code you gave me. I do have another question though. In your earlier message, do I include that part at the beginning with the assembly code into a program? I saw that you didn't have line numbers for that. Or how would I use it in a BASIC program that I make to load pictures? I understood the rest of the code, but I just wasn't sure how to include the assembly part. I assume it would just go at the beginning of the program, like how you wrote it in your message, but I was just thrown off by how it didn't have line numbers and didn't understand how it would get included in a program. I have NEVER done anything with assembly code, and I've only recently just started to read about it.

- Chris
Michael 'AppleWin Debugger Dev'
2017-07-20 02:06:29 UTC
Reply
Permalink
Raw Message
Post by Chris Tobar
Wow! Thank you Michael, for your time and work in writing that! I really appreciate it. It's a lot to digest, so I'm going to have to read through it carefully.
You're welcome.

Take your time -- and if you have any questions feel free to ask!
Post by Chris Tobar
In your earlier message, do I include that part at the beginning with the assembly code into a program?
You load the _binary_ file with the BLOAD command:
i.e.
10 PRINT D$;"BLOAD GR_LOAD_SAVE.BIN"

The binary file GR_LOAD_SAVE.BIN was saved at address $300, so it will default to loading there -- you don't need to specify it for the load.

Technically, we only need to load it once, but for "safety" I load it each time you RUN your program.
Post by Chris Tobar
I saw that you didn't have line numbers for that.
As you correctly surmised Assembly Language programs (and their corresponding binary code) don't have line numbers.

The assembly source (file) is just a plain text file. We use an 6502 assembler to produce an output of raw binary values -- sometimes called Machine Language -- which in our case is the code to "Pack" and "Unpack".

A common way to "LIST" the Machine Language code is with a hex dump. That was the 300:A2 77 ... stuff.

To see the computer show a "disassembly" of the Machine Language code we loaded we can do the following:

BLOAD GR_LOAD_SAVE.BIN
CALL-151
300L
E003G
Post by Chris Tobar
Or how would I use it in a BASIC program that I make to load pictures?
See above and/or my GitHub page.
Post by Chris Tobar
I understood the rest of the code, but I just wasn't sure how to include the assembly part. I assume it would just go at the beginning of the program,
Technically you can BLOAD it anywhere from the Applesoft program just as you load it *BEFORE* you call it. :-) What happens if you try to "CALL" it before it is loaded?

i.e.
If you power cycle your computer and try ...

CALL 768

... you'll get a "hard crash" to the built-in ROM debugger:

304- A=03 X=9D Y=00 P=36 S=E3
*

That's because the "default" code at $300 is sequence of BRK instruction.

300L


When you type RUN or LOAD the Operating System loads the BASIC program into memory at $801.

When we "RUN" our BASIC program we temporarily divert the instructions to our code at $300, and then return.

For example, let try this:

NEW
10 PRINT "HELLO"
CALL-151

This calls the built-in "debugger" in ROM. Our prompt is an "*" asterisk.

We can LIST machine language programs using the "L" command:
D566L

And we can "CALL" the Basic Interpreter to "run" our program via the "G" command:
D566G

Notice our BASIC program was executed (!) and we're back at the Applesoft BASIC prompt via the ']'. :-)
Post by Chris Tobar
but I was just thrown off by how it didn't have line numbers and didn't understand how it would get included in a program. I have NEVER done anything with assembly code, and I've only recently just started to read about it.
One paradigm to help sort out the difference between BASCI and Assembly is that they are two languages, one is English, the other is a sub-set of English verbs and nouns.

With BASIC you can very compactly express commands such as:

PRINT 3.14159

Where as with Assembly you would need MANY instructions to accomplish the same thing. The trade-off is that Assembly is about 1,000x times faster then BASIC and you can do all sorts of things that BASIC can't do.

Your BASIC programs is stored as "byte code" -- technically called "TOKENS" -- in memory starting at $801.

There is a special machine language program built into ROM, called the Applesoft Interpreter, that knows how to read, parse, and execute the tokens. When you type RUN it starts _that_ machine code, which reads your BASIC program, and figures out what to do for each TOKEN.

One of the Applesoft commands is CALL. This lets us directly call a Machine Language program at a specific address.

The CALL 768 calls our code at $300, does the packing, and then returns to the Applesoft interpreter to continue running the BASIC code.

Since you've worked with Visual Basic before it might be handy to think of a Machine Language program as a "module". We can load multiple modules.

Normally on a Windows machine you don't control _where_ in memory modules are loaded. The operating system takes care of that. In the Apple 2 world you have _complete_ control of what gets loaded where.

For example, if we tried to do this ...

BLOAD GR_LOAD_SAVE.BIN,A$801

.. this would be bad as it would *over-write* our BASIC program in memory!

If you try a LIST it will show all sorts of "funny" commands such as:

189 NORMAL

To 'reset' this you'll either have to do:

NEW

or

LOAD HELLO


A recap is this:

DOS3.3 auto-loads and runs a BASIC program called: HELLO
It then calls the Applesoft Interpretor Machine Language program to run our program
Our Applesoft program calls DOS to (B)LOAD our GR binary program to $300
We do some GRaphics drawing
We call our Machine Language program at $300 to pack the GR screen
We call DOS to save the GR screen
We do some more drawing
We (B)LOAD the previously save GR screen
We call our Machine Language program at $336 to show the loaded GR screen.


Here is another example:

Applesoft BASIC has a command called:

HGR

Let's get back to text mode via:

TEXT

It turns out that we can directly call the corresponding Machine Language code at $F3E2.

CALL-151
F3E2G
F398G
E003G

Notice that when we typed: F3E2G is _exactly_ equivalent to the HGR command, and F398G is _exactly_ equivalent to the TEXT commands. That's because the Applesoft Interpreter is CALLing _those_ functions for those commands.

OK, I'll give you a chance to "catch up" with the last email and this one.

Hope this helps
Michael
Chris Tobar
2017-07-23 08:38:29 UTC
Reply
Permalink
Raw Message
I got it! It works! :D

Michael, I typed in the Assembly code that you gave (except I just changed the name for the binary file, since I didn't know how to get an underscore on the Apple II keyboard). Then I split the rest of the code into a "Save image" program, and a "Load Image" program and saved them both on a floppy disk. It worked! The Save Image program uses the code you gave me that plots the image and saves the image as a binary file named "DEMO.GR" Then when I ran the Load Image program, it loads and displays the picture! It's a red line drawn diagonally across a horizontal and vertical line - kind of like a number line plotted on a graph.

This is awesome! I guess this might be simple for people with more experience, but I had NO idea how to do this with the Apple II. It's easy to code with Windows programs, but I was clueless on how to do this with early computers.

The way you explained how the "GR_LOAD_SAVE.BIN" is kind of like a module in Visual Basic really helped me to understand it a little better. I see now how I can re-use it for other programs that save or load pictures.

I pretty much used the code you gave me, but for anyone else who sees this thread later, I'll summarize what I did:

I have this in a BASIC program named "SAVEIMAGE":

5 D$=CHR$(4)
10 PRINT D$; "BLOAD GRLOADSAVE.BIN"
20 HOME
30 GR
40 REM * PLOT SOME STUFF *
50 COLOR=2: HLIN 0,39 AT 20
60 COLOR=3: VLIN 0,39 AT 20
65 COLOR=1: FOR I = 0 TO 23: PLOT I, I: NEXT
70 CALL 768: REM MOVE GR TO HGR
80 PRINT D$; "BSAVE DEMO.GR,A$2000,L$3C0"
90 GR
100 CALL 822: REM MOVE HGR TO GR

And I have this in a program called "LOADIMAGE":

10 D$=CHR$(4)
20 HOME
30 GR
40 PRINT D$; "BLOAD GRLOADSAVE.BIN"
50 PRINT D$; "BLOAD DEMO.GR"
60 CALL 822

All have to do is Run LOADIMAGE and it loads and displays the picture :)

I did have another question though. If I wanted to work with larger images, with HGR, is it about the same? Or is it more complicated?

Thanks, Michael, and everyone else who helped with this!
Michael 'AppleWin Debugger Dev'
2017-07-23 13:16:46 UTC
Reply
Permalink
Raw Message
Post by Chris Tobar
I got it! It works! :D
Awesome!
Post by Chris Tobar
The way you explained how the "GR_LOAD_SAVE.BIN" is kind of like a module in Visual Basic really helped me to understand it a little better. I see now how I can re-use it for other programs that save or load pictures.
I thought having a common frame of reference might do the trick in help explaining the big picture. Glad to hear it did!
Post by Chris Tobar
5 D$=CHR$(4)
10 PRINT D$; "BLOAD GRLOADSAVE.BIN"
20 HOME
30 GR
40 REM * PLOT SOME STUFF *
50 COLOR=2: HLIN 0,39 AT 20
60 COLOR=3: VLIN 0,39 AT 20
65 COLOR=1: FOR I = 0 TO 23: PLOT I, I: NEXT
70 CALL 768: REM MOVE GR TO HGR
80 PRINT D$; "BSAVE DEMO.GR,A$2000,L$3C0"
90 GR
100 CALL 822: REM MOVE HGR TO GR
It is common to "compact" the first few lines 5-30 as:

10 D$=CHR$(4):? D$;"BLOAD GRLOADSAVE.BIN"
20 TEXT:HOME:GR:VTAB 21

Technically, you don't need the last two lines 90-100 for a single image. :-)


If you wanted to modify it to save 3 images you would make these changes

90 GR
100 REM * PLOT SOME STUFF *
170 CALL 768: REM MOVE GR TO HGR
180 PRINT D$; "BSAVE DEMO2.GR,A$2000,L$3C0"
190 GR
200 REM * PLOT SOME STUFF *
270 CALL 768: REM MOVE GR TO HGR
280 PRINT D$; "BSAVE DEMO3.GR,A$2000,L$3C0"
290 GR

You would need to fill in lines 110-160 and 210-260 with your custom drawing code.
Post by Chris Tobar
10 D$=CHR$(4)
20 HOME
30 GR
40 PRINT D$; "BLOAD GRLOADSAVE.BIN"
50 PRINT D$; "BLOAD DEMO.GR"
60 CALL 822
To save some typing, people usually put lines 10-30 on one line like this:

10 D$=CHR$(4):PRINT D$;"BLOAD GRLOADSAVE.BIN"
20 GR:VTAB 21
Michael 'AppleWin Debugger Dev'
2017-07-23 13:23:44 UTC
Reply
Permalink
Raw Message
Post by Chris Tobar
I did have another question though. If I wanted to work with larger images, with HGR, is it about the same? Or is it more complicated?
Thankfully HGR is dead simple!

BSAVE SCREEN1.HGR,A$2000,L$1FF8
BLOAD SCREEN1.HGR


Here is a HGR.SAVE.BAS demo:

0 D$=CHR$(4):REM HGR.SAVE.BAS
10 HGR
20 FOR ROW=0 TO 7:X=ROW*14:U=X+12
30 FOR COL=0 TO 7:Y=COL*14
40 FOR H=0 TO 12 STEP 2:V=Y+H
50 HCOLOR=ROW:HPLOT X,V TO U,V
60 HCOLOR=COL:HPLOT X,V+1 TO U,V+1
70 NEXT
80 NEXT
90 NEXT
100 PRINT D$;"BSAVE SCREEN1.HGR,A$2000,L$1FF8"
110 HGR
120 FOR ROW=0 TO 7:Y=ROW*4
130 FOR H=0 TO 3
140 HCOLOR=ROW:HPLOT 0,Y+H TO 279,Y+H
150 NEXT
160 NEXT
170 PRINT D$;"BSAVE SCREEN2.HGR,A$2000,L$1FF8"

And the corresponding HGR.LOAD.BAS demo:

0 D$=CHR$(4):REM HGR LOAD DEMO
10 HGR
20 PRINT D$;"BLOAD SCREEN1.HGR"
30 GET A$
40 PRINT D$;"BLOAD SCREEN2.HGR"


Of course you if you are saving multiple screen it may be more convenient to have a "Bsave HGR" sub-routine

0 D$=CHR$(4):F=0:VTAB 21:GOTO 10
2 F=F+1:PRINT D$;"BSAVE SCREEN";F;".HGR,A$2000,L$1FF8":RETURN
10 HGR:REM DRAW STUFF
20 HCOLOR=3
90 GOSUB 2:REM SAVE
100 REM DRAW STUFF
110 HCOLOR=3
190 GOSUB 2:REM SAVE

Replace lines 20-80, and 110-180 with your custom drawing code.
Michael 'AppleWin Debugger Dev'
2017-07-23 13:29:45 UTC
Reply
Permalink
Raw Message
Post by Michael 'AppleWin Debugger Dev'
0 D$=CHR$(4):F=0:VTAB 21:GOTO 10
2 F=F+1:PRINT D$;"BSAVE SCREEN";F;".HGR,A$2000,L$1FF8":RETURN
10 HGR:REM DRAW STUFF
20 HCOLOR=3
90 GOSUB 2:REM SAVE
100 REM DRAW STUFF
110 HCOLOR=3
190 GOSUB 2:REM SAVE
Whoops, 100 is missing an HGR command:

100 HGR:REM DRAW STUFF
Michael 'AppleWin Debugger Dev'
2017-07-24 07:34:36 UTC
Reply
Permalink
Raw Message
Post by Chris Tobar
(except I just changed the name for the binary file, since I didn't know how to get an underscore on the Apple II keyboard).
Are you running on real hardware or an emulator?

For the //e, //c, and emulators you can press shift-minus (to the right of the zero key at the top) to generate an underscore.
Chris Tobar
2017-07-24 08:43:37 UTC
Reply
Permalink
Raw Message
I'm using real hardware. I have an Apple II+ :)
Michael 'AppleWin Debugger Dev'
2017-07-24 09:33:23 UTC
Reply
Permalink
Raw Message
Oh wow -- hardcore :)

I used an Apple ][+ for years.
The only I disliked on them is that they used a keyboard before all the symbols were standardized -- so yeah no underscore key for you. :-/

Guess I've been "spoiled" with my //e, //c, IIgs, and Lasers :-)

A common substitution is to use the period which is a good visual substitute for a spacer and connector.
Chris Tobar
2017-07-24 10:35:16 UTC
Reply
Permalink
Raw Message
Haha yeah, I'm using the "real thing." I bought it from someone online. It's in great condition, and even has a few extra things added - an RF modulator, and a small board called a "Paddle Adaple" which lets you connect two game controllers. (ooh fancy!) I had also bought a small vintage tv earlier, which I'm using as a monitor since I like the way the Apple display looks on a CRT screen better. (And the tv is from 1977, so it's more "authentic"!) I did try to hook it up to my LCD tv with the video jack, but to me the colors seemed a little weird and didn't look quite right.

The funny thing is I remember using Apple II computers in school when I was a little kid, around the mid 1980's. But we weren't allowed to do much on them, mostly just play simple educational games. My favorites were "Oregon Trail" and "Lemonade Stand." I remember playing other games for learning about math and geography, etc. I remembered using the big 5.25 floppy disk, and that a disk had to be in the drive when you started the computer. But I never really knew much else about how these computers worked. I was so excited though whenever I got to use these computers at school...and now I actually own one! For me, it feels nostalgic but at the same time it's also new because I was too young to fully understand them.
Bill Garber
2017-07-24 13:49:14 UTC
Reply
Permalink
Raw Message
Post by Michael 'AppleWin Debugger Dev'
Oh wow -- hardcore :)
I used an Apple ][+ for years.
The only I disliked on them is that they used a keyboard before all the
symbols were standardized -- so yeah no underscore key for you. :-/
Guess I've been "spoiled" with my //e, //c, IIgs, and Lasers :-)
A common substitution is to use the period which is a good visual
substitute for a spacer and connector.
The period '.' is a standard delimiter in ProDOS anyway, so, that's better.

Bill Garber * http://www.sepa-electronics.com *
g***@sasktel.net
2017-07-24 18:50:11 UTC
Reply
Permalink
Raw Message
Post by Michael 'AppleWin Debugger Dev'
Oh wow -- hardcore :)
I used an Apple ][+ for years.
The only I disliked on them is that they used a keyboard before all the symbols were standardized -- so yeah no underscore key for you. :-/
Guess I've been "spoiled" with my //e, //c, IIgs, and Lasers :-)
A common substitution is to use the period which is a good visual substitute for a spacer and connector.
The underscore was not available from the keyboard, but to put it into a program I would type "? CHR$(223)" at the prompt, then type in a program line, and when the underscore was needed, use the ESC key move sequence to move to and copy over the underscore.
D Finnigan
2017-07-19 12:58:46 UTC
Reply
Permalink
Raw Message
Post by Chris Tobar
I've been writing some simple BASIC programs to get my Apple II+ to draw
pictures. I just use GR and have it draw pictures line by line with code.
I was wondering, is there a way I could then save the drawn image on the
screen to file on a floppy disk? And another way to load images and
display them back on the screen? I'm sure there has to be a way, but I'm
clueless.
I've done a lot of programming in Visual Basic for modern (ish) computers
running Windows, and it's a piece of cake to work with graphics using
that.
But I'm fairly new to programming with vintage computers like the Apple
II.
Things that are super easy to do with modern computers are a lot more
challenging with these old computers!
There's a good book for people who are new to the Apple II like you, it's
called The New Apple II User's Guide. Take a look:
http://macgui.com/newa2guide/

It covers all the basics of setup, programming in BASIC, using the disk
system, graphics, and all the rest.
--
]DF$
Apple II 40th Anniversary User's Guide:
http://macgui.com/newa2guide/
Tom Porter
2017-07-21 00:12:03 UTC
Reply
Permalink
Raw Message
This is from somebody who has done a lot of lores drawings... Yes the Screen Holes are a problem but they do not do anything except cause recalibration of the disk drive, possibly a few accessories but if you are not accessing those then there is no 'adverse effect'. If you do need to access the disk drive after an image is loaded in dos, it recalibrates and then continues.

The MOST simplest way is to

10 PRINT CHR$(4);"BSAVE IMAGE,A1024,L1020"

OR

10 PRINT CHR$(4);"BLOAD IMAGE,A1024,L1020"
(MOST CASES COULD BE SHORTENED TO 10 PRINT CHR$(4);"BLOAD IMAGE"
qkumba
2017-07-21 13:58:49 UTC
Reply
Permalink
Raw Message
Post by Tom Porter
This is from somebody who has done a lot of lores drawings... Yes the Screen Holes are a problem but they do not do anything except cause recalibration of the disk drive
Oh, that depends very much on what kind of hardware is hosting the disk. For DOS, yes it will recalibrate. For SmartPort and some modern floppy alternatives, you might get complete read failure.
It's best to save and restore the contents of the screen holes.
James Davis
2017-07-21 17:28:16 UTC
Reply
Permalink
Raw Message
Post by qkumba
Post by Tom Porter
This is from somebody who has done a lot of lores drawings... Yes the Screen Holes are a problem but they do not do anything except cause recalibration of the disk drive
Oh, that depends very much on what kind of hardware is hosting the disk. For DOS, yes it will recalibrate. For SmartPort and some modern floppy alternatives, you might get complete read failure.
It's best to save and restore the contents of the screen holes.
Does the newest ProDOS do it for bloads overwriting the screen holes and/or to the display areas? That might be a nice feature!
g***@sasktel.net
2017-07-21 21:36:57 UTC
Reply
Permalink
Raw Message
Post by James Davis
Post by qkumba
Post by Tom Porter
This is from somebody who has done a lot of lores drawings... Yes the Screen Holes are a problem but they do not do anything except cause recalibration of the disk drive
Oh, that depends very much on what kind of hardware is hosting the disk. For DOS, yes it will recalibrate. For SmartPort and some modern floppy alternatives, you might get complete read failure.
It's best to save and restore the contents of the screen holes.
Does the newest ProDOS do it for bloads overwriting the screen holes and/or to the display areas? That might be a nice feature!
Prodos shouldn't be able to load directly into the text/lo-res page as that part of memory is protected. But one could unprotect that part of memory by changing $BF58 to $C0.

Also, to play some DOS games that start at $7FD, I have on occasion changed $BF58 to $CE to free up page# 7 of the text screen.
James Davis
2017-07-26 14:29:31 UTC
Reply
Permalink
Raw Message
IIRC, there is a way to type the underscore on the Apple II Plus that uses a combination of keys, including Escape key (I think) and the Question-Mark key (I think), but I don't remember exactly what it is. I will try to find my notes on it and get back to you when I find them/it. Though, it may be on one of the Beagle Bros' charts or in one of their "Tips and Tricks" booklets, too.
James Davis
2017-07-26 14:44:01 UTC
Reply
Permalink
Raw Message
Post by James Davis
IIRC, there is a way to type the underscore on the Apple II Plus that uses a combination of keys, including Escape key (I think) and the Question-Mark key (I think), but I don't remember exactly what it is. I will try to find my notes on it and get back to you when I find them/it. Though, it may be on one of the Beagle Bros' charts or in one of their "Tips and Tricks" booklets, too.
Found it:
_\[]/_ APPLE ][ _\[]/_

TO AQUIRE THESE SYMBOLS, THE UNDERSCORE,
THE BACKSLASH, AND THE LEFT SQUARE BRACKET,
FROM THE APPLE II KEYBOARD, SIMULTANEOUSLY
TYPE <SHIFT>IU AND, WHILE HOLDING THESE THREE
KEYS, TYPE:

Y--FOR THE UNDERSCORE (UI_Y),

H--FOR THE BACKSLASH (UI\H), OR

J--FOR THE LEFT SQUARE BRACKET (UI[J).

<<

This fits nicely on a 3" x 5" card. It is ALL CAPS because I originally printed it from my Apple ][ Plus.
Loading...