home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC Press 1997 July
/
Sezamfile97_1.iso
/
msdos
/
clipper
/
fxcolor.arj
/
FXCOLOR.ASM
next >
Wrap
Assembly Source File
|
1992-04-16
|
119KB
|
2,513 lines
;▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
;▓
;▓ FXCOLOR.ASM
;▓
;▓ Written by Jim Fowler (CIS 73340,3425).
;▓
;▓ Adapted for Clipper 5.01 from code developed
;▓ by Chris Dunford (CIS 76703,2002).
;▓
;▓ This system contains functions manipulating the VGA color system allowing
;▓ special color effects to be used with Clipper 5.01.
;▓
;▓ Compile with MASM 5.x
;▓
;▓ Version History:
;▓ 04/16/92 1.00 Initial release for Clipper 5.01.
;▓ 04/16/92 1.01 Corrected bug in _UnInstall routine.
;▓
;▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
;░░░░ Callable Functions From Clipper ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ fx_Enable Initializes system, call before using others.
;░ fx_Disable Restores system, call before terminating.
;░ fx_IsFxOn Returns .T. if special effects system enabled, .F. if not.
;░ fx_IsVGA Returns .T. if VGA is present, .F. if not.
;░ fx_Restore Restores all 16 palettes for one attribute to default values.
;░ fx_RestAll Restores all 16 palettes for all attributes to default values.
;░ fx_PalRate Sets/Returns increment rate for palette changes.
;░ fx_IntRate Sets/Returns interval rate between palettes changes.
;░ fx_SetFix Sets/Returns fixed palette status. .T.=fixed palette mode on.
;░ fx_SetPal Sets/Returns the fixed palette number.
;░ fx_Palette Sets/Returns RGB values for all attributes for one palette.
;░ fx_PalAll Sets/Returns RGB values for all attributes for all palettes.
;░ fx_Attr Sets/Returns RGB values for all palettes for one attribute.
;░ fx_AttrAll Sets/Returns RGB values for all palettes for all attributes.
;░ fx_Fade Produces a fading effect for an attribute.
;░ fx_Blink Produces a blinking effect for an attribute.
;░ fx_Pulse Produces a pulsing effect for an attribute.
;░
;░ Additionally, one data item is public to other ASM or C routines. _FxEnabled
;░ is a byte variable indicating whether the color system and the intercept
;░ routine for INT 1C is enabled. A non-zero value indicates it is enabled.
;░ The value should not be reset from another ASM or C routine, or unpredictable
;░ results could occur.
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ Public Declarations ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
Public FX_ENABLE ;
Public FX_DISABLE ;
Public FX_ISFXON ;
Public FX_ISVGA ;
Public FX_RESTORE ;
Public FX_RESTALL ;
Public FX_PALRATE ;
Public FX_INTRATE ;
Public FX_SETFIX ;
Public FX_SETPAL ;
Public FX_PALETTE ;
Public FX_PALALL ;
Public FX_ATTR ;
Public FX_ATTRALL ;
Public FX_FADE ;
Public FX_BLINK ;
Public FX_PULSE ;
Public _FXENABLED ; Byte
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ External Declarations ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
Extrn __ParC:Far ;
Extrn __ParCLen:Far ;
Extrn __ParInfo:Far ;
Extrn __ParL:Far ;
Extrn __ParNI:Far ;
Extrn __Ret:Far ;
Extrn __RetCLen:Far ;
Extrn __RetL:Far ;
Extrn __RetNI:Far ;
Extrn __XFree:Far ;
Extrn __XGrab:Far ;
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ Sub-Function Definitions ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Sub-functions (AL values) for _PalFunc (INT 10h, Function 10h).
;░
_SetPalReg equ 2 ;
_GetPalReg equ 9 ;
_SetDACs equ 12h ; Not used / register level
_SetState equ 13h ;
_GetDACs equ 17h ;
_GetState equ 1Ah ;
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ Structure Definitions ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Structure for storing graded color scaling data. See _CalcScale procedure.
;░
_ScaleFact Struc
_ScaleIncr db ? ;
_XS_Count db ? ;
_XS_Incr db ? ;
_ScaleFact Ends
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;▓▓▓▓ Begin Data Segment ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
;▓
DGROUP Group _FXDATA
_FXDATA Segment Public 'DATA'
_RGBString db 16*3 dup (0) ; Storage for 48-byte RGB string
_RGBDef db 3 dup (0) ; Storage for RBG definitions
_OrigMode db ? ; Original attrib. control mode
_OrigColor db ? ; Original color select reg val
_OrigPals db 16*16*3 dup (0) ; 16 palettes, 16 attrib. each,
; 3 RGB values per attrib.
_NewPals db 16*16*3 dup (0) ; Storage for the augmented pals
_OrigRegs db 17 dup (0) ; Storage for the 16 palatte
; registers + overscan reg
; The 16 new palette register contents we will use, plus overscan.
_NewRegs db 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0
; Storage for factors used to scale one color to another over
; sixteen palettes. Don't separate or re-order; module assumes
; that the R/G/B records are contiguous and in that order.
_RedScale _ScaleFact <>
_GrnScale _ScaleFact <>
_BlueScale _ScaleFact <>
; Color definitions for our 16 base attributes with 3 R/G/B
; values each.
_NewBase Label Byte
db 00h,00h,00h ; Attribute 0 (black)
db 00h,00h,2Ah ; Attribute 1 (blue)
db 00h,2Ah,00h ; Attribute 2 (green)
db 00h,2Ah,2Ah ; Attribute 3 (cyan)
db 2Ah,00h,00h ; Attribute 4 (red)
db 2Ah,00h,2Ah ; Attribute 5 (magenta)
db 2Ah,15h,00h ; Attribute 6 (brown)
db 2Ah,2Ah,2Ah ; Attribute 7 (white)
db 15h,15h,15h ; Attribute 8 (gray)
db 00h,00h,35h ; Attribute 9 (bright blue)
db 00h,35h,00h ; Attribute 10 (bright green)
db 00h,35h,35h ; Attribute 11 (bright cyan)
db 35h,00h,00h ; Attribute 12 (bright red)
db 35h,00h,35h ; Attribute 13 (bright magenta)
db 35h,35h,00h ; Attribute 14 (yellow)
db 35h,35h,35h ; Attribute 15 (bright white)
_FxEnabled db 0 ; Flag: 0=disabled, 1=enabled
_TickRate dw 1 ; Flash rate, in timer ticks
_TickCount dw 3 ; Remaining countdown
_TickDflt dw 3 ; Default tick count
_CurPal db 0 ; Current palette #
_PalRate db 1 ; # palettes to change per flash
_FixedMode db 0 ; Flag: 0=fixed mode OFF, 1=ON
_FixedPal db 0 ; Storage for fixed palette
_XParams db 0 ; Storage for number of params
_XAttrib db 0 ; Storage for base attribute
_XSecond db 0 ; Storage for secondary attrib
_XPalette db 0 ; Storage for palette number
_XTemp db 0 ; Storage for temporary byte
_XTempW dw 0 ; Storage for temporary word
_XMemory Label DWord ; Storage for Clipper memory
_XMemVecLo dw ? ; pointer
_XMemVecHi dw ? ;
_FXDATA Ends
;▓
;▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
;▓▓▓▓ Begin Code Segment ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
;▓
_FXCODE Segment Word 'CODE'
Assume CS:_FXCODE, DS:DGROUP
;░░░░ Code Segment Variables ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
_OldInt1C Label DWord ; Storage for original INT 1Ch
_Int1CLo dw ? ; address
_Int1CHi dw ? ;
_OldInt21 Label DWord ; Storage for original INT 21h
_Int21Lo dw ? ; address
_Int21Hi dw ? ;
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ fx_Enable ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ This function must be called first to initialize the system for color
;░ functions. It accomplishes several tasks:
;░
;░ - Saves the 16 palette registers in _OrigRegs
;░ - Gets the current 256 colors (4 palettes) to _OrigPals
;░ - Duplicates palette 0 in palettes 1-15 and loads it into the VGA
;░ - Installs the INT 1C intercept
;░
;░ On exit, the system is set up, but no special effects are in use (because
;░ palettes 0-15 are identical).
;░
;░ Clipper Usage: fx_Enable()
;░
;░ Returns .F. if no VGA detected, .T. if initialized.
;░
FX_ENABLE Proc Far
Push BP ; Save registers for Clipper
Mov BP,SP ;
Push DS ;
Push SI ;
Push DI ;
Push ES ;
Mov AX,DS ; Set ES=DS
Mov ES,AX ;
Call _CheckVGA ; Test for VGA presence
JC L01_Cont1 ; Yes, continue
Jmp L01_RtnF ; No, exit
L01_Cont1: Test _FxEnabled,0FFh ; Is system already enabled?
JZ L01_Cont2 ; No, continue
Jmp L01_RtnT ; Yes, then don't redo
L01_Cont2: Mov AL,_GetState ;
Call _PalFunc ; A VGA-only function
Mov _OrigMode,BL ;
Mov _OrigColor,BH ;
; Save the 16 current palette registers into _OrigRegs. Reset the
; palette registers to contain 16 "standard" 4-bit colors.
Mov DX,Offset DS:_OrigRegs ;
Mov AL,_GetPalReg ;
Call _PalFunc ; Get current palette regs
Mov AL,_OrigRegs+16 ; Continue to use the current
And AL,0Fh ; border color
Mov _NewRegs+16,AL ;
; Save the original DAC color registers (256 colors) in _OrigPals.
Xor BX,BX ; Start with register 0
Mov CX,100h ; 256 registers
Mov DX,Offset DS:_OrigPals ; Put them in _OrigPals
Mov AL,_GetDACs ;
Call _PalFunc ;
Call _DuplPal0 ; Create 16 standard palettes
Mov DX,Offset DS:_NewRegs ;
Mov AL,_SetPalReg ;
Call _PalFunc ; Load new palette registers
Call _LoadPal ; Load new RGB values
Mov BX,100h ; Set attr control to mode 1
Mov AL,_SetState ;
Call _PalFunc ; Load new control mode 1
CLC ; Set flag for off
Call _HWBlink ; Set hardware blink OFF
Mov AX,_TickDflt ; Set defaults
Mov _TickCount,AX ;
Mov _TickRate,1 ;
Mov _CurPal,0 ;
Mov _PalRate,1 ;
Mov _FixedMode,0 ;
Mov _FixedPal,0 ;
Mov _FxEnabled,1 ; Set enabled flag
Push ES ; Get the current INT 21h
Mov AX,3521h ; address and save it
Int 21h ;
Mov CS:_Int21Lo,BX ;
Mov CS:_Int21Hi,ES ;
Pop ES ;
Push DS ; Set the INTh 21 address to
Mov DX,Offset CS:_Intrcpt21 ; _Intrcpt21.
Mov BX,CS ;
Mov DS,BX ; DS:DX = new address
Mov AX,2521h ;
Int 21h ;
Pop DS ;
Push ES ; Get the current INT 1Ch
Mov AX,351Ch ; address and save it
Int 21h ;
Mov CS:_Int1CLo,BX ;
Mov CS:_Int1CHi,ES ;
Pop ES ;
Push DS ; Set the INT 1Ch address to
Mov DX,Offset CS:_Intrcpt1C ; _Intrcpt1C.
Mov BX,CS ;
Mov DS,BX ; DS:DX = new address
Mov AX,251Ch ;
Int 21h ;
Pop DS ;
L01_RtnT: Mov AX,1 ; Set .T. return flag
Jmp Short L01_Cont3 ;
L01_RtnF: Mov AX,0 ; Set .F. return flag
L01_Cont3: Push AX ;
Call __RetL ; Clipper logical return
Add SP,2 ;
L01_End: Pop ES ; Restore registers
Pop DI ;
Pop SI ;
Pop DS ;
Pop BP ;
CLD ;
Ret ;
FX_ENABLE Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ fx_Disable ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ This function must be called for cleanup when program terminates. It
;░ uninstalls the color effect system.
;░
;░ Clipper Usage: fx_Disable()
;░
;░ Returns a NIL value.
;░
FX_DISABLE Proc Far
Push BP ; Save registers for Clipper
Mov BP,SP ;
Push DS ;
Push SI ;
Push DI ;
Push ES ;
Test _FxEnabled,0FFh ; Is the system enabled?
JZ L02_Exit ; No, then exit
Call _UnInstall ; Disable the system
L02_Exit: Call __Ret ; Clipper NIL return
Pop ES ; Restore registers
Pop DI ;
Pop SI ;
Pop DS ;
Pop BP ;
CLD ;
Ret ;
FX_DISABLE Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ fx_IsFxOn ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Tests for special effects and timer intercept enabled.
;░
;░ Clipper Usage: fx_IsFxOn()
;░
;░ Returns status of _FxEnabled flag (.T./.F.).
;░
FX_ISFXON Proc Far
Push BP ; Save registers for Clipper
Mov BP,SP ;
Push DS ;
Push SI ;
Push DI ;
Mov AL,_FxEnabled ; Get flag status
Xor AH,AH ; Clear AH
Push AX ; AX has return value
Call __RetL ; Clipper logical return
Add SP,2 ;
Pop DI ; Restore registers
Pop SI ;
Pop DS ;
Pop BP ;
CLD ;
Ret ;
FX_ISFXON Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ fx_IsVGA ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Tests for a VGA installed.
;░
;░ Clipper Usage: fx_IsVGA()
;░
;░ Returns .T. if a VGA is installed, else it returns .F.
;░
FX_ISVGA Proc Far
Push BP ; Save registers for Clipper
Mov BP,SP ;
Push DS ;
Push SI ;
Push DI ;
Mov _XTemp,1 ; Set default for .T.
Call _CheckVGA ; Test for VGA presence
JC L04_Cont ; Yes, continue
Mov _XTemp,0 ; Set for .F.
L04_Cont: Mov AL,_XTemp ; _XTemp has return value
Xor AH,AH ; Clear AH
Push AX ;
Call __RetL ; Clipper logical return
Add SP,2 ;
Pop DI ; Restore registers
Pop SI ;
Pop DS ;
Pop BP ;
CLD ;
Ret ;
FX_ISVGA Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ fx_Restore ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Restores all palettes of one attribute to the attribute's original values.
;░
;░ Clipper Usage: c_Restore( cBaseAttribute )
;░
;░ Where cBaseAttribute is the attribute to restore.
;░
;░ Returns NIL value.
;░
FX_RESTORE Proc Far
Push BP ; Save registers for Clipper
Mov BP,SP ;
Push DS ;
Push SI ;
Push DI ;
Test _FxEnabled,0FFh ; Is the system enabled?
JZ L05_Exit ; No, then exit
Call _ParamCnt ; Get number of parameters
Or AX,AX ;
JZ L05_Exit ; If zero params, then exit
Mov AX,1 ; Specify param #
Call _GetCParam ; Get the parameter
JC L05_Exit ; If not color attr, then exit
Mov _XAttrib,AL ; Save the attribute
STC ; Flag _NewBase as source
Call _SetRGBDef ; Store original RGB to _RGBDef
Push SI ; Save SI
Mov SI,Offset DS:_RGBDef ; Set pointer DS:SI to _RGBDef
Mov AL,_XAttrib ; Put attribute in AL
Mov DX,3 ; Set for 3-byte string
Mov CX,0F00h ; Set palette range (0-15)
Call _ColorAttr ; Set the new colors
Pop SI ; Restore SI
Call _LoadPal ; Load the new palettes
L05_Exit: Call __Ret ; Clipper NIL return
Pop DI ; Restore registers
Pop SI ;
Pop DS ;
Pop BP ;
CLD ;
Ret ;
FX_RESTORE Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ fx_RestAll ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Resets all palettes of all attributes to their original values and resets
;░ all flags and counters.
;░
;░ Clipper Usage: fx_RestAll()
;░
;░ Returns NIL value.
;░
FX_RESTALL Proc Far
Push BP ; Save registers for Clipper
Mov BP,SP ;
Push DS ;
Push SI ;
Push DI ;
Push ES ;
Test _FxEnabled,0FFh ; Is the system enabled?
JZ L06_Exit ; No, then exit
Call _DuplPal0 ;
Call _LoadPal ; Reset all palettes
CLI ;
Test _FixedMode,0FFh ; Is fixed palette mode?
JNZ L06_Cont ; Yes, skip setting _TickRate
Mov _TickRate,1 ; Reset counts
L06_Cont: Mov AX,_TickDflt ;
Mov _TickCount,AX ;
Mov _PalRate,1 ;
STI ;
L06_Exit: Call __Ret ; Clipper NIL return
Pop ES ; Restore registers
Pop DI ;
Pop SI ;
Pop DS ;
Pop BP ;
CLD ;
Ret ;
FX_RESTALL Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ fx_PalRate ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Sets the increment value for palette changes. When the timer counts down
;░ and the palette is to be changed, the timer intercept will add/subtract
;░ this number to the current palette number. With a higher _PalRate, the
;░ flashing occurs more rapidly. E.g., with _PalRate=1, the palettes change
;░ 0,1,2,3,...,15. With _PalRate=3, the palette changes are 0,3,6,9,12,15.
;░
;░ Clipper Usage: fx_PalRate( [nIncrement] )
;░
;░ Where nIncrement is the palette increment value in the range 1 to 15.
;░
;░ Returns current palette increment setting.
;░
FX_PALRATE Proc Far
Push BP ; Save registers for Clipper
Mov BP,SP ;
Push DS ;
Push SI ;
Push DI ;
Mov AL,_PalRate ; Get the current Pal rate
Mov _XTemp,AL ; and save it
Test _FxEnabled,0FFh ; Is the system enabled?
JZ L07_Exit ; No, return default
Call _ParamCnt ; Get number of parameters
Or AX,AX ;
JZ L07_Exit ; If zero params, then exit
Mov AX,1 ; Specify param #
Call _GetNParam ; Get the parameter
JC L07_Exit ; If not numeric, quit
Xor AH,AH ; Clear AH
Cmp AL,0Fh ; Is it <= 15?
JA L07_Exit ; No, exit
Or AL,AL ; Is it > 0?
JZ L07_Exit ; No, exit
Mov CL,AL ; Save for calculation
CLI ;
Mov _PalRate,AL ; Save the new rate
Mov AL,_CurPal ; Calculate multiple
Xor AH,AH ;
Div CL ;
Mul CL ;
Mov _CurPal,AL ; Save the new starting palette
STI ;
L07_Exit: Mov AL,_XTemp ; Get prior setting
Xor AH,AH ; Clear AH
Push AX ; AX contains prior rate
Call __RetNI ; Clipper integer return
Add SP,2 ;
Pop DI ; Restore registers
Pop SI ;
Pop DS ;
Pop BP ;
CLD ;
Ret ;
FX_PALRATE Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ fx_IntRate ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Sets the timer interval rate (every Nth ticks) for palette changes.
;░
;░ Clipper Usage: fx_IntRate( [nIntervalRate] )
;░
;░ Where nIntervalRate is the timer interval rate in the range 1 to 65535.
;░
;░ Returns current timer interval setting.
;░
FX_INTRATE Proc Far
Push BP ; Save registers for Clipper
Mov BP,SP ;
Push DS ;
Push SI ;
Push DI ;
Mov AX,_TickRate ; Get the current tick rate
Mov _XTempW,AX ; and save it
Test _FxEnabled,0FFh ; Is the system enabled?
JZ L08_Exit ; No, exit
Call _ParamCnt ; Get number of parameters
Or AX,AX ;
JZ L08_Exit ; If zero params, then exit
Mov AX,1 ; Specify param #
Call _GetNParam ; Get the parameter
JC L08_Exit ; If not numeric, quit
Or AX,AX ; Is it zero?
JZ L08_Exit ; Yes, so cannot set
CLI ;
Mov _TickRate,AX ; Save new setting
Mov _TickCount,AX ;
STI ;
L08_Exit: Mov AX,_XTempW ; AX now contains prior rate
Push AX ;
Call __RetNI ; Clipper integer return
Add SP,2 ;
Pop DI ; Restore registers
Pop SI ;
Pop DS ;
Pop BP ;
CLD ;
Ret ;
FX_INTRATE Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ fx_SetFix ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Sets/reads the _FixedMode flag. The _Fixed flag when non-zero indicates
;░ the same palette should be used and no switching of palettes by the timer
;░ intercept routine occurs. The fixed palette to display is set by the
;░ fx_SetPal() function (defalut is palette 0). When this flag is set
;░ (non-zero), the following routines have no effect:
;░
;░ - fx_PalRate()
;░ - fx_IntRate()
;░ - fx_Fade()
;░ - fx_Blink()
;░ - fx_Pulse()
;░
;░ Clipper Usage: fx_SetFix( [lFixedSetting] )
;░
;░ Where lFixedSetting = .T. cancels palette switching and .F. restores it.
;░
;░ Returns current _FixedMode flag setting (.T./.F.).
;░
FX_SETFIX Proc Far
Push BP ; Save registers for Clipper
Mov BP,SP ;
Push DS ;
Push SI ;
Push DI ;
Mov BL,_FixedMode ; Get the current flag
Mov _XTemp,BL ; And save it
Test _FxEnabled,0FFh ; Is the system enabled?
JZ L09_Exit ; No, exit
Call _ParamCnt ; Get number of parameters
Or AX,AX ;
JZ L09_Exit ; If zero params, then exit
Mov AX,1 ; Specify param #
Call _GetLParam ; Get the parameter
JC L09_Exit ; If not logical, then jump
CLI ;
Mov _FixedMode,AL ; Save new setting
Mov _TickRate,1 ; Set timer rate to default
Test AL,0FFh ; Is fixed mode ON?
JZ L09_Cont ; No, then continue
Mov _TickRate,0FFFFh ; Yes, set timer rate to max
L09_Cont: Mov AX,_TickDflt ;
Mov _TickCount,AX ; Set default count
STI ;
L09_Exit: Mov AL,_XTemp ; Get prior setting
Xor AH,AH ; Clear AH
Push AX ; AX contains prior state
Call __RetL ; Clipper logical return
Add SP,2 ;
Pop DI ; Restore registers
Pop SI ;
Pop DS ;
Pop BP ;
CLD ;
Ret ;
FX_SETFIX Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ fx_SetPal ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Sets the fixed palette number to display. Only applicable if _FixedMode
;░ flag is set (non-zero). Use fx_SetFix() to set the _FixedMode flag.
;░
;░ Clipper Usage: fx_SetPal( [nPalette] )
;░
;░ Where nPalette is the palette number to fix for display. Must be in the
;░ range 0 to 15.
;░
;░ Returns current fixed palette number.
;░
FX_SETPAL Proc Far
Push BP ; Save registers for Clipper
Mov BP,SP ;
Push DS ;
Push SI ;
Push DI ;
Mov AL,_FixedPal ; Get the current fixed palette
Mov _XTemp,AL ; and save it
Test _FxEnabled,0FFh ; Is the system enabled?
JZ L10_Exit ; No, return default value
Call _ParamCnt ; Get number of parameters
Or AX,AX ;
JZ L10_Exit ; If zero params, then exit
Mov AX,1 ; Specify param #
Call _GetNParam ; Get the parameter
JC L10_Exit ; If not numeric, quit
Cmp AL,0Fh ; Is it <= 15?
JA L10_Exit ; No, then exit
CLI ;
Mov _FixedPal,AL ; Set the palette to use
Mov AX,_TickDflt ;
Mov _TickCount,AX ; Reset current count
STI
L10_Exit: Mov AL,_XTemp ; Get prior value
Xor AH,AH ; Clear AH
Push AX ; AX contains prior palette
Call __RetNI ; Clipper integer return
Add SP,2 ;
Pop DI ; Restore registers
Pop SI ;
Pop DS ;
Pop BP ;
CLD ;
Ret ;
FX_SETPAL Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ fx_Palette ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Sets/returns the RGB values for each attribute in a palette via a 48 byte
;░ character string containing RGB values. If no string is received, or if it
;░ is not length 48 bytes, no update will occur. Values in the string greater
;░ than 63 are not updated. Similiar to fx_Attr(), except processes by palette,
;░ not attribute.
;░
;░ Clipper Usage: fx_Palette( nPalette, [cRGBString] )
;░
;░ Where nPalette is the palette number to set/return in the range 0 to 15, and
;░ cRGBString is a string of RGB values (in ASC form) for the attributes in the
;░ palette.
;░
;░ Returns a 48 byte character string containing RGB information for each
;░ attribute in the palette. Returns an empty string if a parameter error
;░ occurs.
;░
;░ RGB string information is stored in the following manner:
;░
;░ Attribute 0 Attribute 15
;░ Red Green Blue Red Green Blue
;░ Byte # -> 1 2 3 ..... 46 47 48
;░
FX_PALETTE Proc Far
Push BP ; Save registers for Clipper
Mov BP,SP ;
Push DS ;
Push SI ;
Push DI ;
Push ES ;
Test _FxEnabled,0FFh ; Is the system enabled?
JNZ L11_Go ; Yes, continue
Jmp L11_NoStr ; No, then exit
L11_Go: Call _ParamCnt ; Get number of parameters
Or AX,AX ; Is zero params?
JNZ L11_Store ; No, then continue
Jmp L11_NoStr ; Yes, then exit
L11_Store: Mov _XParams,AL ; Store the number of params
Mov AX,1 ; Specify param #
Call _GetNParam ; Get the parameter
JC L11_NoStr ; If not numeric, then exit
Cmp AL,0Fh ; Is it <= 15?
JA L11_NoStr ; No, then exit
Mov _XPalette,AL ; Save the palette number
; Copy palette to _RGBString for return string.
Mov BX,DS ; Set ES=DS
Mov ES,BX ;
Mov DI,Offset DS:_RGBString ; Point to _RGBString as dest.
Mov CL,_XPalette ; Set CL=palette
Call _GetPalPtr ; Get offset of palette
Mov SI,BX ; Point to _NewPals as source
Mov CX,18h ; 48 RGB values (24 words)
CLD ;
L11_Loop1: Lodsw ; Load word from _NewPals
Stosw ; Store word in _RGBString
Loop L11_Loop1 ; Loop until CX=0
Cmp _XParams,2 ; Is their a second param?
JB L11_Str ; No, then jump
Mov AX,2 ; Specify param #
Push AX ; Put on stack
Call __ParInfo ; Retrieve type
Add SP,2 ; Restore stack
Cmp AX,1 ; Is param character?
JNE L11_NoStr ; No, quit
Mov AX,2 ; Specify param #
Push AX ; Put on stack
Call __ParCLen ; Retrieve length
Add SP,2 ;
Cmp AX,30h ; Is it length 48?
JNE L11_NoStr ; No, quit
Mov AX,2 ; Specify param #
Push AX ; Put on stack
Call __ParC ; Retrieve value
Add SP,2 ; DX:AX point to color string
; Copy the parameter string into _NewPals.
Mov CL,_XPalette ; Retrieve palette number
Call _GetPalPtr ; Get ptr to _NewPals offset
Mov DI,BX ; Point to _NewPals as dest.
Push DS ; Save DS
Mov BX,DS ; Set ES=DS
Mov ES,BX ;
Mov DS,DX ; Point to param as source
Mov SI,AX ;
Mov CX,30h ; Set for 48 RGB values
CLD ;
L11_Loop2: Lodsb ; Load byte from param string
Cmp AL,63 ; Is RGB value <= 63
JA L11_Empty ; No, then don't store
Stosb ; Store byte in _NewPals
Jmp Short L11_Next ; Continue to next byte
L11_Empty: Inc DI ; Adjust pointer
L11_Next: Loop L11_Loop2 ; Loop until CX=0
Pop DS ; Restore DS
; Now load the new palette to VGA and finish.
Call _LoadPal ; Load the new palette
L11_Str: Mov AX,30h ; Store length (48)
Jmp Short L11_Cont ; Continue
L11_NoStr: Mov AX,0 ; Store length (0)
L11_Cont: Push AX ; Put length on stack
Mov DX,DS ; Get segment
Mov AX,Offset DS:_RGBString ; Get offset
Push DX ; Store segment
Push AX ; Store offset
Call __RetCLen ; Clipper fixed length string
Add SP,6 ;
Pop ES ; Restore registers
Pop DI ;
Pop SI ;
Pop DS ;
Pop BP ;
CLD ;
Ret ;
FX_PALETTE Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ fx_PalAll ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Sets/returns the RGB values for all attributes in all palettes via a 768 byte
;░ character string containing RGB values. If no string is received, or if it
;░ is not length 768 bytes, no update will occur. Values in the string greater
;░ than 63 are not updated. Similiar to fx_AttrAll(), except processes by
;░ palette, not attribute.
;░
;░ Clipper Usage: fx_PalAll( [cRGBString] )
;░
;░ Where cRGBString is a string of RGB values (in ASC form) for all attributes
;░ in the palette.
;░
;░ Returns a 768 byte character string containing RGB information for each
;░ attribute in all palettes. Returns an empty string if a parameter error
;░ occurs.
;░
;░ RGB string information is stored in the following manner:
;░
;░ Attribute 0 Attribute 15
;░ Red Green Blue Red Green Blue
;░ Palette 0 -> 1 2 3 ..... 46 47 48 ─┐
;░ ... -> ... ... ... ..... ... ... ... │ Byte #'s
;░ Palette 15 -> 721 722 723 ..... 766 767 768 ─┘
;░
FX_PALALL Proc Far
Push BP ; Save registers for Clipper
Mov BP,SP ;
Push DS ;
Push SI ;
Push DI ;
Push ES ;
Test _FxEnabled,0FFh ; Is the system enabled?
JNZ L12_Start ; Yes, then jump
; Not enabled, so we want to return a zero-length string and
; bypass allocating any of Clipper's memory.
Mov AX,0 ; Store length (0)
Push AX ; Put length on stack
Mov DX,DS ; Store segment
Mov AX,Offset DS:_NewPals ; Store offset
Push DX ; Put address on stack
Push AX ;
Call __RetCLen ; Clipper fixed length string
Add SP,6 ;
Jmp L12_Exit ;
; Let's grab some memory from Clipper for this one and
; copy the entire _NewPals string into memory for return.
L12_Start: Mov AX,300h ; Request 768 bytes
Push AX ; Put on stack
Call __XGrab ; Pointer returned in DX:AX
Add SP,2 ;
Mov _XMemVecLo,AX ; Save pointer
Mov _XmemVecHi,DX ;
Mov ES,DX ; Point to memory as destination
Mov DI,AX ;
Mov SI,Offset DS:_NewPals ; Point to _NewPals as source
Mov CX,180h ; 768 RGB values (384 words)
CLD ;
L12_Loop1: Lodsw ; Load word from _NewPals
Stosw ; Store word in memory
Loop L12_Loop1 ; Loop until CX=0
; Now check if a parameter string was passed for updating.
Call _ParamCnt ; Get number of parameters
Or AX,AX ;
JZ L12_Str ; If zero params, then exit
Mov AX,1 ; Specify param #
Push AX ; Put on stack
Call __ParInfo ; Retrieve type
Add SP,2 ; Restore stack
Cmp AX,1 ; Is param character?
JNE L12_NoStr ; No, quit
Mov AX,1 ; Specify param #
Push AX ; Put on stack
Call __ParCLen ; Retrieve length
Add SP,2 ;
Cmp AX,300h ; Is it length 768?
JNE L12_NoStr ; No, quit
Mov AX,1 ; Specify param #
Push AX ; Put on stack
Call __ParC ; Retrieve value
Add SP,2 ; DX:AX point to source string
; Copy the parameter string into _NewPals.
Mov BX,DS ; Set ES=DS
Mov ES,BX ;
Mov DI,Offset DS:_NewPals ; Point to _NewPals as dest.
Push DS ; Save DS
Mov DS,DX ; Point to param as source
Mov SI,AX ;
Mov CX,300h ; Set for 768 RGB values
CLD ;
L12_Loop2: Lodsb ; Load byte from param string
Cmp AL,63 ; Is RGB value <= 63
JA L12_Empty ; No, then don't store
Stosb ; Store byte in _NewPals
Jmp Short L12_Next ; Continue to next byte
L12_Empty: Inc DI ; Adjust pointer
L12_Next: Loop L12_Loop2 ; Loop until CX=0
Pop DS ; Restore DS
; Now load the new palette to VGA and finish.
Call _LoadPal ; Load the new palettes
L12_Str: Mov AX,300h ; Store length (768)
Jmp Short L12_Cont ; Continue
L12_NoStr: Mov AX,0 ; Store length (0)
L12_Cont: Push AX ; Put length on stack
Mov DX,_XMemVecHi ; Store segment
Mov AX,_XMemVecLo ; Store offset
Push DX ; Put address on stack
Push AX ;
Call __RetCLen ; Clipper fixed length string
Add SP,6 ;
Push DX ; Put address on stack
Push AX ;
Call __XFree ; Deallocate memory
Add SP,4 ;
L12_Exit: Pop ES ; Restore registers
Pop DI ;
Pop SI ;
Pop DS ;
Pop BP ;
CLD ;
Ret ;
FX_PALALL Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ fx_Attr ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Sets/returns the RGB values for an attribute in all palettes via a 48 byte
;░ character string containing RGB values. If no string is received, or if it
;░ is not length 48 bytes, no update will occur. Values in the string greater
;░ than 63 are not updated. Similiar to fx_Palette(), except processes by
;░ attribute, not palette.
;░
;░ Clipper Usage: fx_Attr( cAttribute, [cRGBString] )
;░
;░ Where cAttribute is the attribute to set/return, and cRGBString is a string
;░ of RGB values (in ASC form) for the attribute in each palette.
;░
;░ Returns a 48 byte character string containing RGB information for each
;░ palette for the attribute. Returns an empty string if a parameter error
;░ occurs.
;░
;░ RGB string information is stored in the following manner:
;░
;░ Palette 0 Palette 15
;░ Red Green Blue Red Green Blue
;░ Byte # -> 1 2 3 ..... 46 47 48
;░
FX_ATTR Proc Far
Push BP ; Save registers for Clipper
Mov BP,SP ;
Push DS ;
Push SI ;
Push DI ;
Push ES ;
Test _FxEnabled,0FFh ; Is the system enabled?
JNZ L13_Go ; Yes, continue
Jmp L13_NoStr ; No, then exit
L13_Go: Call _ParamCnt ; Get number of parameters
Or AX,AX ; Is zero params?
JNZ L13_Store ; No, then continue
Jmp L13_NoStr ; Yes, then exit
L13_Store: Mov _XParams,AL ; Store the number of params
Mov AX,1 ; Specify param #
Call _GetCParam ; Get the parameter
JC L13_NoStr ; If not character, then exit
Mov _XAttrib,AL ; Save the color attribute
; Copy Pals 0-15 for attribute to _RGBString for return string.
Mov BX,DS ; Set ES=DS
Mov ES,BX ;
Mov CX,0F00h ; Set full range for palettes
Call _GetDACPtr ; Get offset of first palette
Mov SI,BX ; Point to _NewPals as source
Mov DI,Offset DS:_RGBString ; Point to _RGBString as dest.
Mov CX,10h ; Set for 16 palettes
L13_Loop: Lodsb ; Load byte from _NewPals
Stosb ; Store byte in _RGBString
Lodsw ; Load word from _NewPals
Stosw ; Store word in _RGBString
Add SI,16*3-3 ; Adjust for next palette
Loop L13_Loop ; Loop until CX=0
Cmp _XParams,2 ; Is their a second param?
JB L13_Str ; No, then jump
Mov AX,2 ; Specify param #
Push AX ; Put on stack
Call __ParInfo ; Retrieve type
Add SP,2 ; Restore stack
Cmp AX,1 ; Is param character?
JNE L13_NoStr ; No, quit
Mov AX,2 ; Specify param #
Push AX ; Put on stack
Call __ParCLen ; Retrieve length
Add SP,2 ;
Cmp AX,30h ; Is it length 48?
JNE L13_NoStr ; No, quit
Mov AX,2 ; Specify param #
Push AX ; Put on stack
Call __ParC ; Retrieve value
Add SP,2 ; DX:AX point to color string
Mov CL,_XAttrib ; Put attribute in CL (temp)
Push DS ; Save DS
Mov BX,DS ; Set ES=DS
Mov ES,BX ;
Mov DS,DX ; Set pointer DS:SI
Mov SI,AX ;
Mov AL,CL ; Move attribute to AL
Xor AH,AH ; Clear AH
Mov DX,30h ; Set flag for 48-byte string
Mov CX,0F00h ; Set palette rabge (0-15)
Call _ColorAttr ; Set the new colors
Pop DS ; Restore DS
Call _LoadPal ; Load the new palettes
L13_Str: Mov AX,30h ; Store length (48)
Jmp Short L13_Cont ; Continue
L13_NoStr: Mov AX,0 ; Store length (0)
L13_Cont: Push AX ; Put length on stack
Mov DX,DS ; Get segment
Mov AX,Offset DS:_RGBString ; Get offset
Push DX ; Store segment
Push AX ; Store offset
Call __RetCLen ; Clipper fixed length string
Add SP,6 ;
Pop ES ; Restore registers
Pop DI ;
Pop SI ;
Pop DS ;
Pop BP ;
CLD ;
Ret ;
FX_ATTR Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ fx_AttrAll ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Sets/returns the RGB values for all attributes in all palettes via a 768 byte
;░ character string containing RGB values. If no string is received, or if it
;░ is not length 768 bytes, no update will occur. Values in the string greater
;░ than 63 are not updated. Similiar to fx_PalAll(), except processes by
;░ attribute, not palette.
;░
;░ Clipper Usage: fx_AttrAll( [cRGBString] )
;░
;░ Where cRGBString is a string of RGB values (in ASC form) for all attributes.
;░
;░ Returns a 768 byte character string containing RGB information for each
;░ attribute in all palettes. Returns an empty string if a parameter error
;░ occurs.
;░
;░ RGB string information is stored in the following manner:
;░
;░ Palette 0 Palette 15
;░ Red Green Blue Red Green Blue
;░ Attribute 0 -> 1 2 3 ..... 46 47 48 ─┐
;░ ... -> ... ... ... ..... ... ... ... │ Byte #'s
;░ Attribute 15 -> 721 722 723 ..... 766 767 768 ─┘
;░
FX_ATTRALL Proc Far
Push BP ; Save registers for Clipper
Mov BP,SP ;
Push DS ;
Push SI ;
Push DI ;
Push ES ;
Test _FxEnabled,0FFh ; Is the system enabled?
JNZ L14_Start ; Yes, then jump
; Not enabled, so we want to return a zero-length string and
; bypass allocating any of Clipper's memory.
Mov AX,0 ; Store length (0)
Push AX ; Put length on stack
Mov DX,DS ; Store segment
Mov AX,Offset DS:_NewPals ; Store offset
Push DX ; Put address on stack
Push AX ;
Call __RetCLen ; Clipper fixed length string
Add SP,6 ;
Jmp L14_Exit ;
; Let's grab some memory from Clipper for this one and
; copy the entire _NewPals string into memory for return.
; We need to adjust the placement because _NewPals stores
; info sequentially by palettes but we want to return the
; info stored sequentially by color attribute. Note that
; values are in blocks of three for RGB.
L14_Start: Mov AX,300h ; Request 768 bytes
Push AX ; Put on stack
Call __XGrab ; Pointer returned in DX:AX
Add SP,2 ;
Mov _XMemVecLo,AX ; Save pointer
Mov _XMemVecHi,DX ;
Mov ES,DX ; Point to memory as destination
Mov DI,AX ;
CLD ;
Mov AX,0 ; Start with attribute 0
L14_Loop1: Push AX ; Save current attrib on stack
Mov CX,0 ; Start with palette 0
Call _GetDACPtr ; Get ptr to _NewPals offset
Mov SI,BX ; Point to _NewPals as source
Mov CX,10h ; Set for 16 palettes
L14_Loop2: Lodsb ; Load byte from _NewPals
Stosb ; Store byte in memory
Lodsw ; Load word from _NewPals
Stosw ; Store word in memory
Add SI,16*3-3 ; Adjust ptr to next palette
Loop L14_Loop2 ; Loop until CX=0
Pop AX ; Retrieve current attribute
Inc AX ; Add one for next
Cmp AX,10h ; Have we done 16 attributes?
JB L14_Loop1 ; No, then do next attribute
; Now check if a parameter string was passed for updating.
Call _ParamCnt ; Get number of parameters
Or AX,AX ;
JZ L14_Str ; If zero params, then exit
Mov AX,1 ; Specify param #
Push AX ; Put on stack
Call __ParInfo ; Retrieve type
Add SP,2 ; Restore stack
Cmp AX,1 ; Is param character?
JNE L14_NoStr ; No, quit
Mov AX,1 ; Specify param #
Push AX ; Put on stack
Call __ParCLen ; Retrieve length
Add SP,2 ;
Cmp AX,300h ; Is it length 256*3?
JNE L14_NoStr ; No, quit
Mov AX,1 ; Specify param #
Push AX ; Put on stack
Call __ParC ; Retrieve value
Add SP,2 ; DX:AX point to source string
; Copy the parameter string into _NewPals. We need to adjust
; the placement from color attribute order (source) to palette
; order (_NewPals - destination). Note that values are in
; blocks of three for RGB.
Push DS ; Save DS
Mov BX,DS ; Set ES=DS
Mov ES,BX ;
Mov DS,DX ; Point to param as source
Mov SI,AX ;
CLD ;
Mov AX,0 ; Start with attribute 0
L14_Loop3: Push AX ; Save current attrib on stack
Mov CX,0 ; Start with palette 0
Call _GetDACPtr ; Get ptr to _NewPals offset
Mov DI,BX ; Point to _NewPals as dest.
Mov CX,10h ; Set for 16 palettes
L14_Loop4: Lodsb ; Load byte from attrib string
Cmp AL,63 ; Is color value <= 63
JA L14_Empty1 ; No, then don't store
Stosb ; Store byte in _NewPals
Jmp Short L14_Get2 ; Continue to next byte
L14_Empty1: Inc DI ; Adjust pointer
L14_Get2: Lodsb ; Load byte from attrib string
Cmp AL,63 ; Is color value <= 63
JA L14_Empty2 ; No, then don't store
Stosb ; Store byte in _NewPals
Jmp Short L14_Get3 ; Continue to next byte
L14_Empty2: Inc DI ; Adjust pointer
L14_Get3: Lodsb ; Load byte from attrib string
Cmp AL,63 ; Is color value <= 63
JA L14_Empty3 ; No, then don't store
Stosb ; Store byte in _NewPals
Jmp Short L14_Next ; Continue to next palette
L14_Empty3: Inc DI ; Adjust pointer
L14_Next: Add DI,16*3-3 ; Adjust ptr to next palette
Loop L14_Loop4 ; Loop until CX=0
Pop AX ; Retrieve current attribute
Inc AX ; Add one for next
Cmp AX,10h ; Have we done 16 attributes?
JB L14_Loop3 ; No, then do next attribute
Pop DS ; Restore DS
; Now load the new palettes to VGA and finish.
Call _LoadPal ; Load the new palettes
L14_Str: Mov AX,300h ; Store length (768)
Jmp Short L14_Cont ; Continue
L14_NoStr: Mov AX,0 ; Store length (0)
L14_Cont: Push AX ; Put length on stack
Mov DX,_XMemVecHi ; Store segment
Mov AX,_XMemVecLo ; Store offset
Push DX ; Put address on stack
Push AX ;
Call __RetCLen ; Clipper fixed length string
Add SP,6 ;
Push DX ; Put address on stack
Push AX ;
Call __XFree ; Deallocate memory
Add SP,4 ;
L14_Exit: Pop ES ; Restore registers
Pop DI ;
Pop SI ;
Pop DS ;
Pop BP ;
CLD ;
Ret ;
FX_ATTRALL Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ fx_Fade ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Produces a fading effect. The attribute slowly fades from base attribute
;░ to secondary attribute and back again repeatedly.
;░
;░ Clipper Usage: fx_Fade( cBaseAttr, cSecondAttr )
;░
;░ Where cBaseAttr is the base attribute to fade (i.e. it is the one whose RGB
;░ values are changed), cSecondAttr is the attribute color to fade TO.
;░
;░ The RGB definition used for both attributes is the values contained in
;░ _NewPals/palette 0.
;░
;░ Returns NIL value.
;░
FX_FADE Proc Far
Push BP ; Save registers for Clipper
Mov BP,SP ;
Push DS ;
Push SI ;
Push DI ;
Test _FxEnabled,0FFh ; Is the system enabled?
JZ L15_Exit ; No, then exit
Call _ParamCnt ; Get number of parameters
Cmp AX,2 ; At least 2 params?
JB L15_Exit ; No, then exit
Mov AX,1 ; Specify param #
Call _GetCParam ; Get the parameter
JC L15_Exit ; If not character, then exit
Mov _XAttrib,AL ; Save the base attribute
Mov AX,2 ; Specify param #
Call _GetCParam ; Get the parameter
JC L15_Exit ; If not character, then exit
CLC ; AL=secondary attribute
Call _SetRGBDef ; Move _NewPals RGB into _RGBDef
Mov SI,Offset DS:_RGBDef ; Get the offset
Mov AL,_XAttrib ; Set AL=base attrib.
Mov CX,0F00h ; Set palette range (0-15)
Call _ScaleAttr ; Set the palette
Call _LoadPal ;
L15_Exit: Call __Ret ; Clipper NIL return
Pop DI ; Restore registers
Pop SI ;
Pop DS ;
Pop BP ;
CLD ;
Ret ;
FX_FADE Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ fx_Blink ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Produces a blinking effect. The attribute blinks from base attribute to
;░ secondary attribute and back again repeatedly creating an On/Off effect.
;░
;░ Clipper Usage: fx_Blink( cBaseAttr, cSecondAttr, [lSoftBlink] )
;░
;░ Where cBaseAttr is the base attribute to blink (i.e. it is the one whose
;░ RGB values are changed), cSecondAttr is the attribute color to blink TO,
;░ and lSoftBlink when .T. indicates to use a fading effect. The default is
;░ .F., or no fading.
;░
;░ The RGB definition used for both attributes is the values contained in
;░ _NewPals/palette 0.
;░
;░ Returns NIL value.
;░
FX_BLINK Proc Far
Push BP ; Save registers for Clipper
Mov BP,SP ;
Push DS ;
Push SI ;
Push DI ;
Test _FxEnabled,0FFh ; Is the system enabled?
JZ L16_Exit ; No, then exit
Call _ParamCnt ; Get number of parameters
Cmp AX,2 ; At least 2 params?
JB L16_Exit ; No, then exit
Mov _XParams,AL ; Save param count
Mov AX,1 ; Specify param #
Call _GetCParam ; Get the parameter
JC L16_Exit ; If not character, then exit
Mov _XAttrib,AL ; Save the base attribute
Mov AX,2 ; Specify param #
Call _GetCParam ; Get the parameter
JC L16_Exit ; If not character, then exit
Mov _XSecond,AL ; Save the background attribute
Mov DL,0 ; Set default softblink .F.
Cmp _XParams,3 ; Is there 3 params?
JB L16_Next ; No, jump to next step
Mov AX,3 ; Specify param #
Call _GetLParam ; Get the param value
JC L16_Exit ; If not logical, exit
Mov DL,AL ; Transfer softblink flag
L16_Next: Test DL,0FFh ; Is softblink on?
JZ L16_Cont ; No, then jump
Mov AL,_XSecond ; Set RGB for background attrib
CLC ;
Call _SetRGBDef ; Move _NewPals RGB into _RGBDef
Mov SI,Offset DS:_RGBDef ; Get the offset
Mov AL,_XAttrib ; Set AL to base attribute
Mov CX,0702h ; Set starting/ending palette
Call _ScaleAttr ; Set the palette
L16_Cont: Mov AL,_XSecond ; Get background attrib to AL
Mov CL,4 ; Multiply by 16 to make it
SHL AL,CL ; in bits 4-7
Add AL,_XAttrib ; Add the attribute (bits 0-3)
Call _Blinker ; Set the palette
Call _LoadPal ; Load the palette
L16_Exit: Call __Ret ; Clipper NIL return
Pop DI ; Restore registers
Pop SI ;
Pop DS ;
Pop BP ;
CLD ;
Ret ;
FX_BLINK Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ fx_Pulse ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Produces a pulsing effect. The attribute pulses from base attribute to
;░ RGB values 75% higher for the attribute and back again from palette ranges
;░ 4 to 15.
;░
;░ Clipper Usage: fx_Pulse( cBaseAttribute )
;░
;░ Where cBaseAttribute is the base attribute to pulse.
;░
;░ Returns NIL value.
;░
FX_PULSE Proc Far
Push BP ; Save registers for Clipper
Mov BP,SP ;
Push DS ;
Push SI ;
Push DI ;
Test _FxEnabled,0FFh ; Is the system enabled?
JZ L17_Exit ; No, then exit
Call _ParamCnt ; Get number of parameters
Or AX,AX ;
JZ L17_Exit ; If zero params, then exit
Mov AX,1 ; Specify param #
Call _GetCParam ; Get the parameter
JC L17_Exit ; If not character, then exit
Mov _XAttrib,AL ; Save the base attribute
CLC ;
Call _SetRGBDef ; _RGBDef = attrib RGB values
Mov DI,0 ; Set offset counter
L17_Loop: Mov AL,_RGBDef[DI] ; Get a RGB value
Mov BL,AL ; Store it for addition
SHR AL,1 ; Divide by 2
Add BL,AL ; Add back to original
SHR AL,1 ; Divide by 2 again
Add BL,AL ; Add back again - now +75%
Cmp BL,63 ; Is it > 63?
JBE L17_Store ; No, jump
Mov BL,63 ; Set maximum 63
L17_Store: Mov _RGBDef[DI],BL ; Set new ending value
Inc DI ; Set for next RGB
Cmp DI,3 ; Is it = 3?
JB L17_Loop ; No, get next
Mov AL,_XAttrib ; Retrieve attribute
Mov CX,0F04h ; Set palette range (4-15)
Mov SI,Offset DS:_RGBDef ; Point to ending values
Call _ScaleAttr ; Now scale the palettes
Call _LoadPal ; Load the palette
L17_Exit: Call __Ret ; Clipper NIL return
Pop DI ; Restore registers
Pop SI ;
Pop DS ;
Pop BP ;
CLD ;
Ret ;
FX_PULSE Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ _ColorAttr ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ This function sets the color definitions for attribute AL in palettes
;░ CL to CH to the RGB definition at DS:SI. DX must contain the length of
;░ the RBG definition string (either 3 or 48 bytes).
;░
_COLORATTR Proc Near
Push BX ; Save registers
Push CX ;
Push SI ;
Push DI ;
Push ES ;
Mov BX,DGROUP ; Set ES=DGROUP
Mov ES,BX ;
; Address the base definition (palette CL) for this attribute.
Call _GetDACPtr ;
Mov DI,BX ; ES:DI -> first definition
Inc CH ;
Sub CH,CL ; CH = # of palettes affected
Mov CL,CH ;
Xor CH,CH ; Now CX
; Loop through the required number of palettes. Copy definitions
; from SI to palette N.
L18_Loop: Cmp DX,3 ; Is 3-byte mode?
JNE L18_Cont1 ; No, then jump
Push SI ; Save SI for 3-byte mode
L18_Cont1: Lodsb ; Load Red value for RGB
Cmp AL,63 ; Is color value <= 63
JA L18_Empty1 ; No, then don't store
Stosb ;
Jmp Short L18_Byte2 ; Continue to next byte
L18_Empty1: Inc DI ; Adjust pointer
L18_Byte2: Lodsb ; Load Green value for RGB
Cmp AL,63 ; Is color value <= 63
JA L18_Empty2 ; No, then don't store
Stosb ;
Jmp Short L18_Byte3 ; Continue to next byte
L18_Empty2: Inc DI ; Adjust pointer
L18_Byte3: Lodsb ; Load Blue value for RGB
Cmp AL,63 ; Is color value <= 63
JA L18_Empty3 ; No, then don't store
Stosb ;
Jmp Short L18_Next ; Continue
L18_Empty3: Inc DI ; Adjust pointer
L18_Next: Cmp DX,3 ; Is it 3-byte mode?
JNE L18_Cont2 ; No, then jump
Pop SI ; Restore SI for 3-byte mode
L18_Cont2: Add DI,16*3-3 ; DI -> color def in pal n+1
Loop L18_Loop ;
Pop ES ; Restore registers
Pop DI ;
Pop SI ;
Pop CX ;
Pop BX ;
Ret ;
_COLORATTR Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ _ScaleAttr ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ This function creates a scaled set of colors for attribute AL. CL contains
;░ a starting palette (0-14) and CH contains an ending palette (1-15, CH>CL).
;░
;░ DS:SI points to the "terminal" color definition, which will be the
;░ definition in palette CH. On exit, palettes CL-CH will contain "scaled"
;░ color definitions for the attribute, so that the displayed color will change
;░ slowly from the base color (in palette CL) to the terminal color (in palette
;░ CH). The color definition at DS:SI is three bytes long (one byte each for
;░ R, G, B intensity). RGB values are modulated into the range 0-63. The new
;░ palette is not sent to the VGA. _LoadPal performs that function.
;░
_SCALEATTR Proc Near
Push BX ; Save registers
Push CX ;
Push SI ;
Push DI ;
Push ES ;
Mov BX,DS ; Set ES=DS
Mov ES,BX ;
; Address the base definition (palette CL) for this color.
Call _GetDACPtr ;
Push BX ; Save initial address
Sub CH,CL ; CH = # of palettes scales
Mov CL,CH ;
Xor CH,CH ; Now CX
Mov DI,Offset DS:_RedScale ;
Call _CalcScale ; Calc red scaling factors
Call _CalcScale ; " grn " "
Call _CalcScale ; " blue " "
Pop SI ; Retrieve initial address
; Loop through the required number of palettes.
L19_Loop: Mov DI,SI ; SI/DI -> color def in pal N
Add DI,16*3 ; DI -> color def in pal N+1
; Augment RGB values for this video DAC color register
Mov BX,Offset DS:_RedScale ; Point to red scale factors
Call _Increment ; Scale red
Call _Increment ; Scale green
Call _Increment ; Scale blue
Add SI,16*3-3 ; Next palette
Loop L19_Loop ;
Pop ES ; Restore registers
Pop DI ;
Pop SI ;
Pop CX ;
Pop BX ;
Ret ;
_SCALEATTR Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ _Blinker ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ This function creates a simulated "blinking" color for attribute AL. Unlike
;░ most of the other functions, this one works with a full 8-bit attribute
;░ (bits 0-3=FG, 4-7=BG, as usual). "Blinking" is accomplished by putting the
;░ background color definition into palettes 8-15 for the selected foreground
;░ attribute.
;░
;░ Note that palettes 0-7 are not altered, so you can do whatever you want with
;░ the "visible" half of the blink text (like scaling it).
;░
_BLINKER Proc Near
Push BX ; Save registers
Push CX ;
Push DX ;
; Get a pointer to the color definition for the BG attribute.
Push AX ;
Mov CL,4 ; Mov high nibble (BG) to low
SHR AL,CL ;
Xor CL,CL ; Get ptr to def in palette 0
Call _GetDACPtr ;
Mov SI,BX ; SI->BG def, palette 0
Pop AX ;
; Now do a _ColorAttr for the FG attribute in palettes 8-15,
; using the color definition at DS:SI (which is the BG color).
And AL,0Fh ; Mask the BG attribute number
Mov CX,0F08h ; Palettes 8-15
Mov DX,3 ; Set for 3-byte string
Call _ColorAttr ;
Pop DX ; Restore registers
Pop CX ;
Pop BX ;
Ret ;
_BLINKER Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ _LoadPal ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Load the set of palettes in _NewPals into the VGA. Sets ES:SI = _NewPals.
;░
_LOADPAL Proc Near
Push ES ; Save registers
Push SI ;
Mov BX,DS ; Set ES=DS
Mov ES,BX ;
Mov SI,Offset DS:_NewPals ;
Call _SetVideo ; Load palettes to VGA
Pop SI ; Restore registers
Pop ES ;
Ret ;
_LOADPAL Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ _DuplPal0 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ This function creates 16 "standard" palettes in _NewPals.
;░
_DUPLPAL0 Proc Near
; Copy the base palette into palette 0 of _NewPals. Each color
; register contains 3 colors (R, G, and B), so the full palette
; is 16*3 bytes long.
Push ES ; Save ES register
Mov BX,DS ; Set ES=DS
Mov ES,BX ;
Mov SI,Offset DS:_NewBase ;
Mov DI,Offset DS:_NewPals ;
Mov CX,16*3/2 ; 16 colors, 3 RGB values each
CLD ;
Rep Movsw ;
; Now duplicate palette 0 (colors 0-15) to pals 1-15 (colors 16-255)
; We simplify this by allowing the copies to overlap.
Mov SI,Offset DS:_NewPals ; SI -> palette 0
Mov DI,Offset DS:_NewPals+16*3 ; DI -> palette 1
Mov CX,15*16*3/2 ; 15 pals, 16 colors, 3 bytes
Rep Movsw ;
Pop ES ; Restore ES register
Ret ;
_DUPLPAL0 Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ _CalcScale ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ This function generates the parameters for scaling a color from an initial
;░ value to a terminal value. On entry, DS:BX points to an initial color value
;░ (0-63), DS:SI points to a terminal color value (0-63), and ES:DI points to a
;░ 3-byte interpolation factor storage area. The function calculates the
;░ numbers needed to scale the color from the initial definition to the terminal
;░ definition over a span of CL palettes (normally 15).
;░
;░ The 3-byte factor storage area is filled as follows:
;░ - byte signed integer: increment/palette
;░ - byte unsigned integer: number of extra increments required
;░ - byte signed integer: excess increment value (1 or -1)
;░
;░ To scale a palette, start with palette 0 and add the increment/palette to
;░ each succeeding palette. Also add the excess increment value (1 or -1) to
;░ the first N palettes (1-N), where N is the number of extra increments. For
;░ example, if the initial color value is 21 and the terminal is 63, the factor
;░ storage area would contain 2,12,1. To scale from 21 to 63, start with the
;░ value in palette 0 and add 3 per palette (2+1) from 1-12 and two per palette
;░ from 13-15:
;░ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
;░ 21 24 27 30 33 36 39 42 45 48 51 54 57 59 61 63
;░ (Everything in the above assumes a 15-palette scale).
;░
;░ On exit, BX and SI have been incremented by one, and DI by 3. This
;░ conveniently points to the next color values and factor storage area.
;░
_CALCSCALE Proc Near
And CL,0Fh ; Make sure CL <= 15
Or CL,CL ;
JNZ L23_Cont ;
Mov CL, 0Fh ;
; Get the initial color to AH and terminal color to AL.
L23_Cont: Mov AL,[BX] ; Initial color value
Inc BX ;
Mov AH,AL ;
Lodsb ; Terminal color value
And AL,3Fh ; Force 0-63
; Compute increment/palette and number of excess increments needed.
Sub AL,AH ; AL = difference (term-init)
CBW ;
IDiv CL ; AL = inc/pal, AL = excess
Mov [DI._ScaleIncr],AL ; Store increment/palette
; Decide whether the excess increment value is +1 or -1. It will
; be -1 if the "excess" calculated above is negative; the excess
; count will also have to be made positive, if so.
Mov AL,1 ; Assume positive
Or AH,AH ; Is it negative?
JNS L23_Save ; No, continue
Neg AL ; Yes, make increment negative
Neg AH ; and count positive
L23_Save: Mov [DI._XS_Count],AH ; Store the values
Mov [DI._XS_Incr],AL ;
Add DI,Type _ScaleFact ; Next storage area
Ret ;
_CALCSCALE Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ _Increment ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ This subfunction increments a color value from palette N to palette N+1
;░ using the scale factors at DS:BX (see _CalcScale procedure).
;░
;░ At entry: DS:BX->scale factors, DS:SI->palette N color value,
;░ ES:DI -> palette N+1 color value. On exit, SI has been incremented (to
;░ point to the next color value), and BX is increased by 3 (to point to the
;░ next scale factor storage area). The _XS_Incr field of the scale factor
;░ record is decremented if not already zero.
;░
_INCREMENT Proc Near
Lodsb ; Get original R/G/B value
Add AL,[BX._ScaleIncr] ; Add per-palette increment
Test [BX._XS_Count],-1 ; Any excess increments left?
JZ L24_NoRem ; No
Dec [BX._XS_Count] ; Yes, dec remain excess count
Add AL,[BX._XS_Incr] ; Add the excess incrmt (1/-1)
L24_NoRem: Stosb ; Store the scaled value
Add BX,Type _ScaleFact ;
Ret ;
_INCREMENT Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ _SetVideo ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ This function sets the 256 video DAC color registers from the table
;░ at ES:SI, i.e., it loads the 256 colors definitions into the VGA.
;░
_SETVIDEO Proc Near
Push AX ; Save registers
Push BX ;
Push CX ;
Push DX ;
Push DS ;
Xor AX,AX ; Get port address of CRT
Mov DS,AX ; status register
Mov DX,DS:[463h] ; DX = 3x8 register
Mov AX,ES ; Set segment of data
Mov DS,AX ; to DS
Add DX,6 ; DX = 3xA, CRT status reg
Mov AH,5 ; Set retrace loop to 5
Xor CX,CX ; Clear CX
L25_Wait: In AL,DX ; Wait for a retrace
Test AL,8 ;
JNZ L25_Change ;
Loop L25_Wait ;
Dec AH ;
JNZ L25_Wait ;
L25_Change: Xor CX,CX ; Set CX = 0
CLI ; Set interrupts off
Mov DX,3C8h ; DAC address register 3C8h
L25_Loop: Mov AL,CL ; Get next DAC register
Out DX,AL ; Select DAC register
Inc DX ; DAC data register 3C9h
Lodsb ;
Out DX,AL ; Send RED value
Lodsb ;
Out DX,AL ; Send GREEN value
Lodsb ;
Out DX,AL ; Send BLUE value
Dec DX ; Back to DAC address register
Inc CX ;
Cmp CX,100h ; Have we did 256 regs?
JNE L25_Loop ; No, then do next
STI ; Set interrupts back on
Pop DS ; Restore registers
Pop DX ;
Pop CX ;
Pop BX ;
Pop AX ;
Ret ;
_SETVIDEO Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ _GetDACPtr ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Returns a pointer in BX to the color definition for attribute AL in palette
;░ CL of _NewPals.
;░
_GETDACPTR Proc Near
Push AX ; Save registers
Push DS ;
Mov BX,DGROUP ; Set DS=DGROUP
Mov DS,BX ;
And AX,0Fh ; Ensure range 0-15
Mov BX,AX ;
Mov AL,_NewRegs[BX] ; Get palreg for this attrib
Mov BX,AX ; Triple it for offset into
SHL BX,1 ; color table
Add BX,AX ; BX = 3 * color #
Mov AL,16*3 ; Bytes/palette
Mul CL ; AX -> offset of palette CL
Add BX,AX ; BX -> offset in _NewPals
Add BX,Offset DS:_NewPals ; BX -> base color definition
Pop DS ; Restore registers
Pop AX ;
Ret ;
_GETDACPTR Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ _GetPalPtr ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Returns a pointer in BX to the start of palette CL of _NewPals.
;░
_GETPALPTR Proc Near
Push DS ; Save registers
Push AX ;
Mov BX,DGROUP ; Set DS=DGROUP
Mov DS,BX ;
Mov BX,Offset DS:_NewPals ; Get offset of _NewPals
Mov AX,30h ; 48 Bytes/palette
Mul CL ; AX = offset into palette CL
Add BX,AX ; BX = start of palette CL
Pop AX ; Restore registers
Pop DS ;
Ret ;
_GETPALPTR Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ _SetRGBDef ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Moves an attribute's RGB original base values into _RGBDef variable. On
;░ entry, AL must be set to attribute. The carry flag determines the source.
;░ If the carry flag is clear, _NewPals/palette 0 is used as the source, else
;░ _NewBase is used as the source.
;░
_SETRGBDEF Proc Near
Push SI ; Save registers
Push DI ;
Push BX ;
Push CX ;
Push ES ;
JNC L28_Cont1 ; Carry clear, use _NewPals
Xor AH,AH ; Use _NewBase as source
Mov BX,AX ; AL=attribute
SHL BX,1 ; Triple it
Add BX,AX ; BX = offset into _NewBase
Add BX,Offset DS:_NewBase ;
Jmp Short L28_Cont2 ; Continue
L28_Cont1: Mov CL,0 ; Set for first palette
Test _FixedMode,0FFh ; Is fixed palette in effect?
JZ L28_GetPtr ; No, then jump
Mov CL,_FixedPal ; Set for fixed palette
L28_GetPtr: Call _GetDACPtr ; Use _NewPals as source
L28_Cont2: Mov SI,BX ; Point to source
Mov DI,Offset DS:_RGBDef ; Point to _RGBDef as dest.
Mov BX,DS ; Set ES=DS
Mov ES,BX ;
Lodsb ; Load byte from source
Stosb ; Store byte in _RGBDef
Lodsw ; Load word from source
Stosw ; Store word in _RGBDef
Pop ES ; Restore registers
Pop CX ;
Pop BX ;
Pop DI ;
Pop SI ;
Ret ;
_SETRGBDEF Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ _ParamCnt ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Test for number of parameters sent to a Clipper function.
;░
;░ Returns AX = Number of parameters.
;░
_PARAMCNT Proc Near
Mov AX,0 ; Specify param count request
Push AX ; Put on stack
Call __ParInfo ; Retrieve value
Add SP,2 ; Restore stack
Ret ; AX=number of parameters
_PARAMCNT Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ _GetNParam ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Checks/gets a Clipper numeric parameter. AX must contain the parameter
;░ number when called. Sets the carry flag if not a numeric parameter.
;░
;░ Returns AX = integer parameter.
;░
_GETNPARAM Proc Near
Push AX ; Save param number
Push AX ; Put param number on stack
Call __ParInfo ; Retrieve param type
Add SP,2 ; Restore stack
Pop BX ; Retrieve param number
Cmp AX,2 ; Is param numeric?
JNE L30_NoNum ; No, jump
Mov AX,BX ; Specify param #
Push AX ; Put on stack
Call __ParNI ; Retrieve value
Add SP,2 ; Restore stack
CLC ; Clear the carry flag
Jmp Short L30_Exit ;
L30_NoNum: STC ; Set the carry flag
L30_Exit: Ret ;
_GETNPARAM Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ _GetLParam ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Checks/gets a Clipper logical parameter. AX must contain the parameter
;░ number when called. Sets the carry flag if not a logical parameter.
;░
;░ Returns AX = logical parameter.
;░
_GETLPARAM Proc Near
Push AX ; Save param number
Push AX ; Put param number on stack
Call __ParInfo ; Retrieve param type
Add SP,2 ; Restore stack
Pop BX ; Retrieve param number
Cmp AX,4 ; Is param logical?
JNE L31_NoLog ; No, jump
Mov AX,BX ; Specify param #
Push AX ; Put on stack
Call __ParL ; Retrieve value
Add SP,2 ; Restore stack
CLC ; Clear the carry flag
Jmp Short L31_Exit ;
L31_NoLog: STC ; Set the carry flag
L31_Exit: Ret ;
_GETLPARAM Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ _GetCParam ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Checks/gets a Clipper character color parameter. AX must contain the
;░ parameter number when called. Sets the carry flag if the parameter passed
;░ is not a character string.
;░
;░ Returns AL = integer color parameter (0-15).
;░
_GETCPARAM Proc Near
Push AX ; Save param number
Push AX ; Put param number on stack
Call __ParInfo ; Retrieve param type
Add SP,2 ; Restore stack
Pop BX ; Retrieve param nummber
Cmp AX,1 ; Is param character?
JNE L32_NoChar ; No, quit
Mov AX,BX ; Specify param #
Push AX ; Put on stack
Call __ParC ; Retrieve value
Add SP,2 ; DX:AX point to color string
Call _CvtColor ; Convert string to a number
Jmp Short L32_Exit ;
L32_NoChar: STC ; Set the carry flag
L32_Exit: Ret ; Color number is in AL
_GETCPARAM Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ _CvtColor ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Converts from a Clipper character color value to a numeric color value.
;░ DX:AX must point to the character value string on entry.
;░
;░ Returns color number (0-15) in AL. Sets the carry flag if invalid color
;░ string.
;░
_CVTCOLOR Proc Near
Push DS ; Save registers
Push SI ;
Mov DS,DX ; Set DS:SI to color string
Mov SI,AX ;
Mov BX,0FFFFh ; Set BX (BH/BL) for empty test
Xor CX,CX ; Clear CX (CH/CL)
CLD ;
; CL serves as storage for high intensity value in color string.
; BH serves as storage for first character value in color string.
; BL serves as storage for second character value in color string.
; AH is temporary storage of color value.
; AL contains the byte read.
L33_GetChr: Xor AH,AH ; Clear AH
Lodsb ; Get a character in AL
Cmp AL,'+' ; Is high intensity character?
JNE L33_CheckN ; No, jump
Mov CL,8 ; Yes, store value for '+'
Jmp Short L33_GetChr ; Get next byte
L33_CheckN: And AL,0DFh ; Convert to upper case
Cmp AL,'N' ; Is 'N' character in string?
JNE L33_CheckB ; No, jump
Mov AH,0 ; Yes, store value for 'N'
Jmp Short L33_Store1 ;
L33_CheckB: Cmp AL,'B' ; Is 'B' character in string?
JNE L33_CheckG ; No, jump
Mov AH,1 ; Yes, store value for 'B'
Jmp Short L33_Store1 ;
L33_CheckG: Cmp AL,'G' ; Is 'G' character in string?
JNE L33_CheckR ; No, jump
Mov AH,2 ; Yes, store value for 'G'
Jmp Short L33_Store1 ;
L33_CheckR: Cmp AL,'R' ; Is 'R' character in string?
JNE L33_CheckW ; No, jump
Mov AH,4 ; Yes, store value for 'R'
Jmp Short L33_Store1 ;
L33_CheckW: Cmp AL,'W' ; Is 'W' character in string?
JNE L33_Null ; No, jump
Mov AH,7 ; Yes, store value for 'W'
Jmp Short L33_Store1 ;
L33_Null: Test AL,0FFh ; Is it a null character?
JZ L33_Calc ; Yes, then jump
Jmp Short L33_Error ; No, then invalid
L33_Store1: Cmp BH,0FFh ; Is BH empty?
JNE L33_Store2 ; No, then check BL
Mov BH,AH ; Yes, save first color value
Jmp Short L33_GetChr ; Get next byte
L33_Store2: Cmp BL,0FFh ; Is BL empty?
JNE L33_Calc ; No, so we must be ready
Mov BL,AH ; Save second color value
Jmp Short L33_GetChr ; Get next byte
L33_Calc: Cmp BH,0FFh ; Is first character empty?
JE L33_Error ; Yes, nothing passed so error
Mov AL,BH ; No, then store first value
Cmp BL,0FFh ; Is second character empty?
JE L33_AddHi ; Yes, then do high intensity
Add AL,BL ; No, add second value to first
L33_AddHi: Add AL,CL ; Add any high intensity value
And AL,0Fh ; Make sure it's range 0-15
CLC ; Set for valid
Jmp Short L33_Exit ;
L33_Error: STC ; Set for error
L33_Exit: Pop SI ; Restore registers
Pop DS ;
Ret ; AL contains color value
_CVTCOLOR Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ _CheckVGA ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Tests for a VGA installed.
;░
;░ Returns carry flag set if present, otherwise carry flag is clear.
;░
_CHECKVGA Proc Near
Mov AX,1A00h ; Test for VGA presence
Int 10h ; Get video display combination
Cmp AL,1Ah ; Supported function?
JNE L34_NoVGA ; No, then no VGA BIOS
Cmp BL,7 ; VGA/mono?
JE L34_GotVGA ; Yes
Cmp BL,8 ; VGA/color?
JE L34_GotVGA ; Yes
L34_NoVGA: CLC ; Set false return flag
Jmp Short L34_Exit ; Quit
L34_GotVGA: STC ; Set true return flag
L34_Exit: Ret ;
_CHECKVGA Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ _HWBlink ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Sets hardware blink on/off. Hardware blink is set ON if carry flag is
;░ set and set OFF if carry flag is clear. When hardware blink is off, it
;░ enables high intensity background colors.
;░
_HWBLINK Proc Near
JC L35_On ; If carry flag set, jump
Xor BL,BL ; Set hardware blink off
Jmp Short L35_Set ;
L35_On: Mov BL,1 ; Set hardware blink on
L35_Set: Mov AX,1003h ;
Int 10h ;
Ret ;
_HWBLINK Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ _PalFunc ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Accesses the palette control video BIOS function (Int 10h). AL contains the
;░ command number. Other appropriate registers should be set before calling.
;░
;░ Returns various information.
;░
_PALFUNC Proc Near
Mov AH,10h ; Set for function 10h
Int 10h ;
Ret ;
_PALFUNC Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ _UnInstall ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Uninstalls the color effects system.
;░ - Deactivates the INT 21h intercept
;░ - Deactivates the INT 1Ch intercept
;░ - Restores the original VGA state
;░
_UNINSTALL Proc Near
Push DS ; Save DS
Mov DX,CS:_Int1CLo ; Restore INT 1Ch to its
Mov AX,CS:_Int1CHi ; original address
Mov DS,AX ;
Mov AX,251Ch ;
Int 21h ;
Mov DX,CS:_Int21Lo ; Restore INT 21h to its
Mov AX,CS:_Int21Hi ; original address
Mov DS,AX ;
Mov AX,2521h ;
Int 21h ;
Pop DS ; Restore DS
; Restore original palette registers and video DAC color registers.
Mov AX,DS ; Set ES=DS
Mov ES,AX ;
Mov DX,Offset DS:_OrigRegs ;
Mov AL,_SetPalReg ;
Call _PalFunc ; Load original pal registers
Mov SI,Offset DS:_OrigPals ; ES:SI = _OrigPals
Call _SetVideo ; Load original RGB values
Xor BL,BL ; Restore original attribute
Mov BH,_OrigMode ; control mode
Mov AL,_SetState ;
Call _PalFunc ; Load original mode
Mov BL,1 ;
Mov BH,_OrigColor ;
Mov AL,_SetState ; Set color select register
Call _PalFunc ; Load original color
STC ; Set flag for ON
Call _HWBlink ; Set hardware blink ON
Mov _FxEnabled,0 ; Set flag for disabled
Ret ;
_UNINSTALL Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ _Intrcpt1C ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ This is the INT 1C intercept. On each timer tick, we decrement the countdown
;░ (if we are enabled). If the count goes to zero, we go to the next palette.
;░ The next palette is determined by the current palette (in _CurPal) and the
;░ _PalRate value. _PalRate is added to the current value and range checked.
;░ If the new palette is out of range, it's brought in range and the sign of
;░ _PalRate is changed. If a fixed palette mode is in effect, then no switching
;░ of palettes occurs.
;░
_INTRCPT1C Proc Far
PushF ; Save registers
Push DS ;
Push AX ;
Push BX ;
Push CX ;
Push DX ;
Mov BX,DGROUP ; Set DS=DGROUP
Mov DS,BX ;
Assume DS:DGROUP ;
CLD ;
Test _FXEnabled,0FFh ; Is the system enabled?
JZ L38_GoOrig ; No, skip
Dec _TickCount ; Is count zero?
JNZ L38_GoOrig ; No, skip
Test _FixedMode,0FFh ; Is fixed palette mode?
JZ L38_Switch ; No
Mov BH,_FixedPal ; Yes, then set fixed palette
Jmp Short L38_PalOK ;
; _TickCount has zeroed, switch palettes by adding the _PalRate.
; If the palette number goes out of range, reverse the sign of the
; _PalRate and bring the palette number back into range. _CurPal
; has the current palette number.
L38_Switch: Mov BH,_CurPal ; Get current palette
Add BH,_PalRate ; Add the _PalRate
JS L38_Revers ; Go if new palette not negative
Cmp BH,15 ; Chk for positive out-of-range
JBE L38_PalOk ; It's OK
L38_Revers: Neg _PalRate ; Reverse the direction
Add BH,_PalRate ; Do twice to cancel out the
Add BH,_PalRate ; earlier addition
L38_PalOk: Mov _CurPal,BH ; Save new palette number
; Use register-level programming of the attribute control reg (ACR).
Xor AX,AX ; Get port address of CRT
Push DS ; status register
Mov DS,AX ;
Mov DX,DS:[463h] ; DX = 3x8 register
Pop DS ;
Add DX,6 ; DX = 3xA, CRT status reg
Mov AH,5 ; Set retrace loop to 5
Push CX ; Save CX
Xor CX,CX ; Clear CX
L38_Wait: In AL,DX ; Wait for a retrace
Test AL,8 ;
JNZ L38_Change ;
Loop L38_Wait ;
Dec AH ;
JNZ L38_Wait ;
L38_Change: Pop CX ; Restore CX
CLI ; Set interrupts off
In AL,DX ; Set addr/data flipflop in ACR
Push DX ; Save CRT status reg port #
Mov DX,3C0h ; ACR reg 14h (color select)
Mov AL,14h ;
Out DX,AL ; Set color select
Jmp $+2 ;
Mov AL,BH ;
Out DX,AL ; Send color select data
Pop DX ; Recover CRT status reg
In AL,DX ; Reset flipflop
Mov DX,3C0h ; ACR again
Mov AL,20h ;
Out DX,AL ; Restore palette
Mov AX,_TickRate ; Reset the count
Mov _TickCount,AX ;
STI ; Set interrupts back on
L38_GoOrig: Pop DX ; Restore registers
Pop CX ;
Pop BX ;
Pop AX ;
Pop DS ;
PopF ;
Assume DS:Nothing ;
Jmp _OldInt1C ; Go to original INT 1C
_INTRCPT1C Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░ _Intrcpt21 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░
;░ Interrupt 21 intercept. Checks for termination function 4Ch. If valid,
;░ it uninstalls the color effects system.
;░
_INTRCPT21 Proc Far
PushF ; Save flags
Cmp AH,4Ch ; Check for program termination
JNE L39_GoOrig ; No, then jump
Push AX ; Save registers
Push BX ;
Push CX ;
Push DX ;
Push SI ;
Push DI ;
Push ES ;
Push DS ;
Mov BX,DGROUP ; Set DS=DGROUP
Mov DS,BX ;
Assume DS:DGROUP ;
CLD ;
Call _UnInstall ; Uninstall
Pop DS ; Restore registers
Pop ES ;
Pop DI ;
Pop SI ;
Pop DX ;
Pop CX ;
Pop BX ;
Pop AX ;
L39_GoOrig: PopF ;
Assume DS:Nothing ;
Jmp _OldInt21 ; Go to original INT 21
_INTRCPT21 Endp
;░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_FXCODE Ends
End
;▓
;▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
; {EOF: fxcolor.asm}