Copy Link
Add to Bookmark
Report
GEnieLamp A2Pro - Vol.5, Issue 32
|||||| |||||| || || |||||| ||||||
|| || ||| || || ||
|| ||| |||| |||||| || |||| Your
|| || || || ||| || ||
|||||| |||||| || || |||||| |||||| GEnieLamp Computing
|| |||||| || || |||||| RoundTable
|| || || ||| ||| || ||
|| |||||| |||||||| |||||| RESOURCE!
|| || || || || || ||
||||| || || || || ||
~ WELCOME TO GENIELAMP A2Pro! ~
"""""""""""""""""""""""""""
~ TIPS AND TECHNIQUES: Compressing Hi-Res Graphics ~
~ Scrolling Text ~ Linear Regression ~ Bezier Curves ~
~ 65C816 in an Atari? ~ Switching Processes in the GNO Shell ~
~ HOT NEWS, HOT FILES, HOT MESSAGES ~
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\////////////////////////////////////
GEnieLamp A2Pro ~ A T/TalkNET Publication ~ Vol.5, Issue 32
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Publisher.................................................John F. Peters
Editor....................................................Tim Buchheim
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\////////////////////////////////////
~ GEnieLamp IBM ~ GEnieLamp Atari ~ GEnieLamp PowerPC ~
~ GEnieLamp A2Pro ~ GEnieLamp Macintosh ~ GEnieLamp TX2 ~
~ GEnieLamp Windows ~ GEnieLamp A2 ~ LiveWire (ASCII) ~
~ Member Of The Digital Publishing Association ~
GE Mail: GENIELAMP Internet: genielamp@genie.com
////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
>>> WHAT'S HAPPENING IN THE A2Pro ROUNDTABLE? <<<
"""""""""""""""""""""""""""""""""""""""""""""""""
~ November 1, 1995 ~
FROM MY DESKTOP ......... [FRM] A2PRO ROUNDTABLE STAFF .. [DIR]
Notes From The Editor. Directory of A2Pro Staff.
TIPS AND TECHNIQUES ..... [TIP] HEY MISTER POSTMAN ...... [HEY]
Compressing Hi-Res Graphics Is That A Letter For Me?
DEVELOPERS CORNER ....... [DEV] LIBRARY BIT BONANZA ..... [LIB]
News From Online Developers. HOT Files You Can Download.
LOG OFF ................. [LOG]
GEnieLamp information.
[IDX]"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
READING GEnieLamp GEnieLamp has incorporated a unique indexing
""""""""""""""""" system to help make reading the magazine easier.
To utilize this system, load GEnieLamp into any ASCII word processor
or text editor. In the index you will find the following example:
A2PRO ROUNDTABLE STAFF .. [DIR]
Directory of A2Pro Staff.
To read this article, set your find or search command to [DIR]. If
you want to scan all of the articles, search for [EOA]. [EOF] will take
you to the last page, whereas [IDX] will bring you back to the index.
MESSAGE INFO To make it easy for you to respond to messages re-printed
"""""""""""" here in GEnieLamp, you will find all the information you
need immediately following the message. For example:
(SMITH, CAT6, TOP1, MSG:58/M530)
_____________| _____|__ _|___ |____ |_____________
|Name of sender CATegory TOPic Msg. Page number|
In this example, to respond to Smith's message, log on to page
530 enter the bulletin board and set CAT 6. Enter your REPly in TOPic 1.
A message number that is surrounded by brackets indicates that this
message is a "target" message and is referring to a "chain" of two
or more messages that are following the same topic. For example: {58}.
ABOUT GEnie GEnie's monthly fee is $8.95 which gives you up to four hours
""""""""""" of non-prime time access to most GEnie services, such as
software downloads, bulletin boards, GE Mail, an Internet gateway, award-
winning multi-player games and friendly chat lines. GEnie's non-prime time
connect rate is only $3.00 per hour. Prime Time (8:00 am to 6:00 pm local
time on weekdays) is only $5.00 per hour. To sign up for GEnie, just
follow these simple steps:
1. Set your communications software to half duplex (local echo) 8 bits, no
parity and 1 stop bit, at 300, 1200, 2400 or 9600 baud.
2. Call (with modem) 1-800-638-8369 (US) or 1-800-387-8330 (Canada).
3. Wait for the U#= prompt. Type: JOINGENIE and hit RETURN. When you
get the prompt asking for the signup/offer code, type: DSD524 and hit
RETURN.
4. Have a major credit card ready, as the system will prompt you for your
information. If you need more information, call GEnie's Customer Service
department at 1-800-638-9636.
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
[EOA]
[FRM]//////////////////////////////
FROM MY DESKTOP /
/////////////////////////////////
Notes From My Desktop
"""""""""""""""""""""
by Tim Buchheim
[A2PRO.GELAMP]
o TOP OF THE PAGE
>>> TOP OF THE PAGE <<<
"""""""""""""""""""""""""
~ A Letter From the Editor ~
GENIE OUTAGES Last month I talked about GEnie's first ten years and how
""""""""""""" much it has changed. Well, it is still in the process of
change; GEnie is in the middle of both hardware and software upgrades. In
the past few weeks, these upgrades have caused some problems with GEnie.
I've received a report on these problems and thought I should pass it on
so you know what's happening.
Here's the report I got:
"As many of you have no-doubt experienced, GEnie has recently had some
recent unplanned system outages. These outages have been both hardware and
software related. The hardware problems have been fixed, and a solution
for the software problem is undergoing rigorous testing and is slated to be
deployed around mid-November. We apologize for any inconvenience these
outages have caused."
Here's a chronology of what happened. [GEIS is GEnie's parent company]
10/17 (Tuesday) around 21:10: All members were knocked off line. By 21:45
''''''''''''''''''''''''''''' GEnie was back on line. The problem was
diagnosed as a software problem for which GEIS had a formulated fix. The
fix has been undergoing rigorous testing and is slated to be deployed
around mid to late November.
10/23 (Monday) and 11/24 (Tuesday) around ~21:00-22:00: On both days,
''''''''''''''''''''''''''''''''''''''''''''''''''''''' GEnie members
again were knocked off line. The problem was diagnosed as a hardware
problem on GEIS equipment that GEnie requires for operation. On Wednesday,
the hardware vendor addressed the incidents by replacing boards that were
identified as bad.
10/27 (Friday) around 19:00 - 23:00: Initially, only some clients were
'''''''''''''''''''''''''''''''''''' knocked off line, but eventually,
all were knocked off. This incident was attributed to a hardware failure
on yet another piece of GEIS equipment. This time a power supply blew out.
The power supply was replaced that evening, and GEnie service was restored.
Each of the incidents displayed the same symptoms, but were caused by
different problems.
EMAIL WEIRDNESS There have also been some strange things happening with
""""""""""""""" Email the past few weeks. GEIS upgraded the internet mail
gateway, fixing several bugs but causing a minor problem. As most of you
know, you can receive email sent to "yourname@genie.com" as well as
"yourname@genie.geis.com" but all outgoing mail is sent with
"yourname@genie.geis.com".
Or at least it's supposed to be that way. When the INET03# mail
connector was upgraded to the new software a few months ago, no one had any
problems because it was configured right. The main connectors,
INTERNET#, INET#, INET00#, and INET01# were upgraded this week but
weren't configured properly, so they send mail as "genie.com" instead of
the correct "genie.geis.com".This has caused problems for people on mailing
lists, because the mailing lists don't recognize this other address.
A temporary solution is to send all mail through INET03# rather than the
other connectors, if you need to have it sent with the "genie.geis.com"
address. The other connectors may be reconfigured, or they may leave
them as "genie.com" since they were scheduled to be set to "genie.com" in a
month or so anyway.
Once they officially announce that internet mail will be through
"genie.com", you should unsubscribe to mailing lists through INET03# and
resubscribe through one of the main connectors, so they recognize your
"genie.com" address instead of "genie.geis.com".
-- Timothy Carl Buchheim
Editor, GEnieLamp A2Pro
P.S. You might have noticed that this issue is much bigger than usual.
Well, I tried to keep it reasonable by not having the "RTC Watch"
and "Spotlight On:" columns this month. Look for those next month,
unless I decide to skip them again in the interest of keeping
download time to a minimum :)
P.P.S. Sorry this issue was a few days late, but I had no time to work on
before the 1st. :/
[*][*][*]
Do you have something to say about GEnieLamp A2Pro? Please
post any questions or comments you may have in Category 1,
Topic 15 in A2Pro's BB (m530;1). Or, feel free to talk to me
(A2PRO.GELAMP) anytime you see me in a Real Time Conference.
Readers out there on the Internet: feel free to email me at
a2pro.gelamp@genie.com When writing, please tell me where
you got your copy of GEnieLamp, if it wasn't on GEnie. I'm
always interested to see how many places GEnieLamp ends up :)
By the way, the current issue and most back issues are
available online in many places. GEnie users should check
Library #2 in the DigiPub libraries (DIGIPUB, page 1395;3)
Those of you not on GEnie should use gopher software to
connect to gopher.genie.com for issues; all recent issues and
most older ones are there.
[*][*][*]
[EOA]
[DIR]//////////////////////////////
A2PRO ROUNDTABLE STAFF /
/////////////////////////////////
By Tim Buchheim
[A2PRO.GELAMP]
o A2Pro STAFF LIST
>>> A2Pro STAFF LIST <<<
""""""""""""""""""""""""
______________________________________________
APPLE II PROGRAMMERS & DEVELOPERS ROUNDTABLE
_____ ______ ______________________________________________
/_____|/______\
/__/|__| ___|__| Head Sysop: Hangtime (HANGTIME)
/__/_|__| /_____/ Your Sysops: Greg Da Costa (A2PRO.GREG)
/________|/__/ __ __ __ Todd P. Whitesel (A2PRO.TODDPW)
/__/ |__|__/______ /_//_// / Nathaniel Sloan (A2PRO.HELP)
/__/ |__|________// / \/_/ Tim Buchheim (A2PRO.GELAMP)
[EOA]
[FEA]//////////////////////////
TIPS AND TECHNIQUES /
/////////////////////////////
Compressing Hi-Res Graphics
"""""""""""""""""""""""""""
By Russell Nielson
[R.NIELSON1]
o COMPRESSING GRAPHICS
o THE PROGRAMS IN THE PIC.COMP10.BXY ARCHIVE
Editor's note: This is the first of what I hope will be a
"""""""""""""" series of articles written by readers. But
it will only work if you send in articles! If your article
is published, then you will be paid with GEnie usage credits.
Any article related to programming Apple II computers will be
considered. Those articles which include sample source code
are especially good, because the whole point of the series is
to provide programmers with ideas and samples, in order to
encourage them to write new software for the Apple II!
This month's article is about compressing graphics files, and
is based on a file in the A2Pro library called PIC.COMP10.BXY
which was uploaded by the author of this article.
>>> COMPRESSING GRAPHICS <<<
"""""""""""""""""""""""""""""""
INTRODUCTION As we all know, any type of graphics take up a lot of disk
"""""""""""" space, and when you have a lot of graphics in one place,
disk space can be eaten up very quickly. I'd like to discuss one form of
graphics on the Apple II called hi-res graphics, which stands for high
resolution graphics. All programmers that have ever programmed on the
Apple II in hi-res know that a single picture takes up a whopping 8187
bytes of memory or 17 blocks on a ProDOS disk! When you have many pictures
stored on disk they can take up a lot of space. Please be aware that
"picture" and "screen" both refer to a single hi-res graphics screen.
When developing software that uses graphic screens and pictures, you need
to store these picture files on disk, load them into memory, and display
them on the hi-res screen. This isn't a problem until you start having
multiple pictures, like a title screen, a menu screen, an options screen, a
high scores screen, etc.. you are talking a lot of graphic data here! The
main problem usually shows up when you only have a certain amount of disk
space available for your entire project. For instance, if you are
writing a cool game and plan on distributing it on one side of a 5.25"
floppy disk, your entire game (were talking all your graphics, code,
data, etc) has to fit in 140k! Not only that, but if you want your disk to
boot into the game automatically then you need to leave enough space for
ProDOS (and BASIC.SYSTEM if part of your program is in Applesoft) to be
copied there. As you can see you will run out of disk space rather
quickly.
During the development of one of my arcade games I had so many graphic
screens saved to disk that it really got me sick to see all the disk
space going to waste! Not only that but loading an entire 8187 bytes of
data just to display one screen takes some time, so I sat back and
thought for a moment. I have this rather simple screen, which is
practically a black screen with a colored border and a small graphic at the
top, which is taking as much disk space as any other screen. I
determined that regardless of how complex or how simple the picture may be,
it's always the same size. If you cleared the hi-res screen to black (a
blank screen) and saved it, it would still be a whopping 17 blocks. The
reason behind this is because the graphics screen on Apple computers is
simply a chunck of memory that reflects what is seen on the monitor. If
you save hi-res screen 1 you would be writing the area of memory from $2000
to $3FFF. This block of memory is always the same size and doesn't
change even if the graphic image is very simple. I needed to come up
with something here to save space.
One solution to saving disk space is to somehow represent the picture on
the screen in a different manner that does not take up the full 8187 bytes.
Welcome to the world of compression. There are many compression methods
around and they are used all the time. For instance, Shrink-It and GS
Shrink-It use compression methods when placing files into archives.
These programs take each file and compress them down as small as the
compression algorithm allows and then stored them into the archive. Take
GEnie's Software Libraries for example, most everything is stored in a
compressed format (.SHK) because compressed files take up less disk space
and cut down on file transfer times.
Although the Shrink-It compression routines are quite complex, this does
not mean that every compression method is complicated. When writing my
routine for compressing the hi-res screen, it had to ensure that no
information was lost during the compression so that the original picture
would be recreated and displayed on the screen EXACTLY how is was before
being compressed.
MY COMPRESSION METHOD After loading numerous pictures and examining the
""""""""""""""""""""" hex dump of the screens, I began to see repetitious
bytes and repeating patterns. I figured that if I could store these
repeating sequences of bytes as a single number, or two, then I would be
saving space. I used a very simple algorithm that would allow me to
represent groups of bytes on the screen in just a couple bytes.
Here's what I came up with:
All black colors on the screen are either $00 or $80, depending on the
color bit. $00 is black #1 and $80 is black #2. Remember that there are
two black colors and two white colors available in hi-res. In contrast,
all white colors on the screen are either $7F or $FF, again depending on
the high bit.
So a black line on the hi-res screen would look something like this:
00 00 00 00 00 00 00 00 00 00
Note: All numbers are represented in hexadecimal.
""""
This segment would be a black line ten bytes wide on the hi-res screen.
The same goes for black #2 ($80), white #1 ($7F) and white #2 ($FF). I
looked at this and said to myself, "Hmmm.. there's gotta be a better way
than to just keep repeating zeroes over and over again wasting space."
So I came up with a method. For every $00, $80, $7F, or $FF I find, I will
count the number that are in a row, store the color, and then store the
number of times this color is repeated. So in the example above, I'd store
all those zeroes like this:
00 0A
Only two bytes are needed to represent that entire group of zeroes! The
above "00 0A" means that color 00 is repeated 10 times! ($0A = 10
decimal). When it comes time to decompress it again, I simply check for a
$00, $80, $7F, or $FF and then repeat that color the number of times the
repeating byte says! The repeating byte always follows directly after
the color byte.
For another example, here's how the following segment would compress:
Raw: 00 00 00 00 00 FF FF FF FF 7F 7F 7F 7F 7F 7F 7F 80 80 80 80 00 00
Compress: 00 05 FF 04 7F 07 80 04 00 02
See how it works? The more repeating bytes in a row, the more space will
be saved! So if you have a picture with lots of black and white areas,
then the compression will be excellent. In the above sample, that's over
50% compression!
WHAT ABOUT COLORS? After I wrote this routine and tested the compression
"""""""""""""""""" on various pictures, I still was not satisfied with
the results. Why? Well, when I had a picture will lots of black and white
areas, this compression scheme worked great, but when I had a picture
with lots of colors and hardly any black and white areas, the compression
was horrible. The reason was because if there were hardly any repeating
black and white bytes, then there was not a whole lot to compress.
I started thinking of a better way to compress the screens and for new
ideas for better compression. After looking at a few more screen dumps, I
noticed that Green, Purple, Red, and Blue colors followed a pattern. Maybe
I could use a compression method to represent repeating color? Sure I
could! Here's what I came up with:
After the examination of the screen dumps, this fact surfaced:
Green lines are repeating patterns of $2A and $55
Purple lines are repeating patterns of $55 and $2A
Red lines are repeating patterns of $D5 and $AA
Blue lines are repeating patterns of $AA and $D5
So a green line on the screen would look like this:
2A 55 2A 55 2A 55 2A 55 2A 55 2A 55
Wow! I see a pattern. I used the same algorithm as the black and white
method, but had to add in a little twist for pattern repetition. Since the
black and white colors were represented as one byte (00, 80, 7F, FF) they
were easy to compress, I just had to store count the number of bytes in a
row and store that count (or repeat number) after the color byte. But
now things are a little different because two bytes represent a color
instead of just one.
To handle colors (now meaning that black and white aren't colors), I will
use a method for pattern recognition by issuing a comparision of two
bytes instead of just one. For example, if I was compressing a screen
and I came across a $2A, I'd immediately check the byte following it and
see if it was a $55. If it was, then I would have found a pattern! I'd go
on an count how many of these patterns were in a row and store that
repeat value as the repeating byte. So in the above example, that green
line would be stored like this:
2A 55 06
In this case, the "2A 55" is the pattern for a green line and the "06"
means that there are six of these patterns in a row. When I'm
decompressing this screen and I came across the $2A byte, and after I
made sure that the next one after it was $55, then I would go ahead an
repeat this pattern 6 times!
The same thing goes for Purple, Red and Blue. Except that I would
compare different numbers because the patterns would be made up of
different byte combinations.
That is basically the extent of my compression algorithm. There are only
two cases in my routine, checking for a non-color byte, and checking for
a color byte. In the case of checking for a non-color sequence, I'd act
on 00, 80, 7F, and FF. In the case of checking for a color pattern, I'd
act on $2A/$55, $55/$2A, $D5/$AA, and $AA/$D5 which represent color
sequences. Any other values would be stored as normal, non-compressed.
DECOMPRESSION Once the screen has been compressed and is stored in this
""""""""""""" new format, it needs to be decompressed and end up in its
original form. This process works just like the compression method but
it is much easier. I start scanning the compressed data and I look for the
key values which are 00, 80, 7F, and FF. Whenever I encounter such a
value, I take the next byte, which is the repeating value, and store that
number of the color value in a row to the screen. So if I came across
"00 1D" I'd store twenty-nine 00's in a row. I'd also scan for key color
sequences which are $2A/$55, $55/$2A, $D5/$AA, and $AA/$D5. Whenever I
find one of these sequences I'd take the next byte, which (again) is the
repeating value, and store this pattern that many times. So ifI came across
"AA D5 03" I'd store three "AA D5"'s in a row on the screen.
DISADVANTAGES Aren't there any disadvantages? Yes, unfortunately there
""""""""""""" are a few. The good thing is that all the advantages
always outweigh the disadvantages. The only bad part about my
compression algorithm is when there is only one $00, $80, $7F, or $FF in
a row, it takes one extra byte to store it compressed than it would to
leave it decompressed. For instance a single $00 would compress to look
like this: 00 01. This is a disadvantage because we started with one
byte and ended up with two. The other bad part is when you only have one
color pattern in a row like $D5 $AA, it would compress to D5 AA 01. We
went from having only two bytes to needing three. The overall advantage is
that the compression method always comes out ahead of the game because
there are usually lots more repeating bytes in a row than there are
single bytes laying around, and because of what I am going to describe
below.
THERE'S GOTTA BE SOMETHING ELSE With that done I went ahead and did some
""""""""""""""""""""""""""""""" more compressions and studied the
results. Everything was working great except for one instance. If I had
a majorly complex screen (one with hardly any repeating bytes) then the
compression would result in hardly any savings, and sometimes would end
up just a little bigger than the original! This was not good. I broke
open a few of my Apple books in search of a secret or two about the
hi-res screen that I may have overlooked, or simply failed to think about.
And soon enough, I found something.
I found out that the hi-res screen was full of "screen holes". What I
mean when I say screen holes, is that the screen has many areas which are
not visible to the viewer. These areas can be safely zeroed out, and these
zeroed out areas will compress. So even if there is not one single
repeating byte on the entire screen, after the compression it will still be
smaller, not by a whole lot, but definetly smaller. Sometimes even just
a few bytes help.
HOW IS IT ALL ACCOMPLISHED? Let me first explain that I have uploaded the
""""""""""""""""""""""""""" entire source code to the A2Pro Software
Libraries. Along with this source is a complete set of utilities to
load, compress, save, and decompress screens. Download file PIC.COMP10.BXY
(file number 3596) if you want to have the entire source and utilities.
I'll explain some of the source code here:
There are two constants I use here. SCREEN is hires screen one, and BUFFER
is hires screen two, which I am using to hold the compressed picture data.
SCREEN equ $2000 ; screen address
BUFFER equ $4000 ; crunch data buffer
Here are some zero page storage variables. Picture and Data are pointers.
Picture equ 0 ; picture to pack
Data equ 2 ; crunch data
PtrnByte1 equ $FE ; 1st pattern byte to store
PtrnByte2 equ $FF ; 2nd pattern byte to store
Here are the non-color and color pattern constants.
Black1 = $00 ; recognition values
Black2 = $80
White1 = $7F
White2 = $FF
Green = $2A ; color recognition values
Purple = $55
Red = $AA
Blue = $D5
Now here is the crunch (or compression) routine.
Crunch
jsr Filter ; filter screen "holes"
lda #>SCREEN ; point to hires screen 1
ldx #<SCREEN
sta Picture+1
stx Picture
lda #>BUFFER ; point to data buffer
ldx #<BUFFER
sta Data+1
stx Data
ldy #0
:NewByte
lda (Picture),y ; load the screen byte
beq :blkwht ; $00, $80, $7F, $FF
cmp #Black2 ; bytes will repeat
beq :blkwht
cmp #White1
beq :blkwht
cmp #White2
beq :blkwht
cmp #Green ; possible Green pattern
beq :green
cmp #Purple ; possible Purple pattern
beq :purple
cmp #Red ; possible Red pattern
beq :red
cmp #Blue ; possible Blue pattern
beq :blue
bne :store ; always
:green jmp :Dgreen
:purple jmp :Dpurple
:red jmp :Dred
:blue jmp :Dblue
:store sta (Data),y ; store screen byte
jsr NextData
jsr NextPic
bcs :finished ; carry set = finished
jmp :NewByte
:blkwht sta (Data),y ; store repeat byte
sta :compbyte
jsr NextData
ldx #0
:repeat
inx
jsr NextPic ; get next picture byte
bcs :storerep ; end of screen, store rep
lda (Picture),y
cmp :compbyte ; match?
beq :same
:limit
txa
sta (Data),y ; store repeat counter
jsr NextData
jmp :NewByte
:same
cpx #0 ; up the repeat counter
beq :limit ; max of 255 repeat bytes
jmp :repeat
:storerep
txa
sta (Data),y ; store repeat counter
jsr NextData
:finished rts
:Dgreen tax
iny ; is this a green pattern?
sta PtrnByte1
lda (Picture),y
cmp #Purple
bne :pstore
sta PtrnByte2
jsr StorePtrn ; store green pattern
bcs :finished
jmp :NewByte
:Dpurple tax
iny ; is this a purple pattern?
sta PtrnByte1
lda (Picture),y
cmp #Green
bne :pstore
sta PtrnByte2
jsr StorePtrn ; store purple pattern
bcs :finished
jmp :NewByte
:Dred tax
iny ; is this a red pattern?
sta PtrnByte1
lda (Picture),y
cmp #Blue
bne :pstore
sta PtrnByte2
jsr StorePtrn ; store red pattern
bcs :finished
jmp :NewByte
:Dblue tax
iny ; is this a blue pattern?
sta PtrnByte1
lda (Picture),y
cmp #Red
bne :pstore
sta PtrnByte2
jsr StorePtrn ; store blue pattern
bcs :finished
jmp :NewByte
:pstore dey
txa
jmp :store
:compbyte ds 1 ; stores comparison byte
*-------------------------------------------------
StorePtrn
ldx #0
ldy #0
lda PtrnByte1 ; store pattern data
sta (Data),y
iny
lda PtrnByte2
sta (Data),y
dey
jsr NextData
jsr NextData
:Ptrnloop
lda (Picture),y
cmp PtrnByte1
bne :endptrn
iny
lda (Picture),y
cmp PtrnByte2
beq :match
dey
:endptrn
txa
sta (Data),y ; store pattern repeat count
jsr NextData
clc
rts
:match
dey
jsr NextPic
jsr NextPic
bcs :done
inx
bne :Ptrnloop
:done dey
txa
sta (Data),y ; store pattern repeat count
sec ; indicate finished
rts
*-------------------------------------------------
* Screen "holes" are 8 bytes in a row at a constant
* increment of $80 (or 128 decimal) through-out
* the hi-res screen. So 504 bytes make up the
* total bytes in screen holes per screen. After
* compression it would only use 126 bytes, so that's
* a savings of 378 bytes in compressed format in
* just the screen holes!
*-------------------------------------------------
Filter lda #>SCREEN ; zero out the screen holes
sta Picture+1
lda #<SCREEN
clc
adc #$78 ; start at 1st screen hole
sta Picture
:Hole lda #0
ldy #8 ; store all zeroes there
:loop dey
sta (Picture),y
bne :loop
lda Picture
clc
adc #$80 ; advance to next hole
sta Picture
bcc :ok
inc Picture+1
:ok
lda Picture+1 ; finished last hole?
cmp #>SCREEN+$2000
bne :Hole ; nope, loop for more
rts ; yep, finshed
*-------------------------------
* Adjust screen pointer
*-------------------------------
* Exit, carry set if done
NextPic pha
inc Picture ; next picture address
bne :noinc
inc Picture+1 ; see if at bottom of screen
:noinc lda Picture
bne :nottop
lda Picture+1
cmp #>SCREEN+$2000
bcc :nottop
pla
sec ; carry set = done
rts
:nottop pla
clc ; carry clear, more
rts
*-------------------------------
* Adjust data pointer
*-------------------------------
NextData inc Data ; next data buffer address
bne :noinc
inc Data+1
:noinc rts
You'll notice that the first thing I do it call the Filter routine which
simply fills all the screen holes with zeroes so the compression routine
works effectively in all cases, regardless of the complexity of the screen.
Next I set up the Picture pointer to point to hires screen one and set up
the buffer to store the compressed data to hires screen two. I am only
using hires screen two because it is a convienent place in memory to
store the data. It could be anywhere.
Then the compression loop begins at :NewByte. The next byte is loaded from
the hires screen and it is checked to see if it is a $00, $80, $7F, or $FF.
If the screen byte is any of these values then the program goes to the
:blkwht routine which stores the color value, counts the number of color
values in a row, and then stores the value as the repeating byte; then
loops for more.
If the screen byte is a $2A, $55, $AA, or $D5 then there is a possible
pattern so the program branches to the appropriate color routine which
checks the next byte to try and match a color pattern, then if a color
pattern is found it counts the number of patterns in a row and stores the
value as the repeating byte; then loops for more.
That's it for the compression routine. Now for the decompression routine.
Unpack
lda #>SCREEN ; point to hires screen 1
ldx #<SCREEN
sta Picture+1
stx Picture
lda #>BUFFER ; point to data buffer
ldx #<BUFFER
sta Data+1
stx Data
ldy #0
:NewByte
lda (Data),y ; load the data byte
bmi :high
beq :blkwht ; $00, $80, $7F, $FF repeat
cmp #Green ; possible Green Pattern
beq :green
cmp #Purple ; possible Purple Pattern
beq :purple
cmp #White1
beq :blkwht
bpl :store
:high
cmp #Black2
beq :blkwht
cmp #Blue ; possible Blue pattern
beq :blue
cmp #Red ; possible Red pattern
beq :red
cmp #White2
beq :blkwht
:store sta (Picture),y ; store screen byte
jsr NextData
jsr NextPic
bcs :finished ; carry set = finished
bcc :NewByte ; always
:green tax
iny ; is this a green pattern?
sta PtrnByte1
lda (Data),y
cmp #Purple
bne :pstore
sta PtrnByte2
jsr ScreenPtrn ; store green pattern
bcs :finished
bcc :NewByte ; always
:purple tax
iny ; is this a purple pattern?
sta PtrnByte1
lda (Data),y
cmp #Green
bne :pstore
sta PtrnByte2
jsr ScreenPtrn ; store purple pattern
bcs :finished
bcc :NewByte ; always
:red tax
iny ; is this a red pattern?
sta PtrnByte1
lda (Data),y
cmp #Blue
bne :pstore
sta PtrnByte2
jsr ScreenPtrn ; store red pattern
bcs :finished
bcc :NewByte ; always
:blue tax
iny ; is this a blue pattern?
sta PtrnByte1
lda (Data),y
cmp #Red
bne :pstore
sta PtrnByte2
jsr ScreenPtrn ; store blue pattern
bcs :finished
bcc :NewByte ; always
:finished rts
:blkwht pha
jsr NextData ; get repeat byte
lda (Data),y
jsr NextData
tax ; and use as counter
pla
:repeat sta (Picture),y ; store to screen
jsr NextPic
bcs :finished
dex
bne :repeat ; loop
jmp :NewByte
:pstore dey
txa
jmp :store
*-------------------------------------------------
ScreenPtrn
jsr NextData ; grap repeat counter
jsr NextData
ldy #0
lda (Data),y
tax
jsr NextData
:Ptrnloop
ldy #0 ; store pattern to screen
lda PtrnByte1
sta (Picture),y
iny
lda PtrnByte2
sta (Picture),y
dey
jsr NextPic
jsr NextPic
bcs :out
dex ; pattern loop
bne :Ptrnloop
clc
:out rts
The unpack (or decompress) routine starts just as the compression
routines did. It sets up the Picture and Data pointers. This time it
reads the Data byte and compares it to see if it is a $00, $80, $7F, or
$FF. If it is one of these bytes then it grabs the repeating byte and
stores that many of the color value to the screen (or unpack address, which
happens to be hires screen one). Then loops for more.
Just like the compression routine, again, when a color pattern is found, it
is stored to the screen as many times as the repeat value.
That's it! My compression routines are not very complex but they work very
fast and very well for hires graphics.
>>> THE PROGRAMS IN THE PIC.COMP10.BXY ARCHIVE <<<
""""""""""""""""""""""""""""""""""""""""""""""""""""
All the programs and utilities are freeware, including the "dirty" graphics
that I "quickly" drew to demonstrate my routines.
PIC.COMPRESSOR - This is the main compression program. It allows you to
'''''''''''''' choose and load a hi-res graphic, compress it, and then
give you the option to save it and watch it decompress.
Use this program to compress all your pictures.
UNPACK.TEST - This program will search the CRUNCHED subdirectory and
''''''''''' load and unpack all the compressed picture files to the
screen. It works like a slide show.
SCREEN.HOLES - Little program I used while trying to find all those
'''''''''''' screen holes.
CRUNCH - This is the machine language compression and unpack
'''''' routines. It does all the compressing and decompressing
because of its speed.
UNPACK - This is ONLY the unpack routine. If you write a program
'''''' that needs to load and unpack compressed pictures, then
this is all you need. You don't need the compressor
because you won't be compressing pictures, you'll just
unpack them.
DIRECTORY STRUCTURE The way the programs are set up now, they will look
""""""""""""""""""" for picture files in the subdirectory called PICS.
When the compression program saves the crunched picture it will save it
in the subdirectory called CRUNCHED with the extension .PCC. So every
picture that you would like to crunch must be copied into the PICS
subdirectory.
TECHNICAL BABBLE The way the routines are set up now, the compressed
"""""""""""""""" picture must be loaded onto hi-res screen 2 ($4000) and
it gets unpacked to hi-res screen 1 ($2000). The compressing/unpacking
routines are at $7000 and $7003. After loading CRUNCH, a CALL to 28672
will compress the picture on screen 1 to screen 2 and a CALL to 28675
will unpack the compressed picture on screen 2 to screen 1.
After loading UNPACK, it will reside at $7000 also, except that only one
CALL is used. A CALL to 28672 will unpack the compressed picture
residing on screen 2 to screen 1.
SOURCE CODE The source code to the routines was written with the MERLIN """"""""""" assembler. The CRUNCH.S source and UNPACK.S source may be
modified to suit your needs. You can change the compile address (ORG) to
something else if you'd like the (un)compression routines to reside
somewhere else in memory. You can also change the values of "Picture"
and "Data" to tell the routines where to look for the compressed picture
and where to uncompress the picture to. You may want to set up a "load"
buffer where the compressed picture will be loaded and then unpack it to
either of the hi-res screens. It's up to you.
The source code is fully commented therefor I think that you will find it
very interesting to browse through and read all the other technical junk as
well.
[*][*][*]
We want your articles! If you want to write an article for
GEnieLamp A2Pro, then contact the editor, A2PRO.GELAMP for
more information. We pay for articles with usage credits.
[*][*][*]
[EOA]
[HEY]//////////////////////////////
HEY MISTER POSTMAN /
/////////////////////////////////
Is That A Letter For Me?
""""""""""""""""""""""""
By Tim Buchheim
[A2PRO.GELAMP]
o BULLETIN BOARD HOT SPOTS
o WHAT'S NEW
o PROGRAMMERS' TIPS
o MESSAGE SPOTLIGHT
>>> BULLETIN BOARD HOT SPOTS <<<
""""""""""""""""""""""""""""""""""
~ Where All the Action Is! ~
[*] CAT 2, TOP 5, MSG {59}.....Using the Merlin 8 assembler
[*] CAT 2, TOP 8, MSG {43}.....Assembly language and AppleSoft BASIC
[*] CAT 3, TOP 4, MSG {113}....The Merlin 16+ Assembler
[*] CAT 3, TOP 19, MSG {138}....General Assembly Questions
[*] CAT 11, TOP 8, MSG {111}....Programming Algorithms and Structures
>>> WHAT'S NEW <<<
""""""""""""""""""""
~ Announcements ~
A HALLOWEEN VISITOR BOO!
"""""""""""""""""""
I am sure programmers just love computer goblins <g>
(SKELETON, CAT1, TOP2, MSG:211/M530)
>>> PROGRAMMERS' TIPS <<<
"""""""""""""""""""""""""""
~ Helpful Advice from the Experts ~
STARTING SOURCEROR Help! My Merlin-8 manual is packed away and I cannot
"""""""""""""""""" remember...
How do I start Sourceror? I remember the BRUN SOURCER/OBJ, but then what?
(PAUL.RSM, CAT2, TOP5, MSG:59/M530)
>>>>> Paul,
"""""
1. Load the program to be disassembled.
2. BRUN SOURCEROR
3. Accept the $2500 (default) address for the source file.
4. Hit <return> if the loaded program is at its "running location"
Is that enough?
...John at Wood-n-Shavings
_____
/ \
(=====)
\___+_/
!... Hans
(H.HAUMANN, CAT2, TOP5, MSG:61/M530)
<<<<< I found a friend's Merlin manual. After BRUN SOURCER/OBJ, enter
""""" the editor. Kill the 80 column screen with Esc Ctrl-Q. Type USER.
(PAUL.RSM, CAT2, TOP5, MSG:62/M530)
SCROLLING TEXT I need to be able to scroll the IIe 40-column text screen
"""""""""""""" upwards. Does anyone have or know of a routine that can
do that for me?
This looks comparatively trivial to do, and I sat down to write the code,
only to discover that I have nearly completely forgotten how to code 6502
assembly. Use it or lose it. <sigh>
I can relearn assembly, but I would rather get this project on the road
=now=. <g>
TomZ
(A2.TOMZ, CAT2, TOP8, MSG:43/M530)
<<<<< >I need to be able to scroll the IIe 40-column text screen upwards.
"""""
Oops. I =meant= to say DOWNwards. It's not hard to get it to scroll
upwards. <g>
TomZ
(A2.TOMZ, CAT2, TOP8, MSG:44/M530)
>>>>> First, I've never done this so I'm speculating, but...
"""""
If you want to scroll downward and back upward, as in a word processor
file, then maybe you need a buffer with the text properly broken into
line-length sections. Then it's a small matter to re-draw the screen by
shifting pointers. I'm sure that there is a better way to do this. ;)
Will you control the text content, or will it be input by the user?
Charlie
(A2.CHARLIE, CAT2, TOP8, MSG:45/M530)
<<<<< The program would be doing all writing to the screen. This is
""""" intended to be an arcade effect for an Eamon game in development.
All I need is a routine that will write each line to the line below it.
This was once =well= within my capabilities as an assembly user, but I
haven't written a line of assembly in several years and find that I have
totally lost everything I once knew on the subject. (I find this
discovery to be extremely depressing, BTW)
If nobody has such a routine handy, we can work around it OK. We're not
even sure we want to do it that way.
TomZ
(A2.TOMZ, CAT2, TOP8, MSG:46/M530)
>>>>> Maybe this will help...
"""""
First push the registers to the stack to store them so that you can restore
them after you are finished.
PHA
TYA
PHA
TXA
PHA
You can also store any other flags, etc. that way.
Next, you'll need a routine for locating the cursor. Load the x register
with the horizontal cursor location, and the y register with the vertical
location. Then JSR GOTOXY
GOTOXY DEX ;go back one for range
STX CH ;store horiz. location CH = $24
DEY ;go back one for range
TYA
PHA ;calculate base address
LSR ; based on BASCALC ($FBC1)
AND #3
ORA #4
STA BASH ;BASH = $29
PLA
AND #$18
BCC :1
ADC #$7F
:1 STA BASL ;BASL = $28
ASL
ASL
ORA BASL
STA BASL
RTS
Next set up a counter to use to loop through the lines from 23 to 2.
BEGIN LDX #1
STX HOR :HOR = $06
LDX #23
STX VER ;VER = $07
:1 LDX HOR
LDY VER
JSR GOTOXY
LDY CH ;horiz. pos
:2 LDX HOR
LDA (BASL),Y ;get character on screen
STA BUFFER,X ;BUFFER = $200
INC HOR
INC CH
LDY CH
CPY #40 ;finished with line?
BNE :2
LDX #1
STX HOR
LDX VER
INX
STX VER
JSR GOTOXY
LDY CH
:3 LDX HOR
LDA BUFFER,X
STA (BASL),Y
INC HOR
INC CH
LDY CH
CPY #40
BNE :3
LDX #1
STX HOR
LDX VER
DEX
DEX
STX VER
CPX #1
BEQ :4
JMP :1
:4 RTS
After this you will have to place the new line 1 message on line 1. Be sure
to restore your registers when you are done.
Hope this helps.
Charlie
(A2.CHARLIE, CAT2, TOP8, MSG:47/M530)
>>>>> That'll get you up and running, but if you decide to go with it
""""" then you'll probably want to speed it up. BTW you didn't mention if
it should respect the text window or not; Charlie's routine uses the
numbers for the whole screen.
Todd Whitesel
(A2PRO.TODDPW, CAT2, TOP8, MSG:48/M530)
>>>>> Hey Tom!!
"""""
I wrote a blazingly fast downscroll routine for use in a project for
Softdisk 8-bit, but they ceased publication and I haven't finished the
program yet. The project was the ProDOS version of Electric Duet and it
uses the 40-column text mode exclusively, written in 6502 opcodes so it's
compatible on all Apple II's!! This is so fast because I use text screen
row tables instead of computing the address.
All you need to do here is make sure Top, Bottom, Left, and Right are set
to the values to define the text window, normally they are setup for full
screen, but this routine allows you to scroll ANY portion of the text
screen! The neat thing about this routine is that after the text window is
scrolled, the top line is filled with spaces.
Charlies' routine looks as if it will work, but if you want speed (usually
arcade style games need the fastest code possible) then try my routine! :)
Have fun!
- Russ
P.S. If you'd rather not type this in, I'll be happy to shoot the source
code file to you via attached file in email.
*-------------------------------------------------
* Zero page constants
*-------------------------------------------------
ptr equ $06 ; general usage pointer (trashable)
Left equ $20 ; left margin of text window
Right equ $21 ; right margin of text window
Top equ $22 ; top of text window
Bottom equ $23 ; bottom of text window
zp equ $eb ; general zero page (trashable)
*-------------------------------------------------
* Downscroll
*-------------------------------------------------
* Entry: Top, Bottom, Left, Right set to text window
Downscroll
lda Bottom ; start at bottom of text window
sta zp
dec zp
:Next_Row
ldy zp ; get current row
lda LOTAB,y ; set up "from" copy address
sta :downmod+1
lda HITAB,y
sta :downmod+2
dec zp ; get previous row address
ldy zp ; set up "to" copy address
lda LOTAB,y
sta ptr
lda HITAB,y
sta ptr+1
ldy Left ; start at left of text window
dey
:Do_Row
lda (ptr),y ; get screen byte
:downmod sta $FFFF,y ; store one line down (self modified!)
cpy Right ; finished row?
bne :Do_Row ; nope, keep going
lda Top ; at top of text window?
cmp zp
bne :Next_Row ; nope, do next screen row
Blankline
lda #" " ; fill with spaces character
ldy Left ; start at left of text window
:Blank
sta (ptr),y ; put space there
iny
cpy Right ; finished row?
bne :Blank ; nope, keep going
rts ; ok, finished
*-------------------------------------------------
* Text screen line lookup table
*-------------------------------------------------
LOTAB hex 0080008000800080
hex 28a828a828a828a8
hex 50d050d050d050d0
HITAB hex 0404050506060707
hex 0404050506060707
hex 0404050506060707
(R.NIELSON1, CAT2, TOP8, MSG49/M530)
>>>>> Use Russ' routine. :) Mine was just a quick hack to get you
""""" heading in the right direction; his is good. :)
Charlie
(A2.CHARLIE, CAT2, TOP8, MSG:51/M530)
>>>>> Here's a slightly tweaked up version of Russell's screen downscroll
""""" routine that's a tad smaller, a tad faster, and missing an infinite
loop bug :)
Note that this uses an additional pair of zero page locations ($FE,$FF)
which I've found are typically safe to grab... Also the Blankline routine
is no longer externally callable.
*
*-------------------------------------------------
*
* 40 column text screen downscroller
* by: Russell Nielson
* Tweaks by Harold Hislop
*
* Downscrolls the current text _window_
* 6502 clean
*
*-------------------------------------------------
*
case se ;enable case sensitivity
tr on
tr adr
xc off ;kill 65C02/802/816 ops
org $900 ;or wherever...
*
*-------------------------------------------------
*
* Zero Page stuff(ings)
*
*-------------------------------------------------
*
ptr equ $06 ;general usage pointer (trashable)
zp equ $EB ;general zero page (trashable)
XtraZP equ $FE ;Russ didn't use this originally.
*
Left equ $20 ;left margin of text window
Right equ $21 ;right margin of text window
Top equ $22 ;top of text window
Bottom equ $23 ;bottom of text window
*
*-------------------------------------------------
*
* Here there be code...
*
* Entry: Top, Bottom, Left, Right set to text window
*
*-------------------------------------------------
*
Downscroll
ldx Bottom ;get bottom of current window
dex ;refer to prev line
*
]LnLp lda LOTAB,x ;set up the "Get" pointer
sta ptr
lda HITAB,x
sta ptr+1
*
dex ;get previous line number
stx zp ;prep for 'nother pass
*
lda LOTAB,x ;and the "Put" ptr...
sta XtraZP
lda HITAB,x
sta XtraZP+1
*
ldy Left ;start at left of text window
]MvLp dey
lda (ptr),y ;get screen byte
sta (XtraZP),y ;store one line down (self modified!)
cpy Right ;finished line?
bne ]MvLp ;nope, so loop
*
ldx zp ;assume another loop needed...
cpx Top ;at top of window yet?
bne ]LnLp ;nope, do next screen row
*
lda #" " ;fill with spaces character
]Clr sta (ptr),y ;put space there
dey
cpy Left ;finished row?
bne ]Clr ;nope, keep going
rts ;ok, finished
*
*-------------------------------------------------
*
* Text screen line lookup table
*
*-------------------------------------------------
*
LOTAB hex 0080008000800080
hex 28A828A828A828A8
hex 50D050D050D050D0
*
HITAB hex 0404050506060707
hex 0404050506060707
hex 0404050506060707
*
*-------------------------------------------------
-Harold
(hope the formatting comes out Ok...)
(HAROLD.H, CAT2, TOP8, MSG:51/M530)
>>>>> Charlie, your quick hack was a good one! The reason I've never
""""" used the BASCalc monitor routines is because I have a habit of
doing everything on my own, and in my own way... just so I can customize
any routine I write to do EXACTLY what I need it to do. :)
(R.NIELSON1, CAT2, TOP8, MSG:53/M530)
>>>>> > and missing an infinite loop bug :)
"""""
I KNEW IT!! Ratz! I posted that routine directly from my project code
but there was a little editing that I had to do to the code here in the
post. In my original downscroll routine I had certain columns of the
screen that didn't get scrolled (they were data dividers) so I had the
routine skip these specified columns. I edited out the column checking
code from the routine and I must've done it hastily and left an infinite
loop in there... thanks for spotting it and reposted a better version
Harold.
The reason the Blankline routine was external was because it was used by
the Downscroll _and_ Upscroll routines, which saved valuable bytes in the
object code, because I was running low on space.
Anyway,
Cool!
(R.NIELSON1, CAT2, TOP8, MSG:54/M530)
>>>>> Harold,
"""""
Sorry, but your version doesn't work. I loaded it into Merlin, assembled
it, tested it, and it just fills the screen with random characters, and I
can see why. :)
I can see a couple of problems right away:
ldy Left ;start at left of text window
]MvLp
dey <====== DEY???
lda (ptr),y ;get screen byte <===== from ptr???
sta (XtraZP),y ;store one line down (self modified!)
cpy Right ;finished line?
bne ]MvLp ;nope, so loop
You are starting at the Left margin, why would you DEY? And, you have the
to pointers switched, you want to grab data from XtraZP and place at ptr.
This should be:
ldy Left ;start at left of text window
dey
]MvLp
iny
lda (XtraZP),y ;get screen byte
sta (ptr),y ;store one line down (self modified!)
cpy Right ;finished line?
bne ]MvLp ;nope, so loop
Tony, here's my routine again without the infinite loop.
*-------------------------------------------------
* Downscroll
*-------------------------------------------------
* Entry: Top, Bottom, Left, Right set to text window
Downscroll
lda Bottom ; start at bottom of text window
sta zp
:Next_Row
dec zp
ldy zp ; get current row
lda LOTAB,y ; set up "from" copy address
sta :downmod+1
lda HITAB,y
sta :downmod+2
dec zp ; get previous row address
ldy zp ; set up "to" copy address
lda LOTAB,y
sta ptr
lda HITAB,y
sta ptr+1
ldy Left ; start at left of text window
dey
:Do_Row
iny ; <==== this was the missing INY :)
lda (ptr),y ; get screen byte
:downmod sta $FFFF,y ; store one line down (self modified!)
cpy Right ; finished row?
bne :Do_Row ; nope, keep going
lda Top ; at top of text window?
cmp zp
bne :Next_Row ; nope, do next screen row
Blankline
lda #" " ; fill with spaces character
ldy Left ; start at left of text window
:Blank
sta (ptr),y ; put space there
iny
cpy Right ; finished row?
bne :Blank ; nope, keep going
rts ; ok, finished
(R.NIELSON1, CAT2, TOP8, MSG:56/M530)
>>>>> Russell,
"""""
>> and missing an infinite loop bug :)
<< I KNEW IT!! Ratz!
Hehehe, I've been there too (as you proceed to point out :)
Infact it seems that I'm there again... sigh.
>> The reason the Blankline routine was external was because it was used
>> by the Downscroll _and_ Upscroll routines, which saved valuable bytes in
>> the object code, because I was running low on space.
I suspected that might have been the case originally.
>> You are starting at the Left margin, why would you DEY?
uhm... Dyslexic Register Command Syndrome? ;-)
>> And, you have the to pointers switched, you want to grab data from
>> XtraZP and place at ptr.
Drat! I hate making stupid errors like that... (came about when I changed
your code from self modifying to zpage ptr)
Speaking of "saving valuable bytes"... Using a pair of Zpage locs that are
known to be expendable (instead of self modifying object) comes out several
bytes smaller (and faster by a few cycles too :) The locs that are used by
the monitor's RdKey routine (for the pseudo random number generator) are
free for the taking if you're not making use of them anyway. [a point I
often forget about, so I figure others might miss this too]
Take another look at my entry code... at least I got that part right, it's
tight enough to make a duck float ;-) {s quack}
-Harold
(HAROLD.H, CAT2, TOP8, MSG:57/M530)
>>>>> Harold, using Zpage instead of self-modifying absolute only makes
""""" the code faster if the loop executes just once. On most text
windows, you're executing the loop upwards of 10 times, so saving cycles
in the loop at the expense of the setup code is good from a speed standpoint.
If you really want to crank for speed, I'd recommend two things:
1. use self-modifying absolute for both pointers
This saves you 2
cycles per loop over using Zpage for both, but costs 4 in
setup (1 from each ZP store changed to an absolute store). It breaks even
when the window is 2 wide and wins for anything wider.
2. add "Left" to the pointers and loop from "Right-Left" down to 0
This eliminates a CPY from the loop, saving you 3 cycles times the width of
the window, but costs 15 cycles in setup. It breaks even when the window is 5
wide and wins for anything wider.
These changes would give you a core section that looked something like:
ldx line
clc
lda lotab,x
adc Left
sta labld+1
lda hitab,x
sta labld+2
lda lotab+1,x
adc Left ;carry already clear, from previous ADC
sta labst+1
lda hitab+1,x
sta labst+2
sec
lda Right
sbc Left
tay
lp:
labld: lda $FFFF,y
labst: sta $FFFF,y
dey
bpl lp
Todd Whitesel
(A2PRO.TODDPW, CAT2, TOP8, MSG:58/M530)
>>>>> Todd,
"""""
Nice explanation of execution cycle time and setup/overhead time. Cool
example too. :)
(R.NIELSON1, CAT2, TOP8, MSG:59/M530)
>>>>> I may be off base here, but assuming you have an enhanced //e can't
""""" you turn on the enhanced video firmware (PR#3), issue a CNTL-Q for
40 column screen and use the CNTL-V to scroll down and CNTL-W to scroll
up??
It's been a long time since I played with this but the information is in
the looseleaf "About Your Enhanced Apple IIe: Programmer's Guide" manual
that came with the //e Enhancement kit.
Bob, AF6C
(R.ECKWEILER, CAT2, TOP8, MSG:61/M530)
RESIZING YOUR STACK Hi Assembly Gurus:
"""""""""""""""""""
I have written a couple of CDAs (in Merlin 16+); then I wrote a memory
query utility for GNO/ME THEN I obtained a pre-written GNO/ME mem util
(written in C).
Using these I found that I am using 65%+ of stack under GNO/ME and my
CDAs are using 4K each.
Now the question ... under assembly programs like Merlin 16+, how do I
control the allocated stack size. Ok, how do I do it under ORCA/M as
well!!!
The pragma stacksize give me control under ORCA/C.
The Assembly manuals (Merlin and ORCA/M) mention the defaults BUT not how
to change them.
Thanks in advance!
Doug M.
(D.MITTON, CAT3, TOP4, MSG:113/M530)
>>>>> You override the GS/OS default stack size of 4k by linking a stack
""""" segment into your program. I don't know how to create a stack
segment, though.
for more information about stack/direct-page segments, see pages 38-39 and
476-477 in the _GS/OS Reference_.
(A2PRO.GELAMP, CAT3, TOP4, MSG:114/M530)
>>>>> Doug,
"""""
Here is a piece of code that explains what I've been able to do.
**************************************************
* *
* Linker command file *
* *
**************************************************
typ TOL
lkv 2
asm stuff.s
asm dp.s
lnk stuff.l
sav stuff
knd $12 ;"direct-page/stack" object segment as mentioned
;in Apple IIGS GS/OS Reference manual. Page 37.
lnk dp.l
sav dp
Next file
**************************************************
* *
* Direct page space *
* *
**************************************************
typ TOL
rel
ds $200 ;Makes 2 pages of direct page space
sav dp.L
**************************************************
Next file
**************************************************
* *
* Stuff program *
* *
**************************************************
type TOL
rel
;stuff's stuff
sav stuff.L
**************************************************
Clay
Warning! Opinions will change due to new facts.
Clayburn W. Juniel, III - Effective Software Solutions
clay1@primenet.com
(C.JUNIEL, CAT3, TOP4, MSG:115/M530)
>>>>> And, since you asked, it's pretty much the same under ORCA/M. The
""""" details are in the manual; see the KIND directive on page 328 and
the various kind fields on page 490. You can also do a lot more than just
create a stack segment, and I suspect Merlin can, too.
And now, back to our regularly featured assembler...
Mike Westerfield
(BYTEWORKS, CAT3, TOP4, MSG:116/M530)
>>>>> Thanks for the information on creating a DP segment in Merlin 16+
""""" (and ORCA/M), it was exactly what I was looking for.
One additional point to any other interested parties, make sure you are using
Linker.XL (lkv 2) for the previous examples to work. My installation
defaulted to Linker.GS which was perfect for my CDAs and ProDOS8 stuff but
not for this.
ORCA/M was a little more straight forward to implement once I figured out
what was going on BUT I still don't think I would have gotten either out of
the manual(s). (I know, they are for reference, not tutorial!!!! :-))
Thanks Again!!!
Doug M.
(D.MITTON, CAT3, TOP4, MSG:117/M530)
LINEAR REGRESSION Mike W,
"""""""""""""""""
I'd like to duplicate the curve fit function used by Quick Click Calc in a
small project. On p. 51 of the QCC manual, you give the equation for the
first, second, and third order fits. The third order fit is given as:
2 3
y = A + Bx + Cx + Dx
This looks a lot like a cubic polynomial expression for a spline function
(although the examples I've seen reverse the order of the terms). If this
is a spline function, then what basis matrix are you using? If not, what
are the A B C and D coefficients?
But the manual mentions that this is a "linear regression"--a term I
haven't heard of before. Worse, I can't find it in any of my books,
including a fairly recent college Algebra & Trig textbook. Is it safe to
assume that the coefficients are the dataset's y-values i, i+1, i+2, and
i+3?
Can you help me out?
Michael
(ANIMASIA, CAT11, TOP8, MSG:111/M530)
>>>>> Hi Michael,
"""""
Linear regression is a pretty standard method for finding coefficients
yielding the smallest error between a curve fit and a set of data points. I
could cite a gob of sources, but most of the books I learned from (and
still use) are 20 years old, so you might have trouble finding them. Try
looking through any halfway decent college probability & statistics text,
vurtually any data analysis book for the physical sciences, or a linear
algebra text that is engineering oriented, rather than oriented towards
theoretical mathematics.
I'll try to give you a quick version here, but do try to find the books--
among other things, they will tell you how to figure the error in the fit!
You basically create two matrices. One is a cube; it has the sum of the
independent variable (x in most notations) raised to various powers. The
power starts at 0 in the top left position, and you add one across the
top row and left column. The power for the interior values is the sum of
the power to the top and left. So, showing only the powers in the
correct spot, the cubic array looks like this (ASCII is a pain for matrices
with powers; write it on a sheet of paper :)
0 1 2 3 4 ...
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
You can keep going as long as you like. The matrix I've shown is for a 4th
order polynomial fit. To actually calculate the terms, you sum the
values raised to the power I've shown. Since I can't use mathematical
notation, I'll use Pascal. :) In this case, all of the values are
stored in two arrays, x[size] and y[size]. So to compute the value for 4
in the array, you would sum all of the x values raised to the 4th power,
like this:
s4 := 0.0;
for i := 1 to size do
s4 := s4 + sqr(sqr(x[i]));
The second array is a column (or a vector). It's the sum of the
dependent variable times a power of the independent variable. The powers
for the independent variable are the same as for the left column of the
square matrix. Calculating the third term down would go something like
this:
sy2 := 0.0;
for i := 1 to size do
sy2 := sy2 + y[i]*sqr(x[i]);
There is a third matrix; it contains the coefficients for the polinomial.
From the manual, that's A, B, C, etc. It's a column, too, just like the
second one. The last step is to combine these equations into a matrix
equality. Calling the square one S, the coefficients c, and the second
matrix with the x and y powers n, the equation is
Sc = n
You solve this set of simultaneous equations for the coefficients. For
higher or lower order polinomials, simply adjust the size of the matrices.
CAUTION: The equations are not well behaved. You can get numerical
'''''''' errors, like divide by zero, with many off the shelf equation
solvers. Guard for that!
Finally, if this didn't make much sense, rest assured that it's a lot
easier with a blackboard or book, where you can use matrix notation,
powers, and summation signs. :) If this confused you, find a discussion
in a book.
Mike Westerfield
(BYTEWORKS, CAT11, TOP8, MSG:112/M530)
<<<<< Mike--
"""""
Excellent overview! I actually understood your ASCII power notation matrice
and your Pascal sources, which is not surprising because I remember your
Call -APPLE articles being so well written. I feel I have a much better
idea of what I have to work towards than before. However, I still don't see
how the three matrices relate to eachother to produce the results that they
do. So it looks like I'm going to stop at the university library tomorrow
to investiage your sources; "data analysis for physcial sciences" sounds
like a good bet. I'll let you know how it works out. Thank you!
Michael
(ANIMASIA, CAT11, TOP8, MSG:113/M530)
>>>>> Hi Michael,
"""""
If you got everything but how to solve the matrix equation, concentrate
on linear algebra books. In fact, you might even want to find one of those
encyclopedia sized books on engineering mathematics that I assume are still
used to cover 4-6 math courses in an engineering curriculum. Concetrate on
simultaneous solutions to multiple equations, which is what you are
actually doing.
Once you get to the point where you're actually doing it, switch to a
good introductory text on numerical analysis, or check out something like
Sedgewick's Algorithms book. All will have better methods for actually
solving the matrix equations than the math books are likely to show,
since the methods that work well on a computer are a little different
from the ones that work well by hand.
Mike Westerfield
(BYTEWORKS, CAT11, TOP8, MSG:114/M530)
<<<<< Mike,
"""""
I spent the better part of the day at the library looking through the types
of books you suggested. You were right; there are tons of books which cover
linear regression in many different fields. Some good. Some bad. I
backtracked and began investigating how to find the closest fit to a first
order function and even that slowed me down. Not surprisingly, I found
myself having to relearn much of the matrix operations for solving
simultaneous solutions. So it looks like I'll have to go back and start
from the beginning. I'll check into "Sedgewick's Algorithms" too. Still,
I'm enjoying this because it's no longer abstract theory.
Michael
(ANIMASIA, CAT11, TOP8, MSG:115/M530)
>>>>> Cool. FWIW, linear regression was the first thing I ever did with
""""" a matrix (back in high school) and it remains one of the most-used,
and IMHO, most usefull things I've ever done with a matrix. :) And in
physics and math, I've seen quite a few matricies.
Mike Westerfield
(BYTEWORKS, CAT11, TOP8, MSG:116/M530)
>>>>> One book that covers this subject fairly well is _Advanced
""""" Engineering Mathematics_ by Erwin Kreyszig. It's an older college
text book (1964 - fourth edition) but should be able to be found in used
book stores. What I like about this book is that it contains a lot of
practical examples instead of just dry theory.
Another book that may be of interest is "BASIC Computer Programs in Science
and Engineering" by Jules Gilder 1980 (A Hayden PaperBack). It is full of
BASIC programs. Chapter 4 is "Matrix Mathematics" and Chapter 5 is "Data
Analysis" including linear a least-squares fit and various logarithmic
least-squares fit programs
In the seventies and early eighties I wrote many programs on a Tektronix
4054 desktop computer. It had built-in matrix functions and you could
solve multiple equations with multiple unknowns with one BASIC call.
Bob, AF6C
(R.ECKWEILER, CAT11, TOP8, MSG:117/M530)
BEZIER CURVES Speaking of least-squares fit algorithms, I once had an
""""""""""""" interest in how Bezier curves were drawn. You know, a
spline curve where the points can be unordered in both the X and Y axes.
I wanted to, given a completely random set of points, draw a smooth curve
through the points.
Best I ever came up with was limited. The method would only work if the X
(or Y) coordinates were listed in order (increasing or decreasing).
Does anyone know how these are computed? I know it can be done, because I've
seen it in some paint/draw programs.
...Chris
(K.FLYNN, CAT11, TOP8, MSG:120/M530)
>>>>> Chris,
"""""
Bezier curves are pretty easy to draw once you know how it's done. The
simplest Bezier curve has four points: two endpoints and two handle points
which define the shape of the curve. Image that the following four points
will create a smooth Bezier curve. ep is endpoint and hp is handle point.
hp1
ep1
ep2
hp2
When a Bezier curve is drawn, the drawing algorithm starts drawing from the
first endpoint, ep1, toward the first handle point, hp1, but never actually
touches hp1 because as it goes along, it begins to head toward the next
handle point, hp2. Again, the curve doesn't touch hp2 because it heads
toward the last endpoint, ep2. The curve therefore touches the endpoints
but only heads toward the handle points. The handle points are called
handles because if you drag these handles around, you'll change the shape
of the curve. These are the curves that Postscript uses for its foundation;
same for most any illustration program.
There are two ways you can draw a Bezier curve. The first is to say that a
variable t will be increased from 0 to 1 over series of steps and a basis
matrice function will be solved for x and y with t. You simply connect the
x and y's as you increment t. This is slow and entirely too precise for
drawing on the screen.
The second way is much faster because it recursively splits the Bezier
curve into two smaller Bezier curves until the curves become straight
enough to be approximated by lines. This only uses shifts and adds and
you'll find the source code to this below.
Still, you wanted to know how to connect a whole series of points. That's
easy too. To lengthen a Bezier curve, add three more points: two handles
and an endpoint. Because the last endpoint of the first Bezier is the first
endpoint of the second Bezier, that endpoint is reused. So you need to have
"(curves * 3) + 1" points. Another thing to keep in mind is that to have
the overall Bezier curve look smooth between adjacent sub-curves requires
you to position the two handles on either side of an endpoint to line up in
a straight line across the endpoint. Otherwise, you'll have a sharp bend in
your curve, (which may be what you want too).
However, this won't _completely_ solve your problem because you
specificially wanted to have this curve pass through _all_ of your points.
Well, a Bezier curve, like I mentioned, only passes through the endpoints
but not the handles. There are different types of curves, and the one you
would want to use to pass through all points is a Catmull-Rom curve, which
are harder to draw than Bezier curves because you can't as easily subdivide
them.
But don't let that discourage you because Bezier curves are great and if
you can get them to work (no problem) you're on your way to creating an
illustration program for the GS :)
Michael
(This C source code is old and doesn't use the bit shift operator to divide
by two. This is because I assumed there was a problem with the way Orca/C
generated code if it tried to bit shift a negative number. I wanted to use
negatives because I wanted to have a Cartesian coordinate plane, but this
could easily be solved if you use only the positve quadrant of the plane,
such as screen coordinates. Also, it refers to endpoints as control
points.)
#include <types.h>
#include <quickdraw.h>
#define BezDepth 4 /* greater the depth, the smoother the curve */
#define NumBezPts 17 /* must be >= 2^BezDepth + 1 */
/* It's important to note that increasing BezDepth
makes smoother curves--up to a point. We reach
diminishing returns in increasing BezDepth too
much, since the accumulated error of repeated
averaging eventually throws the calculations off
by one or more pixels. This could be soved by
using fixed point math. */
typedef struct {int top, left, bottom, right;} rect2, *rect2ptr;
typedef struct
{int x, y;} intVector2, intPoint2, *intVector2ptr, *intPoint2ptr;
intPoint2 bezPts [NumBezPts];
intPoint2ptr bezPtsPtr;
int xCenter, yCenter;
void SubdivideBezier (intPoint2 p0, intPoint2 p1, intPoint2 p2, intPoint2
p3, int depth);
void DrawBezier (intPoint2 ctrl1, intPoint2 hand1, intPoint2 hand2,
intPoint2 ctrl2);
void main (void)
{
rect2 viewPort;
intPoint2 ctrl1, hand1, hand2, ctrl2;
/* Define Bezier curve's points: */
ctrl1.x = -100; ctrl1.y = 0; /* Cartesian coordinates */
hand1.x = -30; hand1.y = 60;
hand2.x = 10; hand2.y = -80;
ctrl2.x = 100; ctrl2.y = 0;
GetPortRect ((RectPtr) &viewPort);
xCenter = (viewPort.left + viewPort.right) / 2;
yCenter = (viewPort.top + viewPort.bottom) / 2;
SetPenSize (2, 1);
SetPenMode (modeCopy);
SetSolidPenPat (0);
DrawBezier (ctrl1, hand1, hand2, ctrl2);
/* Draw handles as dots: */
MoveTo (hand1.x + xCenter, yCenter - hand1.y);
LineTo (hand1.x + xCenter, yCenter - hand1.y);
MoveTo (hand2.x + xCenter, yCenter - hand2.y);
LineTo (hand2.x + xCenter, yCenter - hand2.y);
}
void DrawBezier (intPoint2 ctrl1, intPoint2 hand1, intPoint2 hand2,
intPoint2 ctrl2)
{
int i;
bezPtsPtr = bezPts;
*bezPtsPtr++ = ctrl1;
SubdivideBezier (ctrl1, hand1, hand2, ctrl2, BezDepth);
MoveTo (bezPts [0].x + xCenter, yCenter - bezPts [0].y);
for (i = 1; i < NumBezPts; i++)
LineTo (bezPts [i].x + xCenter, yCenter - bezPts [i].y);
}
void SubdivideBezier (intPoint2 p0, intPoint2 p1, intPoint2 p2, intPoint2
p3, int depth)
{
intPoint2 q0, q1, q2, r0, r1, s0;
int x, y;
if (!depth)
{
*bezPtsPtr++ = p3;
return;
}
q0.x = (p0.x + p1.x) / 2; q0.y = (p0.y + p1.y) / 2;
x = q0.x; y = q0.y;
q1.x = (p1.x + p2.x) / 2; q1.y = (p1.y + p2.y) / 2;
x = q1.x; y = q1.y;
q2.x = (p2.x + p3.x) / 2; q2.y = (p2.y + p3.y) / 2;
x = q2.x; y = q2.y;
r0.x = (q0.x + q1.x) / 2; r0.y = (q0.y + q1.y) / 2;
x = r0.x; y = r0.y;
r1.x = (q1.x + q2.x) / 2; r1.y = (q1.y + q2.y) / 2;
x = r1.x; y = r1.y;
s0.x = (r0.x + r1.x) / 2; s0.y = (r0.y + r1.y) / 2;
x = s0.x; y = s0.y;
SubdivideBezier (p0, q0, r0, s0, --depth); /* subdivide into left half */
SubdivideBezier (s0, r1, q2, p3, depth); /* subdivide into right half */
}
(ANIMASIA, CAT11, TOP8, MSG:121/M530)
>>>>> Oh yeah. I forgot to mention that to compile and use the code you
""""" can use Prizm's Graphics Output window. Just open that window and
choose Compile to Memory. It's best to make the Graphics Output window as
big as it can be (Mike- the zoom box on that window doesn't do anything.)
Also, the curve won't look stunningly smooth because of the accumulated
division error inherent in integer math. You'll need to use fixed-point
math to get perfectly smooth curves.
Michael
(ANIMASIA, CAT11, TOP8, MSG:122/M530)
>>> MESSAGE SPOTLIGHT <<<
"""""""""""""""""""""""""""
~ Important or Interesting Messages ~
65816 IN AN ATARI? Greetings! I've got a 65816 transplanted into my
"""""""""""""""""" 8-bit Atari (please no flames) and was searching here
for some 65816 assembler examples. This seems to be the biggest collection
of '816 programmers on GEnie; what can you point to? I've programmed for
over 10 years on the 6502, and was looking for fast signed multiply
routines, etc. Also, since everything here is ".BXY", can anyone suggest a
path to some other archive format like ARC or LZH? Thanks in advance...
(JDPOTTER, CAT3, TOP19, MSG:138/M530)
>>>>> JDPOTTER,
"""""
>> I've got a 65816 transplanted into my 8-bit Atari (please no flames) and
>> was searching here for some 65816 assembler examples.
Hey, no flames from me! How did you get the 816 in the Atari anyway? (by
leaving pin 1 out of the socket?? That's what I did on my IIc, works great!
:))
Most likely most of the source you'll find here for 816's will be for the
Apple IIgs, which won't do you tooo much good... (the IIgs has a "toolbox"
(part rom, part in the OS) that covers a =lot= of ground... math routines
included.)
>> Also, since everything here is ".BXY", can anyone suggest a path to some
>> other archive format like ARC or LZH? Thanks in advance...
Chances are if some file or other (or more than one :) sounds like a likely
candidate for what you're looking for it could be unpacked by one of the
folks around here and either emailed to you that way, or maybe packed up
using another method... (I think there's a utility around somewheres for
producing ARC files on an Apple II)
-Harold
(HAROLD.H, CAT3, TOP19, MSG:139/M530)
>>>>> There's also a MS-DOS utility to unpack .BXY and .SHK archives
""""" (both ShrinkIt archives), if that's of any help to you.
Doug
"As Canadian as possible under the circumstances."--Heather Scott
(EDITOR.A2, CAT3, TOP19, MSG:140/M530)
>>>>> There are some fast math routines for signed and insigned 2, 4 and
""""" 8 byte integer math in the ORCA/M package. The source code is
available separately as GS-13 ORCA/Sublib Source $25, available from Byte
Works. The files are ASCII files with the SRC file type stamp. The biggest
problem you would face is getting the files from the Apple IIGS 3.5" disk
they ship on to your computer. A friend with an Apple ][ or Mac can help.
If you're interested, let me know. I can send you a catalog; you can at
least get an idea what we have. I'll need your mailing address if you want
the catalog.
Mike Westerfield
(BYTEWORKS, CAT3, TOP19, MSG:141/M530)
<<<<< Harold.H, I got the 65816 from the guy who bought the rights to all
""""" ICD Atari 8-bit products. It's the 65C816 and a PAL mounted in a
socket, plugs directly into my 6502 socket. I saw some interesting code
tips in the "Optomeisters" topic. I'm really looking for a 16 x 16 -> 32
bit signed multiply; I was able to adapt some of their fast routines, but
would like to see more. Thanks.
Jeff
(JDPOTTER, CAT3, TOP19, MSG:142/M530)
>>>>> Jeff,
"""""
> I'm really looking for a 16 x 16 -> 32 bit signed multiply
You might want to check out the "Apple Assembly Lines" archives in the
libraries. They have some _excellent_ articles w/source on all sorts of
algorithms such as various sized multiples. (They even have a 8 x 8 -> 16
bit multiply that executes in 65 cycles!) Search on "AAL" for all the
issues, or "multiply" or "multiplication" for the ones you need.
Michael
(ANIMASIA, CAT3, TOP19, MSG:143/M530)
[*][*][*]
While on GEnie, do you spend most of your time downloading
files? If so, you may be missing out some excellent
information in the Bulletin Board area. The messages listed
above only scratch the surface of what's available and
waiting for you in the bulletin board area.
If you are serious about your Apple II, the GEnieLamp staff
strongly urges you to give the bulletin board area a try.
There are literally thousands of messages posted from people
like you from around the world.
[*][*][*]
[EOA]
[DEV]//////////////////////////////
DEVELOPER'S CORNER /
/////////////////////////////////
News From The A2Pro Online Developers
"""""""""""""""""""""""""""""""""""""
By Tim Buchheim
[A2PRO.GELAMP]
o ONLINE SUPPORT IN A2Pro
o EDIT-16 SUPPORT
o USING THE GNO SHELL
o THE SPLAT! SOURCE LEVEL DEBUGGER
>>> ONLINE SUPPORT IN A2Pro <<<
"""""""""""""""""""""""""""""""
CAT TOP COMPANY
=== === =======
29 INDEPENDENT DEVELOPERS ONLINE
2 DYA/DigiSoft Innovations Online
8 Simplexity Software Online
14 Quality Computers Q-LABS Online
20 DreamWorld Software Online
26 METAL/FV Software Online
32 Kitchen Sink Software Online
38 EdIt-16 (Bill Tudor)
30 PROCYON, INC.
31 SOFTDISK PUBLISHING
33 GS+ MAGAZINE
34 JEM SOFTWARE
35 PRODEV, INC.
36 THE BYTE WORKS
Each month this column feature highlights and news from various
developers who provide support via A2Pro.
>>> EDIT-16 SUPPORT <<<
"""""""""""""""""""""""""
EDIT-16 REQUEST Bill,
"""""""""""""""
Is there anything new to report about Edit-16 or are no more updates planned?
My only real desire is to have it handle files larger than 64k. Other than
that, I can't think of a thing. And if no further improvements are planned, I
can understand that.
Bob
(R.FISCHER7, CAT29, TOP38, MSG:108/M530)
>>> USING THE GNO SHELL <<<
"""""""""""""""""""""""""""""
SWITCHING PROCESSES How do you switch processes in GNO? I've found the
""""""""""""""""""" GNO shell to be very confusing. Is Edit-16
compatible? I haven't been able to get it to work with the shell yet. Any
help would be appreciated!
Brian Gillespie, Jaunt! Software
(B.GILLESPIE3, CAT30, TOP2, MSG:193/M530)
<<<<< I've learned some more about switching processes, but how do you
""""" switch out of the ORCA editor? It eats the Control-Z keypress.
Thanks!
Brian Gillespie, Jaunt! Software
(B.GILLESPIE3, CAT30, TOP2, MSG:194/M530)
>>>>> You need to set the auxtype of the ORCA editor to something (I
""""" think $DC00 but it should be in the GNO docs somewhere, so don't
trust me, trust them) to tell GNO it needs to handle the input stuff
differently. Maybe someone else here can tell us just what it does
differently?
Todd Whitesel
(A2PRO.TODDPW, CAT30, TOP2, MSG:196/M530)
>>>>> From the GNO Shell User's Manual (Appendix E, Non-Compliant
""""" applications, page 50): "Setting the auxtype of an application to
$DC00 disables the interrupt driven keyboard buffering and turns off the
GNO/ME cursor. Desktop programs use the GNO/ME keyboard I/O via the Event
Manager, and thus should NOT have their auxtype changed."
However, I always thought EXE (and S16) files were supposed to follow the
FTN that details the $DBxx auxtype. The ORCA editor has an auxtype of $DB01
(at least mine does.)
- Tony
(A2.TONY, CAT30, TOP2, MSG:197/M530)
>>>>> >However, I always thought that EXE (and S16) files were supposed
""""" >to follow the FTN that details the $DBxx auxtype.
They are. :) But when you use a S16 or EXE program in GNO, it is being
loaded and executed by GNO itself with direct calls to the System Loader
toolset..
Only _QuitGS looks for that $DBxx in the auxtype.. since GNO isn't loading
the program through _QuitGS, it can require the auxtype to be whatever it
needs. (I assume that it properly handles the defined bits in a $DBxx
auxtype, though.)
Note that GNO doesn't require any weird auxtypes for desktop programs.. so
leave them set to whatever is appropriate for the specific app.
(A2PRO.GELAMP, CAT30, TOP2, MSG:198/M530)
>>>>> > Only _QuitGS looks for that $DBxx in the auxtype..
"""""
Okay, so there's no harm in changing EXE auxtypes for files that run on a
shell from $DB01 to $DC00 (ie. the ORCA editor.) However, I wouldn't want
to change a S16 auxtype like that unless I only plan on running the program
from the shell, right?
- Tony
(A2.TONY, CAT30, TOP2, MSG:199/M530)
>>>>> right, although I would assume that most S16 programs you use
""""" aren't text programs, and therefore wouldn't need any auxtype
changes. (Programs that use the Event Manager, such as desktop programs,
work fine in GNO, from what I understand.. but I don't have GNO, so I can't
be sure. :)
(A2PRO.GELAMP, CAT30, TOP2, MSG:200/M530)
>>>>> You can't change the auxtype of a S16 file to $DC00 if the file is
""""" on an HFS volume, due to the way the HFS FST maps between ProDOS
and HFS types. (At least, not the standard GS/OS way. Don't know if you
can get around it by mucking with the optionList.)
(S.REEVES2, CAT30, TOP2, MSG:202/M530)
>>>>> huh? why can't you change the auxtype of a S16 file on an HFS
""""" volume? A S16 file with an auxtype of $DC00 would have a creator
type of "pdos" and a file type of "p" $B3 $DC $00
(A2PRO.GELAMP, CAT30, TOP2, MSG:203/M530)
>>>>> The HFS FST won't preserve a non-zero auxtype of a S16 file unless
""""" it starts with $DB (this is described on page 334 of the
Programmer's Reference for System 6.0). It seems you can set it to $DC00
by directly changing the Mac filetype to "p" $B3 $DC $00 (via the
optionList), but you must do this manually. GNO's standard chtyp command
won't do it for you.
(S.REEVES2, CA30, TOP2, MSG:204/M530)
>>>>> yuck. that's stupid. :(
"""""
(A2PRO.GELAMP, CAT30, TOP2, MSG:205/M530)
>>> THE SPLAT! SOURCE LEVEL DEBUGGER <<<
""""""""""""""""""""""""""""""""""""""""""
USING SPLAT! Hi, I have two questions related to Splat!
""""""""""""
1.) I have searched the manual cover to cover trying to figure out how to
display strings in hex in the variables window/dialog a la the 'mem'
command does in the ORCA debugger. I am manipulating text, control
characters and NULL's in char arrays and would like to see the changes
in hex while stepping through the program. Can I do this with Splat!?
Currently I am using Splat! for debugging program control but switch
over to ORCA debugger to watch the changes in the arrays because I can
only get the ascii text in double quotes using Splat!.
Which brings me to question 2.
2.) Are there any known problems having Splat! and ORCA debugger in the
ORCA shell at the same time. So far I haven't noticed any problems but
I would like to know ahead of time what to watch out for.
My setup has the 'shell' version of Splat! installed in ORCA/shell 2.x, and
the ORCA/Debugger init and debugger utilities installed. I use a script to
run ORCA/D. I 'cmpl +d {program}.cc keep={program}' once, and type 'splat
{program}' to use Splat! or 'debug {program}' to use the ORCA/D.
This, so far, works ok (my programs are ANSI C, text display only, no
toolbox) but I prefer Splat!'s interface to ORCA/D's and want to save the
hassle of jumping from one to the other.
Thanx.
Eric Heim
(of course, by using both there is no spent money wasted :)
(E.HEIM3, CAT30, TOP9, MSG:31/M530)
>>>>> Eric,
"""""
I'm not familiar with Orca/Debugger's mem command, but I'm afraid you can't
do what you're asking for (showing characters as hex) in Splat! at this
time. I believe unprintable characters show up either as octal or hex
(it's been a while since I've used it much) but I know that's not what
you're after.
I don't know imagine there would be any problems with the setup you are
running (Orca INIT and Splat! shell version), but it's not something that
I've ever tested and certainly don't guarantee. If it works, then it
works. And until there's a major upgrade to Splat! (don't ask), I guess
you'll have to continue to use both to get what you want. Sorry.
Mike Hackett
(M.HACKETT, CAT30, TOP9, MSG:32/M530)
<<<<< Hi Mike H.,
"""""
Don't be sorry, Splat! is great. ORCA/Debugger is great. I'm glad I
have both. I was just hoping that Splat! had EVERYTHING to save a little
time while trying to fix my latest 'index past the end of array' ;-)
Eric Heim
(E.HEIM3, CAT30, TOP9, MSG:33/M530)
>>>>> Eric,
"""""
> display strings in hex in the variables
Well it *is* possible, but it doesn't look pretty...
Here is a way to see 4 characters in hex from a string. The text characters
are stored in a pointer that doesn't really point to anything. Pointers are
displayed in their hex values. The hex values can also be displayed in
the output window.
Look at BadAddress to see the 4 chars displayed in hex, not what it
points to. It doesn't really point anywhere.:)
#pragma keep "Program"
#pragma debug -1
#include <stdio.h>
#include <string.h>
struct StringPlus
{
char SPlus[10];
};
void main (void)
{
struct StringPlus ASP;
unsigned int x;
/* Declare address and set to unique numbers */
unsigned char *BadAddress;
asm {
lda #0xFFFF
sta BadAddress+2
lda #0xFFFF
sta BadAddress
}
strcpy(ASP.SPlus, "5678\n");
ASP.SPlus[6] = 0;
for(x=0;x<10;x++) {
/* Notice ordering to keep string characters lined up */
/* Copy string characters to the hex address for hex display */
asm {
lda ASP
sep #0x20
sta BadAddress+3
rep #0x20
}
asm {
ldx #1
lda ASP,x
sep #0x20
sta BadAddress+2
rep #0x20
}
asm {
ldx #2
lda ASP,x
sep #0x20
sta BadAddress+1
rep #0x20
}
asm {
ldx #3
lda ASP,x
sep #0x20
sta BadAddress
rep #0x20
}
/* Increment string chars for viewing change */
ASP.SPlus[0]++;
ASP.SPlus[1]++;
ASP.SPlus[2]++;
ASP.SPlus[3]++;
/* Display some of string in hex in output window */
printf(" Hex=%X, %X\n", ASP.SPlus[0], ASP.SPlus[2]);
}
exit(0);
}
More chars can be copied into more hex addresses for display,
but this can be used to view some important ones.
- James - [IMAGE]
(J.GRAY38, CAT30, TOP9, MSG:34/M530)
<<<<< James,
"""""
Thanx for your reply.
Actually, my interest in looking at the hex in the string was purely for
debugging purposes. This particular function is a filter for raw data
and somehow (thanks to Splat! and ORCA/Debugger I found the problem) it
was indexing past the end of an array under certain conditions. The array
is part of a structure and the next element was a pointer that would get
blasted when the indexing went too far. Easy to fix once I saw what was
happening :)
Eric Heim
(E.HEIM3, CAT30, TOP9, MSG:35/M530)
[EOA]
[LIB]//////////////////////////////
LIBRARY BIT BONANZA /
/////////////////////////////////
HOT Files You Can Download
""""""""""""""""""""""""""
By Tim Buchheim
[A2PRO.GELAMP]
o GREAT NEW FILES!
>>> GREAT NEW FILES! <<<
""""""""""""""""""""""""""
File #4871 MTL.PUB.SRC.BXY (ALL)
Uploaded on 10/28/95 by JUST.DAVE
About 124K (d/l time approx. 9 minutes @ 2400 baud)
This file is part of the release of METAL v1.09.07.
It contains the source code that was released with METAL v1.09.07.
Read MTL7.README.TXT (file #25957) in the A2 library for details.
File #4870 FOREACH.BXY (GS)
Uploaded on 10/19/95 by S.REEVES2
About 13K (d/l time approx. 1 minute @ 2400 baud)
This is a version of the UNIX shells' built-in "foreach" construction, for
iterating a series of commands over different values of a variable. It was
written by Sean McAfee (mcafee@umich.edu). Requires an Apple IIgs and
GNO 2.0 or higher (works with ORCA/Shell 2.0 too, but ORCA already has an
equivalent command).
File #4868 REZTHINGY.BXY V1.0B2 (GS)
Uploaded on 10/15/95 by B.WELLS5
About 5K (d/l time under 1 minute @ 2400 baud)
This Spectrum script will allow you to name resources in your REZ source
code and then run the script to generate all the rName resources for each
'named' resource. Cool, eh? :) This is just a very quick hack, so the
only documentation is what appears when you run the script. An example
REZ file is also included.
File #4867 HTMLEDIT.BXY (GS)
Uploaded on 10/14/95 by C.STILES3
About 81K (d/l time approx. 5 minutes @ 2400 baud)
Obtained from the Internet - source is Nova Scotia user group. See the
description on A2 for more info, or just donload it and extract the info.
Promotes the use of HTML. No doc file, but help button is available.
File #4864 PRSET1.0B1.BXY (GS)
Uploaded on 10/1/95 by R.ECKWEILER
About 19K (d/l time approx. 1 minute @ 2400 baud)
PRSet is an ORCA utility that allows configuring the .PRINTER driver
directly from the ORCA command line or from an exec file. By putting a
PRSET command in the LOGIN file for ORCA the printer may be configured
automatically each time ORCA is run. The program allows you to set all the
parameters normally set by the CDA or CDEV programs and has extensive
printer initialization string inputting capabilities.
[EOA]
[LOG]///////////////////////////////
LOG OFF //
//////////////////////////////////
GEnieLamp Information
"""""""""""""""""""""
o COMMENTS: Contacting GEnieLamp
o GEnieLamp STAFF: Who Are We?
GEnieLamp Information GEnieLamp is published on the 1st of every month
""""""""""""""""""""" on GEnie page 515. You can also find GEnieLamp on
the main menus in the following computing RoundTables.
RoundTable Keyword GEnie Page RoundTable Keyword GEnie Page
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
DigiPub DIGIPUB 1395 Atari ST ST 475
Macintosh MAC 605 IBM PC IBMPC 615
Apple II A2 645 Apple II Dev. A2PRO 530
Macintosh Dev. MACPRO 480 Geoworks GEOWORKS 1050
BBS BBS 610 CE Software CESOFTWARE 1005
Mini/Mainframe MAINFRAME 1145 Programming PROGRAMMING 1445
Data Comm. DATACOMM 1450 IBM PC Prog IBMPCPRO 617
PowerPC PPC 1435 PowerPCProg PPCPRO 1440
GEnieLamp is also distributed on CrossNet and many public and
commercial BBS systems worldwide.
o To reach GEnieLamp on Internet send mail to genielamp@genie.com
o Back issues of GEnieLamp are available in the DigiPub RoundTable
Library #2 on page 1395 (M1395;3). Internet users should use
the GEnie gopher (gopher.genie.com) which has most back issues
(but might be missing a few of them). After you connect to
gopher.genie.com, choose the "Magazines and newsletters" item
and then choose the menu item for the Apple II.
o GEnieLamp pays for articles submitted and published with online
GEnie credit time. Upload submissions in ASCII format to library
#31 in the DigiPub RoundTable on page 1395 (M1395;3) or Email it to
GENIELAMP. On Internet send it to: genielamp@genie.com
o We welcome and respond to all E-Mail. To leave comments,
suggestions or just to say hi, you can contact us in the DigiPub
RoundTable (M1395) or send GE Mail to John Peters at [GENIELAMP] on
page 200.
o If you would like to meet the GEnieLamp staff "live" we meet every
Wednesday night in the Digi*Pub Real-Time Conference at 9:00 EDT
(M1395;2).
o The Digital Publishing RoundTable is for people who are interested
in pursuing publication of their work electronically on GEnie or via
disk-based media. For those looking for online publications, the
DigiPub Software Libraries offer online magazines, newsletters,
short-stories, poetry and other various text oriented articles for
downloading to your computer. Also available are writers' tools and
'Hyper-utilties' for text presentation on most computer systems. In
the DigiPub Bulletin Board you can converse with people in the
digital publishing industry, meet editors from some of the top
electronic publications and get hints and tips on how to go about
publishing your own digital book. The DigiPub RoundTable is the
official online service for the Digital Publishing Association. To
get there type DIGIPUB or M1395 at any GEnie prompt.
>>> GEnieLamp STAFF <<<
"""""""""""""""""""""""
GEnieLamp o John Peters [GENIELAMP] Publisher
""""""""" o Mike White [MWHITE] Managing Editor
APPLE II o Doug Cuff [EDITOR.A2] EDITOR
"""""""" o Ray Pasold [R.PASOLD] A2 Staff Writer
o Charlie Hartley [A2.CHARLIE] A2 Staff Writer
A2Pro o Tim Buchheim [A2PRO.GELAMP] EDITOR
"""""
ATARI o Sheldon H. Winick [GELAMP.ST] ATARI EDITOR
""""" o Bruce Smith [B.SMITH123] EDITOR/TX2
o Mel Motogawa [M.MOTOGAWA] Atari Staff Writer
o Richard Brown [R.BROWN30] Atari Staff Writer
o Al Fasoldt [A.FASOLDT] Atari Staff Writer
o Timothy V. Steed [T.STEED1] Atari Staff Writer
o Lloyd E. Pulley [LEPULLEY] Atari Staff Writer
IBM o Sharon La Gue [SHARON.LAMP] IBM EDITOR
""" o Tika Carr [LAMP.MM] MULTIMEDIA EDITOR
o Susan M. English [S.ENGLISH1] Multimedia Graphics Artist
o Wayne & Chris Ketner[C.KETNER] IBM Staff Writers
MACINTOSH o Richard Vega [GELAMP.MAC] MACINTOSH EDITOR
""""""""" o Tom Trinko [T.TRINKO] Mac Staff Writer
o Bret Fledderjohn [FLEDDERJOHN] Mac Staff Writer
o Ricky J. Vega [GELAMP.MAC] Mac Staff Writer
POWER PC o Ben Soulon [BEN.GELAMP] POWER PC EDITOR
"""""""" o Eric Shepherd [SHEPPY] Power PC Staff Writer
WINDOWS o Bruce Maples [GELAMP.WIN] EDITOR
""""""" o Tika Carr [LAMP.MM] Windows Staff Writer
ETC. o Jim Lubin [J.LUBIN] Add Aladdin Scripts
"""" o Scott Garrigus [S.GARRIGUS] Search-ME!
o Mike White [MWHITE] (oo) / DigiPub SysOp
o John Peters [GENIELAMP] DigiPub SysOp
o Phil Shapiro [P.SHAPIRO1] Contributing Columnist
o Sanford E. Wolf [S.WOLF4] Contributing Columnist
o Douglas Parks [DELUXE] Contributing Columnist
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\////////////////////////////////////
Opinions expressed herein are those of the individual authors, and do
not necessarily represent opinions of GEnie Information Services,
GEnieLamp Online Magazines, or T/TalkNet Online Publishing. Bulletin
board messages are reprinted verbatim, and are included in this publi-
cation with permission from GEnie Information Services and the source
RoundTable. GEnie Information Services, GEnieLamp Online Magazines,
and T/TalkNet Publishing do not guarantee the accuracy or suitability
of any information included herein. We reserve the right to edit all
letters and copy.
Material published in this edition may be reprinted under the fol-
lowing terms only. Reprint permission granted, unless otherwise noted,
to registered computer user groups and not for profit publications.
All articles must remain unedited and include the issue number and
author at the top of each article reprinted. Please include the fol-
lowing at the end of all reprints:
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\///////////////////////////////////
The preceeding article is reprinted courtesy of GEnieLamp Online
Magazine. (c) Copyright 1995 T/TalkNET Publishing and GEnie Infor-
mation Services. Join GEnie now and receive $50.00 worth of online
credit. To join GEnie, set your modem to 9600 baud (or less) and half
duplex (local echo). Have the modem dial 1-800-638-8369 in the United
States or 1-800-387-8330 in Canada. When you see the U#= prompt,
type: JOINGENIE and hit the RETURN key. When you get the prompt
asking for the signup code, type DSD524 and hit RETURN. GEnie will
then ask you for your signup information. For more information call
(voice) 1-800-638-9636.
////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
[EOF]
ÿÿ
.