; do not modify source - made by solar designer in 1996,
; source traded by lord caligo/1997

.model tiny
.code
.startup
.186

cld
emCPU:
mov  si,emIP
lodsw
xchg ax,di
mov  di,[di]
lodsw
xchg ax,bx
or   di,[bx]
lodsw
xchg ax,di
not  ax
mov  emIP,si
stosw
jmp  short emCPU

em86_CALLER:
pusha
mov  ax,em86_R2
mov  word ptr emCPU,ax
cli
mov  em86_SP,sp
mov  sp,offset em86_REGS
popa
mov  sp,em86_SP
sti
push offset em86_RETURN
push em86_R1
em86_RETN:
retn
em86_RETURN:
cli
mov  em86_R1,sp
mov  sp,offset em86_REGS+18
pushf
pusha
mov  sp,em86_R1
mov  em86_SP,sp
sti
popa
jmp  short emCPU

em86_JMP_CALLER:
db   0EBh, offset em86_CALLER - 103h

em86_ADD:
add  ax,cx
sbb  cx,cx
retn

even
emIP dw emCode
emSP dw emStack

emConstFFFF dw 0FFFFh

emNOR macro Src1, Src2, Dst
   dw offset Src1, offset Src2, offset Dst
endm

emNOT macro Src, Dst
   emNOR Src, Src, Dst
endm

emOR macro Src1, Src2, Dst
   emNOR Src1, Src2, emR1
   emNOT emR1, Dst
endm

emAND macro Src1, Src2, Dst
   emNOT Src1, emR1
   emNOT Src2, emR2
   emNOR emR1, emR2, Dst
endm

emXOR macro Src1, Src2, Dst
   emOR Src1, Src2, emR3
   emAND Src1, Src2, emR4
   emNOT emR4, emR4
   emAND emR3, emR4, Dst 
endm

emCLR macro Dst
   emNOT Dst, emR1
   emNOR emR1, Dst, Dst 
endm

emMOV macro Src, Dst
   emOR Src, Src, Dst
endm

emJMPi macro Src
   emMOV Src, emIP
endm

emJMP macro Lbl
   local Src
   emJMPi Src
   Src dw offset Lbl
endm

emJMPsi macro Src1, Src2, Src3
   emAND Src1, Src2, emR3
   emNOT Src3, emR1
   emNOR Src1, emR1, emR4
   emOR emR3, emR4, emIP
endm

emJMPs macro Src, Lbl1, Lbl2
   local Src1, Src2
   emJMPsi Src, Src1, Src2
   Src1 dw offset Lbl1
   Src2 dw offset Lbl2
endm

emMOVv_ALT macro Val, Dst
   local Src, Lbl
   emNOR Src, Src, Dst
   emJMP Lbl
   Src dw not Val
Lbl:
endm

emMOVv macro Val, Dst
   local Src, Lbl
   emMOV Src, Dst
   emJMP Lbl
   Src dw Val
Lbl:
endm

emMOVmv macro Mem, Dst
   local Mod1, Mod2
   emMOV Mem, Mod1
   emMOV Mem, Mod2
Mod1 = this word
Mod2 = this word + 2
   emMOV Dst, Dst
endm

emMOVvm macro Src, Mem
   local Mod
   emMOV Mem, Mod
   emMOV Src, Src
Mod = this word - 2
endm

emSTOP macro
   emMOV em86_RETN, emCPU
endm

em86_CALL macro Lbl
   emMOVv <offset Lbl>, em86_R1
   emMOV emCPU, em86_R2
   emMOV em86_JMP_CALLER, emCPU
endm

em86_INT macro Num
   local Lbl1, Lbl2
   em86_CALL Lbl1
   emJMP Lbl2
Lbl1:
   int Num
   retn
Lbl2:
endm

emADD macro Src1, Src2, Dst
   emMOV Src1, em86_AX
   emMOV Src2, em86_CX
   em86_CALL em86_ADD
   emMOV em86_AX, Dst
endm

emADDv macro Val, Src, Dst
   local SrcVal, Lbl
   emADD SrcVal, Src, Dst
   emJMP Lbl
   SrcVal dw Val
Lbl:
endm

emBIN macro Src, Dst
   emADD emConstFFFF, Src, emR1
   emMOV em86_CX, Dst
endm

emJMPci macro Src1, Src2, Src3
   emBIN Src1, emR5 
   emJMPsi emR5, Src2, Src3
endm

emJMPc macro Src, Lbl1, Lbl2
   local Src1, Src2
   emJMPci Src, Src1, Src2
   Src1 dw offset Lbl1
   Src2 dw offset Lbl2
endm

emPUSH macro Src
   emMOVvm Src, emSP
   emADDv 2, emSP, emSP
endm

emPUSHv macro Val
   local Src, Lbl
   emPUSH Src
   emJMP Lbl
   Src dw Val
Lbl:
endm

emPOP macro Dst
   emADDv -2, emSP, emSP
   emMOVmv emSP, Dst
endm

emCALL macro Lbl
   local RetLbl
   emPUSHv <offset RetLbl>
   emJMP Lbl
RetLbl:
endm

emRET macro
   emPOP emIP
endm

emByteMask:
   dw 0FFh

emCode:
   emMOVv <offset Copyright>, emVR1
   emCALL emPrintText
   emCALL emPrintCRLF

   emMOVv <offset EnterPwd>, emVR1
   emCALL emPrintText

   emCALL emInputText
   emCALL emPrintCRLF

   emCALL emEncryptPwd
   emXOR emV_EncryptedPwd1, emVR4, emVR1
   emJMPc emVR1, emWrongPwd, emExtraCheck

emExtraCheck:
   emXOR emV_EncryptedPwd2, emVR5, emVR1
   emJMPc emVR1, emWrongPwd, emCorrectPwd

emWrongPwd:
   emMOVv <offset WrongPwdMsg>, emVR1
   emJMP emPrintPwdMsg

emCorrectPwd:
   emMOVv <offset CorrectPwdMsg>, emVR1

emPrintPwdMsg:
   emCALL emPrintText
   emCALL emPrintCRLF

   emSTOP

emPrintText:
   emMOVv 0AAh, emVR4
emPrintNext:
   emMOVmv emVR1, emVR3
   emXOR emVR4, emVR3, emVR2
   emMOV emVR3, emVR4
   emAND emByteMask, emVR2, emVR2
   emJMPc emVR2, emDoPrint, emLeavePrint
emDoPrint:
   emADDv 1, emVR1, emVR1
   emCALL emPrintChar
   emJMP emPrintNext
emLeavePrint:
   emRET

emPrintChar:
   emMOV emVR2, em86_DX
   emMOVv 200h, em86_AX
   em86_INT 21h
   emRET

emPrintCRLF:
   emMOVv 13, emVR2
   emCALL emPrintChar
   emMOVv 10, emVR2
   emCALL emPrintChar
   emRET

emInputText:
   emMOVv <offset emV_Buffer>, em86_DX
   emMOVv 0A00h, em86_AX
   em86_INT 21h
   emRET

emEncryptPwd:
   emMOVv <offset emV_Buffer + 2>, emVR1
   emCLR emVR4
emEncryptNext:
   emMOVmv emVR1, emVR3
   emAND emByteMask, emVR3, emVR2
   emXOR emConst000D, emVR2, emVR2
   emJMPc emVR2, emDoEncrypt, emLeaveEncrypt
emDoEncrypt:
   emADDv 1, emVR1, emVR1
   emMOV emVR4, emVR5
   emXOR emVR3, emVR4, emVR4
   emJMP emEncryptNext
emLeaveEncrypt:
   emRET

EncryptText macro Text
   local Val
   Val = 0AAh
   irpc Char, <&Text>
      Val = Val xor '&Char'
      db Val
   endm
   db Val
endm

Copyright:
EncryptText <Emulated Solar CPU  Copyright (c) 1996 by Solar Designer>

EnterPwd:
EncryptText <Enter password: >

WrongPwdMsg:
EncryptText <Incorrect password>

CorrectPwdMsg:
EncryptText <Thanks>

emV_EncryptedPwd1 dw 7528h
emV_EncryptedPwd2 dw 784Dh

emConst000D dw 000Dh

emV_Buffer db 16, 19 dup (?)

even
em86_R1 dw ?
em86_R2 dw ?

em86_REGS:
em86_DI dw ?
em86_SI dw ?
em86_BP dw ?
em86_SP dw ?
em86_BX dw ?
em86_DX dw ?
em86_CX dw ?
em86_AX dw ?
em86_FLAGS dw ?

emR1 dw ?
emR2 dw ?
emR3 dw ?
emR4 dw ?
emR5 dw ?
emR6 dw ? 

emVR1 dw ?
emVR2 dw ?
emVR3 dw ?
emVR4 dw ?
emVR5 dw ?
emVR6 dw ? 

emStack:

end
