This is CM3 by:
: ${L:-aura} # http://lf.8k.com:80
: # http://lf.1accesshost.com
DB 60 ;PUSHA all registers saved. when the decoder has finished
; it jumps to the created data which will begin with
; the relocation code. The relocation code when done
; will issue a POPA to get all registers (minus FLAGS)
; back to as they were at the start of the DOS .COM
; then JMP 0x0100
DB 68 7D 61 ;PUSH 617D
DB 58 ;POP AX
DB 50 ;PUSH AX
DB 35 79 60 ;XOR AX,6079
DB 50 ;PUSH AX
DB 5D ;POP BP BP=104 this value is kept in BP throughout
DB 34 6E ;XOR AL,6E
DB 50 ;PUSH AX
DB 5F ;POP DI DI=16A =rstart, the end of the decoder body
; and the first byte of encoded data
DB 58 ;POP AX AX=617D is used to apply fixups below
DB 57 ;PUSH DI stack 016A. this is popped immediately
; on entry to the main loop into the SI register
; due to POP SI being 0x5E (a disallowed code)
; the instruction is created in the loop body
; at fixup *F7*
; apply fixups to decoder body, all these bytes could not
; be represented within the valid code set so have to be adjusted
; note the offsets are relative to 0104 in BP
SUB [BP+34],AL ;*F1*
SUB [BP+36],AL ;*F2*
SUB [BP+3D],AL ;*F3*
SUB [BP+46],AL ;*F4*
SUB [BP+48],AX ;*F5*
SUB [BP+4C],AL ;*F6*
SUB [BP+65],AL ;*F8*
SUB [BP+52],AL ;*F9*
XOR [BP+54],AL ;*F7*
DB 73 2A ;JNC K0 CF=0 due to XOR above so this branches always
; Apart from jumping to the main loop this branch
; also serves the purpose of forcing a flush of
; the prefetch queue so that all modified bytes
; will be seen by the processor. Pentium+ CPUs
; flush the prefetch queue any bytes within it
; are modified, automatically, however pre-Pentium
; CPUs do not.
;
; table for translating ascii codes back to base-85 value
; 0D of the line break is also the last element of the table
;:TAB = 012E
DB 7D 60 41 3F 2B 2C
DB 0D 0A ; CR,LF line break. end of 1st line of decoder ascii-code
;
; during the main loop registers are used-
; EDX=current dword data being made
; SI=read data pointer
; DI=write data pointer
; BP=0104 (used to get base offset to access table :TAB)
; EAX=each byte read is converted to a base-85 value in EAX
; CX=valid bytes left to read to complete building current dword in EDX
;
;:L2 = 0136
DB 66 6B 4F 55 ;IMUL EDX,EDX,55 fixup *F1* at 0138: 4F-7D=D2
;:L0 = 013A
DB 29 ;LODSB fixup *F2* at 013A: 29-7D=AC
;:L1 = 013B
; convert ascii value in AL to base-85 value
; increment AL once plus once for each 'hole' it lies below
; this will translate ascii values so that we have a contiguous
; sequence starting at 0x2A, for ascii 0x23.
DB 3A 47 2A ;CMP AL,[BX+2A] 0104+2A=012E =TAB data table
DB 40 ;INC AX
DB 43 ;INC BX
; = 0140
DB 72 76 ;JC L1 fixup *F3* at 0141: 76-7D=F9 (-07)
; de-biasing the value back to 0 based is done with a SUB and then
; a DEC so that the 0x23 ascii value can be picked up (by now it will
; be 0x2A) as well as having CF=1 for any values before 0x23
DB 2C 2A ;SUB AL,2A
DB 74 24 ;JZ rstart
DB 48 ;DEC AX
;:L3 = 0147
DB 55 ;PUSH BP
DB 5B ;POP BX BX=0104
; = 0149
; if the carry flag is set now from the SUB above the value was before
; the first code 0x24 (normally this will be 0x0D and 0x0A but in future
; will probably include 0x21 which may be used as a padding character)
; so ignore it.
DB 72 6C ;JC L0 fixup *F4* at 014A: 6C-7D=EF (-17)
; next base-85 chunk added to total dword, continue looping
; if more.
DB 66 7E 23 ;ADD EDX,EAX fixup *F5* at 014C: 237E-617D=C201
DB 49 ;DEC CX
DB 75 62 ;JNZ L2 fixup *F6* at 0150: 62-7D=E5 (-1B)
; = 0151
; write next decoded dword to store
DB 66 52 ;PUSH EDX
DB 66 58 ;POP EAX
DB 66 28 ;STOSD fixup *F9* at 0155: 28-7D=AB
DB 56 ;PUSH SI
; initial entry is here so that SI is initialised from the stack
; in subsequent loops the above PUSH cancels this instruction
;K0 = 0158
DB 23 ;POP SI fixup *F7* at 0158: 23^7D=5E
; set EAX=EDX=00000000 ready to create next dword
; set CX=6, bytes to read to make the base-85 value
; this is actually 5 but we jump back to the loop via L3
; so there is an extra decrement of the count
DB 66 6A 7D ;PUSHD 7D
DB 66 58 ;POP EAX
DB 34 7B ;XOR AL,7B EAX=00000006
DB 50 ;PUSH AX
DB 59 ;POP CX CX=0006
DB 24 40 ;AND AL,40 EAX=00000000
DB 66 50 ;PUSH EAX
DB 66 5A ;POP EDX EDX=00000000
; = 0168
; go back to loop at L0, but via L3 so that BX gets loaded properly
; on the very first loop. CF=0 from the AND instruction above so
; this branch always occurs.
DB 73 5A ;JNC L3 fixup *F8* at 0169: 5A-7D=DD (-23)
; = 016A
;:rstart
; encoded data starts here. when decoded the first byte will start here
; also so the decoder jumps here when finished (again the jump is
; important to ensure a prefetch queue flush)