MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.ansi.asm
2021-01-12 17:31:39 -06:00

432 lines
14 KiB
NASM

; this is ripped off from pd code in RBBS-ASM (was ANSI1-7.ASM)
; has been heavily modified by M. Kimes, who isn't much of an
; asm-programmer. Now works with C in a strange way and supports
; configurable window. It's momma wouldn't know it now (and probably
; would claim it's the type of program she warned it about).
; I reckon it was public domain before, and still is.
;
; int far pascal ansi (char far *str);
; void far pascal setcoords (int topx,int topy,int botx,int boty);
; void far pascal getcoords (int far *topx,int far *topy,int far *botx,int far *boty);
; void far pascal setfastansi (int fast);
;
.model large
ANSI_PRNT SEGMENT PUBLIC 'CODE'
ASSUME CS:ANSI_PRNT
PUBLIC ANSI,SETCOORDS,GETCOORDS,SETFASTANSI,GETFASTANSI
PUBLIC _atop,_atopy,_atopx,_abot,_aboty,_abotx,_fastansiout
VID_PAGE DB 0 ;Active video page
_atop LABEL WORD
_atopy DB 0 ;top y coord
_atopx DB 0 ;top x coord
_abot LABEL WORD
_aboty DB 17h ;bottom y coord
_abotx DB 4Fh ;bottom x coord
_fastansiout DB 1 ;fast ansi writes?
GETCOORDS PROC FAR ;void pascal far getcoords(int *topx,int *topy,
; int *botx,int *boty);
; get window coordinates (0 based)
PUSH BP
MOV BP,SP
PUSH DS
MOV AH,0
MOV AL,_atopx
MOV BX,[BP]+18
MOV DS,[BP]+20
MOV [BX],AX
MOV AL,_atopy
MOV DS,[BP]+16
MOV BX,[BP]+14
MOV [BX],AX
MOV AL,_abotx
MOV DS,[BP]+12
MOV BX,[BP]+10
MOV [BX],AX
MOV AL,_aboty
MOV DS,[BP]+8
MOV BX,[BP]+6
MOV [BX],AX
POP DS
POP BP
RET 16
GETCOORDS ENDP
SETCOORDS PROC FAR ;void pascal far setcoords(int topx,int topy,
; int botx,int boty);
; set window coordinates (0 based)
PUSH BP
MOV BP,SP
MOV AH,[BP]+12
MOV _atopx,AH
MOV AH,[BP]+10
MOV _atopy,AH
MOV AH,[BP]+8
MOV _abotx,AH
MOV AH,[BP]+6
MOV _aboty,AH
POP BP
RET 8
SETCOORDS ENDP
SETFASTANSI PROC FAR ;void pascal far setfastansi(int fast);
; set fast ansi (0 = off, ffh = BIOS)
PUSH BP
MOV BP,SP
MOV AH,[BP]+6
MOV _fastansiout,AH
POP BP
RET 2
SETFASTANSI ENDP
GETFASTANSI PROC FAR ;int pascal far getfastansi(void);
; get fast ansi setting (0 = off)
XOR AX,AX
MOV AH,_fastansiout
RET
GETFASTANSI ENDP
ANSI PROC FAR ;int pascal far ansi(char far *str);
; display a string through DOS' ANSI driver, respecting a window
PUSH BP ;set up stack frame
MOV BP,SP
PUSH DS ;save ds
MOV AH,15 ;get current video state
INT 10H
MOV VID_PAGE,BH ;save it
MOV BX,[BP]+6 ;get string address
MOV DS,[BP]+8 ;set ds
PUSH BX ;save original address
MOV CX,BX
XOR AX,AX
ALOOP:
CALL DOCHECKPOS
MOV AL,[BX] ;set al to char to print
CMP AL,10 ;\n?
JNZ CHKCR ;no
MOV DX,AX
MOV AH,2
INT 21H ;display it
CALL DOCHECKPOS
MOV AL,13 ;and do cr
JMP NOEXIT1
CHKCR:
CMP AL,13 ;\r?
JNZ CHKANSI ;no
MOV DX,AX
MOV AH,2
INT 21H ;display it
CALL DOCHECKPOS
MOV AL,10 ;and do lf
JMP NOEXIT1
CHKANSI:
CMP AL,27 ;escape?
JNZ GOON ;no, skip all this...
CMP BYTE PTR [BX]+1,'[' ; check for various ansi
JNZ GOON ; commands that would screw
CMP BYTE PTR [BX]+2,'2' ; up our window
JNZ GOON1 ; \x1b[2J
CMP BYTE PTR [BX]+3,'J'
JNZ GOON2
ADD BX,4
CALL CLEARSCRN
JMP SHORT ALOOP
GOON1:
CMP BYTE PTR [BX]+2,'K' ; \x1b[K
JNZ GOON3
ADD BX,3
CALL CLEARLINE
JMP SHORT ALOOP
GOON3:
CMP BYTE PTR [BX]+2,'k' ;\x1b[k
JNZ GOON
ADD BX,3
CALL CLEAREOL
JMP SHORT ALOOP
GOON2:
CMP BYTE PTR [BX]+3,'j' ;\x1b[2j
JNZ GOON
ADD BX,4
CALL CLEAREOS
JMP ALOOP
GOON:
CMP AL,0 ;End of string?
JNZ NOEXIT1
JMP SHORT EXIT1
NOEXIT1:
CMP _fastansiout,0 ;fast ansi writes?
JZ BIOSWRITES ;nope
INT 29H
JMP SHORT SKIPSLOW
BIOSWRITES:
CMP _fastansiout,255 ;bios writes?
JZ SLOWWRITES ;nope
PUSH BX
PUSH CX
MOV BH,VID_PAGE
INT 10H
POP CX
POP BX
JMP SHORT SKIPSLOW
SLOWWRITES:
MOV DX,AX
MOV AH,2
INT 21H ;display it
SKIPSLOW:
INC BX
CMP BYTE PTR [BX],0 ;end of string?
JZ EXIT1 ;yep
CMP BX,CX ;string too long?
JZ EXIT1 ;yep, it wrapped; avoid crash
JMP ALOOP ;nope
EXIT1: ;wrap it up...
CALL DOCHECKPOS
POP AX ;retrieve old start pos
SUB BX,AX ;subtract from current pos
MOV AX,BX ;return length of string printed
POP DS
POP BP
RET 4
ANSI ENDP
DOCHECKPOS: ;check cursor pos, protect window
PUSH AX ;Save the registers that will be affected
PUSH BX
PUSH CX
PUSH DX
CALL WHERE_ARE_WE ; where the cursor is.......
CHECKTOPX:
CMP DL,_atopx
JGE CHECKBOTX
MOV AH,2
MOV DL,_atopx
MOV BH,VID_PAGE
INT 10H
JMP SHORT CHECKTOPY
CHECKBOTX:
CMP DL,_abotx
JLE CHECKTOPY
MOV DL,_atopx
INC DH
MOV AH,2
MOV BH,VID_PAGE
INT 10H
CHECKTOPY:
CMP DH,_atopy
JGE CHECKBOTY
MOV AH,2
MOV DH,_atopy
MOV BH,VID_PAGE
INT 10H
JMP SHORT OUTTAHERE
CHECKBOTY:
CMP DH,_aboty ; Row ???
JLE OUTTAHERE ; Jump if less
CALL SCROLLIT ; else scroll, we're too low
MOV DH,_aboty ; put cursor back in window
MOV BH,VID_PAGE
INT 10H
OUTTAHERE:
POP DX ;Restore registers
POP CX
POP BX
POP AX
RET
WHERE_ARE_WE: ;Get the current cursor position
PUSH AX ;Save the registers
PUSH BX
PUSH CX
MOV AH,03 ;SET UP FOR ROM-BIOS CALL (03H)
MOV BH,VID_PAGE ;TO READ THE CURRENT CURSOR POSITION
INT 10H ; DH = ROW DL = COLUMN
POP CX ;Restore the registers
POP BX
POP AX
RET ;And go back from wence we came
SCROLLIT: PUSH AX ;Save the registers that will be affected
PUSH BX
PUSH CX
PUSH DX
MOV AH,2 ;Now set cursor position to ???,???
MOV DH,_aboty
MOV DL,_atopx
MOV BH,VID_PAGE ;attribute
INT 10H
MOV AH,8 ;Get the current character attribute
MOV BH,VID_PAGE
INT 10H
MOV BH,AH ;Transfer the attribute to BH for next call
MOV AH,6 ;Otherwise scroll ??? lines
MOV AL,1 ;Only blank line ???
MOV CH,_atopy
MOV CL,_atopx
MOV DH,_aboty
MOV DL,_abotx
INT 10H ;And do it.......
MOV AH,2 ;Now set cursor position to ???,???
MOV DH,_aboty
MOV DL,_atopx
MOV BH,VID_PAGE
INT 10H
POP DX ;Restore the stack like it was
POP CX
POP BX
POP AX
RET
CLEARSCRN: ;Clear current window
PUSH AX ;Save the registers
PUSH BX
PUSH CX
PUSH DX
MOV AH,2 ;Now set cursor position to ???,???
MOV DH,_aboty
MOV DL,_atopx
MOV BH,VID_PAGE ;attribute
INT 10H
; MOV AH,8 ;Get the current character attribute
; MOV BH,VID_PAGE
; INT 10H
; MOV BH,AH ;Transfer the attribute to BH for next call
MOV BH,7
MOV AH,6 ;Otherwise scroll ??? lines
MOV AL,0 ;clear screen
MOV CH,_atopy
MOV CL,_atopx
MOV DH,_aboty
MOV DL,_abotx
INT 10H ;And do it.......
MOV AH,2 ;Now set cursor position to ???,???
MOV DH,_atopy
MOV DL,_atopx
MOV BH,VID_PAGE
INT 10H
POP DX ;Restore the stack like it was
POP CX
POP BX
POP AX
RET
CLEAREOS: ;Clear to end of current window
PUSH AX ;Save the registers
PUSH BX
PUSH CX
PUSH DX
MOV AH,8 ;Get the current character attribute
MOV BH,VID_PAGE
INT 10H
MOV BH,AH ;Transfer the attribute to BH for next call
MOV AH,6 ;Otherwise scroll ??? lines
MOV AL,0 ;clear
CALL WHERE_ARE_WE
PUSH DX ;save it
MOV CX,DX
MOV DH,_aboty
MOV DL,_abotx
INT 10H ;And do it.......
MOV AH,2
MOV BH,VID_PAGE
POP DX
INT 10H ;restore position
POP DX ;Restore the stack like it was
POP CX
POP BX
POP AX
RET
CLEARLINE: ;Clear current line
PUSH AX ;Save the registers
PUSH BX
PUSH CX
PUSH DX
MOV AH,8 ;Get the current character attribute
MOV BH,VID_PAGE
INT 10H
CALL WHERE_ARE_WE
PUSH DX ;save it
MOV BH,AH ;Transfer the attribute to BH for next call
MOV AH,6 ;Otherwise scroll ??? lines
MOV AL,0 ; clear line
MOV CX,DX
MOV CL,_atopx
MOV DL,_abotx
INT 10H ; And do it.......
MOV AH,2 ;Now set cursor position to ???,???
MOV DL,_atopx
MOV BH,VID_PAGE
INT 10H
MOV AH,2
MOV BH,VID_PAGE
POP DX
INT 10H ;restore position
POP DX ;Restore the stack like it was
POP CX
POP BX
POP AX
RET
CLEAREOL: ;Clear to end of current line
PUSH AX ;Save the registers
PUSH BX
PUSH CX
PUSH DX
MOV AH,8 ;Get the current character attribute
MOV BH,VID_PAGE
INT 10H
CALL WHERE_ARE_WE
PUSH DX ;save it
MOV BH,AH ;Transfer the attribute to BH for next call
MOV AH,6 ;Otherwise scroll ??? lines
MOV AL,0 ;clear line
MOV CX,DX
MOV DL,_abotx
INT 10H ;And do it.......
MOV AH,2
MOV BH,VID_PAGE
POP DX
INT 10H ;restore position
POP DX ;Restore the stack like it was
POP CX
POP BX
POP AX
RET
ANSI_PRNT ENDS
END