home *** CD-ROM | disk | FTP | other *** search
- 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
-
-