home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
fish
/
programming
/
patchcompiler
/
source
/
patchstarcompiler.ass
< prev
next >
Wrap
Text File
|
1991-01-16
|
24KB
|
1,161 lines
opt l+
XREF PATCH_MODULE_END,PATCH_MODULE_START
XREF.l PATCH_MODULE_SIZE
; V19
;
; PatchStartCompiler
;
; © 1990 Roger Fischlin, Steigerwaldweg 6, 6450 Hanau 7, Germany
;
incdir "ram:include/"
include exec/memory.i
include exec/exec_lib.i
include exec/interrupts.i
include libraries/dos_lib.i
include libraries/dos.i
include libraries/dosextens.i
DOS macro ; one library, one macro .....
move.l a5,a6
jsr _LVO\1(a6)
endm
DOS_TEXT macro
lea.l .Text\@(pc),a0
moveq.l #.TextEnd\@-.Text\@,d0
bsr CLI_Text
bra.s .Label\@
.Text\@ dc.b \1
.TextEnd\@
even
.Label\@ tst d0
endm
PSC_ERROR macro
lea.l .Text\@(pc),a0
moveq.l #.TextEnd\@-.Text\@,d0
bsr CLI_Text
bra.s .Label\@
.Text\@ dc.b " ERROR : "
dc.b \1
dc.b 10
.TextEnd\@
even
.Label\@ tst d0
endm
clr.b -1(a0,d0)
move.l a0,CommandString
lea dosname(pc),a1 ; open DOS
moveq.l #33,d0
CALLEXEC OpenLibrary
move.l d0,a5
tst.l d0
beq NoDOS
bsr Main
move.l a5,a1 ; close DOS
CALLEXEC CloseLibrary
NoDOS moveq.l #0,d0
rts
dosname DOSNAME
CommandString dc.l 0
Source_FH dc.l 0
Object_FH dc.l 0
Info_FH dc.l 0
LineCounter dc.l 0
BEGINCounter dc.l 0
LastIF dc.b 0
InfoName dc.l 0
SourceName dc.l 0
PatchName dc.l 0
even
Main bsr COMMAND ; check args
tst.w d0
bmi INFO
DOS_TEXT <10,$9b,"4m"," PatchStar - Compiler V1.00 © 1990 by Roger Fischlin ",$9b,"0m",10,10>
bne .Error
move.l PatchName(pc),d1 ; open object file
move.l #MODE_NEWFILE,d2
DOS Open
move.l d0,Object_FH
bne.s .Label2
DOS_TEXT <"couldn't open object file !",10>
bra .Error
.Label2 DOS_TEXT <$9b,"1;32m"," 1.Writing patch module",10,$9b,"0;31m">
bsr WRITE_MODULE
move.w d0,d6
DOS_TEXT <" done.",10,10>
tst.w d6 ; error ?
bne DeleteObject
DOS_TEXT <$9b,"1;32m"," 2.Writing info string",10,$9b,"0;31m">
bsr WRITE_INFO
move.w d0,d6
DOS_TEXT <" done.",10,10>
tst.w d6 ; error ?
bne DeleteObject
DOS_TEXT <$9b,"1;32m"," 3.Compiling",10,$9b,"0;31m">
bsr COMPILE_SOURCE
move.w d0,d6
DOS_TEXT <10," done.",10,10>
tst.w d6 ; error ?
bne.s DeleteObject
DOS_TEXT <$9b,"1;32m"," 4.Saving as executable",10,$9b,"0;31m">
bsr EXECUTABLE
move.w d0,d6
DOS_TEXT <" done.",10,10>
tst.w d6 ; error ?
bne.s DeleteObject
move.l Object_FH(pc),d1 ; close object file
DOS Close
.Error rts
DeleteObject move.l Object_FH(pc),d1 ; close object file
DOS Close
move.l PatchName(pc),d1 ; delete object
DOS DeleteFile
DOS_TEXT <10,10>
rts
;
; COMPILE SOURCE
;
COMPILE_SOURCE move.l SourceName(pc),d1 ; open source file
move.l #MODE_OLDFILE,d2
DOS Open
move.l d0,Source_FH
bne.s .Label1
PSC_ERROR <"couldn't open source file !",10>
bra NoSource
.Label1 clr.l LineCounter
clr.b LastIF
NextLine moveq.l #0,d0 ; check if CTRL-C
moveq.l #0,d1
CALLEXEC SetSignal
btst #12,d0
beq.s .NoUserBreak
DOS_TEXT <" User break .",10> ; write msg
bra COMP_Error
.NoUserBreak addq.l #1,LineCounter
bsr WriteLine ; write current line number
bsr ReadLine ; get next line
tst.b Line ; end of file ?
beq COMP_CloseSource
tst d0
beq .NoError ; error ?
bmi .DosError
PSC_ERROR <"Line too long !">
bra COMP_Error
.DosError PSC_ERROR <"DOS error !">
bra COMP_Error
.NoError lea.l Line(pc),a0
bsr NextCommand ; skip spaces etc.
tst d0
beq NextLine ; no more commands...
move.b (a0)+,d0 ; a0 ^command
bsr UpCase ; upcase
cmp.b #"B",d0 ; which command ?
beq BEGIN
tst.b LastIF ; if the last command is IF, the next one must be BEGIN !
beq.s .NotIF
PSC_ERROR <"IF without BEGIN !"> ; write error msg
bra DeleteObject
.NotIF cmp.b #"E",d0
beq END
cmp.b #"Q",d0
beq QUIT
cmp.b #"T",d0
beq TEXT
cmp.b #"P",d0
beq PATCH
cmp.b #"C",d0
beq CHECK
cmp.b #"I",d0
beq _IF
subq.l #1,a0
bra PATCH_2 ; patch ? without "PATCH"
SytaxError PSC_ERROR <"sytax error !">
bra COMP_Error
DOSError PSC_ERROR <"DOS error !">
bra.s COMP_Error
COMP_CloseSource
tst.l BEGINCounter ; check if there are more BEGINs without ENDs
beq.s .OK
PSC_ERROR <"BEGIN without END !",10>
bra.s COMP_Error
.OK move.l Object_FH(pc),d1 ; write END OF PATCH
move.l #EOP,d2
moveq.l #2,d3
DOS Write
cmp.l d0,d3
bne DOSError
move.l Source_FH(pc),d1
DOS Close
moveq.l #0,d0 ; no error
rts
COMP_Error move.l Source_FH(pc),d1
DOS Close
NoSource moveq.l #-1,d0 ; error
rts
EOP dc.b ".",0
even
;
; Write info string
;
INFO lea.l .String(pc),a0
move.l #.StringEnd-.String,d0
bra CLI_Text
.String dc.b 10,10," ",$9b,"4;31;42m"
dc.b " PatchStar - Compiler V1.00 "
dc.b $9b,"0;31;40m",10,10
dc.b " This program is ",$9b,"1m","FREEWARE",$9b,"0m"," !",10
dc.b " © 1990"
dc.b $9b,"0;33m"
dc.b " Roger Fischlin, Steigerwaldweg 6, D-6450 Hanau 7, Germany",10
dc.b $9b,"0;31m",10
dc.b " Usage : PSCompiler <info file> <source file> <patch>",10,10
.StringEnd
even
;
; Write Text to CLI
;
CLI_Text movem.l a0/d0,-(sp)
DOS Output ; get handle to CLI window
move.l d0,d1
move.l (sp)+,d3
move.l (sp)+,d2
DOS Write
cmp.l d0,d3 ; write error
beq.s .OK
moveq.l #-1,d0
rts
.OK moveq.l #0,d0
rts
;
; WriteLine
;
WriteLine lea.l .Number(pc),a0
move.l LineCounter(pc),d0
bsr .MakeASCII
move.l a0,d0
lea.l .LineText(pc),a0
sub.l a0,d0
bra CLI_Text
.MakeASCII moveq.l #10-1,d2
moveq.l #0,d3
lea.l .Potenzen(pc),a1
.Label1 move.b #"0"-1,d1
.Label2 addq #1,d1
sub.l (a1),d0
bcc.s .Label2
add.l (a1)+,d0
tst.b d2
beq.s .Label3
cmp.b #"0",d1
beq.s .Label4
moveq.l #1,d3
bra.s .Label3
.Label4 tst.b d3
beq.s .Label5
.Label3 move.b d1,(a0)+
.Label5 dbra d2,.Label1
rts
.Potenzen dc.l 1000000000
dc.l 100000000
dc.l 10000000
dc.l 1000000
dc.l 100000
dc.l 10000
dc.l 1000
dc.l 100
dc.l 10
dc.l 1
.LineText dc.b 10,$9b,$41," Line : "
.Number ds.b 12
;
; GetLong
;
; input : a0 ^string
;
; result : a0 ^end of number+1
; d0 number
; d1 0 OK
; 1 Overflow
; -1 error
;
GetLong movem.l d3-d3/a1-a3,-(sp)
bsr.s .Main
movem.l (sp)+,d3-d3/a1-a3
rts
.Main moveq.l #0,d0
moveq.l #0,d1
moveq.l #0,d2
.Label1 move.b (a0)+,d3
cmp.b #" ",d3
beq.s .Label1
cmp.b #9,d3
beq.s .Label1
cmp.b #"$",d3
beq .Hex
cmp.b #"%",d3
beq .Bin
cmp.b #"@",d3
beq .Octal
cmp.b #"-",d3
beq.s .Negativ
cmp.b #"9",d3
bhi .Fehler
cmp.b #"0"-1,d3
bhi .Dezimal
.Fehler subq.l #1,a0
moveq.l #-1,d1
rts
.Negativ tst.b d2
bne.s .Fehler
moveq.l #1,d2
bra .Label1
.Dezimal subq.l #1,a0
move.l a0,a1
.Label_D2 move.b (a0)+,d3
cmp.b #"9",d3
bhi.s .Label_D3
cmp.b #"0"-1,d3
bhi.s .Label_D2
.Label_D3 lea.l .Data10(pc),a2
subq.l #1,a0
move.l a0,a3
.Label_D5 move.l (a2)+,d4
beq.s .Overflow
moveq.l #0,d3
move.b -(a3),d3
sub.b #"0"+1,d3
bmi.s .D_Zero
.Label_D4 add.l d4,d0
dbra d3,.Label_D4
.D_Zero cmp.l a3,a1
bne.s .Label_D5
.Vorzeichen tst.b d2
beq.s .NotNegative
tst.l d0
bmi .Overflow
neg.l d0
.NotNegative moveq.l #0,d1
rts
.Data10 dc.l 1
dc.l 10
dc.l 100
dc.l 1000
dc.l 10000
dc.l 100000
dc.l 1000000
dc.l 10000000
dc.l 100000000
dc.l 1000000000
dc.l 0
.Overflow moveq.l #1,d1
rts
.Bin move.b (a0)+,d3
cmp.b #"0",d3
beq.s .Label_B1
cmp.b #"1",d3
bne .Fehler
.Label_B1 lea.l -1(a0),a1
.Label_B2 move.b (a0)+,d3
cmp.b #"1",d3
beq.s .Label_B2
cmp.b #"0",d3
beq.s .Label_B2
subq.l #1,a0
move.l a0,a2
moveq.l #0,d1
.Label_B3 move.b -(a2),d3
cmp.b #"0",d3
beq.s .B_Zero
bset d1,d0
.B_Zero addq.l #1,d1
cmp.b #32,d1
bhi.s .Overflow
cmp.l a2,a1
bne.s .Label_B3
bra .Vorzeichen
.Octal move.b (a0)+,d3
cmp.b #"7",d3
bhi .Fehler
cmp.b #"0"-1,d3
bls .Fehler
lea.l -1(a0),a1
.Label_O2 move.b (a0)+,d3
cmp.b #"7",d3
bhi.s .Label_O3
cmp.b #"0"-1,d3
bhi.s .Label_O2
.Label_O3 lea.l .Data8(pc),a2
subq.l #1,a0
move.l a0,a3
.Label_O5 move.l (a2)+,d4
beq.s .Overflow
moveq.l #0,d3
move.b -(a3),d3
sub.b #"0"+1,d3
bmi.s .O_Zero
.Label_O4 add.l d4,d0
dbra d3,.Label_O4
.O_Zero cmp.l a3,a1
bne.s .Label_O5
bra .Vorzeichen
.Data8 dc.l @1
dc.l @10
dc.l @100
dc.l @1000
dc.l @10000
dc.l @100000
dc.l @1000000
dc.l @10000000
dc.l @100000000
dc.l @1000000000
dc.l @10000000000
dc.l 0
.Hex move.b (a0)+,d3
bsr.s .Nibble
bmi .Fehler
lea.l -1(a0),a1
.Label_H2 move.b (a0)+,d3
bsr.s .Nibble
bpl.s .Label_H2
subq.l #1,a0
move.l a0,a2
moveq.l #0,d1
.Label_H3 move.b -(a2),d3
bsr .Nibble
lsl.l d1,d4
add.l d4,d0
addq.l #4,d1
cmp.b #32,d1
bhi .Overflow
cmp.l a2,a1
bne.s .Label_H3
bra .Vorzeichen
.Nibble moveq.l #0,d4
cmp.b #"a"-1,d3
bls.s .N1
cmp.b #"f",d3
bhi.s .N_Error
sub.b #"a"-"A",d3
.N1 sub.b #"0",d3
cmp.b #9,d3
bls.s .Ziffer
sub.b #"@"-"9",d3
cmp.b #$f,d3
bhi.s .N_Error
.Ziffer move.b d3,d4
rts
.N_Error moveq.l #-1,d4
rts
;
; check whole command word
;
CheckWhole move.l (sp)+,a3 ; get return address
.Label1 move.b (a1)+,d1
beq.s .Exit
move.b (a0)+,d0 ; next character
beq SytaxError
bsr UpCase
cmp.b d1,d0 ; compare characters
bne SytaxError
bra.s .Label1
.Exit jmp (a3) ; return
;
; UpCase d0
;
UpCase cmp.b #"a"-1,d0 ; range "a"-"z"
bls.s .Exit
cmp.b #"z",d0
bhi.s .Exit
sub.b #"a"-"A",d0
.Exit rts
;
; Read line from Source
;
ReadLine moveq.l #(512/4)-1,d0 ; clear buffer
lea.l Line(pc),a0
.Label1 clr.l (a0)+
dbra d0,.Label1
move.l #Line,d2
.Loop move.l Source_FH(pc),d1 ; read one byte
moveq.l #1,d3
DOS Read
tst.l d0
beq.s .EndOfFile
cmp.l d3,d0
bne.s .ReadError
move.l d2,a0
cmp.l #Line,a0 ; first byte ?
bne.s .Label2
cmp.b #" ",(a0) ; skip spaces & tabs in front of command
beq.s .Loop
cmp.b #9,(a0)
beq.s .Loop
.Label2 cmp.b #10,(a0) ; end of line ?
beq.s .Ok
addq.l #1,d2
cmp.l #Line+512,d2 ; end of buffer ?
bne.s .Loop
moveq.l #1,d0 ; line too long !!!
rts
.EndOfFile
.Ok moveq.l #0,d0 ; no error
rts
.ReadError moveq.l #-1,d0 ; dos error
rts
;
; get pointer to next command (skip spaces ...)
;
; return d0 0 empty line
; 1 command line
; a0 : ^command
NextCommand move.b (a0)+,d0
beq.s .EndOfLine
cmp.b #10,d0 ; LF ?
beq.s .EndOfLine
cmp.b #" ",d0 ; space ?
beq.s NextCommand
cmp.b #9,d0 ; tab ?
beq.s NextCommand
cmp.b #"*",d0 ; rem line ?
beq.s .EndOfLine
cmp.b #";",d0 ; rem line ?
beq.s .EndOfLine
subq.l #1,a0 ; ^command
moveq.l #1,d0
rts
.EndOfLine moveq.l #0,d0
rts
Line ds.b 512
;
; BEGIN
;
BEGIN clr.b LastIF ; last command wasn't IF
lea.l .BeginText(pc),a1 ; check rest of command
bsr CheckWhole
bsr NextCommand ; no more chars in that line ?
tst d0
bne SytaxError ; this command needs no arguments !
addq.l #1,BEGINCounter
move.l Object_FH(pc),d1 ; write to output
move.l #.BeginCode,d2
moveq.l #2,d3
DOS Write
cmp.l d0,d3 ; error ?
beq NextLine
bra DOSError
.BeginText dc.b "EGIN",0
even
.BeginCode dc.b "B",0
even
;
; END
;
END clr.b LastIF ; last command wasn't IF
lea.l .EndText(pc),a1 ; check rest of command
bsr CheckWhole
bsr NextCommand ; no more chars in that line ?
tst d0
bne SytaxError ; this command needs no arguments !
subq.l #1,BEGINCounter
bmi .Error2
move.l Object_FH(pc),d1 ; write to output
move.l #.EndCode,d2
moveq.l #2,d3
DOS Write
cmp.l d0,d3 ; error ?
beq NextLine
bra DOSError
.Error2 PSC_ERROR <"END without BEGIN !">
bra DeleteObject
.EndText dc.b "ND",0
even
.EndCode dc.b "E",0
even
;
; QUIT
;
QUIT clr.b LastIF ; last command wasn't IF
lea.l .QuitText(pc),a1 ; check rest of command
bsr CheckWhole
bsr NextCommand ; no more chars in that line ?
tst d0
bne SytaxError ; this command needs no arguments !
move.l Object_FH(pc),d1 ; write to output
move.l #.QuitCode,d2
moveq.l #2,d3
DOS Write
cmp.l d0,d3 ; error ?
beq NextLine
bra DOSError
.QuitText dc.b "UIT",0
even
.QuitCode dc.b "Q",0
even
;
; TEXT
;
TEXT clr.b LastIF ; last command wasn't IF
lea.l .TextText(pc),a1 ; check rest of command
bsr CheckWhole
bsr NextCommand ; get ^string
lea.l .Buffer(pc),a1
tst d0
beq.s .Label3 ; just LF
.Label1 move.b (a0)+,d0
cmp.b #"'",d0 ; " or ' ?
beq.s .Label2
cmp.b #'"',d0
bne SytaxError ; else sytax error
.Label2 move.b (a0)+,d1 ; copy string to buffer
beq.s .Label3
cmp.b #10,d1 ; end of string : 0-byte, LF, "' ?
beq.s .Label3
cmp.b d0,d1
beq.s .Label3
move.b d1,(a1)+
bra.s .Label2
.Label3 move.b #10,(a1)+
lea.l .Buffer(pc),a2
sub.l a2,a1
move.l a1,d3
move.b d3,.Size ; write size
addq.l #2+1,d3 ; add Command and
bclr #0,d3 ; get word size
move.l Object_FH(pc),d1 ; write to output
move.l #.TextCode,d2
move.l a0,a2 ; save a0
DOS Write
cmp.l d0,d3 ; error ?
bne DOSError
move.l a2,a0
bsr NextCommand
tst d0
bne SytaxError ; end of line ?
bra NextLine
.TextText dc.b "EXT",0
even
.TextCode dc.b "T"
.Size dc.b 0
.Buffer ds.b 256
even
;
; IF
;
_IF move.b #1,LastIF ; last command was IF
lea.l .IFText(pc),a1 ; check rest of command
bsr CheckWhole
bsr NextCommand ; get argument
beq .Error ; no argument ...
move.b (a0)+,d0
bsr UpCase
cmp.b #"T",d0
beq.s .True
cmp.b #"F",d0
bne.s .Error
lea.l .FalseText(pc),a1 ; check rest of boolean expression
bsr CheckWhole
move.b #1,.Boolean ; boolean = FALSE
.Write move.l Object_FH(pc),d1 ; write to output
move.l #.IFCode,d2
moveq.l #2,d3
DOS Write
cmp.l d0,d3 ; error ?
beq NextLine
bra DOSError
.True lea.l .TrueText(pc),a1 ; check rest of boolean expression
bsr CheckWhole
clr.b .Boolean ; boolean = TRUE
bra.s .Write
.Error PSC_ERROR <"IF without boolean expression (TRUE/FALSE) !">
bra DeleteObject
.IFText dc.b "F",0
even
.FalseText dc.b "ALSE",0
even
.TrueText dc.b "RUE",0
even
.IFCode dc.b "I"
.Boolean dc.b 0
even
;
; CHECK / PATCH
;
CHECK moveq #"C",d0 ; Check mode
lea.l .CheckText(pc),a1 ; check rest of command
bra.s Patch_Check
.CheckText dc.b "HECK",0
even
PATCH_2 moveq.b #"p",d0 ; patch mode
bra.s Patch_Check ; (patch command without "PATCH")
PATCH move.b #"P",d0 ; patch mode
lea.l .PatchText(pc),a1 ; check rest of command
bra.s Patch_Check
.PatchText dc.b "ATCH",0
even
; both command have nearly the same sytax !
Patch_Check cmp.b #"p",d0
bne.s .Label0
move.b #"P",.Code
bra.s .Label_1
.Label0 move.b d0,.Code
.Label_1 bsr CheckWhole
clr.b LastIF ; last command wasn't IF
bsr GetLong ; get file offset
tst.l d1
bne SytaxError ; wrong file offset !
move.l d0,.Offset
.Label1 move.b (a0)+,d0
cmp.b #" ",d0 ; skip spaces, tabs ,"=" & ":"
beq.s .Label1
cmp.b #9,d0
beq.s .Label1
cmp.b #":",d0
beq.s .Label1
cmp.b #"=",d0
beq.s .Label1
cmp.b #"'",d0
beq .String ; string !
cmp.b #'"',d0
beq .String ; string !
clr.b .Size
subq.l #1,a0
lea.l .Args(pc),a1
.Label10 bsr NextCommand ; more chars in that line ?
tst d0
beq .Label2 ; NO !
cmp.b #"$",(a0)
bne.s .Label11
addq.l #1,a0 ; skip "$"
.Label11 bsr GetHex ; read byte
tst.l d0 ; error ?
bmi SytaxError
move.b d0,(a1)+
addq.b #1,.Size
cmp.b #255,.Size ; at least 255 bytes
bne.s .Label10
bra .Label5
.String lea.l .Args(pc),a1
moveq.l #0,d2
.Label3 move.b (a0)+,d1 ; next character
beq.s .Label2 ; end of file ?
cmp.b #10,d1 ; end of line ?
beq.s .Label4
cmp.b d0,d1 ; end of string ?
beq.s .Label4
move.b d1,(a1)+ ; write to buffer
addq.l #1,d2
cmp.w #255,d2 ; at least 255 bytes !
bls.s .Label3
.Label5 PSC_ERROR <"Line too long !">
bra DeleteObject
.Label4 move.b d2,.Size
.Label2 tst.b .Size
beq SytaxError
bsr NextCommand ; no more chars in that line ?
tst d0
bne SytaxError ; this command needs no arguments !
move.l Object_FH(pc),d1 ; write to output
move.l #.Code,d2
move.b .Size(pc),d3
addq.l #2+4+1,d3
bclr #0,d3 ; even !
DOS Write
cmp.l d0,d3 ; error ?
beq NextLine
bra DOSError
even
.Code dc.b "C"
.Size dc.b 0
.Offset dc.l 0
.Args ds.b 256
even
GetHex move.b (a0)+,d0
lea.l .Hex(pc),a2 ; ASCII -> Hex
moveq.l #-1,d1 ; get 1. nibble
.W3 addq.l #1,d1
cmp.w #32,d1
bhi.s .W6
cmp.b (a2)+,d0
bne.s .W3
and.w #$f,d1
move.b (a0)+,d0
lea.l .Hex(pc),a2 ; ASCII -> Hex
moveq.l #-1,d2 ; get 2. nibble
.W4 addq.l #1,d2
cmp.w #32,d2
bhi.s .W6
cmp.b (a2)+,d0
bne.s .W4
and.w #$f,d2
lsl.b #4,d1
or.b d1,d2
.W5 move.b d2,d0
rts
.W6 moveq.l #-1,d0
rts
.Hex dc.b "0123456789abcdef"
dc.b "0123456789ABCDEF"
;
; COMMAND
;
; prepare Args
;
COMMAND move.l CommandString(pc),a0
move.l a0,a1
moveq.l #0,d0
bsr.s .Label1
cmp.b #3,d0 ; number of args ?
beq.s .Label10
moveq.l #-1,d0
rts
.Label10 move.l CommandString(pc),a0
move.l a0,InfoName
.Label11 tst.b (a0)+
bne.s .Label11
move.l a0,SourceName
.Label12 tst.b (a0)+
bne.s .Label12
move.l a0,PatchName
moveq.l #0,d0
rts
.Label1 bsr.s .Next ; prepare command line
tst.b d1
beq.s .End
addq.l #1,d0
cmp.b #"'",d1
beq.s .Quote
cmp.b #'"',d1
beq.s .Quote
subq.l #1,a0
.Label2 move.b (a0)+,d1
beq.s .LastArg
cmp.b #" ",d1
beq.s .EndOfArg
cmp.b #9,d1
beq.s .EndOfArg
move.b d1,(a1)+
bra.s .Label2
.EndOfArg clr.b (a1)+
bra.s .Label1
.Quote move.b (a0)+,d2
beq.s .LastArg
cmp.b d2,d1
beq.s .EndOfArg
move.b d2,(a1)+
bra.s .Quote
.LastArg clr.b (a1)+
.End rts
.Next move.b (a0)+,d1
cmp.b #" ",d1
beq.s .Next
cmp.b #9,d1
beq.s .Next
rts
;
; Write Patch INFO string
;
WRITE_INFO move.l InfoName(pc),d1 ; open info file
move.l #MODE_OLDFILE,d2
DOS Open
move.l d0,Info_FH
bne.s .Label1
PSC_ERROR <"couldn't open info file !",10>
bra .NoInfo
.Label1 moveq.l #0,d4 ; file size
.Label2 moveq.l #0,d0 ; check if CTRL-C
moveq.l #0,d1
CALLEXEC SetSignal
btst #12,d0
beq.s .NoUserBreak
DOS_TEXT <" User break .",10> ; write msg
bra .Error
.NoUserBreak move.l Info_FH(pc),d1 ; copy info string
move.l #.Buffer,d2
move.l #256,d3
DOS Read ; read part of info string
move.l d0,d3
bmi.s .DosError ; DOS error ?
beq.s .End ; end of info string ?
add.l d0,d4 ; calculate file size
move.l #.Buffer,d2
move.l Object_FH(pc),d1
DOS Write ; copy to patch file
cmp.l d0,d3
beq .Label2 ; dos error ?
.DosError PSC_ERROR <"DOS error !">
.Error move.l Info_FH(pc),d1
DOS Close
.NoInfo moveq.l #-1,d0 ; error
rts
.End moveq.l #1,d3 ; terminate info string with $00 byte and write word alligned
btst #0,d4
bne.s .Alligned ; alligned afteradding $00 byte ?
addq.l #1,d3
.Alligned move.l #.Buffer2,d2
move.l Object_FH(pc),d1
DOS Write
cmp.l d0,d3
bne.s .DosError
.OK move.l Info_FH(pc),d1 ; close file
DOS Close
moveq.l #0,d0 ; no error
rts
.Buffer ds.b 256+2
even
.Buffer2 dc.b 0,0
;
; Write Patch Module
;
WRITE_MODULE move.l #EXEC_HEADER,d2 ; write Executable Header
move.l #EXEC_HEADER_SIZE,d3
move.l Object_FH(pc),d1
DOS Write
cmp.l d0,d3
bne.s .DosError
move.l #PATCH_MODULE_START,d2
move.l #PATCH_MODULE_SIZE,d3
move.l Object_FH(pc),d1
DOS Write ; copy to patch module
cmp.l d0,d3
beq .Label2 ; dos error ?
.DosError PSC_ERROR <"DOS error !">
moveq.l #-1,d0
rts
.Label2 moveq.l #0,d0 ; check if CTRL-C
moveq.l #0,d1
CALLEXEC SetSignal
btst #12,d0
beq.s .NoUserBreak
DOS_TEXT <" User break .",10> ; write msg
moveq.l #-1,d0
rts
.NoUserBreak moveq.l #0,d0
rts
EXEC_HEADER dc.l $3f3
dc.l 0
dc.l 1
dc.l 0
dc.l 0
HUNK_SIZE1 dc.l -1
dc.l $3e9
HUNK_SIZE2 dc.l -1
EXEC_HEADER_END
EXEC_HEADER_SIZE equ EXEC_HEADER_END-EXEC_HEADER
;
; saving as executable
;
EXECUTABLE move.l Object_FH(pc),d1
moveq.l #0,d2
moveq.l #OFFSET_CURRENT,d3
DOS Seek ; get file pos
sub.l #EXEC_HEADER_SIZE-4,d0
move.l d0,d1
lsr.l #2,d1
move.l d1,HUNK_SIZE1
move.l d1,HUNK_SIZE2
and.l #%11,d0
moveq.l #4,d1
sub.w d0,d1
and.w #%11,d1 ; bytes to add to get longword alligned
move.l #.Data+4,d2
moveq.l #4,d3
add.l d1,d3
sub.l d1,d2
move.l Object_FH(pc),d1
DOS Write ; write pad bytes and $3f2
cmp.l d0,d3
beq.s .Label1
.Error PSC_ERROR <"DOS error !">
moveq.l #-1,d0
rts
.Label1 moveq.l #0,d0 ; check if CTRL-C
moveq.l #0,d1
CALLEXEC SetSignal
btst #12,d0
beq.s .NoUserBreak
DOS_TEXT <" User break .",10> ; write msg
moveq.l #-1,d0
rts
.NoUserBreak move.l Object_FH(pc),d1 ; write hunk size
moveq.l #0,d2
moveq.l #OFFSET_BEGINNING,d3
DOS Seek ; get file pos
move.l #EXEC_HEADER,d2 ; write Executable Header (second time)
move.l #EXEC_HEADER_SIZE,d3
move.l Object_FH(pc),d1
DOS Write
cmp.l d0,d3
bne .Error
moveq.l #0,d0
rts
.Data dc.l 0
dc.l $3f2