Norton Utilities For The Atari 8-bit
Continuing with the theme of my last post, I will now give my account of my adventures with my Atari 130XE 8-bit computer.
The Atari 8-bit was the first computer I owned. My mother bought it for me in 1984. This computer came equipped with 128-Kbytes of memory (which was 64-Kbytes more than the norm at the time), built-in Atari BASIC, a cartridge slot, and an expansion slot.
By the time Norton Utilities 7 came out for the IBM PC I already owned several, and SpartaDOS 3.2d (a command-line DOS) was already a hit with the Atari 8-bits. This was a great OS that allowed me to easily code command-line programs I was already coding on the IBM PC for the Atari 8-bit .
At that time I was working with huge .arc files (.arc is the extension of the archival shrinking program used before .zip came along) and when I needed to unerase some of these out of necessity I always ended-up damning the unerase command of SpartaDOS because it was so buggy. So I devised a plan to write my own. This idea later merged into a goal to convert many of the Norton Utilities command-line programs to the Atari 8-bit.
My language of choice on the Atari 8-bit was Action! by OSS, Inc. 1 Action! was easy to program in and generated some of the fastest and most compact code I have seen on the Atari 8-bits.
Here are a few lines of code of UnDel (my unerase version) written in Action! 2
SET $E = $2200
SET $491 = $2200
;SET $E = $2100
;SET $491 = $2100
;SET $495 = $A ; increase variable table
BYTE RTS = [$60]
; primitive system library routines
INCLUDE "D2:>SYS>SYSLIB.ACT"
; IO routines
INCLUDE "D2:>SYS>SYSIO.ACT"
; misc. routines
INCLUDE "D2:>UNERASE>SYSMISC.ACT"
; string routines
INCLUDE "D2:>UNERASE>SYSSTR.ACT"
; Modified SECTIO.ACT
INCLUDE "D2:>RTNS>MSectIO.Act"
; Modified BLKIO.ACT
INCLUDE "D2:>RTNS>MBlkIO.ACT"
; Modified REAL library
INCLUDE "D2:>UNERASE>MREAL.ACT"
; UnErase Code:
byte Version = $701, ; SpartaDOS Version
prompt = [0], ; prompt user before unerasing file
integrity, ; integrity flag
drive = [0], ; drive to read sectors from
UD_flag = [0], ; unerase dirs also
DO_flag = [28], ; dir open flag (update or read[list deleted])
dir_flag = [0], ; unerase as dir(1) or file(0)
A_flag = [0], ; attribute scan flag
a_bit, ; archive attribute scan (Set or Cleared)
ss, ; density of sectors (128 or 256)
sd, ; density of sectors for SectIO routines in MSectIO
wr, ; MSectIO write command — write or write with verify
n_a, ; three byte note (xio 38)
n_b,
n_c,
lsb, ; 24 bit numbers in lsb, nsb and msb format
nsb,
msb,
bit, ; bit to read or modify
byyte, ; byte who's bit will be read or modified
Key, ; used by the the GetKey function
CWD_flag = [0],
l
byte array arg1(30), ; comm-line argument
path(30),
bin(8), ; bin data from ml routine decbin
str_real(20), ; hold a string real-number
hold(128), ; do a cwd back to the user's cwd dir
boot(128), ; boot sector
BMaps(256), ; store bitmaps
SMaps(256), ; store sectormaps
fcomp(13), ; file1 for dir entry compare
cmpfile(13), ; file2 for dir entry compare
subdir(29), ; put the path
fname(13), ; and the filename
raw(24), ; holds raw dir entries
atEOL(1) = [$01 $9B], ; Atari EOL
INCLUDE "D2:>RTNS>DecBin.Act"
,
INCLUDE "D2:>RTNS>BinDec.Act"
card p, n, ts, fbm, cBMap = [0], BMap = [0], dosvec = 10,
UC_flag = [0] ; recover dir entry count flag
real rDensity, r256, r65, rnum1, rnum2, realr, ; real result
rBMap, bits
. . .
Proc Main()
byte num
;close(1) ; use when compiling in
; SpartaDOS 3.2x
device = 0 ; initialize ACTION!'s system device
error = MyError ; now give ACTION! the address of MyError Proc
ZCrName = dosvec + 3 ; ZCRNAME
Path(0) = 0
ValR( "65536″, r65 )
ValR( "256″, r256 )
ValR( "8″, bits )
pute()
printe( "UnErase Version 1.0 1-Jan-1996″ )
printe( " Copr. 1996, Nelson Nieves" )
pute()
; make sure that we are in SpartaDOS 3.2d or X:
if Version < $32 then
printe ("Not SpartaDOS 3.2d or X!")
if peek($700) <> 'S then ; if in another DOS give the user a chance to
GetKey() ; read the message
fi
Return
fi
;cmlinput() ; puts command line
; arguments into lbuf
; for debugging
num = NumArgs() ; get number of comm-line arguments
if num = 0 or num > 5 then
Usage()
Return
else
for l = 1 to num do
GetArgs(0, arg1)
if Proc_Args(arg1) = 0 then
Usage()
Return
fi
od
fi
if Path(0) = 0 then
printe("Must specify drive or path!")
Return
fi
PathParse( Path, subdir, fname )
if fname(0) = 0 then
scopy(fname, "*.*")
fi
;setblock( fcomp+1, 12, $20) ; put spaces in fcomp
for l = 0 to 12 do
fcomp(l) = $20
od
fcomp(0) = 8 ; set fcomp string to the length of 8
for l = 1 to fname(0) do
if fname(l) = '. then
scopys( bin, fname, l, l+4)
makestr(fcomp, bin, 0)
exit
else
fcomp(l)=fname(l)
fi
od
fcomp(0) = 12 ; just incase
fcomp(9) = '. ; just incase
SetUp()
ChkDisk()
_dir() ; do a dir? and put the result in hold
OpenDir()
if DO_flag = 28 then
if UC_flag = 0 then
pute()
print("No dir entry")
else
pute()
printc(UC_flag)
print(" dir entr")
if UC_flag < = 1 then
print("y")
else
print("ies")
fi
fi
printe(" recovered.")
else
if UC_flag = 0 then
printe("No deleted dir entries.")
fi
fi
User_cwd()
usr(dosvec, 0) ; exit to dos
Return
Many of these program survive today, mostly online in many of the Atari 8-bit archives and in one of my own Atari 8-bit websites.
One of the last programs I had started was a defragmentor for the Atari 8-bit. Because of the 128 Kbytes limit of the Atari 8-bit it was to be composed of two command-line programs to accomplish the task. The first program was to be the directory optimizer (this would have removed many of the deleted entries in the directories prior to running the defragmentor—and possibly freeing up sectors.) But by then, it was too late, the Atari 8-bit was already dead and I had no free time to continue investing my time in the project.
- On Wikipidea I noticed that the description given to Action! is that of a language similar to BASIC and C, this is wrong in my opinion, Action! has the best of both C and Pascal, not BASIC. [back]
- This is an older code, where I used a lot of floating point functions (which I later recoded into integer functions [in assembly] for a more compact and faster program). I lost the most recent versions of the codes to many of the programs, although the compiled binary versions of the programs on my website are the most recent versions. [back]
I agree with you: Action! looks like a mix of Pascal and C, with a few Basci genes (peek()). Its sintax looks so clean.
You know more than your CV shows. I guess you consider unnecessary (or or unfavourable) to mention your Atari programming experience.
Not unfavorable, I just never tought of putting it into my resume.
I loved Action! and it definitely was the best of both C and Pascal. I loved it’s speed of code execution, and flexibility in capability. I remember coding a “mouse” pointer (using joystick) for a Star Trek game I had worked on using custom character sets.