home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
fish
/
programming
/
patchcompiler
/
source
/
patchstarmodule.ass
< prev
next >
Wrap
Text File
|
1991-01-16
|
10KB
|
415 lines
opt l+ ; linkable
; V11
;
; Patch Module V1.00
;
; © Roger Fischlin, Steigerwaldweg 6, 6450 Hanau 7, Germany
;
opt p+
XDEF PATCH_MODULE_START,PATCH_MODULE_END
XDEF.l PATCH_MODULE_SIZE
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
PATCH_MODULE_START
; Commands
;
; BEGIN "B" Byte
; 0 Byte
;
; END "E" Byte
; 0 Byte
;
; QUIT "Q" Byte
; 0 Byte
;
; TEXT "T" Byte
; Size Byte
; ASCII Byte (word alligned)
;
; PATCH "P" Byte
; Size Byte
; Address Long
; Data Byte (word alligned)
;
; CHECK "C" Byte
; Size Byte
; Address Long
; Data Byte (word alligned)
;
; IF "I" Byte
; true/false Byte (true = 0)
;
; end of patch "." Byte
; 0 Byte
;
DOS macro ; one library, one macro .....
move.l a5,a6
jsr _LVO\1(a6)
endm
OpenThem clr.b -1(a0,d0) ; a0 ^begin of arg
move.l a0,a4
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
Main cmp.b #"?",(a4) ; check args !
beq INFO
tst.b (a4)
beq INFO ; no arg ?
.Loop1 move.b (a4)+,d0
cmp.b #" ",d0 ; skip spaces and tabs
beq.s .Loop1
cmp.b #9,d0
beq.s .Loop1
cmp.b #"'",d0
beq.s .Quote
cmp.b #'"',d0
bne.s .Label1
.Quote move.l a4,a0 ; save ^file name
.Loop2 move.b (a0)+,d1 ; skip name
beq.s OpenFile ; file name not in quotation marks !
cmp.b d0,d1 ; same quotation mark ?
bne.s .Loop2
clr.b -1(a0) ; terminate file name
addq.l #1,a4 ; skip next command ..
bra.s OpenFile
.Label1 move.l a4,a0 ; terminate end of file name
.Loop3 move.b (a0)+,d0
beq.s OpenFile
cmp.b #" ",d0
beq.s .Label2
cmp.b #9,d0
bne.s .Loop3
.Label2 clr.b -1(a0) ; terminate with $00 byte
OpenFile subq.l #1,a4
move.l a4,d1 ; open file
move.l #MODE_OLDFILE,d2
DOS Open
lea.l Filehandle(pc),a0
move.l d0,(a0)
bne.s .Label1
lea.l .ErrorText1(pc),a0 ; write error msg
moveq.l #.ErrorText1E-.ErrorText1,d0
bra CLI_Text
.ErrorText1 dc.b "Couldn't open file !",$a
.ErrorText1E even
.Label1 lea.l Command(pc),a4 ; start patching
.Label0 tst.b (a4)+ ; skip info text
bne.s .Label0
move.l a4,d0 ; word alligned !
addq.l #1,d0
bclr #0,d0
move.l d0,a4
Next moveq.l #0,d0 ; CTRL-C ?
moveq.l #0,d1
CALLEXEC SetSignal
btst #12,d0
bne UserBreak
move.b (a4)+,d0 ; get command
cmp.b #"T",d0 ; text ?
beq TEXT
cmp.b #"P",d0 ; patch ?
beq PATCH
cmp.b #"C",d0 ; check ?
beq CHECK
cmp.b #"I",d0 ; If ?
beq _IF
cmp.b #"B",d0 ; begin ?
beq BEGIN
cmp.b #"E",d0 ; end ?
beq END
cmp.b #"Q",d0 ; quit ?
beq.s QUIT
cmp.b #".",d0 ; end of patch ?
beq.s QUIT
UnknownCommand lea.l UCText1(pc),a0 ; write "unknown command"
moveq.l #UCText1E-UCText1,d0
bsr CLI_Text
bra.s QUIT
UserBreak lea.l UBText1(pc),a0 ; write "user break"
moveq.l #UBText1E-UBText1,d0
bsr CLI_Text
QUIT move.l Filehandle(pc),d1 ; close file
DOS Close
rts
UCText1 dc.b "unknown command !",$a
UCText1E even
UBText1 dc.b "user break.",$a
UBText1E even
Filehandle dc.l 0
CountBEGIN dc.l 0
Flag dc.b 0
even
;
; BEGIN
;
BEGIN addq.l #1,a4
lea.l CountBEGIN(pc),a0 ; one more BEGIN
addq.l #1,(a0)
bra Next
;
; END
;
END addq.l #1,a4
lea.l CountBEGIN(pc),a0
tst.l (a0) ; check if there are more ENDs than BEGINs
beq .MoreENDs
subq.l #1,(a0) ; one BEGIN-END depth less
bra Next
.MoreENDs lea.l .ErrorText1(pc),a0 ; write error msg
moveq.l #.ErrorText1E-.ErrorText1,d0
bsr CLI_Text
bra QUIT
.ErrorText1 dc.b "END without BEGIN !",$a
.ErrorText1E even
;
; TEXT
;
TEXT moveq.l #0,d0 ; get text length
move.b (a4),d0
moveq.l #0,d1
move.b (a4)+,d1 ; get pointer to next command
move.l a4,a0
addq.l #1,d1
bclr #0,d1
add.l d1,a4
bsr CLI_Text ; write text
beq Next
bra QUIT ; write error
;
; PATCH
;
PATCH moveq.l #0,d4 ; get patch length
move.b (a4)+,d4
move.l Filehandle(pc),d1 ; get file position to patch
move.l (a4)+,d2
moveq.l #OFFSET_BEGINNING,d3
DOS Seek
move.l d4,d3
move.l a4,d2
move.l d4,d0 ; get pointer to next command
addq.l #1,d0
bclr #0,d0
add.l d0,a4
move.l Filehandle(pc),d1 ; patch
DOS Write
cmp.l d0,d3 ; write error ?
beq Next
lea.l .ErrorText1(pc),a0 ; write error msg
moveq.l #.ErrorText1E-.ErrorText1,d0
bsr CLI_Text
bra QUIT
.ErrorText1 dc.b "Write error !",$a
.ErrorText1E even
;
; CHECK
;
CHECK moveq.l #0,d4 ; get check length
move.b (a4)+,d4
move.l Filehandle(pc),d1 ; get file position
move.l (a4)+,d2
moveq.l #OFFSET_BEGINNING,d3
DOS Seek
lea.l .Buffer(pc),a0
move.l a0,d2
move.l d4,d3
move.l Filehandle(pc),d1 ; get file data
DOS Read
cmp.l d0,d3 ; write error ?
bne .Error
lea.l Flag(pc),a2
clr.b (a2) ; set flag to true
subq.l #1,d4
lea.l .Buffer(pc),a0
move.l a4,a1
move.l d4,d0 ; get pointer to next command
addq.l #1+1,d0
bclr #0,d0
add.l d0,a4
.Loop cmpm.b (a0)+,(a1)+ ; compare
bne.s .False
dbra d4,.Loop
bra Next
.False move.b #1,(a2) ; set flag to false
bra Next
.Error lea.l .ErrorText1(pc),a0 ; write error msg
moveq.l #.ErrorText1E-.ErrorText1,d0
bsr CLI_Text
bra QUIT
.ErrorText1 dc.b "Read error !",$a
.ErrorText1E even
.Buffer ds.b 255
even
;
; IF
;
_IF move.b (a4)+,d0 ; true or false ?
cmp.w #"B"<<8,(a4) ; next command "BEGIN" ?
bne.s .Error
cmp.b Flag(pc),d0
beq Next ; execute next commands
move.l CountBEGIN(pc),d5 ; continue with same depth
.Skip
.WordCommand move.b (a4)+,d0 ; skip command
moveq.l #0,d1
move.b (a4)+,d1
cmp.b #"B",d0
beq.s .Begin
cmp.b #"E",d0
beq.s .End
cmp.b #"Q",d0 ; command consists of one word
beq.s .WordCommand
cmp.b #"I",d0 ; command consists of one word
beq.s .WordCommand
cmp.b #".",d0 ; end of patch ?!?
beq .Error2
cmp.b #"P",d0 ; command consists of several bytes
beq.s .BytesCommand
cmp.b #"C",d0 ; command consists of several bytes
beq.s .BytesCommand
cmp.b #"T",d0 ; text command
beq.s .TextCommand
bra UnknownCommand ; unknown .....
.BytesCommand addq.l #4,a4
.TextCommand addq.l #1,d1
bclr #0,d1 ; word alligned
add.l d1,a4
bra.s .Skip
.Begin lea.l CountBEGIN(pc),a0 ; one more BEGIN
addq.l #1,(a0)
bra .Skip
.End lea.l CountBEGIN(pc),a0
tst.l (a0) ; check if there are more ENDs than BEGINs
beq .Error3
subq.l #1,(a0)
cmp.l (a0),d5 ; reached old depth ?
beq Next
bra .Skip
.Error lea.l .ErrorText1(pc),a0 ; write error msg
moveq.l #.ErrorText1E-.ErrorText1,d0
.Label1 bsr CLI_Text
bra QUIT
.ErrorText1 dc.b "IF without BEGIN !",$a
.ErrorText1E even
.Error2 lea.l .ErrorText2(pc),a0 ; write error msg
moveq.l #.ErrorText2E-.ErrorText2,d0
bra.s .Label1
.ErrorText2 dc.b "Unextected end of patch !",$a
.ErrorText2E even
.Error3 lea.l .ErrorText3(pc),a0 ; write error msg
moveq.l #.ErrorText3E-.ErrorText3,d0
bra.s .Label1
.ErrorText3 dc.b "END without BEGIN !",$a
.ErrorText3E even
;
; INFO
;
INFO lea.l Command(pc),a0 ; get length of info string
moveq.l #-1,d0
.Label1 addq.l #1,d0
tst.b (a0)+
bne.s .Label1
lea.l Command(pc),a0 ; write string
; bra CLI_Text
;
; 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
tst d0
rts
.OK moveq.l #0,d0
tst d0
rts
Command
PATCH_MODULE_END
PATCH_MODULE_SIZE equ PATCH_MODULE_END-PATCH_MODULE_START