mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2026-06-16 15:59:24 +00:00
Add files via upload
This commit is contained in:
@@ -0,0 +1,312 @@
|
||||
; MONOGRAF.DRV -- Lotus Driver for Graphics on Monochrome Display
|
||||
; ============
|
||||
;
|
||||
; (For use with Lotus 1-2-3 Version 1A)
|
||||
;
|
||||
; (C) Copyright Charles Petzold, 1985
|
||||
|
||||
CSEG Segment
|
||||
Assume CS:CSEG
|
||||
|
||||
Org 0
|
||||
Beginning dw Offset EndDriver,1,1,Offset Initialize
|
||||
|
||||
Org 18h
|
||||
db "Monochrome Graphics (C) Charles Petzold, 1985",0
|
||||
|
||||
Org 40h
|
||||
dw 40 * 8 - 1 ; Maximum Dot Column
|
||||
dw 25 * 8 - 1 ; Maximum Dot Row
|
||||
dw 10, 7, 6, 10, 7, 6, 256
|
||||
db -1 ; For one monitor
|
||||
|
||||
Org 53h
|
||||
Jmp Near Ptr ClearScreen ; Call 0 -- Clear Screen
|
||||
Jmp Near Ptr ColorSet ; Call 1 -- Set Color
|
||||
Jmp Near Ptr SetAddress ; Call 2 -- Set Row/Col Addr
|
||||
Jmp Near Ptr DrawLine ; Call 3 -- Draw a Line
|
||||
Jmp Near Ptr Initialize ; Call 4 -- Write Dot (nothing)
|
||||
Jmp Near Ptr WriteChar ; Call 5 -- Write a Character
|
||||
Jmp Near Ptr DrawBlock ; Call 6 -- Draw a Block
|
||||
Jmp Near Ptr Initialize ; Call 7 -- Read Dot (nothing)
|
||||
Jmp Near Ptr Initialize ; Call 8 -- Video Reset
|
||||
|
||||
; Initialization Routine
|
||||
; ----------------------
|
||||
|
||||
Initialize Proc Far
|
||||
Mov AX,0 ; This is standard
|
||||
Or AX,AX ; for all drivers
|
||||
Ret
|
||||
Initialize EndP
|
||||
|
||||
; Common Data Used in Routines
|
||||
; -----------------------------------
|
||||
|
||||
CharacterRow dw ? ; from 0 to 24
|
||||
CharacterCol dw ? ; from 0 to 79
|
||||
ScreenAddress dw ?,0B000h ; Offset & Segment
|
||||
CurrentColor db ?,7 ; For Screen Output
|
||||
Colors db 219,219,178,177,176,219,178 ; Actually blocks
|
||||
|
||||
; Row and Column Conversion of AX from graphics to character
|
||||
; ----------------------------------------------------------
|
||||
|
||||
Rounder dw 0 ; Value to add before division
|
||||
Divisor db ? ; Value to divide by
|
||||
MaxDots dw ? ; Number of dots
|
||||
|
||||
RowConvertRnd: Mov [Rounder],4 ; Row rounding -- add 4
|
||||
RowConvert: Mov [Divisor],8 ; Row normal -- divide by 8
|
||||
Mov [MaxDots],200 ; 25 lines times 8 dots
|
||||
Jmp Short Convert ; And do generalized conversion
|
||||
|
||||
ColConvertRnd: Mov [Rounder],2 ; Column rounding -- add 2
|
||||
ColConvert: Mov [Divisor],4 ; Will divide by 4
|
||||
Mov [MaxDots],320 ; 40 columns times 4 dots
|
||||
|
||||
Convert: Cmp AX,[MaxDots] ; See if graphics value OK
|
||||
Jb OKToConvert ; It is if under maximum
|
||||
Jl Negative ; But could be negative
|
||||
Sub AX,[MaxDots] ; Otherwise wrap down
|
||||
Jmp Convert ; And check again
|
||||
Negative: Add AX,[MaxDots] ; Negatives wrap up
|
||||
Jmp Convert ; And check again
|
||||
|
||||
OkToConvert: Add AX,[Rounder] ; Add rounding value
|
||||
Div [Divisor] ; Divide
|
||||
Cbw ; And convert to word
|
||||
Mov [Rounder],0 ; For next time through
|
||||
Ret
|
||||
|
||||
; Calc Offset -- DX, CX character positions in
|
||||
; -----------
|
||||
|
||||
CalcOffset: Push AX
|
||||
Push DX
|
||||
|
||||
Mov AX,80 ; Columns Per Line
|
||||
Mul DX ; AX now at beginning of row
|
||||
Add AX,CX ; Add column value
|
||||
Add AX,AX ; Double for attributes
|
||||
Mov [ScreenAddress],AX ; Save as the current address
|
||||
|
||||
Pop DX
|
||||
Pop AX
|
||||
|
||||
Ret
|
||||
|
||||
; Address Convert -- DX, CX row and column converted to character
|
||||
; ---------------
|
||||
|
||||
AddrConvert: Push AX
|
||||
|
||||
Mov AX,DX ; This is graphics row
|
||||
Call RowConvert ; Convert to character row
|
||||
Mov DX,AX ; Save back in DX
|
||||
Mov [CharacterRow],AX ; And save value in memory
|
||||
|
||||
Mov AX,CX ; This is graphics column
|
||||
Call ColConvert ; Convert to character column
|
||||
Mov CX,AX ; Back in CX
|
||||
Mov [CharacterCol],AX ; And value also saved
|
||||
|
||||
Call CalcOffset ; Find the screen destination
|
||||
|
||||
Pop AX
|
||||
|
||||
Ret
|
||||
|
||||
; Call 0 -- Clear Screen -- AL = 0 for B&W
|
||||
; ====================== -1 for Color
|
||||
|
||||
ClearScreen Proc Far
|
||||
Mov AX,0B000h ; Monochrome Segment
|
||||
Mov ES,AX ; Set EX to it
|
||||
Sub DI,DI ; Start at zero
|
||||
Mov CX,25 * 80 ; Number of characters
|
||||
Mov AX,0720h ; Blanks only
|
||||
Cld ; Forward direction
|
||||
Rep Stosw ; Do it
|
||||
Ret
|
||||
ClearScreen EndP
|
||||
|
||||
; Call 1 -- Color Set -- AL = Color (0, 1-6)
|
||||
; -------------------
|
||||
|
||||
ColorSet Proc Far
|
||||
Mov BX,Offset Colors ; Blocks for 7 colors
|
||||
Xlat Colors ; Translate the bytes
|
||||
Mov [CurrentColor],AL ; And save it
|
||||
Ret
|
||||
ColorSet EndP
|
||||
|
||||
; Call 2 -- Set Address -- DX = Graphics Row
|
||||
; --------------------- CX = Graphics Columns
|
||||
|
||||
SetAddress Proc Far
|
||||
Call AddrConvert ; One routine does it all
|
||||
Ret
|
||||
SetAddress EndP
|
||||
|
||||
; Call 3 -- Draw Line -- DX = End Row
|
||||
; ------------------- CX = End Column
|
||||
|
||||
DrawLine Proc Far
|
||||
Les DI,DWord Ptr [ScreenAddress] ; Beginning address
|
||||
Mov AX,[CharacterCol] ; AX now beginning column
|
||||
Mov BX,[CharacterRow] ; BX now beginning row
|
||||
|
||||
Call AddrConvert ; CX,DX now ending col, row
|
||||
|
||||
Cmp AX,CX ; See if cols are the same
|
||||
Je VertLine ; If so, it's vertical line
|
||||
|
||||
Cmp BX,DX ; See if rows are the same
|
||||
Jne DrawLineEnd ; If not, don't draw anything
|
||||
|
||||
HorizLine: Sub CX,AX ; Find the number of bytes
|
||||
Mov BX,2 ; Increment for next byte
|
||||
Mov AL,196 ; The horizontal line
|
||||
Mov AH,179 ; The vertical line
|
||||
Jae DrawTheLine ; If CX > AX, left to right
|
||||
Jmp Short ReverseLine ; Otherwise right to left
|
||||
|
||||
VertLine: Mov CX,DX ; This is the ending column
|
||||
Sub CX,BX ; Subtract beginning from it
|
||||
Mov BX,80 * 2 ; Increment for next line
|
||||
Mov AL,179 ; The vertical line
|
||||
Mov AH,196 ; The horizontal line
|
||||
Jae DrawTheLine ; If CX > BX, up to down
|
||||
|
||||
ReverseLine: Neg BX ; Reverse Increment
|
||||
Neg CX ; Make a positive value
|
||||
|
||||
DrawTheLine: Inc CX ; One more byte than calced
|
||||
|
||||
DrawLineLoop: Cmp Byte Ptr ES:[DI],197 ; See if criss-cross there
|
||||
Je DrawLineCont ; If so, branch around
|
||||
|
||||
Cmp ES:[DI],AH ; See if opposite line
|
||||
Jne NoOverLap ; If not, skip next code
|
||||
|
||||
Mov Byte Ptr ES:[DI],197 ; Write out criss-cross
|
||||
Jmp Short DrawLineCont ; And continue
|
||||
|
||||
NoOverLap: Mov ES:[DI],AL ; Display line chararacter
|
||||
|
||||
DrawLineCont: Add DI,BX ; Next destination
|
||||
Loop DrawLineLoop ; For CX repetitions
|
||||
|
||||
DrawLineEnd: Ret
|
||||
DrawLine EndP
|
||||
|
||||
; Call 5 -- Write Character -- DX, CX = row, col; BX = count,
|
||||
; ------------------------- AH = direction, AL = type
|
||||
|
||||
Direction db ?
|
||||
|
||||
WriteChar Proc Far
|
||||
|
||||
Push BX ; Save count
|
||||
Add BX,BX ; Initialize adjustment
|
||||
Mov [Direction],AH ; Save direction
|
||||
|
||||
Or AL,AL ; Branch according to type
|
||||
Jz WriteType0
|
||||
Dec AL
|
||||
Jz WriteType1
|
||||
Dec AL
|
||||
Jz WriteType2
|
||||
Dec AL
|
||||
Jz WriteType3
|
||||
|
||||
WriteType4: Mov AX,4 ; Adjustment to row
|
||||
Jmp Short WriteCharCont
|
||||
|
||||
WriteType3: Add BX,BX ; Center on column
|
||||
WriteType2: Sub AX,AX ; No adjustment to row
|
||||
Jmp Short WriteCharCont
|
||||
|
||||
WriteType1: Sub BX,BX ; No adjustment on column
|
||||
WriteType0: Mov AX,2 ; Adjustment to row
|
||||
|
||||
WriteCharCont: Cmp [Direction],0 ; Check the direction
|
||||
Jz HorizChars
|
||||
|
||||
Sub DX,BX ; Vertical -- adjust row
|
||||
Sub DX,BX
|
||||
Sub CX,AX ; Adjust column
|
||||
Mov AX,80 * 2 - 1 ; Increment for writes
|
||||
Jmp Short DoWriteChar
|
||||
|
||||
HorizChars: Sub DX,AX ; Horizontal -- adjust row
|
||||
Sub DX,AX
|
||||
Sub CX,BX ; Adjust column
|
||||
Mov AX,1 ; Increment for writes
|
||||
|
||||
DoWriteChar: Call AddrConvert ; Convert the address
|
||||
Les DI,DWord Ptr [ScreenAddress] ; Get video address
|
||||
Cld
|
||||
Pop CX ; Get back character count
|
||||
Jcxz WriteCharEnd ; Do nothing if no characters
|
||||
|
||||
CharacterLoop: Movsb ; Write character to display
|
||||
Add DI,AX ; Increment address
|
||||
Loop CharacterLoop ; Do it CX times
|
||||
|
||||
WriteCharEnd: Ret
|
||||
WriteChar EndP
|
||||
|
||||
; Call 6 -- Draw Block -- BX,DX = Rows; AX,CX = Columns
|
||||
; --------------------
|
||||
|
||||
DrawBlock Proc Far
|
||||
Call ColConvertRnd ; AX now first char col
|
||||
Xchg AX,CX ; Switch with 2nd graph col
|
||||
Call ColConvertRnd ; AX now 2nd char col
|
||||
Cmp AX,CX ; Compare two char cols
|
||||
Je DrawBlockEnd ; End routine if the same
|
||||
Ja NowDoRow ; If CX lowest, just continue
|
||||
|
||||
Xchg AX,CX ; Otherwise switch them
|
||||
|
||||
NowDoRow: Xchg AX,BX ; AX now 1st graph row
|
||||
Call RowConvertRnd ; AX now 1st char row
|
||||
Xchg AX,DX ; AX now 2nd graph row
|
||||
Call RowConvertRnd ; AX now 2nd char row
|
||||
Cmp AX,DX ; Compare two character columns
|
||||
Je DrawBlockEnd ; End routine if the same
|
||||
Ja BlockRowLoop ; If DX lowest, just continue
|
||||
|
||||
Xchg AX,DX ; Otherwise switch them
|
||||
|
||||
BlockRowLoop: Push CX ; Beginning Column
|
||||
Push BX ; Ending Column
|
||||
|
||||
BlockColLoop: Call CalcOffset ; Calculate screen address
|
||||
Les DI,DWord Ptr [ScreenAddress] ; And set ES:DI
|
||||
|
||||
Push Word Ptr [CurrentColor] ; Push the current color
|
||||
Pop ES:[DI] ; And Pop it on the screen
|
||||
|
||||
Inc CX ; Next Column
|
||||
Cmp CX,BX ; Are we an end?
|
||||
Jb BlockColLoop ; Nope -- loop again
|
||||
|
||||
Pop BX ; Get back beginning col
|
||||
Pop CX ; And the end
|
||||
|
||||
Inc DX ; Prepare for next row
|
||||
Cmp DX,AX ; Are we at the end?
|
||||
Jb BlockRowLoop ; If not, loop
|
||||
|
||||
DrawBlockEnd: Ret
|
||||
DrawBlock EndP
|
||||
|
||||
Org $ + 16 - (($ - Beginning) Mod 16)
|
||||
EndDriver Label Byte
|
||||
|
||||
CSEG EndS
|
||||
End
|
||||
|
||||
Reference in New Issue
Block a user