home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
215.lha
/
FixFD
/
ReadMe
< prev
next >
Wrap
Text File
|
1996-02-14
|
24KB
|
1,016 lines
To : Aspiring M68000 Programmers
From: Peter Wyspianski
Date: 01 Jan 89
As I was getting ready to archive my 'FixFD' utility, it occured to me that
some aspects of programming the Amiga would have been a LOT easier to learn if
I just had a few examples to look over.
I came to the Amiga programming enviroment from the MacIntosh. So I was no
stranger to the M68000 or the sort of things you have to do with it in such a
complex enviroment. Still, it has been a struggle. While writing this utility
I had to learn how to detect the user hitting 'ctrl-c' to abort the program.
No big deal, but I wasted a couple hours looking in the wrong places for the
information (the AmigaDOS manual and some magazines). Turns out it is not
really documented anywhere, at least not specifically.
But I wonder where I would be now if I was a complete novice M68000 programmer?
It's not like the 6502 days when you could just drop into a machine language
monitor and hand-code some instructions to see what they do (that is how I
first learned ML).
I have decided to include the source code for the main program. You may study
it, and even use the routines if you like. I just hope you learn something.
I have NOT included my 'Std_Macs68k' file. This file just contains a bunch of
macros that match my programming style. For example, if I am testing a
register for zero, I like to be able to code 'bz.s xxx' rather then the more
ambiguous 'beq.s xxx'. So in my macro file I have a macro called 'bz'.
I have also not included the 'dos_lib.i' file. This file can be created by
using FixFD like so:
>FixFD dos_lib.fd dos_lib.i
in my case, I then edited the dos_lib.i file to add a 'PREASM' option and ran
it through the assembler (CAPE68k from Inovatronics). This feature of CAPE
lets it inhale the 'INCLUDE' file without pausing to assemble it. A real
timesaver in larger projects. This step is entirely optional.
Finally, the code must be linked with Std_Startup.obj. This file is my
customized version of AStartup.obj. I have included 'Std_Startup.obj' but not
the source code for it. If you want to play around with FixFD, you could link
with AStartup.obj instead. Here is how you get the link to work:
>BLink with FixFD.link
if you don't happen to have the freely-redistributable 'BLink' then substitute
the name of your linker (probably 'ALink'). The file 'FixFD.link' is also
included. Take a look at it, because it expects to find everything in 'RAM:'.
Good luck! Remember to read the docs. And if you have any questions or
comments then please send me a postcard (my address is in the docs).
-Peter W.SHAR_EOF
cat << \SHAR_EOF > FixFD.asm
; file:FixFD.asm
;-----------------------------
; Fix FD
;-----------------------------
; A utility to convert FD files to EQU files.
;
; Copyright (c) 1988 by Peter Wyspianski
;
; Revision History
; ----------------
; 30 Dec 88 created
; 01 Jan 89 changed to use the 'dos_lib.i' file
;----------------------------------------
; Constants
null equ $00
bs equ $08
tab equ $09
lf equ $0a ; amiga eoln
cr equ $0d ; CR only
esc equ $1b
csi equ $9b ; control sequence introducer
; DOS Constants:
MODE_OLDFILE equ 1005
MODE_NEWFILE equ 1006
SIGBREAKB_CTRL_C EQU $0C
SIGBREAKB_CTRL_D EQU $0D
SIGBREAKB_CTRL_E EQU $0E
SIGBREAKB_CTRL_F EQU $0F
SIGBREAKF_CTRL_C EQU $1000
SIGBREAKF_CTRL_D EQU $2000
SIGBREAKF_CTRL_E EQU $4000
SIGBREAKF_CTRL_F EQU $8000
;**SIGBREAK_ANY equ $F000
SIGBREAK_ANY equ $1000
; Exec Base Offsets:
ThisTask EQU $114
; Task Control Structure Offsets:
TC_SIGRECVD EQU $1A
TC_SIGALLOC EQU $12
;----------------------------------------
; Includes
MACFILE "RAM:Std_Macs68k"
INCLUDE "RAM:dos_lib.i"
;----------------------------------------
; Publics
XDEF _main
XDEF Exit
;----------------------------------------
; Externals:
; from std.startup:
XREF _exit
XREF _stdin,_stdout,_SysBase,_DOSBase
;----------------------------------------
; The beginning
SECTION Main,CODE
; just a little something to brighten some file-zapper's day:
dc.b 'Be Happy!',null
cnop 0,2
;-------------------------------
; BCD_Left [18 Nov 88]
;
; - converts hex word to a string of one to five left justified BCD digits
; - string is null terminated
;
; Inputs : d0.w = hex word
; a0.l = starting address of string
; Outputs: all regs preserved
;
; Notes : - from 1 to five digits can be returned plus the zero termination
; for a total of up to six characters
; - starts by determining number of digits in the string
BCD_Left
pushm d0-d3/a0-a1
move.w #3,d2 ; # digits - 2
lea LBCDTAB,a1 ; point to ten thousands
1$ cmp.w (a1)+,d0 ; determine number of digits in result
bcc.s 2$ ; (ubge) taken if right size
dbra d2,1$ ; taken for 10K through 10
bra.s 6$ ; we have just a ones digit
2$ subq.l #2,a1 ; compensate for following pre-decrement
3$ move.w (a1)+,d1 ; d1=BCD digit weight
move.b #'0',d3 ; init digit to ASCII '0'
4$ cmp.w d1,d0 ; digit weight ? remainder
blt 5$ ; taken if done with this digit
addq.b #1,d3 ; inc BCD digit result
sub.w d1,d0 ; decrement total
bnz.s 4$ ; go for more
5$ move.b d3,(a0)+ ; stash digit
dbra d2,3$ ; next digit position
6$ or.b #'0',d0 ; form ones digit
move.b d0,(a0)+
clr.b (a0) ; form zero terminator
pullm d0-d3/a0-a1
rts
LBCDTAB dc.w 10000,1000,100,10
;----------------------------------------
; GetDec [30 Dec 88]
;
; - converts a decimal string to a hex value
;
; Inputs : a0 = ^ string
; Outputs: d0.l = value
;
; Reg Use: d1,a0-a1
;
; Calls : none
; Uses : none
;
; Notes : - Non-numeric input produces garbage (GIGO applies).
; - Excessively long strings cause wrap-around.
GetDec:
clr.l d0 ; result
1$ move.b (a0)+,d1 ; fetch next digit
bz.s 2$ ; if 'digit' is a null then all done
; here the running result is multiplied by ten:
asl.l #1,d0 ; x2
move.l d0,a1 ; save the x2 value (a1 = scratch)
asl.l #2,d0 ; x4 x8
add.l a1,d0 ; x8 + x2 = x10
; the latest 'units' digit is added to the result:
sub.b #'0',d1 ; force digit to range 0-9
add.l d1,d0 ; splice into result
bra.s 1$ ; and go for more!
2$ rts
;----------------------------------------
; PrStr [31 Dec 88] _stdout
; FPrStr [31 Dec 88] a file
;
; - sends a null terminated string to a file (_stdout)
;
; Inputs : a0 = ^string
; a1 = file handle (FPrStr only)
;
; Outputs: none
;
; Calls : Write (DOS.Library)
; Uses : _DOSBase (library base)
; _stdout
;
; Notes : exits via the call to Write
PrStr:
move.l _stdout,a1
FPrStr:
push.l a1 ; save file handle
move.l a0,a1 ; find the string length
1$ tst.b (a1)+
bnz.s 1$ ; loop until end of string
sub.l a0,a1 ; start-end+1 = len+1
sub.l #1,a1 ; fix the length
pull.l d1 ; recover file handle
move.l a0,d2 ; ^buffer
move.l a1,d3 ; length
move.l _DOSBase,a6
jmp _LVOWrite(a6) ; exit via this routine
;----------------------------------------
; ReadLn [31 Dec 88] from _stdin
; FReadLn [31 Dec 88] from a file
;
; - reads a line from a file (_stdin)
; - terminator (lf) is NOT stored
; - string is returned null-terminated
;
; Inputs : a0 = ^string buffer
; a1 = file handle (FReadLn only)
;
; Outputs: d0 = result: 1 = ok, 0 = eof, -1 = error
;
; Reg Use: d0-d3/a0-a2
;
; Calls : Read (DOS.Library)
; Uses : _DOSBase (library base)
ReadLn:
move.l _stdin,a1
FReadLn:
move.l a0,a2 ; keep ^buffer safe
move.l a1,a3 ; keep file handle safe
1$ move.l a3,d1 ; file handle
move.l a2,d2 ; ^buffer
move.l #1,d3 ; read one char
CallDOS Read
cmp.l #1,d0 ; what was returned?
bne.s 2$ ; exit if error or eof
move.b (a2)+,d1 ; fetch character and bump ^buffer
cmp.b #lf,d1 ; end of line?
bne.s 1$ ; taken if not
2$ move.b #null,-1(a2) ; null terminate the string
rts ; and exit
;----------------------------------------
; FileOpenError [31 Dec 88]
;
; - calls IoErr to get a specific error number for a failed file open.
; - prints an error message of the form:
;
; Error #xxx opening file "yyyy".
;
;
; Inputs : a0 = ^filename
; Outputs: none
;
; Reg Use: d0-d1/a0-a1
;
; Calls : IoErr (DOS.Library)
; BCD_Left
; PrStr
; Uses : _DOSBase (library base)
; BCDBuff
FileOpenError:
push.l a0 ; save ^file name
CallDOS IoErr ; must do this FIRST
push.w d0 ; save the bad news
lea BadOpenMsg,a0
jsr PrStr
pull.w d0 ; recover error number
lea BCDBuff,a0
jsr BCD_Left
lea BCDBuff,a0
jsr PrStr ; show the number
lea BadOpenMsg1,a0 ; second half of error message
jsr PrStr
pull.l a0 ; fetch ^file name
jsr PrStr
lea BadOpenMsg2,a0 ; third half of error message
jsr PrStr
rts
*----------------------------------------
* Main [30 Dec 88]
*
* here is a picture of the entry stack:
*
* 12 --- not ours!
* 8 ^argvArray pointer to argvArray
* 4 argc argument count
* sp 0 RA our return address
_main:
clr.l TheError ; default good return
move.l sp,savesp ; to ensure that we clean up on exit
pull.l ReturnAddr ; just in case we need it...
; make a pointer to our TC_SIGRECVD:
move.l _SysBase,a0 ; base of the Exec library
move.l ThisTask(a0),a0 ; ^Task Control Structure (that's us!)
lea TC_SIGRECVD(a0),a0 ; ^the flags
move.l a0,TaskSigs ; save the pointer for later
; and we're off:
lea GreetMsg,a0 ; say hello
jsr PrStr
pull.l argc ; argc (argument count)
pull.l argv ; ^argv (argument array)
move.l argc,d0 ; argv format: <name> <source> <dest>
cmp.l #3,d0 ; we need three arguments...
blt.l Help ; ...taken if 'confused user' error!
move.l argv,a0 ; fetch ^argv
move.l 4(a0),a0 ; point to first argument
move.l a0,SName ; save ^source file name
move.l argv,a0 ; fetch ^argv
move.l 8(a0),a0 ; point to second argument
move.l a0,DName ; save ^dest file name
; open the input file:
move.l SName,d1
move.l #MODE_OLDFILE,d2 ; must already exist
CallDOS Open
move.l d0,sfile ; save source file handle
bnz.s 1$ ; taken if ok
; handle problems opening the input file:
move.l SName,a0
jsr FileOpenError
move.l #30,TheError
bra.l Exit ; bye!
; open the output file:
1$ move.l DName,d1
move.l #MODE_NEWFILE,d2
CallDOS Open
move.l d0,dfile ; save dest file handle
bnz.s ScanFD ; taken if ok
; handle problems opening the output file:
move.l DName,a0
jsr FileOpenError
move.l #30,TheError
bra.l Exit2
; read lines of the input file until EOF is true:
ScanFD:
; If the output file is acutally the tube then we don't want
; line numbers cluttering the display:
move.l dfile,d1 ; output file handle
CallDOS IsInteractive
move.b d0,TubeOut ; -1 = yeah, 0 = nope
lea HeaderMsg,a0
move.l dfile,a1 ; output file handle
jsr FPrStr
move.l DName,a0
move.l dfile,a1 ; output file handle
jsr FPrStr
lea HeaderMsg1,a0
move.l dfile,a1 ; output file handle
jsr FPrStr
tst.b TubeOut ; skip screen formatting if outfile...
bnz.s 1$ ; ... is connected to the tube.
lea StatusMsg,a0
jsr PrStr
lea CursorOff,a0
jsr PrStr
1$ move.w line,d0 ; bump line number
add.w #1,d0
move.w d0,line
tst.b TubeOut ; gonna use the tube?
bnz.s 8$ ; taken if not (being used by out file)
lea BCDBuff,a0 ; convert line number to a dec string
jsr BCD_Left
lea BCDBuff,a0 ; show the line number
jsr PrStr
; This gets REAL fancy by adding one 'bs' to StrBuff for every
; non-null char in BCDBuff:
lea BCDBuff,a0
lea StrBuff,a1
2$ move.b #bs,(a1)+ ; put one in there
tst.b (a0)+ ; check for a null
bnz.s 2$ ; taken if not
move.b #null,-1(a1) ; kill the last bs and null terminate
lea StrBuff,a0 ; backup
jsr PrStr
8$ move.l TaskSigs,a0 ; see if the user hit ctrl-c thru ctrl-f
move.l (a0),d0 ; d0 = SigsRecvd
and.l #SIGBREAK_ANY,d0 ; mask all but ours
bnz.l Abort ; taken if we hit
lea StrBuff,a0 ; fetch a line from the input file
move.l sfile,a1
jsr FReadLn
tst.l d0 ; see what's up!
bz.l Exit0 ; taken if EOF
bmi.l Exit0 ; taken if error
;----------------------------------------
; determine what sort of line it is here:
;
; # = option (process further)
; A-Z,a-z,'_','.' = FD entry (strip)
;
; all others are ignored ('*',';', and anything else)
move.b StrBuff,d0 ; fetch first char
cmp.b #'#',d0 ; option?
beq 6$ ; taken if so
cmp.b #'.',d0 ; fd entry?
beq.s 3$ ; taken if so
cmp.b #'_',d0 ; fd entry?
beq.s 3$ ; taken if so
cmp.b #'A',d0 ; fd entry?
blt.l 1$ ; taken if NOT (ignore)
or.b #$20,d0 ; force to lowercase
cmp.b #'z',d0 ; fd entry?
bgt.l 1$ ; taken if NOT (ignore)
;---------------------------------------------------------------
; strip the line (scan for a space, open paren, or end of line)
; there are NO blank lines here (eliminated above):
;
3$ lea LVOMsg,a0 ; prefix the routine name with '_LVO'
move.l dfile,a1
jsr FPrStr
lea StrBuff,a0
5$ move.b (a0)+,d0 ; fetch a char and bump pointer
bz.s 4$ ; taken if end of line
cmp.b #' ',d0 ; space?
beq.s 4$ ; taken if so
cmp.b #'(',d0 ; open paren?
bne.s 5$ ; taken if so
4$ move.b #null,-1(a0) ; null-terminate right AT the 1st excess char
pea -1(a0) ; save ^end of string (for later)
lea StrBuff,a0 ; show the line
move.l dfile,a1 ; output file handle
jsr FPrStr
lea StrBuff,a0
pull.l d0 ; fetch ^end of string
;*** sub.l a0,d0 ; d0 = string len
;*** lea EQU8Msg,a0 ; <tab> <tab> equ <tab>-
;*** cmp.l #8,d0 ; seven chars or less?
;*** blt.s 44$ ; taken if so (output extra tab)
lea EQUMsg,a0 ; <tab> equ <tab>-
44$ move.l dfile,a1 ; output file handle
jsr FPrStr
move.w bias,d0 ; convert the bias to a decimal string
lea BCDBuff,a0
jsr BCD_Left
lea BCDBuff,a0
move.l dfile,a1 ; output file handle
jsr FPrStr ; show the bias
lea EQUMsg1,a0 ; finish the line off
move.l dfile,a1 ; output file handle
jsr FPrStr
move.w #6,d0 ; bump bias
add.w d0,bias
bra.l 1$ ; and go again!
;----------------------------------------
; check for the '##bias' option:
6$ move.l StrBuff+2,d0 ; fetch 4 chars (should be 'bias')
or.l #$20202020,d0 ; force to lowercase
cmp.l #'bias',d0
bne.l 1$ ; ignore if not the option
; scan for a space:
lea StrBuff+6,a0 ; skip the '##bias'
7$ move.b (a0)+,d0 ; fetch a char and bump pointer
bz.l 1$ ; taken if end of line (ignore)
cmp.b #' ',d0 ; space?
bne.s 7$ ; taken if not
; fetch and show the bias:
jsr GetDec ; a0 should be pointing at the number
move.w d0,bias ; save it
; show the 'bias = ' message:
lea BiasMsg,a0
move.l dfile,a1 ; output file handle
jsr FPrStr
move.w bias,d0 ; convert the bias to a decimal string
lea BCDBuff,a0
jsr BCD_Left
lea BCDBuff,a0
move.l dfile,a1 ; output file handle
jsr FPrStr ; show the bias
lea BiasMsg1,a0
move.l dfile,a1 ; output file handle
jsr FPrStr
bra.l 1$ ; go for another line
;-------------------------------------------
; show the help message and exit:
Help:
lea HelpMsg,a0
jsr PrStr
bra.s Exit
;-------------------------------------------
; show the 'break...' message and exit:
Abort:
lea BreakMsg,a0
jsr PrStr
bra.s ExitA
;-----------------------------
; Exit routines [30 Dec 88]
;
Exit0:
lea DoneMsg,a0
jsr PrStr
ExitA:
lea CursorOn,a0
jsr PrStr
Exit1:
move.l dfile,d1 ; close the dest file
CallDOS Close
Exit2:
move.l sfile,d1 ; close the source file
CallDOS Close
Exit:
push.l TheError ; error code
jsr _exit ; and wind it up
;----------------------------------------
; constants
SECTION Constants,DATA
GreetMsg:
dc.b lf
dc.b csi,'0;33;40m'
dc.b ' FixFD '
dc.b csi,'0;31;40m'
dc.b 'v1.0 - Copyright ',$a9
dc.b ' 1988, Peter Wyspianski',lf,lf
dc.b null
HelpMsg
dc.b ' This utility takes an ''.FD'' file and generates a set of',lf
dc.b ' EQUates that can be used by an assembler.',lf,lf
dc.b ' Parameters: source_file dest_file.',lf,lf
dc.b ' See the docs for more info! -PW',lf,lf,null
BadOpenMsg:
dc.b csi,'0;33;40m'
dc.b ' Error '
dc.b csi,'0;31;40m'
dc.b '#'
dc.b null
BadOpenMsg1:
dc.b ' opening file "',null
BadOpenMsg2:
dc.b '"',lf,lf,null
CursorOff
dc.b csi
dc.b '0 p'
dc.b null
CursorOn
dc.b csi
dc.b ' p'
dc.b null
StatusMsg:
dc.b ' Reading line '
dc.b null
DoneMsg
dc.b lf,lf
dc.b csi,'0;33;40m'
dc.b ' Finished.'
dc.b csi,'0;31;40m'
dc.b lf,lf,null
BreakMsg
dc.b lf,lf
;*** dc.b csi,'0;33;40m'
dc.b '*** BREAK'
;*** dc.b csi,'0;31;40m'
dc.b lf,lf,null
HeaderMsg
dc.b '; file:',null
HeaderMsg1
dc.b lf
dc.b ';',lf
dc.b '; generated by FixFD v1.0',lf
dc.b ';',lf
dc.b null
BiasMsg
dc.b '; Bias = ',null
BiasMsg1
dc.b lf
dc.b ';',lf
dc.b null
LVOMsg
dc.b '_LVO',null
EQU8Msg
dc.b tab
EQUMsg
dc.b tab
dc.b 'equ -'
dc.b null
EQUMsg1
dc.b lf
dc.b null
;----------------------------------------
; Uninitialized storage
SECTION Variables,BSS
TaskSigs ds.l 1 ; pointer to our TC_SIGRECVD
TheError ds.l 1 ; error return code
SName ds.l 1 ; ^source file name
DName ds.l 1 ; ^dest file name
sfile ds.l 1 ; source file handle
dfile ds.l 1 ; dest file handle
savesp ds.l 1 ; entry stack pointer
argc ds.l 1 ; argument count
argv ds.l 1 ; argument array pointer
ReturnAddr ds.l 1 ; program return address
bias ds.w 1 ; library entry bias
line ds.w 1 ; current line number
TubeOut ds.b 1 ; -1 = yes, 0 = nope
ds.b 1 ; alignment
BCDBuff ds.b 6 ; bcd string buffer
StrBuff ds.b 256 ; longest possible string
ENDSHAR_EOF
cat << \SHAR_EOF > FixFD.docs
FixFD v1.0
User Manual
Copyright (C) 1988 by Peter Wyspianski
[31 Dec 88]
----------------------
Please Read The Manual
----------------------
The FixFD utility is not complicated, but please take a couple minutes to read
through this manual before you try it. Thanks!
--------
Abstract
--------
FixFD is a utility for the Amiga series of computers that reads an '.FD' file
to produce an assembler 'include' file.
-----------
Legal Stuff
-----------
Amiga is a trademark of Commodore-Amiga, Inc.
The author is in no way connected with Commodore-Amiga, Inc.
The FixFD utility package, consisting of the program and documentation file, is
copyrighted. Permission is granted for NON-COMMERCIAL distribution of
UNMODIFIED copies of the entire package. All other rights are reserved.
Distribution of separate parts of the package, or of modified copies is
specifically prohibited. Failure to abide by these rules may result in a fine,
and/or jail term. Additionally you may get a guilty conscience and I certainly
won't visit you. Pass the word, pass this program!
-----------------------
Who Needs This Utility?
-----------------------
If you are an Amiga assembly language programmer (or want to be), then read on.
Otherwise, this utility is NOT for you (sorry)!
-----------
The Problem
-----------
When you're programming in assembly language, the most common way to define a
'Library Vector Offset' (LVO) is to use the XLIB macro like so:
XLIB Open ; DOS.Library
XLIB Close ; DOS.Library
where the 'XLIB' macro looks something like this:
XLIB macro ; <routine name>
xref _LVO\1
endm
so by the time the assembler has sorted out those first couple of definitions
here is what you got:
xref _LVOOpen
xref _LVOClose
Later on in the program you may want to call the 'Open' routine:
move.l DOSBase,a6
jsr _LVOOpen(a6)
Of course most of us use a macro for those lines. But here is a question -
just where IS the actual value of the symbol '_LVOOpen' defined? It is defined
in the scanned library 'Amiga.Lib'!
The problem is that Amiga.Lib is about 80K bytes long, and contains a LOT of
things besides the _LVO definitions. Having the _LVOs defined in Amiga.Lib
requires that you ALWAYS link your code with Amiga.Lib. This effectively
neutralizes assemblers that produce loadable object files. It also makes for
some very long link times.
------------
The Solution
------------
The ideal solution to the problem of having the LVOs defined in Amiga.Lib is to
just equate them to their proper values:
_LVOOpen EQU -30
_LVOClose EQU -36
Now you don't have to link with Amiga.Lib and the assembler will probably get
done a bit sooner as it doesn't have to do as much work. To get these equates
you simply use FixFD!
------------
What It Does
------------
The Extras disk includes a drawer called 'FDx.x' (where x.x is the operating
system revision, currently '1.3'. Within this drawer are a number of files
whose names end with '.FD'. These '.FD' files all have a standard format.
They completely define all the LVOs within a particular library. The '.FD'
files are updated with every new revision of the operating system.
FixFD simply reads an '.FD' format file and cranks out a file that your
assembler can read (using 'INCLUDE'). And thats all there is to it!
You have a lot of choices when it comes to putting the resultant 'include'
files to use. Adding a bunch of 'INCLUDE' statements is one possibility. Or
you could merge them into one big include file. If your assembler supports
'preassembled symbols' then you can preassemble the LVO file(s) for lightning
assembly speed!
I like to have all the LVOs in one big file. That way I can use the cut-and-
paste features of my text editor to put just the LVOs I need right into the
assembly file I'm working on.
There is probably a utility somewhere out there that does exactly the same
thing as FixFD. Too bad I haven't seen it (yet)! So here is my contribution.
Incidentally, it would have been far quicker to write this in something like
BASIC, but I simply wanted some practice at working with DOS files from
assembly.
-----------
Using FixFD
-----------
From the CLI (Command Line Interpreter) or Shell type:
>fixfc source_file dest_file
where 'source_file' is the name of the '.FD' file you want to read
and 'dest_file' is the name of the new file you want to make
You can use an asterix ('*') for the dest file, to send output to the CLI
window. In that case the fancy line number display is suppressed so it doesn't
tangle up the output.
FixFD can be aborted in the usual way (ctrl-c). And if you forget one of the
file names (or use '?'), you get a little blurb reminding you what to do.
It DOESN'T work from WorkBench so don't try it (crashes the system). I could
make it WorkBench compatible but why bother?
Thats about it. I sure hope you like it!
--------------------
So How Does It Work?
--------------------
[This section is for the curious; it may be safely skipped by others.]
FixFD scans each line of the input file looking for one of the following:
##bias xx
Where xx is a decimal number 0-65535. Sets the base from which subsequent LVOs
are calculated. Defaults to zero. The usual value is 30.
<LVO name> <whatever>
An LVO name is any line that starts with one of these characters:
a-z, A-Z, period ('.'), underline ('_')
When an LVO name is found, the line is scaned for an open paren ('(') or space.
If one is found, the line is chopped from that point on. In any case, the LVO
name is written to the dest file with the prefix '_LVO'. Following the name is
a tab, the word 'equ', another tab, and the decimal offset of the LVO.
All other lines (including blank lines, and lines beginning with ';' or '*')
are ignored.
-------------------------
Send Postcards Not Money!
-------------------------
The Author enjoys getting mail. Especially picture post cards. If you like
this program, hate it, or want to see some improvements, please send me a
post card:
Peter Wyspianski
5-10A Brock Cres
Kingston, Ont
CANADA K7K 5K6
Don't bother sending money. However, all offers of employment will be
seriously considered.
-----------------
End of the Manual
-----------------
Congradulations on having read this far. Current research indicates that you
are one of only 9.23% of users who bother to read the manual.
-------------------------
Technical Details/Credits
-------------------------
FixFD is written in M68000 Assembly Language. Total development time was about
eight hours, including writing this doc file. I had to write most of the DOS
file code from scratch. I already had the decimal conversion and formatting
routines.
Some of the better products used in the development of this utility include:
CAPE 68010 Assembler (Inovatronics)
BLink (Software Distillery)
Uedit (Rick Stiles)
(The preceeding was an unsolicited endorsement).
Special Thanks: Sharon W.