Category : Files from Magazines
Archive   : VOL11N21.ZIP
Filename : MLPRINT2.INC

 
Output of file : MLPRINT2.INC contained in archive : VOL11N21.ZIP
;MLPrint2.INC
;Copyright (c) 1992 Jay Munro
;First Published in PC Magazine December 15, 1992
;Extra modules for MLPrint.COM

;PrintZStr - prints an asciiZ string to the screen at an absolute cursor
; location

PrintZStr Proc Near, StrAddr:Word, SColor:Word, AbsLoc:Word
Push ES ;save ES
Mov ES,ScrnSeg ;assign ES to point at screen mem
Mov SI,StrAddr ;get address of string to print
Mov AX,SColor
Mov AH,AL ;put attribute into AH
Mov DX,RTP ;retrace port
Mov DI,AbsLoc ;ES:DI points at screen location
PrLoop:
Lodsb ;get a character
Or AL,AL ;is it a zero???
Jz @F
Call DPrint
Jmp PrLoop
@@:
Pop ES
Ret

PrintZStr EndP

SetScreenString Proc Near Uses DI SI, StBuffer:Word, NumChars:Word, Row:Byte, Col:Byte, Mode:Byte

Mov AH,Mode ;not used, but eliminates pesky warnings
Mov ES,ScrnSeg ;set ES to screen seg
Mov CX,NumChars ;get number of characters to get
Xor AH,AH
Mov DH,AH ;calculate screen location
Mov AL,Row ;
Mov DL,160
Mul DL ;AX contains rows * 160
Mov DL,Col ;
Shl DX,1 ;columns * 2 to consider attribute
Add AX,DX
Mov DI,AX ;save so far
Mov SI,StBuffer ;get address of string buffer
Mov DX,RTP ;setup retrace port
Mov AX,HiLite ;highlite color
Mov AH,AL ;set up AH

SetLoop:
Lodsb
Call DPrint ;print it
Loop SetLoop
Ret
SetScreenString EndP

;GetString receives a string and the number of characters to transfer
;to the buffer.
;Returns when the user hits the end of the line.
;Exits with extended keys as negative values in AX.
;Last key hit in AX.

GetString Proc Near Uses DI SI, StBuffer:Word, NumChars:Word, Row:Byte, Col:Byte, Mode:Byte
Mov ES,ScrnSeg ;set ES to screen seg
Mov CX,NumChars ;get number of characters to get
Mov DH,Row ;row in DH
Mov DL,Col ;col in DL
Mov AL,DL ;save original
Mov MaxPos,DX ;set max chars too
Dec CX ;Max chars is org + numchars - 1
Add MaxPos,CX ;add max chars to starting pos
Mov OrgPos,DX ;save original position
Call SetCursor ;starting cursor

CharLoop:
Call GetChar ;get a char
Or AL,AL ;did we get an extended character?
Jns PosChar ;no regular

;--- check for cursor movement
Cmp AL,-68 ;F10
Jnz @F
Jmp ReadChars
@@:
Cmp AL,-60 ;F2
Jnz @F
Jmp ReadChars

@@:
Cmp AL,-59 ;F1
Jnz @F
Call HelpPrint
Jmp CharLoop

@@:
Cmp AL,-83 ;delete key?
Jnz @F ;no
Mov AL,32 ;print a space
Call GPrint ;do it
Jmp SetCurOnly ;go for another
@@:
Cmp AL,-75 ;left arrow
Jnz @F ;no
Dec DL ;move to the left
Cmp DX,OrgPos ;did we go too far?
Jge SetCurOnly ;no, just set cursor
Inc DL ;yes, reset column
Jmp SetCurOnly ;

@@:
Cmp AL,-77 ;right arrow
Jnz @F ;no
Inc DL ;bump column
Cmp DX,MaxPos ;greater than maxpos?
Jle SetCurOnly ;no, go set cursor
Dec DL ;dec DL
Jmp SetCurOnly ;set cursor
@@:
Cmp AL,-72 ;
Je ReadChars
Cmp AL,-80 ;
Je ReadChars
Cmp AL,-15
Je ReadChars
Jmp GetAgain

PosChar:
Cmp AL,27 ;escape pressed
Je ReadChars ;leave with key code
Cmp AL,13 ;carriage return?
Je ReadChars ;
Cmp AL,9 ;tab key
Je ReadChars ;
Cmp AL,8 ;back space key?
Jnz NormalChar ;
Dec DL ;backup one char
Cmp DX,OrgPos ;are we past the beginning?
Jge @F
Inc DL ;put it back
Jmp GetAgain ;and just loop
@@:
Call SetCursor ;set cursor
Mov AL,32 ;print a space
Call GPrint ;print it
Jmp GetAgain

NormalChar:
Call CharFilter ;filter it according to mode
Jc GetAgain ;if no good skip
Call GPrint ;print the character
Inc DL ;bump column
Cmp DX,MaxPos ;did we fall off the end?
Jle SetCurOnly ;nope, keep going
Mov AL,13 ;fake a CR to go to next field
Jmp ReadChars ;

SetCurOnly:
Call SetCursor ;set cursor for next char

GetAgain:
Jmp CharLoop

ReadChars:
Push AX ;save exit character
Mov DX,OrgPos
Mov AL,DH ;get row
Xor AH,AH ;clear AH for multiplication
Mov DH,AH ;clear rows to add in columns
Mov CL,160
Mul CL ;get to the row
Shl DL,1 ;take into account the attribute.
Add AX,DX ;add in the columns
Mov SI,AX ;SI now has the first char position to read
Mov DX,RTP ;get retrace port value
Push DS
Push ES
Push DS
Pop ES
Pop DS

Mov DI,StBuffer ;get address of buffer
Mov CX,NumChars ;get number of characters to get

ReadScreen:
Or DX,DX
Jz Mono_Ega2 ;yes, go do it

No_Retrace2:
In AL,DX ;get the video status byte
Test AL,1 ;test just the horizontal retrace bit
Jnz No_Retrace2 ;if doing a retrace, wait until it's not
Cli ;disable interrupts until we're done writing to screen

Retrace2:
In AL,DX ;get the status byte again
Test AL,1 ;are we currently doing a retrace?
Jz Retrace2 ;no wait until we are

Mono_EGA2:
Lodsw ;read screen memory
Stosb ;store the character in the buffer
Sti ;re-enable interrupts
Loop ReadScreen
Pop DS ;retrieve DS
Pop AX ;retrieve return character
Ret

GPrint:
Mov CX,1
Mov AH,0Ah ;service 9
Xor BH,BH
Push BP
Int 10h ;print it
Pop BP
Retn

SetCursor:
;location in DX
Mov AH,02h ;service 2
Xor BH,BH ;clear BH for 0 page
Push BP ;really old PC's trash BP on int 10h
Int 10h ;set cursor
Pop BP
Retn

CharFilter:
Mov BL,Mode ;get the mode
Or BL,BL ;if it's zero, don't filter at all
Jz FiltOk ;skip
Cmp BL,1 ;is it numeric?
Jnz @F
Call IsNumber ;check it
Jnc FiltOk ;if ok, the exit
Cmp AL,'.' ;is it a period?
Jz FiltOk ;yes, ok it
Jmp NotOk ;otherwise skip out
@@:
;uppercase letter first ;
Cmp AL,'a' ;is it less than an a ?
Jl Ctnu ;yes, no caps needed
Cmp AL,'z' ;ok, greater than a z ?
Jg Ctnu ;yes, still no caps needed
Sub AL,32 ;capitalize it
Ctnu:
Cmp BL,2 ;Yes/No
Jnz LabelEnvFilt ;assume ok
Cmp AL,'Y'
Jz FiltOk
Cmp AL,'N'
Jnz NotOk
Jmp FiltOk

LabelEnvFilt:
Cmp BL,4 ;Yes/No
Jnz FiltOk ;assume ok
Cmp AL,'L'
Jz FiltOk
Cmp AL,'E'
Jnz NotOk
Jmp FiltOk

FiltOk:
Clc ;clear carry flag -- everything is ok
Retn

NotOk:
Stc
Retn

OrgPos DW ?
MaxPos DW ?
GetString EndP

CursorPos DW 0 ;variable to remember current cursor status
CursorOn Proc Near, CursorLoc:Word
Push AX
Push CX
Push BP
Mov CX,CursorLoc
Mov AH,01
Int 10h
Pop BP
Pop CX
Pop AX
Ret
CursorOn EndP

CursorOff Proc Near, CursorLoc:Word
Push AX
Push CX
Push BP
Mov AH,03
Mov BH,0
Int 10h
Push BX
Mov BX,CursorLoc
Mov [BX],CX
Pop BX
Mov CX,2020h
Mov AH,01
Int 10h
Pop BP
Pop CX
Pop AX
Ret
CursorOff EndP

;GetChar - Bios keyboard routine. Returns character in AL. If extended
; character, it makes it negative. ie. F1 = -59

GetChar Proc Near
Mov AH,0h ;service 0
Int 16h ;wait for a character
Or AL,AL ;is AL zero, if so make a negative keycode
Jnz @F
Xchg AH,AL
Neg AL ;neg it
@@:
Retn
GetChar EndP

;IsNumber - check if incoming characters are in the range 0 - 9
; Entry - AL = character
; Exit - Carry set if not number, clear if it is

IsNumber Proc Near ;enters with AL containing character
Cmp AL,'0' ;is it below a zero?
Jl @F
Cmp AL,'9' ;or above a 9 ?
Jg @F
Clc ;clear carry if number
Ret
@@:
Stc ;set if not
Ret
IsNumber EndP

;CLS - clears portion of screen to current screen color set by variable COLOR

CLS Proc Near, LRow:Word, LCol:Word, RRow:Word, RCol:Word
;clears screen
Mov AX,Color ;color or attribute
Mov BH,AL ;color into BH
Mov AX,600h ;service 6, clear whole screen (AL = 0)
Mov CX,LRow ;set up row/colume to clear
Xchg CH,CL
Add CX,LCol
Mov DX,RRow
Xchg DH,DL
Add DX,RCol
Push BP ;preserve BP for old PC's
Int 10h ;video interrupt
Pop BP ;retrieve BP
Ret
CLS EndP

;--- File routines

;--- Seek - positions a file pointer

Seek Proc Near, Handle1:Word, Pointer:Dword
Mov ErrorNum,0 ;reset error number
Mov AX,4200h ;service 42h, offset from start of file
Mov BX,Handle1 ;file handle to use
Mov DX,Word Ptr Pointer ;low value
Mov CX,Word Ptr Pointer[2] ;high value
Int 21h
Jnc @F
Call ExtError
Mov ErrorNum,AX ;save error number
@@:
Ret ;return with new file pointer position in
;DX:AX
Seek EndP

; Read - Reads BufSize number of characters of file data into buffer
; pointed at by Buffer parameter.

Read Proc Near, Handle2:Word, Buffer:Word, BufSize:Word
Reread2:
Mov ErrorNum,0 ;reset error number
Mov AH,3Fh ;service 3Fh - read file
Mov BX,Handle2 ;file handle
Mov CX,BufSize ;get number of bytes to read
Mov DX,Buffer ;get address of buffer
Int 21h ;do it
Jnc @F ;no errors
Call ExtError
Mov ErrorNum,AX
Jmp ReadExit ;we got an error, no need to check anymore

ReadErrMsg DB 'Input past end of file',0

@@:
Cmp AX,BufSize ;did we read past end of file
Jz ReadOk ;no, clear carry and split
Invoke MessageBox,Addr ReadErrMsg
Jnc ReTry2
Jmp ReadExit
ReTry2:
Jmp ReRead2
ReadOk:
Clc
ReadExit:
Ret
Read EndP

; Write - Writes BufSize number of characters stored in Buffer to file handle
; Handle3.

PrtError DB 'Printer Not Responding',0
OutFileErr DB 'Disk Full on Output File',0
EscOutErr DB 0

Write Proc Near, Handle3:Word, Buffer:Word, BufSize:Word
ReWrite:
Mov DOSErrCode,0 ;clear the DOS error variable
Mov CritErrFlag,0 ;clear the critical error flag
Mov ErrorNum,0 ;reset error number
Mov AH,40h ;service 40h, write to a file
Mov BX,Handle3 ;file handle
Mov CX,BufSize ;number of bytes to write
Mov DX,Buffer ;address of buffer
Int 21h ;write the buffer
Jnc NoWriteError ;no errors, skip ahead
Cmp Byte Ptr EscOutErr, 0 ;did this happen before?
Jnz @F
Call ExtError
Cmp AL,27 ;esc ?
Jnz ReTry1
Mov Byte Ptr EscOutErr,-1
@@:
Stc
Jmp WriteExit

NoWriteError:
Cmp AX,BufSize ;disk full?
Jz WriteOk ;nope, exit ok
Cmp Byte Ptr UseDestFile,'N'
Jz @F
Lea DI,OutFileErr
Jmp PrintErrorMsg
@@:
Xor DH,DH ;clear hi byte
Mov DL,PrPortBuf ;get printer port character
Sub DL,'1' ;make it a 0 - 2
Mov AH,02h ;check status
Int 17h
And AH,010000b ;clear everything but the paper out
Jz @F
Lea DI,OutOfPaper ;print paper out message
Jmp PrintErrorMsg
@@:
Lea DI,PrtError

PrintErrorMsg:
Stc
Cmp Byte Ptr EscOutErr,0
Jnz WriteExit
Invoke MessageBox,DI
Jnc ReTry1
Mov Byte Ptr EscOutErr,-1
Jmp WriteExit
ReTry1:
Mov Byte Ptr EscOutErr,0
Jmp ReWrite

WriteOk:
Clc

WriteExit:
Ret

Write EndP

;--- Close - Closes file specified by Handle4
Close Proc Near, Handle4:Word
Mov ErrorNum,0 ;reset error number
Mov AH,3Eh ;service 3Eh, close file
Mov BX,Handle4 ;file handle
Int 21h ;close the file
Ret
Close EndP

;--- ClearPunct - Clears out punctuation and capitalizes all letters to P.O.
; standards. Punctuation is replaced by spaces.

ClearPunct Proc Near, SBuffer:Word, SBufSize:Word
Mov BX,SBuffer ;get address of buffer
Mov CX,SBufSize ;get length of buffer
Mov AH,32 ;replace chararcter = space

ClearLoop:
Mov AL,[BX] ;get a character
Cmp AL,'0' ;if less than 0, replace
Jl Replace ;
Cmp AL,'9' ;if in this range, then ok
Jle Ok
Cmp AL,'A' ;if less than an A, replace
Jl Replace ;do it.
Cmp AL,'Z' ;if greater than a Z, replace
Jle Ok ;other wise, continue
Cmp AL,'a' ;check for capitization
Jl Replace ;nope, replace
Cmp AL,'z' ;ok?
Jg Replace ;
Sub AL,AH ;capitalize by subtracting a space
Mov [BX],AL ;replace with capital letter
Jmp Short Ok

Replace:
Cmp AL,13 ;CR ?
Jz Ok
Cmp AL,10 ;LF ?
Jz OK
Call ForeignChar ;AL contains char to check
;Mov [BX],AH ;replace with a space
Mov [BX],AL ;replace with a space
Ok:
Inc BX
Loop ClearLoop
Ret
ClearPunct EndP

; Num2Ascii - places the ascii values of an integer in ABuffer
; Preserves SI
; Incoming DI = pointer to buffer
; Trashes AX,BX,CX,DX,

Num2Ascii Proc Near, Num2Conv:Word , ABuffer:Word
Push DI
Mov DI,ABuffer ;get pointer to buffer

Add DI,4 ;assume up to 5 digits
Mov BX,DI ;save starting pointer
Mov AX,Num2Conv ;get number to put into buffer
Mov CX,10 ;number to divide by...
Std ;backwards storage

DivLoop:
Xor DX,DX
Div CX ;divide by 10
Add DL,48 ;make it ascii
Xchg DL,AL
Stosb
Xchg DL,AL
Or AX,AX ;remainder in AX
Jnz DivLoop
Cld ;now move forward
Xchg BX,DI
Sub DI,BX ;subtract start from finish to get length
Inc DI ;offset by 1
Mov AX,DI ;return with number of digits
Or AX,AX ;if it's zero, all is cool
Jz Num2Exit
Push AX ;save length
Push SI ;save SI
Mov DI, ABuffer
Mov SI,DI
Mov BX,AX
Mov CX,5 ;use offset to show how many chars to do
Xor AL,AL
RepE ScaSb ;scan until we hit a character
Dec DI
Xchg SI,DI ;DI should be pointing at first char
Mov CX,BX ;now slide a few chars
Swap:
LodSb ;source is in AL
Mov AH,[DI] ;get destination into AH
Mov [SI-1],AH ;put it
StoSb
Loop Swap
Pop SI ;retrieve SI
Pop AX ;return with number of digits

Num2Exit:
Pop DI
Ret
NumChar DB 0
Num2Ascii EndP
;----------------------------------------------------------------------------

SetRawMode Proc Near Handle1:Word
Mov BX,Handle1 ;get mode of print handle
Mov AX,4400h ;service 44, subf 00
Int 21h
Jc SRExit
Or DL,100000b ;force "raw" data mode (don't expand Tabs, etc.)
Xor DH,DH ;DOS requires that we clear DH
Mov AX,4401h ;service 44, subf 01
Int 21h
SRExit:
Ret
SetRawMode EndP

OpenFile Proc Near, FileName:Word, Attr:Word
ReTryOpen: ;put a zero on the strings
Mov SI,FileName ;get address of file
Mov DX,SI ;save it for use later
Mov CX,40

MakeZStr:
Lodsb
Cmp AL,32
Jz @F
Or AL,AL
Jz @F ;already a zero
Loop MakeZStr
@@:
Mov [SI-1],CH ;put a zero in
Mov AX,Attr ;get attribute (Read/Write)
Cmp AH,3Ch ;are we forcing a create?
Jz @F ;yes
Mov AH,3Dh ;open existing file
@@:
Xor CX,CX ;clear CX for attributes
Mov DX,FileName ;get address of filename
Int 21h ;
Jnc @F
Call ExtError ;print an error now
Jnc ReTryOpen
@@:
Ret
OpenFile EndP

FileSize Proc Near
Mov BX,LFileHandle ; BX = file handle
Mov AX,4202h ; AH = function #,
; AL = move to end of
Sub CX,CX ; file plus offset
Sub DX,DX ; CX:DX = offset (zero)
Int 21h ; Move File Read/Write Pointer

Mov Word Ptr LFileSize,AX ; Assign size to our variable
Mov Word Ptr LFileSize[2],DX
Push AX ; Tuck size away for a moment
Push DX
Mov BX,LFileHandle ; BX = file handle
Mov AX,4200h ; AH = function #,
; AL = move to beginning of file
Sub CX,CX ;
Sub DX,DX ; CX:DX = offset (zero)
Int 21h ; Move File Read/Write Pointer
Pop DX ; Retrieve size and return
Pop AX
Ret
FileSize EndP

;---------------------------------------------------------------------------
; Printer Macros Section
;---------------------------------------------------------------------------
LoadBarMacros Proc Near
Cld ;forward direction as always
;--- Create Frame Bar macro as # 10
Invoke StartMacro,10 ;frame bar is macro 10
Invoke SendIt,Addr FirstBar ;do it...
Invoke Sendit,Addr Space
Invoke EndMacro
Lea SI,Number
Mov DI,Offset Zero
Xor AX,AX
Mov Word Ptr MacroCounter,AX ;set memloc's to zero

DoLoop:
Lodsb ;get a character
Or AL,AL ;if zero then we're done
Jz NumberDone
Push AX
Invoke StartMacro,MacroCounter ;start macro to go
Pop AX
Sub AL,30h ;make it a real number

CheckEntry:
Mov BX,DI ;get
Xor AH,AH
Add BX,AX
Mov DH,[BX] ;get template
Shl DH,1
Shl DH,1
Shl DH,1
Mov CX,5

BitLoop:
Push CX
Clc
Rcl DH,1 ;shift it left
Jc TallOne ;carry, it a 1
Invoke Sendit,Addr ShortCodes ;do short one
Invoke Sendit,Addr Space
Jmp @F

TallOne:
Invoke Sendit,Addr TallCodes
Invoke Sendit,Addr Space

@@:
Pop CX
Loop BitLoop
Invoke EndMacro ;end macro
Inc Word Ptr MacroCounter ;print macro
Jmp DoLoop

NumberDone:
Ret
LoadBarMacros EndP

SendIt Proc Near, StrPtr:Word ;prints a string to printer or file
Push DI
Push DX
Push CX
Push ES
Push DS
Pop ES
Mov DI,StrPtr ;get address of string to print
Xor AL,AL
Mov CX,0FFFFh
Cld
Repne Scasb ;get it's Len
Not CX
Dec CX
Invoke Write,OFileHandle, StrPtr , CX
Pop ES
Pop CX
Pop DX
Pop DI
Ret
SendIt EndP

SetId Proc Near, IDNum:Word
Mov AX,IDNum
Mov BL,10
Div BL ;divide AX to get number
Or AL,AL ;
Jz ClipZero
Add AX,3030h ;add '0' to get ascii values
Mov Word Ptr IDCode,AX ;
Mov Byte Ptr IDCode + 2,'Y'
Jmp @F

ClipZero:
Add AX,3059h ;
Xchg AH,AL
Mov Word Ptr IDCode,AX ;
Mov Byte Ptr IDCode + 2,0 ;
@@:
Invoke SendIt,Addr IDSetCode
Ret
SetID EndP

StartMacro Proc Near, IDNum:Word
Invoke SetID,IDNum
Invoke SendIt,Addr MacStart
Ret
StartMacro EndP

EndMacro Proc Near
Invoke SendIt,Addr MacEnd
Ret
EndMacro EndP

FireMacro Proc Near, IDNum:Word
Invoke SetID,IDNum
Invoke SendIt,Addr MacFire
Ret
FireMacro EndP

DeleteMacro Proc Near
Invoke SendIt,Addr ClearAll
Ret
DeleteMacro EndP

;--- Menu of label sizes and choices
MainCur DW ?
LabelMenu Proc Near, DefFlg:Word ;returns the index of the labels user wants
Invoke CursorOff, Addr CS:MainCur
Push SI ;preserve SI
Mov DI,Bloc ;get address on screen where to put menu
;ES:DI points to screen
Add DI,8 ;indent
Mov TopRowOff,DI
Lea SI,MenuHead ;get first line of text--heading

HeaderLoop:
Invoke PrintZStr,Addr MenuHead, Color, DI
Jmp MenuLoop ;jump back for more

MenuLoop: ;now do the menu portion
Lea SI,MenuData ;get address of menu items
Mov DI,TopRowOff
Add DI,NextRow ;bump to next line...
Mov TopBarRow,DI
Cmp LabelIndex,0 ;never have a 0 index!
Jnz @F
Mov Byte Ptr LabelIndex,1 ;make it a 1

@@:
Invoke CLS,13,0,16h,49h ;screen coords to clear
Mov CX,10 ;show 8 at a time

ItemLoop:
Push DI
Push CX
Invoke PrintZStr,SI, Color, DI
Pop CX
Pop DI
Add DI,NextRow ;bump down
Cmp Byte Ptr [SI],0 ;is it the end of the list?
Jz @F
Loop ItemLoop

@@:
;--- highlight loop
Sub Word Ptr TopBarRow,2
Mov DI,TopBarRow

HiLoop:
Call PrintFromIndex
Cmp Word Ptr DefFlg,0
Jnz ExitLabLily

KeyLoop:
Call GetChar ;get a key
Or AL,AL ;did we get an extended key?
Js @F
Cmp AL,27 ;esc?
Jz ExitLabLily ;yes, jump out
Cmp AL,13 ;did we hit
Jnz KeyLoop

ExitLabLily:
Jmp ExitLabMenu ;yes, jump out

@@:
Cmp AL,-72 ;Up arrow?
Jnz DownArrow
Cmp Word Ptr LabelIndex,1
Jg @F
Jmp KeyLoop

@@:
Call UnHilite
Dec Word Ptr LabelIndex
Call PrintFromIndex
Jmp KeyLoop

DownArrow:
Cmp AL,-80 ;down arrow
Jnz Home
Cmp Word Ptr LabelIndex,10
Jl @F
Jmp KeyLoop
@@:
Call UnHilite
Inc Word Ptr LabelIndex
Call PrintFromIndex
Jmp KeyLoop

Home:
Cmp AL,-71 ;home
Jnz EndKey
Call UnHilite
Mov Word Ptr LabelIndex,1
Call PrintFromIndex
Jmp KeyLoop

EndKey:
Cmp AL,-79 ;end
Jnz F10F1
Call UnHilite
Mov Word Ptr LabelIndex,10
Call PrintFromIndex
Jmp KeyLoop

F10F1:
Cmp AL,-59 ;F1?
Jnz @F
Call HelpPrint
Jmp Short LoopBack
@@:
Cmp AL,-60 ;F2?
Jz ExitLabMenu
Cmp AL,-68 ;F10
Jz ExitLabMenu

LoopBack:
Jmp KeyLoop

UnHiLite:
Push DI
Invoke PaintBar,Color, MenuWidth
Pop DI
RetN

HiLiteIt:
Push DI
Invoke PaintBar,HiLite, MenuWidth
Pop DI
RetN

ExitLabMenu:
Pop SI
Push AX
Invoke CursorOn, CS:MainCur
Pop AX
Ret

PrintFromIndex:
Mov AX,LabelIndex
Dec AX
Mul NextRow
Mov DI,TopBarRow
Add DI,AX
Call HiLiteIt
RetN
LabelMenu EndP

;--- Paintbar - entry ES:DI = start location
PaintBar Proc Near, AtrColr:Word, Numchars:Word
Mov DX,RTP
Mov CX,NumChars
Mov BX,AtrColr
Inc DI ;offset
PL:
Or DX,DX ;are we doing monochrome or EGA?
Jz Mono_Ega3 ;yes, go do it

No_Retrace3:
In AL,DX ;get the video status byte
Test AL,1 ;test just the horizontal retrace bit
Jnz No_Retrace3 ;if doing a retrace, wait until it's not
Cli ;disable interrupts until we're done writing to screen

Retrace3:
In AL,DX ;get the status byte again
Test AL,1 ;are we currently doing a retrace?
Jz Retrace3 ;no wait until we are

Mono_EGA3:
Mov AL,BL
Stosb ;store the attribute into screen memory
Sti ;re-enable interrupts
Inc DI
Loop PL
Ret
PaintBar EndP

PrintZipBarcode Proc Near, ZipCode:Word
Invoke Write,OFileHandle, Addr BackUpForZip, 7
Jc NoBar
Invoke ZStrLen, ZipCode
Mov AH,2
Sub AL,2
Cmp AL,5 ;5 digit zip?
Je DoBar
Cmp AL,9 ;9 digit zip?
Je DoBar
Cmp AL,11 ;11 digit zip?
Je DoBar
Clc ;not an error, just no barcode
Jmp NoBar
DoBar:
Invoke FireMacro,10 ;print vertical bar
Jc NoBar
Mov SI,ZipCode ;get number to do
Mov Byte Ptr CheckDig,0
Mov DL,-1 ;one through the loops

PrintNumLoop:
Mov BX,SI ;save pointer to character
Lodsb ;get a number
Or AL,AL ;are we done yet?
Jz DoCheck ;yes, go do a check digit
Cmp AL,32 ;is it a space
Jnz @F
Mov Byte Ptr [BX],'-' ;put in the dash
Jmp PrintNumLoop ;yes, skip it
@@:
Xor AH,AH ;clear AH to use AX
Sub AL,30h ;make it a real number
Add CheckDig,AL ;get digit
Invoke FireMacro,AX ;fire corresponding macro
Jc NoBar
Jmp PrintNumLoop ;go do it again

DoCheck: ;calculate check digit
Or DL,DL ;been through here?
Jz BeenThru
Mov AL,CheckDig ;get digit
Xor AH,AH
Mov BL,10
Div BL
Sub BL,AH
Cmp BL,10 ;did we luck out and get a 10
Jnz @F
Sub BL,10 ;clear to 0
@@:
Mov AL,BL
Mov CheckDig,BL
Xor DL,DL

Mov SI,Offset EndIt

Add AL,30h ;make it real
Mov [SI],AL
Jmp PrintNumLoop

BeenThru:
Invoke FireMacro,10
NoBar:
Ret
PrintZipBarcode EndP

;---Message Box
; Enters with pointer to messsage in Message, Flag for keystroke
; in KFlag 0 - open & return, 1 - close & return, -1 = wait for keystroke

MessageBox Proc Near, Message:Word
Push ES

Push DI
Push SI
Call SaveScrn
Push ES
Mov ES,ScrnSeg
Mov DI,BoxStart
Invoke PrintZStr,Addr DblLine,ErrColor, DI
Mov BX,ScrnMsgAddr ;start with message address
Invoke ZStrLen,Message
Sub BX,AX ;sub to get location
And BL,011111110b
Mov CX,ErrColor
Or CX,128
Invoke PrintZStr,Message, CX, BX
Pop ES
Call GetChar
Push AX ;preserve character
Push ES
Mov ES,CS:ScrnSeg
Call RestScrn
Pop ES
Pop AX
Pop SI
Pop DI
Pop ES
Cmp AL,27 ;check for ESC
Jnz @F
Stc
Jmp MSGExit
@@:
Clc
MSGExit:
Ret
MessageBox EndP

ZStrLen Proc Near, Message:Word
Push DI
Push ES
Push DS
Pop ES
Mov CX,-1
Xor AL,AL
Mov DI,Message
Cld
Repne Scasb
Neg CX
Mov AX,CX
Pop ES
Pop DI
Ret
ZStrLen EndP

SaveScrn Proc Near
Mov SI, 0 ;CS: BoxStart ;get box to save
Lea DI,Offset ScrnBuffer ;and destination
Mov CX,ScrnBufLen ;move 240 words-char & attribute
Shr CX,1 ;divide by 2 because we're doing words
Push DS
Push DS
Pop ES
Mov DS,CS:ScrnSeg
Call VidRead
Pop DS
Invoke CLS,10,0,12,80 ;clear section
Ret
SaveScrn EndP

RestScrn Proc Near
Mov DI, 0 ;CS:BoxStart ;get box to save
Lea SI,ScrnBuffer ;and destination
Mov CX,ScrnBufLen ;move 240 words-char & attribute
Shr CX,1 ;divide by 2 because we're doing words
Call VidRead
Ret
RestScrn EndP


VidRead Proc Near
Mov DX,CS:RTP ;get retrace port

VidScreen:
Or DX,DX ;if zero, then we're not on CGA
Jz Mono_Ega4 ;yes, go do it

No_Retrace4:
In AL,DX ;get the video status byte
Test AL,1 ;test just the horizontal retrace bit
Jnz No_Retrace4 ;if doing a retrace, wait until it's not
Cli ;disable interrupts until we're done writing to screen

Retrace4:
In AL,DX ;get the status byte again
Test AL,1 ;are we currently doing a retrace?
Jz Retrace4 ;no wait until we are

Mono_EGA4:
Lodsw ;read screen memory
Stosw ;store the character in the buffer
Sti ;re-enable interrupts
Loop VidScreen
Ret
VidRead EndP

;Foreign Character translation module
;Looks up a character and returns with appropriate character in AL

ForeignChar Proc Near
Cmp AL,225 ;is it a German á
Jnz @F
Mov AL,'S' ;convert to an S
Jmp BExit

@@:
Cmp AL,129 ;foreign chars?
Jl RExit
Cmp AL,165 ;in the range?
Jle BExit

RExit:
Mov AL,20h

BExit:
Ret
ForeignChar EndP

;---Exist
Exist Proc Near, FileName:Word
Mov DX,Offset DTA ;set DTA address
Mov AH,1Ah
Int 21h ;service 1Ah, int 21h
Mov AH,4Eh ;find first, service 4Eh
XOR CX,CX ;normal file attribute
Mov DX,FileName ;file to check for
Int 21h
Ret
Exist EndP


  3 Responses to “Category : Files from Magazines
Archive   : VOL11N21.ZIP
Filename : MLPRINT2.INC

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. 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/