Category : A Collection of Games for DOS and Windows
Archive   : EMPIREU.ZIP
Filename : PATCHER.ASM
Output of file : PATCHER.ASM contained in archive : EMPIREU.ZIP
PAGE 44,132
PUBLIC IPATCH, LOCSEG, PLMSG, SET_PLOG
DATA SEGMENT PUBLIC
EMMISM DB 13,10,'>> Two sizes of sample in segment description',13,10,'$'
EMNOMA DB 13,10,'>> No matches to sample text found',13,10,'$'
EMTOOB DB 13,10,'>> Patch too big',13,10,'$'
EMTOOM DB 13,10,'>> More than one match to sample text found',13,10,'$'
HEXBUF DB ?,?,?,?,'$'
HEXDIG DB '0','1','2','3','4','5','6','7'
DB '8','9','A','B','C','D','E','F'
MLFWW1 DB 'Looking for what was $'
MLFWW2 DB ':$'
MLFWW3 DB '..$'
MLFWW4 DB 13,10,'$'
MFMAS1 DB 'Found match at segment $'
MFMAS2 DB 13,10,'$'
PDESC LABEL BYTE ; patch description
; description of patch to be inserted
PATSEG DW ? ; observed value of segment to be patched
PATBEG DW ? ; offset of beginning of region to be patched
PATEND DW ? ; offset of end of region to be patched
NEWSEG DW ? ; segment containing patch
NEWBEG DW ? ; offset of beginning of patch
NEWEND DW ? ; offset of end of patch
PDESC_END LABEL BYTE ; END of patch description
LMSG DB ? ; 0 unless to print log messages
SDESC LABEL BYTE ; segment description
; description of segment observed with a
; debugger, allowing the current
; value of that segment to be
; determined
OBSSEG DW ? ; observed value of segment
OBSBEG DW ? ; offset in segment of beginning of sample
OBSEND DW ? ; offset in segment of end of sample
SAMSEG DW ? ; segment containing text of sample
SAMBEG DW ? ; offset to beginning of text of sample
SAMEND DW ? ; offset to end of sample
SDESC_END LABEL BYTE ; END of segment description
CURSEG DW ? ; current value of desired segment
DATA ENDS
CODE SEGMENT PUBLIC
ASSUME CS : CODE
ASSUME DS : DATA
IPATCH PROC ; Inject Patch
; ES:SI pointer to description of
; patch to be injected
; assumes reference segment has
; been established by calling
; LOCSEG
; returns CARRY if patch too big
PUSH AX
PUSH BX
PUSH CX
PUSH DI
PUSH DS
PUSH DX
PUSH ES
PUSH SI
MOV AX,DATA
MOV DS,AX
; copy patch description
PUSH DS
MOV AX,ES
MOV DS,AX
POP ES
PUSH ES
MOV DI,OFFSET PDESC
MOV CX,OFFSET PDESC_END - OFFSET PDESC
REP MOVSB
POP DS
; check that patch will fit
MOV AX,PATEND
SUB AX,PATBEG
INC AX
MOV CX,NEWEND
SUB CX,NEWBEG
INC CX
CMP AX,CX
JB IPATCH_TOO_BIG
; copy patch
MOV DI,PATBEG
; compute current value of segment
; to be patched
MOV AX,PATSEG
SUB AX,OBSSEG
ADD AX,CURSEG
MOV ES,AX
MOV SI,NEWBEG
PUSH DS
MOV DS,NEWSEG
REP MOVSB
POP DS
CLC ; success
JMP IPATCH_EXIT
IPATCH_TOO_BIG: ; patch too big
MOV DX,OFFSET EMTOOB
JMP IPATCH_ERROR_EXIT
IPATCH_ERROR_EXIT:
MOV AH,9
INT 21H
STC
IPATCH_EXIT:
POP SI
POP ES
POP DX
POP DS
POP DI
POP CX
POP BX
POP AX
RET
IPATCH ENDP
LOCSEG PROC ; Locate Segment
; ES:SI pointer to description of
; segment to be located
; returns AX = current value of
; segment
; returns CARRY if more than one
; match
PUSH BX
PUSH CX
PUSH DI
PUSH DS
PUSH DX
PUSH ES
PUSH SI
MOV AX,DATA
MOV DS,AX
; copy segment description
PUSH DS
MOV AX,ES
MOV DS,AX
POP ES
PUSH ES
MOV DI,OFFSET SDESC
MOV CX,OFFSET SDESC_END - OFFSET SDESC
REP MOVSB
POP DS
; apprise operator
CALL MLFWW
; search all segments for those with sample text at
; specified offset
MOV AX,OBSEND
SUB AX,OBSBEG
INC AX
MOV CX,SAMEND
SUB CX,SAMBEG
INC CX
CMP AX,CX
JNZ LOCSEG_MISMATCH
MOV DX,SAMSEG ; segment containing sample text
MOV SI,SAMBEG ; beginning of sample text
MOV AX,0 ; first segment to try
MOV ES,AX
MOV DI,OBSBEG ; offset where sample will lie
PUSH DS
MOV DS,DX ; segment containing sample text
MOV DX,0 ; number of matches
LOCSEG_CHECK_SEG: ; check next segment
PUSH CX
PUSH DI
PUSH SI
REPE CMPSB
POP SI
POP DI
POP CX
JNZ LOCSEG_NEXT_SEG
; found a match
CALL MFMAS
; make sure it's not the sample text
PUSH BX
PUSH CX
MOV AX,SI
AND AX,0FH
MOV BX,DI
AND BX,0FH
CMP AX,BX
JNZ LOCSEG_CHECKED
MOV AX,SI
SHR AX,1
SHR AX,1
SHR AX,1
SHR AX,1
MOV BX,DS
ADD AX,BX
MOV BX,DI
SHR BX,1
SHR BX,1
SHR BX,1
SHR BX,1
MOV CX,ES
ADD BX,CX
CMP AX,BX
LOCSEG_CHECKED:
POP CX
POP BX
JZ LOCSEG_NEXT_SEG
INC DX ; definite match
MOV BX,ES ; save segment
LOCSEG_NEXT_SEG:
MOV AX,ES
INC AX
MOV ES,AX
JNZ LOCSEG_CHECK_SEG
POP DS
MOV CURSEG,BX ; save a copy for ourselves
CMP DX,0
JZ LOCSEG_NO_MATCH
CMP DX,1
JNZ LOCSEG_TOO_MANY
MOV AX,BX ; one and only one match found
CLC ; success
JMP LOCSEG_EXIT
LOCSEG_MISMATCH: ; mismatch between sample text and
; observed offsets
MOV DX,OFFSET EMMISM
JMP LOCSEG_ERROR_EXIT
LOCSEG_NO_MATCH: ; no matches at all
MOV DX,OFFSET EMNOMA
JMP LOCSEG_ERROR_EXIT
LOCSEG_TOO_MANY: ; too many matches found
MOV DX,OFFSET EMTOOM
JMP LOCSEG_ERROR_EXIT
LOCSEG_ERROR_EXIT:
MOV AH,9
INT 21H
STC
LOCSEG_EXIT:
POP SI
POP ES
POP DX
POP DS
POP DI
POP CX
POP BX
RET
LOCSEG ENDP
MFMAS PROC ; Message: Found match at segment...
PUSH AX
PUSH DS
PUSH DX
MOV AX,DATA
MOV DS,AX
CMP LMSG,0
JZ MFMAS_EXIT
MOV DX,OFFSET MFMAS1
CALL PLMSG
MOV AX,ES
CALL WHEX
MOV DX,OFFSET MFMAS2
CALL PLMSG
MFMAS_EXIT:
POP DX
POP DS
POP AX
RET
MFMAS ENDP
MLFWW PROC ; Message: Looking for what was...
PUSH AX
PUSH DX
CMP LMSG,0
JZ MLFWW_EXIT
MOV DX,OFFSET MLFWW1
CALL PLMSG
MOV AX,OBSSEG
CALL WHEX
MOV DX,OFFSET MLFWW2
CALL PLMSG
MOV AX,OBSBEG
CALL WHEX
MOV DX,OFFSET MLFWW3
CALL PLMSG
MOV AX,OBSEND
CALL WHEX
MOV DX,OFFSET MLFWW4
CALL PLMSG
MLFWW_EXIT:
POP DX
POP AX
RET
MLFWW ENDP
PLMSG PROC ; Patch Log Message
; print message if printing log messages
; DS:DX = offset to "$" terminated message
PUSH AX
PUSH DS
MOV AX,DATA
MOV DS,AX
CMP LMSG,0
POP DS
POP AX
JZ PLMSG_EXIT
MOV AH,9
INT 21H
PLMSG_EXIT:
RET
PLMSG ENDP
SET_PLOG PROC ; Set Patch Logging mode
; AL = 0 unless log messages to be
; printed
PUSH CX
PUSH DS
MOV CX,DATA
MOV DS,CX
MOV LMSG,AL
POP DS
POP CX
RET
SET_PLOG ENDP
WHEX PROC ; Write AX to screen in hex
PUSH AX
PUSH BX
PUSH CX
PUSH DI
PUSH DS
PUSH DX
MOV DX,AX
MOV AX,DATA
MOV DS,AX
MOV BX,OFFSET HEXDIG
MOV DI,OFFSET HEXBUF
MOV CX,4
WHEX_DIG_LOOP:
ROL DX,1
ROL DX,1
ROL DX,1
ROL DX,1
MOV AX,DX
AND AX,0FH
XLAT
MOV [DI],AL
INC DI
LOOP WHEX_DIG_LOOP
MOV DX,OFFSET HEXBUF
MOV AH,9
INT 21H
POP DX
POP DS
POP DI
POP CX
POP BX
POP AX
RET
WHEX ENDP
CODE ENDS
END
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/