| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638 |
- ;
- ; Command & Conquer Red Alert(tm)
- ; Copyright 2025 Electronic Arts Inc.
- ;
- ; This program is free software: you can redistribute it and/or modify
- ; it under the terms of the GNU General Public License as published by
- ; the Free Software Foundation, either version 3 of the License, or
- ; (at your option) any later version.
- ;
- ; This program is distributed in the hope that it will be useful,
- ; but WITHOUT ANY WARRANTY; without even the implied warranty of
- ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ; GNU General Public License for more details.
- ;
- ; You should have received a copy of the GNU General Public License
- ; along with this program. If not, see <http://www.gnu.org/licenses/>.
- ;
- ;***************************************************************************
- ;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
- ;***************************************************************************
- ;* *
- ;* Project Name : Westwood 32 bit Library *
- ;* (Mouse Routines)
- ;* *
- ;* File Name : KEYIREAL.ASM *
- ;* *
- ;* Programmer : Philip W. Gorrow *
- ;* *
- ;* Start Date : May 21, 1992 *
- ;* *
- ;* Last Update : July 13, 1994 [PWG] *
- ;* *
- ;* This file sort of breaks the standard of keeping all of the keyboard *
- ;* and mouse routines isolated. This is done because the mouse and *
- ;* the keyboard share data, and the best way to do this is to put *
- ;* them in the same segment. This should probably be split into several *
- ;* include files to help make the code clearer once it is finally put *
- ;* together. *
- ;* *
- ;*-------------------------------------------------------------------------*
- ;* Functions: *
- ;* KeyNum_Translate -- Translates extended keynums to normal keynums *
- ;* Stuff_Key_Word -- Stuffs a word of data into keyboard buffer *
- ;* Stuff_Key_Num -- Stuffs a key num code into the circular buffer *
- ;* Keystroke_Interrupt -- Real mode handler of input from the keyboard *
- ;* Break_Interrupt -- Handles the break key interrupt *
- ;* Call_Interrupt_Chain -- Function PM calls to call RM interrupt chain *
- ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
- ;* *
- ;* Keyboard driver -- 8086 Assembly portion; *
- ;* updated by: Phil Gorrow for 32 bit Protected Mode *
- ;***************************************************************************
- ;---------------------------------------------------------------------------
- ; Set the assembly directives
- ;---------------------------------------------------------------------------
- IDEAL ; the product runs in ideal mode
- P386N ; use 386 real mode instructions
- MODEL TINY ; code must be tiny so it fits
- LOCALS ?? ; ?? is the symbol for a local
- WARN ; generate all warnings we can
- JUMPS ; optimize jumps if possible
- ;---------------------------------------------------------------------------
- ; Include all of the keyboard specific defines
- ;---------------------------------------------------------------------------
- INCLUDE "keyboard.inc"
- CONDHIDE EQU 08000H ; bit for testing conditional region
- CONDHIDDEN EQU 04000H ; bit for testing conditional hidden
- RESTORE_VISIBLE_PAGE EQU 0
- STORE_VISIBLE_PAGE EQU 1
- GLOBAL set_vesa_page :near
- GLOBAL set_vesa_window :near
- GLOBAL get_vesa_window :near
- GLOBAL next_vesa_page :near
- ECHOON equ 0
- ;---------------------------------------------------------------------------
- ; WARNING!!!! All of the following code segment variables are shared by
- ; the protected mode interrupt. Do not change these unless you make the
- ; proper changes to KEYSTRUC.INC. If you do not know what you are doing,
- ; find someone who does!!!
- ;---------------------------------------------------------------------------
- CODESEG
- ;---------------------------------------------------------------------------
- ; Begin definition of Keyboard specific variables
- ;---------------------------------------------------------------------------
- SoundOn DW 1 ; toggled by alt S
- MusicOn DW 1 ; toggled by alt M
- KeyFlags DD REPEATON+CTRLALTTURBO ; all but repeat for now
- Break DW 0
- KeyMouseMove DB -1,0,1
- DB -16,0,16
- ScreenEdge DW 320/2,0 ; North
- DW 319,0 ; North-East
- DW 319,138/2 ; East
- DW 319,137 ; South-East
- DW 320/2,137 ; South
- DW 0,137 ; South-West
- DW 0,138/2 ; West
- DW 0,0 ; North-West
- DW 320/2,138/2 ; Center
- Bits DB 01H,02H,04H,08H,10H,20H,40H,80H
- CondPassKey DW 0220H, 0320H, 060CH, 070DH, 066AH
- DW 0669H, 0230H, 0330H, 007DH, 017DH
- DW 025AH, 035AH, 0200H, 0410H, 046EH
- DW 026EH, 007CH
- CondPassCond DW CTRLSON, CTRLSON, CTRLALTTURBO, CTRLALTTURBO, CTRLALTTURBO
- DW CTRLALTTURBO, CTRLCON, CTRLCON, SCROLLLOCKON, SCROLLLOCKON
- DW PAUSEON, PAUSEON, BREAKON, TASKSWITCHABLE, TASKSWITCHABLE
- DW TASKSWITCHABLE, BREAKON
- EscRoutine DD 0 ; vector to execute on esc key press (0=none)
- ; Extended raw keycodes to be converted to Westwood keycodes.
- ExtCodes DB 038H,01DH,052H,053H,04BH,047H,04FH,048H,050H,049H
- DB 051H,04DH,035H,01CH,037H
- DB 046H
- ; The matching Westwood keycodes.
- ExtNums DB 62, 64, 75, 76, 79, 80, 81, 83, 84, 85
- DB 86, 89, 95, 108, 124, 0
- ; If extended mapping is disabled, then these codes really are...
- ExtRemap DB 60, 58, 99, 104, 92, 91, 93, 96, 98, 101
- DB 103, 102, 55, 43, 124, 0
- ExtRemapEnd DB 0
- ExtKeyboard DB 0 ; flag for 101/102-key keyboard
- KeyBuffer DW 128 DUP(0) ; set to empty
- KeyBufferHead DD 0 ; set to first entry
- KeyBufferTail DD 0 ; set to head for empty buffer
- KeyLock DW 0 ; num and caps lock bits
- KeyNums DB 127,110,002,003,004,005,006,007,008,009,010,011,012,013,015,016
- DB 017,018,019,020,021,022,023,024,025,026,027,028,043,058,031,032
- DB 033,034,035,036,037,038,039,040,041,001,044,029,046,047,048,049
- DB 050,051,052,053,054,055,057,100,060,061,030,112,113,114,115,116
- DB 117,118,119,120,121,090,125,091,096,101,105,092,097,102,106,093
- DB 098,103,099,104,127,127,127,122,123
- KeysCapsLock DB 0,0,0FEH,087H,0FFH,0C0H,01FH,0,0,0,0,0,0,0,0,0
- KeysNumLock DB 0,0,0,0,0,0,0,0,0,0,0,038H,0EFH,1,0,0
- KeysUpDown DB 16 DUP(0) ; set to all keys up
- KeyStream DB 16 DUP(0) ; set to all keys up
- PassCount DW 0
- KeyStreamIndex DW 0
- LastKeyE0 DB 0
- LastKeyE1 DB 0
- ;
- ; Westwood key number values of keys to pass through
- ;
- ; CAPS, LEFT_SHIFT, RIGHT_SHIFT, LEFT_CTRL, LEFT_ALT,
- ; RIGHT_ALT, RIGHT_CTRL, NUM_LOCK, UNKNOWN
- PassAlways DB 30, 44, 57, 58, 60, 62, 64, 90, 128, 128
- PassAlwaysEnd DB 128 ; invalid code to END PassAlways
- CtrlFlags DB 0
- Buffer DW ?
- Time DW ?
- ADJUST = 1 ; do not modify DRD
- XYAdjust DB -ADJUST, -ADJUST ; 91 -> upleft
- DB -ADJUST, 0 ; 92 -> left
- DB -ADJUST, ADJUST ; 93 -> downleft
- DB 0, 0 ; 94 illegal
- DB 0, 0 ; 95 illegal
- DB 0, -ADJUST ; 96 -> up
- DB 0, 0 ; 97 illegal (center)
- DB 0, ADJUST ; 98 -> down
- DB 0, 0 ; 99 illegal
- DB 0, 0 ; 100 illegal
- DB ADJUST, -ADJUST ; 101 -> upright
- DB ADJUST, 0 ; 102 -> right
- DB ADJUST, ADJUST ; 103 -> downright
- EdgeConv DW 8,2,8,6,4,3,8,5,8,8,8,8,0,1,8,7
- MouseUpdate DW 0
- MouseX DW 0,0
- LocalMouseX DW 0
- MouseY DW 0,0
- LocalMouseY DW 0
- IsExtKey DB 0
- ExtIndex DW 0
- KeyOldRMI DD 0 ; The origianl RM interrupt seg:off.
- KeyOldPMIOffset DD 0 ; The origianl PM interrupt offset
- KeyOldPMISelector DD 0 ; The original PM interrupt segment.
- KeyCodeOffset DW RM_Keystroke_Interrupt ; Offset of the code in the RM stuff.
- CallKeyRMIntOffset DW Call_Interrupt_Chain ; Offset of function to call DOS timer interrupt.
- CallKeyRMIntAddr DD 0 ; PM address of CallRealIntOffset for speed.
- PMIssuedKeyInt DD 0
- BrkOldRMI DD 0 ; The origianl RM interrupt seg:off.
- BrkOldPMIOffset DD 0 ; The origianl PM interrupt offset
- BrkOldPMISelector DD 0 ; The original PM interrupt segment.
- BrkCodeOffset DW RM_Break_Interrupt ; Offset of the code in the RM stuff.
- CallBrkRMIntOffset DW 0
- CallBrkRMIntAddr DD 0 ; PM address of CallRealIntOffset for speed.
- PMIssuedBrkInt DD 0
- KeyIntDisabled DD 0
- DbgOldPMIOffset DD 0 ; The origianl PM interrupt offset
- DbgOldPMISelector DD 0 ; The original PM interrupt segment.
- ;---------------------------------------------------------------------------
- ; Begin definition of Mouse Specific Variables for real mode
- ;---------------------------------------------------------------------------
- Button DB 0 ; current value of the mouse button
- MDisabled DB 0 ; Is the mouse driver disabled
- MInput DB 1 ; Defaults to mouse input allowed.
- Adjust DW 0 ; flag to adjust coordinates if necessary
- MouseStepX DW 0 ; step values if the mouse moves at
- MouseStepY DW 0 ; more than one pixel at a time
- MouseOffsetX DW 0 ; Fractional step values used if a mouse
- MouseOffsetY DW 0 ; moves at less than one pixel at a time
- MState DW 0,0 ; Tracks if mouse is hidden (TRUE) or not (FALSE)
- MouseXOld DW 0 ; Holds last MouseX and MouseY to determine if
- MouseYOld DW 0 ; mouse needs to be redrawn
- MCState DW 0 ; Tracks if mouse conditional hidden (TRUE) or not
- MouseCXLeft DW 0,0 ; Conditional hide mouse left x position
- MouseCYUpper DW 0,0 ; Conditional hide mouse top y position
- MouseCXRight DW 0,0 ; Conditional hide mouse right x position
- MouseCYLower DW 0,0 ; Conditional hide mouse lower y position
- MouseCursor DD 0 ; Pointer to the mouse cursor to draw
- MouseCursorSize DW 0 ; Pointer to buffer mouse is saved in
- MouseBuffer DD 0 ; Pointer to buffer mouse is saved in
- MouseXHot DW 0,0 ; Offset to mouse's x hot spot
- MouseYHot DW 0,0 ; Offset to mouse's y hot spot
- MouseBuffX DW 0,0 ; X position background was saved at
- MouseBuffY DW 0,0 ; Y position background was saved at
- MouseBuffW DW 0,0 ; Width of the region saved for mouse
- MouseBuffH DW 0,0 ; Height of the region saved for mouse
- MouseWidth DW 0,0 ; Mouse cursor theoretical width
- MouseHeight DW 0,0 ; Mouse cursor theoretical height
- MouseCodeOffset DW RM_Mouse_Interrupt ; Offset of the code in the RM stuff.
- MouseRight DW 0,0
- MouseBottom DW 0,0
- ShadowPtr dw 0
- DrawMousePtr dw 0
- VGAMouseDraw dw VGA_Draw_Mouse
- VGAMouseShadow dw VGA_Mouse_Shadow_Buffer
- VESAMouseDraw dw VESA_Draw_Mouse
- VESAMouseShadow dw VESA_Mouse_Shadow_Buffer
- VesaPtr dd 0
- banktable dd 8 dup ( 0 )
- Adjust_XPos dw 0 , 0
- Adjust_YPos dw 0 , 0
- align 2
- Keyboard_App_Stack_ES dw 0 ; This the System Stack Offsset
- Keyboard_App_Stack_SS dw 0 ; This the System Stack Selector
- Keyboard_StackPointer dw 0DEADh ; We Create a Local Application
- Keyboard_Stack dw 512 dup (0)
- Keyboard_StackStart dw 0
- Mouse_State dw 0 ; Mouse Temp Variable
- Mouse_Cond dw 0 ; Mouse Temp Variable
- Mouse_App_Stack_ES dw 0 ; This the System Stack Offsset
- Mouse_App_Stack_SS dw 0 ; This the System Stack Selector
- Mouse_StackPointer dw 0DEADh ; We Create a Local Application
- Mouse_Stack dw 512 dup (0)
- Mouse_StackStart dw 0
- current_page dw 0
- ;***************************************************************************
- ;* KEYNUM_TRANSLATE -- Translates extended keynums to normal keynums *
- ;* *
- ;* INPUT: UWORD the keynum to translate *
- ;* *
- ;* OUTPUT: WORD the translated keynum *
- ;* *
- ;* PROTO: UWORD KeyNum_Translate(UWORD keynum); *
- ;* *
- ;* HISTORY: *
- ;* 07/11/1994 PWG : Created. *
- ;*=========================================================================*
- GLOBAL KeyNum_Translate:FAR
- PROC KeyNum_Translate C FAR
- USES cx,di,es,ds
- ARG keycode:WORD
- mov ax,cs ; since we are in tiny model
- mov ds,ax ; set cs = ds
- mov es,ax ; set es up for scansb
- mov ax,[keycode]
- test [WORD PTR KeyFlags],TRACKEXT
- jne short ??fini
- mov cx,ExtRemap-ExtNums
- mov di,OFFSET ExtNums
- repne scasb
- jcxz short ??fini ; No match found.
- mov di,OFFSET ExtRemapEnd
- dec di
- sub di,cx
- mov al,[es:di]
- ??fini:
- ret
- ENDP KeyNum_Translate
- ;***************************************************************************
- ;* STUFF_KEY_WORD -- Stuffs a word of data into keyboard buffer *
- ;* *
- ;* INPUT: WORD the code to stick into the circular buffer *
- ;* *
- ;* OUTPUT: WORD !=0 is sucessful, ==0 is not enough room *
- ;* *
- ;* PROTO: VOID Stuff_Key_WORD(WORD code); *
- ;* *
- ;* HISTORY: *
- ;* 07/11/1994 PWG : Created. *
- ;*=========================================================================*
- GLOBAL C Stuff_Key_WORD:FAR
- PROC Stuff_Key_WORD C FAR
- USES si,bx,ds
- ARG code:WORD
- mov ax,cs ; since we are in tiny model
- mov ds,ax ; set cs = ds
- mov ax,[WORD PTR KeyBufferTail]
- mov si,ax
- add ax,2
- and ax,0FFh ; New KeyBufferTail value.
- cmp [WORD PTR KeyBufferHead],ax
- je short ??noroom
- mov bx,[code]
- mov [KeyBuffer+si],bx ; Record the keystroke.
- mov [WORD PTR KeyBufferTail],ax
- xor ax,ax
- ret
- ??noroom:
- mov ax,1
- ret
- ENDP Stuff_Key_WORD
- ;***************************************************************************
- ;* STUFF_KEY_NUM -- Stuffs a key num code into the circular buffer *
- ;* *
- ;* INPUT: WORD the keycode to stuff *
- ;* *
- ;* OUTPUT: WORD !=0 is sucessful, ==0 is not enough room *
- ;* *
- ;* PROTO: VOID Stuff_Key_Num(WORD keynum); *
- ;* *
- ;* HISTORY: *
- ;* 07/11/1994 PWG : Created. *
- ;*=========================================================================*
- GLOBAL C Stuff_Key_Num:FAR
- PROC Stuff_Key_Num C FAR
- USES bx,cx,dx,di,si,ds
- ARG keycode:WORD
- LOCAL tail:WORD ; Original keybuffer tail (safety copy).
- LOCAL size:WORD ; Size of write.
- pushf
- cli ; disable interrupts
- ; Abort key recognition if in record mode and unable
- ; to output key due to simultaneous DOS operation.
- mov ax,cs ; since we are in tiny model
- mov ds,ax ; set cs = ds
- ; Record the mouse position to be stuffed into buffer.
- mov ax,[MouseX]
- mov [LocalMouseX],ax
- mov ax,[MouseY]
- mov [LocalMouseY],ax
- ??cando:
- mov ax,[keycode] ; get the code
- or ax,ax ; Null keycodes are not recorded.
- jne short ??validkey
- jmp ??exit
- ??validkey:
- test [WORD PTR KeyFlags],KEYMOUSE ; is the numeric keypad moving the mouse?
- je ??no_pad_move
- ; ALT-cursor keys are undefined. Pass them on to the program.
- test ah,ALTPRESS ; is either alt key down?
- jne ??no_pad_move
- test [WORD PTR KeyFlags],SIMLBUTTON ; are we simulating left mouse presses
- je short ??chkinsert
- cmp al,KN_RETURN
- je short ??forceleft
- cmp al,KN_SPACE
- je short ??forceleft
- cmp al,KN_KEYPAD_RETURN
- je short ??forceleft
- ??chkinsert:
- cmp al,KN_INSERT
- jne short ??regular
- ??forceleft:
- mov al,KN_LMOUSE
- or [Button],1 ; Left mouse bit.
- test ah,KEYRELEASE
- je ??mousefake
- and [Button],NOT 1
- jmp ??mousefake
- ??regular:
- cmp al,KN_DELETE
- jne short ??regular2
- mov al,KN_RMOUSE
- or [Button],2 ; Right mouse bit.
- test ah,KEYRELEASE
- je ??mousefake
- and [Button],NOT 2
- jmp ??mousefake
- ??regular2:
- ; DRD correction to ignore key releases for key mouse movement
- test ah,KEYRELEASE
- jne ??no_pad_move
- cmp al,KN_CENTER
- je short ??pad_move
- cmp al,KN_UPLEFT ; less than upleft?
- jb ??no_pad_move ; yes, then it isn't a keypad key
- cmp al,KN_DOWNRIGHT ; greater than downright?
- ja ??no_pad_move ; yes, then it isn't a keypad key
- cmp al,KN_DOWNLEFT ; is it UPLEFT, LEFT, or DOWNLEFT?
- jbe short ??pad_move
- cmp al,KN_UPRIGHT ; is it UPRIGHT, RIGHT, or DOWNRIGHT?
- jae short ??pad_move
- cmp al,KN_UP ; up?
- je short ??pad_move
- cmp al,KN_DOWN ; down?
- jne ??no_pad_move
- ??pad_move:
- ; DRD correction to use ch for ah
- mov ch,ah ; save shift-ctrl-alt-rlse status
- xor ah,ah ; get rid of any bits
- sub al,KN_UPLEFT ; get a number between 0 and 12
- mov bx,ax
- shl bx,1 ; double for WORD index
- add bx,OFFSET XYAdjust
- mov ax,[bx] ; get x,y add value
- mov bl,ah
- cbw
- xchg ax,bx
- cbw
- xchg ax,bx ; AX = mouse x delta, BX = mouse y delta
- ; DRD correction to use ch
- ; The CTRL key moves the mouse to the edge of the screen.
- test ch,CTRLPRESS ; is either ctrl key down?
- jne short ??ctrlon ; if so, ctrl is on
- ; DRD correction to use ch
- ; use fast speed of the mouse move if the shift key is held down.
- mov dx,1 ; for slow speed
- test ch,SHIFTPRESS ; is either shift key down?
- je short ??normspeed ; if not then neither shift is down
- ??doublespeed:
- add dx,3 ; for fast speed
- ??normspeed:
- add bx,dx ; add speed for y index
- mov bl,[KeyMouseMove+bx] ; get speed for y delta
- xchg ax,bx ; swap with ax to extend sign
- cbw
- xchg ax,bx
- xchg bx,dx ; save mouse y delta
- add bx,ax ; add speed for x index
- mov al,[KeyMouseMove+bx] ; get speed for x delta
- cbw
- xchg bx,dx ; restore mouse y delta
- jmp short ??ctrloff
- ??ctrlon:
- ; Table lookup method for determining hotkey positions for CTRL
- ; cursor combination. This algorithm is hard coded for an ADJUST
- ; value of 3. If this value changed, then this section will also
- ; have to be modified.
- and bx,011b ; Y = 1, 0, 3
- and ax,011b ; X = 1, 0, 3
- ; Table lookup method for determining hotkey positions for CTRL
- ; cursor combination. This algorithm is hard coded.
- ; -1, 0, 1
- and bx,011b ; Y = 3, 0, 1
- and ax,011b ; X = 3, 0, 1
- shl bx,1
- shl bx,1
- or bx,ax ; Lookup index.
- ; Convert raw index into logical (clockwise) index.
- shl bx,1
- mov bx,[EdgeConv+bx]
- shl bx,1
- shl bx,1
- mov ax,[ScreenEdge+bx] ; New absolute X
- mov bx,[ScreenEdge+bx+2] ; New absolute Y
- mov [LocalMouseX],ax
- mov [LocalMouseY],bx
- ??set_xyz:
- mov ax,[LocalMouseX] ; get new mouse x,y
- mov bx,[LocalMouseY]
- jmp short ??set_xy
- ; Process a normal faked mouse move.
- ??ctrloff:
- ; DRD change
- add [LocalMouseX],ax ; save it in our local
- jns short ??not_negative_x
- xor ax,ax
- mov [LocalMouseX],ax ; clear our local
- ??not_negative_x:
- ; DRD change
- add [LocalMouseY],bx ; save it in our local
- jns short ??not_negative_y
- xor bx,bx
- mov [LocalMouseY],bx ; clear our local
- ??not_negative_y:
- mov ax,[LocalMouseX] ; get new mouse x,y
- mov bx,[LocalMouseY]
- cmp ax,MAX_X_PIXEL ; bigger than
- jle short ??check_y
- mov ax,MAX_X_PIXEL
- ??check_y:
- cmp bx,MAX_Y_PIXEL ; bigger than
- jle short ??set_xy
- mov bx,MAX_Y_PIXEL
- ??set_xy:
- mov [LocalMouseX],ax
- mov [LocalMouseY],bx
- mov [MouseX],ax
- mov [MouseY],bx
- cmp [MouseUpdate],0 ; wait until mouse interrupt is done
- jne short ??noshow
- call Low_Hide_Mouse
- call Low_Show_Mouse
- ??noshow:
- mov ax,KN_MOUSE_MOVE
- ??mousefake:
- mov [keycode],ax ; Fake a MOUSE_MOVE event.
- ??no_pad_move:
- ; Fetch working pointers to the keyboard ends.
- mov si,[WORD KeyBufferTail]
- mov [tail],si ; Safety record.
- mov di,[WORD PTR KeyBufferHead]
- ; Record the base keycode (if there is room).
- push ax
- call Stuff_Key_WORD
- add sp,2
- or ax,ax
- jne short ??jmpnoroom
- ; Also record the mouse coordinates if necessary.
- mov ax,[keycode] ; get key code
- cmp al,KN_MOUSE_MOVE ; mouse move?
- je short ??recordmouse ; yes? then record the mouse cooordinates
- cmp al,KN_LMOUSE
- je short ??recordmouse
- cmp al,KN_RMOUSE
- je short ??recordmouse
- jmp short ??ok
- ??jmpnoroom:
- jmp ??noroom
- ; Record mouse coordinate X.
- ??recordmouse:
- push [LocalMouseX]
- call Stuff_Key_WORD
- add sp,2
- or ax,ax
- jne ??jmpnoroom
- add [size],2
- ; Record mouse coordinate Y.
- push [LocalMouseY]
- call Stuff_Key_WORD
- add sp,2
- or ax,ax
- jne ??jmpnoroom
- add [size],2
- ??ok:
- ; If PASSBREAKS is not active and this is a keyboard
- ; break AND it is not a mouse event, then don't put
- ; it into the buffer.
- mov bx,0101h ; Bit control tools.
- mov ax,[keycode]
- cmp al,KN_MOUSE_MOVE
- je short ??notreal
- cmp al,127
- je short ??notreal
- test ah,KEYRELEASE
- je short ??real
- xor bl,bl
- test [WORD PTR KeyFlags],PASSBREAKS
- jne short ??real
- cmp al,KN_LMOUSE
- je short ??real
- cmp al,KN_RMOUSE
- je short ??real
- ??notreal:
- mov [WORD PTR KeyBufferTail],si ; Nullify any KeyBufferTail changes.
- ??real:
- ; Update the KeysUpDown bit array.
- mov di,ax
- and di,07Fh
- mov cl,3
- shr di,cl ; DI = Byte offset into bit table.
- mov cl,al
- and cl,0111b ; CL = Bit offset into bit table byte.
- shl bx,cl
- not bh
- ; If this is a reapeat key and the key is already being held
- ; down, then don't stuff it into the keyboard buffer.
- test bl,[KeysUpDown+di]
- je short ??notalready
- test [WORD PTR KeyFlags],REPEATON
- jne short ??notalready
- mov [WORD PTR KeyBufferTail],si ; Nullify any KeyBufferTail changes.
- ??notalready:
- and [KeysUpDown+di],bh ; Force key bit to zero.
- or [KeysUpDown+di],bl ; Insert key bit as appropriate.
- ;??notreal:
- ; Successful keybuffer stuff could result in a
- ??norecord:
- mov ax,1
- jmp short ??exit
- ; Unsuccessful keybuffer stuff.
- ??noroom:
- mov ax,[tail]
- mov [WORD PTR KeyBufferTail],ax
- xor ax,ax ; Signal an error.
- ??exit:
- popf
- ret
- ENDP Stuff_Key_Num
- ;***********************************************************
- ;***************************************************************************
- ;* KEYSTROKE_INTERRUPT -- Handles input that comes from the keyboard *
- ;* *
- ;* This routine intercepts the key codes on their way to the *
- ;* BIOS. With the adjustment of the Flags described above *
- ;* you can get a wide variety of effects. *
- ;* *
- ;* INPUT: none *
- ;* *
- ;* OUTPUT: none *
- ;* *
- ;* WARNINGS: This is an interrupt function *
- ;* *
- ;* HISTORY: *
- ;* 07/13/1994 PWG : Created. *
- ;*=========================================================================*
- label RM_Keystroke_Interrupt
- GLOBAL C Keystroke_Interrupt:FAR
- PROC Keystroke_Interrupt C FAR
- IF 0
- push ax
- inc ax
- pop ax
- iret
- ELSE
- push ax
- push bx
- push cx
- push di
- push ds
- push dx
- push es
- push si
- cld
- mov ax,cs ; set ds to cs to avoid cs overide
- mov ds,ax
- ; At this point we do not know if the SS selector is a
- ; System Stack or the Application Stack pointer.
- ; Soo to be in the safe side we create our own local
- ; Stack Pointer Selector Relative to DS
- ; Note Do not try this trick in a reentrant interrupt
- mov cx, ss ; get SS
- mov [Keyboard_App_Stack_ES], sp ; Protect ES
- mov [Keyboard_App_Stack_SS], cx ; Protect SS
- lea dx, [Keyboard_StackStart ] ; Compute Local Stack size
- and dx, -2;
- cli ; Disable All interrupts
- mov ss, ax ; Set new SS Selector
- mov sp, dx ; Set new Stack Offset
- sti ; Enable Interrupts
- cmp [WORD PTR PMIssuedKeyInt],0; Check to see if PM made Int call.
- mov [WORD PTR PMIssuedKeyInt],0; Make it false.
- jne ??passcode ; if so, just call Int Chain.
- mov dx,[WORD PTR KeyFlags]
- ;*** The following fix allows proper caps and num lock tracking on Tandy
- ; 10-6-89 LJC, DRD
- and [KeyLock],NOT (NUMLOCK OR CAPSLOCK); assume caps and num inactive
- mov ax,040H ; BIOS segment
- mov es,ax ; put in es
- test [BYTE PTR es:017H],040H ; test Caps lock bit in BIOS
- je short ??bioscapsoff ; skip activate code
- or [KeyLock],CAPSLOCK ; Caps Lock active
- ??bioscapsoff:
- test [BYTE PTR es:017H],020H ; test Num lock bit in BIOS
- je short ??biosnumoff ; skip activate code
- or [KeyLock],NUMLOCK ; Num Lock active
- ??biosnumoff:
- mov [ExtKeyboard],TRUE ; assume 101/102-key keyboard
- test [BYTE PTR es:096H],010H ; test for 101/102-key keyboard
- jne short ??extkeyboard ; skip deactivate code
- mov [ExtKeyboard],FALSE ; no 101/102-key keyboard
- ??extkeyboard:
- mov ax,cs ; set ds to cs to avoid cs overide
- mov es,ax
- cld ; clear direction flag for strings
- xor ah,ah ; clear ctrl flags to 0
- mov bx,0101H ; set key to a make by default
- in al,KEYDATA ; get a code from the keyboard
- ;
- ; New CODE to montior key stream
- ;
- mov bx,[KeyStreamIndex]
- mov [KeyStream+bx],al
- inc bx
- and bx,15
- mov [KeyStreamIndex],bx
- mov bx,0101H ; set key to a make by default
- ;
- ; END OF SEQUENCE
- ;
- ;
- ; Handle the PAUSE key being pressed. If it is pressed, then
- ; signal that the next two input codes are to be thrown out.
- ;
- cmp al,0E1H ; see if this is a pause/break
- jne short ??notpcode ; not a pause/break start code
- mov [LastKeyE1],3 ; absorb this and next two codes
- ??notpcode:
- cmp [LastKeyE1],0 ; are we in a pause/break code
- je short ??notpause ; no, just keep going
- dec [LastKeyE1] ; yes, dec the count
- test dx,PAUSEON ; should it pass these codes
- jne ??passcode ; pass the code
- jmp ??absorbcode ; don't pass code
- ??notpause:
- ;
- ; Record any extended key codes that arrive. They will be
- ; taken into account with the next code.
- ;
- cmp al,0E0H ; is it an extended code
- jne short ??notextcode ; if not skip to handle key
- mov [LastKeyE0],TRUE ; set the extended code to 1
- ??jmppasscode:
- jmp ??passcode ; always pass E0s
- ??notextcode:
- ;
- ; Check and acknowledge if the key is a make or a break.
- ;
- test al,080H ; test for high bit
- je short ??make ; if off its a make
- xor bl,bl ; set make/break to break
- and al,07FH ; clear high bit
- or ah,KEYRELEASE ; CDY NEW -- ABSENT IN OLD CODE
- ??make:
- ;
- ; Translate the raw keycode into the Westwood keycode.
- ;
- cmp [LastKeyE0],FALSE ; was the prev byte an E0?
- je short ??normal ; if not it is a normal key
- mov [LastKeyE0],FALSE ; if so clear for next read
- mov [IsExtKey],TRUE ; it is an extended key
- mov di,OFFSET ExtCodes ; get offset of extended codes table
- mov cx,(ExtNums-ExtCodes) ; get number of entrys in ext table
- repne scasb ; look for a match
- jcxz ??absorbcode ; Not recognized, so throw it away.
- mov al,[(ExtNums - ExtCodes) - 1 + di] ; get the match
- mov [IsExtKey],FALSE ; it is not an extended key
- jmp short ??notext
- ??normal:
- cmp al,07Ah
- jne short ??normok
- mov al,128
- jmp short ??notext
- ??normok:
- mov di,ax ; use code as an index
- and di,007Fh ; Mask off any release bit.
- mov al,[KeyNums+di] ; get the key number of this key
- ??notext:
- ;
- ; Test and set the CTRL bit.
- ;
- test [KeysUpDown+8],001H ; is the right ctrl down?
- jne short ??ctrlon ; if so, ctrl is on
- test [KeysUpDown+7],004H ; is the left ctrl down?
- je short ??ctrloff ; if not, neither are down, no ctrl
- ; DRD
- ; check for CTRL-NUMLOCK for pause on some keyboards
- cmp al,KN_NUMLOCK ; check for CTRL-NUMLOCK
- jne short ??ctrlon
- cmp [ExtKeyboard],TRUE ; if 101/102-key keyboard it is ok
- je short ??ctrlon
- test dx,PAUSEON ; should it pass these codes
- jne short ??ctrlon ; pass the code
- jmp ??absorbcode ; don't pass code
- ??ctrlon:
- or ah,CTRLPRESS ; or on the ctrl bit in flags
- ??ctrloff:
- ;
- ; Test and set the ALT bit.
- ;
- test [KeysUpDown + 7],050H ; is either alt key down?
- je short ??altoff
- or ah,ALTPRESS ; or on the alt bit in flags
- ??altoff:
- ;
- ; Remap the keyboard keys if this is requested. (Do not set DGROUP
- ; as it is unecessary)
- push ax
- call KeyNum_Translate
- add sp,2
- ;------ Set the shift bit if necessary.
- test [KeysUpDown+5],010H ; is the left shift down?
- jne short ??shifton ; if so the shift is on
- test [KeysUpDown+7],002H ; is the right shift down?
- je short ??shiftoff ; if not then neither shift is down
- ??shifton:
- or ah,SHIFTPRESS ; or on the shift bit in flags
- ??shiftoff:
- ;
- ;------ Toggle the shift state if the caps lock key is on (if necessary).
- ;
- mov di,ax
- and di,07Fh
- shr di,1
- shr di,1
- shr di,1
- mov bx,ax
- and bx,07Fh
- and bl,0111b
- mov ch,[Bits+bx] ; get the bit to test
- test [KeyLock],CAPSLOCK ; is the caps lock on?
- je short ??capsoff ; if not don't worry about it
- test ch,[KeysCapsLock+di] ; get code for keycaps
- je short ??capsoff ; its not effected
- xor ah,SHIFTPRESS ; toggle the shift flag
- ??capsoff:
- ;
- ;------ Toggle the shift state if the num-lock key is on (if necessary).
- ;
- test [KeyLock],NUMLOCK ; is the num lock key on?
- je short ??numlockoff ; if not don't worry about it
- test ch,[KeysNumLock+di] ; get code for numlock
- je short ??numlockoff ; if not effected skip toggle
- xor ah,SHIFTPRESS ; toggle the shift flag if effected
- ??numlockoff:
- ;------ Remember the current control/shift/alt bit settings for later use.
- ;??noshiftever:
- mov [CtrlFlags],ah ; save off shift-ctrl-alt flags
- ; for the mouse and joystick routines
- ; to use in stuffing key into the
- ; keyboard buffer.
- test dx,DEBUGINT
- jz ??not_toggle
- IF DEBUG
- cmp [KeyIntDisabled],1
- jne ??not_currently_disabled
- cmp ax,115 ; is it the F4 key
- je ??disable
- cmp ax,118 ; is it less then F7 key
- jb ??justpass
- cmp ax,120 ; is it greater than F9 key
- ja ??justpass
- ??disable:
- mov [KeyIntDisabled],0
- ??justpass:
- jmp ??passcode
- ??not_currently_disabled:
- cmp ax,125
- jne ??not_toggle
- mov [KeyIntDisabled],1
- jmp ??absorbcode
- ENDIF
- ??not_toggle:
- ;------ The CTRL-ALT-DEL key combination always gets passed to the system.
- cmp ax,0668H ; is it ctrl alt del?
- je ??passcode
- cmp ax,064CH ; is it ctrl alt ext del?
- je ??passcode ; if so don't add it to the buffer
- ;------ Special Ctrl-C check.
- cmp ax,0230h
- je short ??breaker
- cmp ax,027Eh
- jne short ??nobreak
- ??breaker:
- mov [Break],1
- ??nobreak:
- ;------ Check for Music and Sound control keys.
- cmp ax,0420H ; is this an alt s
- jne short ??checkmusic ; toggle the Sound variable
- push ax
- mov ax,[SoundOn]
- xor ax,01H
- push ax
- add sp,2
- pop ax
- ??checkmusic:
- cmp ax,0434H ; is this an alt m
- jne short ??esc ; toggle the Music variable
- push ax
- mov ax,[MusicOn]
- xor ax,01H
- push ax
- add sp,2
- pop ax
- ??esc:
- push ax
- call Stuff_Key_Num
- pop ax
- ??skipstuff:
- ;------ Do the special ESC routine if necessary.
- cmp al,110 ; is this the esc key?
- jne short ??noroutine ; if not goto the pass always
- cmp [WORD PTR EscRoutine+2],0 ;if vector is 0 don't jump
- je short ??noroutine
- push ax
- call [EscRoutine]
- pop ax
- ??noroutine:
- ;------ Check to see if the key is to be passed to the system or not.
- mov di,OFFSET PassAlways ; get offset to table
- mov cx,(PassAlwaysEnd - PassAlways) ; get number of pass always CDY JLB MOD 7/11 was +1
- repne scasb ; look for a match
- or cx,cx ; see if there was no match
- jne ??passcode ; CDY JLB 7/11 optimization
- ??passalways:
- ; now check for conditional passes
- mov di,OFFSET CondPassKey ; get offset to cond key table
- mov cx,(CondPassCond-CondPassKey) ; get number of entries
- shr cx,1 ; cut in half for words
- repne scasw ; look for a match
- jcxz short ??notcondpass ; OPTIMIZATION CDY JLB
- mov bx,[(CondPassCond - CondPassKey) - 2 + di]
- and bx,dx ; are the conditions met?
- je short ??notcondpass ; NO... check normally.
- jmp short ??passcode ; YES... pass back to system.
- ;
- ;------ Last check before passing keycode back to the system.
- ;
- ??notcondpass:
- test dx,FILTERONLY ; is the filter only flag on?
- je short ??absorbcode ; if not, absorb the code.
- ??passcode:
- inc [cs:PassCount]
- ;mov ax , 0B000h
- ;mov es, ax
- ;inc [BYTE PTR es : 40h]
- ; Now it is time to set up for the call to the System Keyboard
- ; interrupt handler.
- ; 1 -Restore System Stack Pointer Selector before exit Interrupt
- ; 2- We Create a Returning Point from Interrupt by Push A
- ; Interupt Stack Frame into the Stack Pointer
- ; 3- We make a Far jump to the interuupt handler
- cmp [Keyboard_StackPointer],0DEADh
- je ??stackok
- push cx
- push di
- push ax
- push es
- mov ax,0A000h
- mov es,ax
- xor di,di
- mov cx,64000
- mov ax,1
- rep stosb
- pop es
- pop ax
- pop di
- pop cx
- ??stackok:
- cli ; disable Interrupts
- mov dx, [Keyboard_App_Stack_SS]
- mov ss, dx ; Get System Stack Selector
- mov sp, [Keyboard_App_Stack_ES] ; Get System Stack offset
- sti ; Enable Interrupts
- lea dx, [??Call_Back_Keyboard] ; Get Return address offset
- pushf ; push flags
- push cs ; push Code segment
- push dx ; push Offset
- ; Now we need to simulate an interrup call by using ired
- ; because we still want to come back here from the
- ; Old Keyboard interrupt handle.
- pushf
- push [word ptr KeyOldRMI + 2] ; push orig segment.
- push [word ptr KeyOldRMI] ; push orig offset.
- iret ; call interrupt
- ??absorbcode:
- ;mov ax , 0B000h
- ;mov es, ax
- ;inc [BYTE PTR es : 0h]
- in al,KEYCTRL ; get the control port
- mov ah,al
- or al,080H ; reset bit for keyboard
- out KEYCTRL,al
- xchg ah,al ; get orig control data
- out KEYCTRL,al ; restore control data
- mov ax,040h ; BIOS paragraph is always @ 040h
- mov es,ax ; put in es as BIOS paragraph
- mov al,[es:96h] ; get extended keys
- and al,0FDh ; turn off last key e0 flag
- mov [es:96h],al ; set extended keys
- mov al,CLEARISR ; value to clear In Service Register
- out INTCHIP0,al ; 8259 interrupt chip controller 0
- cmp [Keyboard_StackPointer],0DEADh
- je ??stackok2
- push cx
- push di
- push ax
- push es
- mov ax,0A000h
- mov es,ax
- xor di,di
- mov cx,64000
- mov ax,1
- rep stosb
- pop es
- pop ax
- pop di
- pop cx
- ??stackok2:
- ; Restore System Stack Pointer Selector before exit Interrupt
- mov dx, [Keyboard_App_Stack_SS]
- cli ; disable Interrupts
- mov ss, dx ; Get Syatem Stack Selector
- mov sp, [Keyboard_App_Stack_ES] ; Get Syatem Stack offset
- sti ; Enable Interrupts
- ??Call_Back_Keyboard:
- pop si
- pop es
- pop dx
- pop ds
- pop di
- pop cx
- pop bx
- pop ax
- iret
- ENDIF
- ENDP Keystroke_Interrupt
- ;***************************************************************************
- ;* Break interrupt routines begin here!
- ;***************************************************************************
- ;***************************************************************************
- ;* BREAK_INTERRUPT -- Handles the break key interrupt *
- ;* *
- ;* INPUT: none *
- ;* *
- ;* OUTPUT: none *
- ;* *
- ;* WARNINGS: This is an interrupt routine. *
- ;* *
- ;* HISTORY: *
- ;* 07/13/1994 PWG : Created. *
- ;*=========================================================================*
- label RM_Break_Interrupt
- GLOBAL C Break_Interrupt:FAR
- PROC Break_Interrupt C FAR
- pushf
- push ax
- push es
- mov ax,0B000h ; ES:DI = Mono RAM address.
- mov es,ax
- inc [BYTE PTR es:0]
- pop es
- pop ax
- popf
- iret
- ENDP Break_Interrupt
- ;**************************************************************************
- ;* CALL_INTERRUPT_CHAIN -- Function PM calls to call the RM interrupt chain*
- ;* *
- ;* *
- ;* INPUT: none *
- ;* *
- ;* OUTPUT: none *
- ;* *
- ;* HISTORY: *
- ;* 07/08/1994 SKB : Created. *
- ;*=========================================================================*
- Call_Interrupt_Chain:
- pushf
- call Keystroke_Interrupt ;[KeyOldRMI]
- retf
- ;----------------------------------------------------------------------------
- ; LOW_HIDE_MOUSE:
- ;
- ; This function hides the mouse cursor on the screen if it was shown. It
- ; will not hide the mouse if it is already hidden.
- ;
- ; PROTOTYPE:
- ;
- ; VOID Low_Hide_Mouse(VOID);
- ;
- ; NOTE: does not check if mouse is currently being updated.
- ;
- ;----------------------------------------------------------------------------
- GLOBAL C Low_Hide_Mouse:FAR
- PROC Low_Hide_Mouse C FAR
- USES ax,bx,cx,dx,ds
- mov ax,cs ; since we are in tiny model
- mov ds,ax ; set cs = ds
- cmp [MDisabled],0 ; check if mouse is disabled
- jne short ??end
- cmp [MState],0 ; check if it was hidden before
- jne short ??endnodraw ; no need to hide again
- ;------ Move the saved graphic buffer to the seenpage to hide the mouse.
- ; call Buffer_To_Page C,[buffx],[buffy],[buffw],[buffh],[MouseBuffer],SEENPAGE
- mov ax,RESTORE_VISIBLE_PAGE
- push ax
- push cs
- call [ ShadowPtr ]
- add sp,2
- ;------ Record that the mouse has been hidden.
- ??endnodraw:
- add [MState],1
- adc [MState],0
- ??end:
- ret
- ENDP Low_Hide_Mouse
- ;----------------------------------------------------------------------------
- ;----------------------------------------------------------------------------
- ; LOW_SHOW_MOUSE:
- ;
- ; This function displays the mouse cursor on the screen if it was hidden.
- ;
- ; PROTOTYPE:
- ; VOID Low_Show_Mouse(VOID);
- ;
- ; NOTE: does not check if mouse is currently being updated.
- ;----------------------------------------------------------------------------
- GLOBAL C Low_Show_Mouse:FAR
- PROC Low_Show_Mouse C FAR
- USES ax,bx,cx,dx,si,di,ds,es
- LOCAL mousex:WORD ; Draw X position.
- LOCAL mousey:WORD ; Draw Y position.
- mov ax,cs ; since we are in tiny model
- mov ds,ax ; set cs = ds
- ;----- Don't show the mouse if it is not hidden, disabled.
- cmp [MDisabled],0 ; is the mouse disabled
- jne ??exit ; if so then exit
- cmp [MState],0 ; is the mouse already visible
- je ??exit ; if so then exit
- dec [MState]
- cmp [MState],0 ; can the mouse be shown
- jne short ??exit
- ;------ Determine the drawing position of the mouse.
- mov cx,[MouseWidth] ; Theoretical buffer width (pixel).
- mov dx,[MouseHeight] ; Theoretical buffer height (pixel).
- mov ax,[MouseX]
- ; sub ax,[MouseXHot]
- mov [mousex],ax ; Draw X pixel.
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- IF 0
- ; jns short ??xnotneg
- ; add cx,ax ; Reduce width accordingly.
- ; mov ax,0
- ??xnotneg:
- ENDIF
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- mov bx,[MouseY]
- ; sub bx,[MouseYHot]
- mov [mousey],bx ; Draw Y pixel.
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- IF 0
- ; jns short ??ynotneg
- ; add dx,bx ; Reduce height of mouse accordingly.
- ; mov bx,0
- ??ynotneg:
- ENDIF
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;------ Determine the theoretical coordinates and dimensions of the
- ; area the mouse shape will be rendered upon.
- mov [MouseBuffX],ax
- mov [MouseBuffY],bx
- mov [MouseBuffW],cx
- mov [MouseBuffH],dx
- ;------ Move the area that will be drawn upon, to the graphic buffer.
- mov ax,STORE_VISIBLE_PAGE
- push ax
- push cs
- call [ ShadowPtr ]
- add sp,2
- ;------ Draw the mouse shape to the seenpage.
- push [mousey]
- push [mousex]
- push cs
- call [ DrawMousePtr ]
- add sp,4
- ??exit:
- ret
- ENDP Low_Show_Mouse
- ;----------------------------------------------------------------------------
- ;----------------------------------------------------------------------------
- GLOBAL C Mouse_KeyNum:FAR
- PROC Mouse_KeyNum C FAR
- USES bx
- ARG state:WORD ; Current mouse state.
- LOCAL keynum:WORD ; Determined keynum.
- mov ax,cs ; since we are in tiny model
- mov ds,ax ; set cs = ds
- mov [keynum],KN_MOUSE_MOVE ; Presume just a mouse move.
- mov bx,[state]
- mov ax,bx
- xor bl,[Button] ; Bits of state change.
- je short ??fini
- mov [Button],al ; Record new mouse state.
- test bl,0010b
- je short ??notright
- mov [keynum],KN_RMOUSE
- test al,0010b
- jne short ??notright
- or [keynum],0800h ; Release bit on.
- ??notright:
- ; DRD
- ; note: the left mouse button has priority over the right mouse button
- ; this should be changed at a later date to process them independently
- test bl,0001b
- je short ??notleft
- mov [keynum],KN_LMOUSE
- test al,0001b
- jne short ??notleft
- or [keynum],0800h ; Release bit on.
- ??notleft:
- ??fini:
- mov ax,[keynum]
- ret
- ENDP Mouse_KeyNum
- ;----------------------------------------------------------------------------
- ;----------------------------------------------------------------------------
- ; MOUSE_INT:
- ;
- ; This routine is called automatically when the Mouse_Int is installed. It
- ; automatically updates the global variables stored in the code segment so
- ; that the mouse information is automatically known at all times.
- ;
- ; INPUTS (from int): AX = condition mask ( bit 0 == cursor position chg,
- ; bit 1 == left button press,
- ; bit 2 == left button release,
- ; bit 3 == right button press,
- ; bit 4 == right button release,
- ; 5-15 == not used )
- ; BX = button state ( bit 0 == left button down,
- ; bit 1 == right button down,
- ; bit 2 == middle button down.
- ; 3-15 == not used )
- ; CX = cursor coordinate (horizontal axis)
- ; DX = cursor coordinate (vertical axis)
- ; DI = horizontal mouse count (mickeys)
- ; SI = vertical mouse count (mickeys)
- ;
- ; RETURNS: none
- ;
- ; MODIFIES: modifies the variables _Button, _ButtonChange,
- ; _MouseX,_MouseY,_ButtonLatch
- ;
- ; PROTOTYPE:
- ; This routine is called from an interrupt.
- ;----------------------------------------------------------------------------
- label RM_Mouse_Interrupt
- PROC Mouse_Int C FAR
- USES ax,bx,cx,dx,ds,si,es,di
- LOCAL cond:WORD ; Local copy of mouse event.
- LOCAL state:WORD ; Local copy of button state.
- mov [cs:Mouse_State],bx
- mov [cs:Mouse_Cond],ax
- mov ax,cs ; since we are in tiny model
- mov ds,ax ; set cs = ds
- ; At this point we do not know if the SS selector is a
- ; System Stack or the Application Stack pointer.
- ; Soo to be in the safe side we create our own local
- ; Stack Pointer Selector Relative to DS
- ; Note Do not try this trick in a reentrant interrupt
- mov bx, ss ; get SS
- mov [Mouse_App_Stack_ES], sp ; Protect ES
- mov [Mouse_App_Stack_SS], bx ; Protect SS
- lea bx, [Mouse_StackStart ] ; Compute Local Stack size
- and bx, -2;
- cli ; Disable All interrupts
- mov ss, ax ; Set new SS Selector
- mov sp, bx ; Set new Stack Offset
- sti ; Enable Interrupts
- push ax
- push dx
- mov dx,3c8h
- xor al,al
- out dx,al
- inc dx
- out dx,al
- mov dx,3c9h
- mov ax,cx
- shr ax,3
- out dx,al
- jmp ??j1
- ??j1: xor al,al
- out dx,al
- jmp ??j2
- ??j2: out dx,al
- jmp ??j3
- ??j3:
- pop dx
- pop ax
- ;------ Process the mouse interrupt only if the mouse is enabled (whether
- ; present or not).
- cmp [MDisabled],0
- jne ??exit
- cmp [MInput],0
- je ??exit
- ;------ This was added because of missing mouse presses and
- ; releases during a mouse update.
- mov ax,[Mouse_Cond]
- and ax,0001EH ; bits for left and right press and release
- jne short ??dopress_release
- cmp [MouseUpdate],0 ; if mouse move and mouse updating exit
- jne ??exit
- ??dopress_release:
- ;------ In EEGA mode mouse X coordinates as 0..639. Make adjustment
- ; to keep within 0..319 range.
- cmp [Adjust],1 ; if the x coordinate is returned
- jne short ??noadjust ; incorrectly then
- shr cx,1 ; adjust x coord from 640 pixel screen
- ??noadjust:
- ; scale mouse posX and PosY
- ; cmp [Adjust_XPos] , 0
- ; jz short ??no_scaleX
- ; push dx
- ; mov ax , [MouseRight]
- ; imul cx
- ; idiv [Adjust_XPos]
- ; mov cx , ax
- ; pop dx
- ??no_scaleX:
- ; cmp [Adjust_YPos] , 0
- ; jz short ??no_scaleY
- ; mov ax , [MouseBottom]
- ; imul dx
- ; idiv [Adjust_YPos]
- ; mov dx , ax
- ??no_scaleY:
- ;------ Keep mouse within screen bounds.
- cmp cx,[MouseRight] ; in EGAMODE, the mouse may go to 320
- jb short ??boundX_ok ; force it to stay at least one pixel
- mov cx,[MouseRight] ; on the screen
- dec cx
- ??boundX_ok:
- cmp dx,[MouseBottom] ; in EGAMODE, the mouse may go to 320
- jb short ??boundY_ok ; force it to stay at least one pixel
- mov dx,[MouseBottom] ; on the screen
- dec dx
- ??boundY_ok:
- IF 0
- ;------ Remap the middle button to equal the right button.
- test bx,04h
- je ??noremap
- or bx,0010b ; Set the right button bit.
- ??noremap:
- ENDIF
- mov [MouseX],cx ; and store in mouse x
- mov [MouseY],dx ; store y coord in mouse y
- test [KeyFlags],KEYMOUSE
- jne short ??nostuffit
- call Mouse_KeyNum C,[Mouse_State] ; Convert mouse state to key number code.
- call Stuff_Key_Num C,ax ; Record mouse keynumber code.
- ??nostuffit:
- ;------ The check for Mouse in the middle of updating CAN NOT BE MOVED
- ; any farther up because mouse presses and releases will be LOST!!
- cmp [MouseUpdate],0
- jne ??exit
- ;??jexit:
- ; jmp ??exit
- christopher:
- ??chkxy:
- ;------ Signal that no mouse updating can occur at this time.
- ; cmp [_MouseUpdate],0
- ; jne ??exit
- ; mov [_MouseUpdate],1
- ;------ Perform any X movement grid adjustment.
- cmp [MouseStepX],0 ; are we stepping on the X?
- je short ??no_x_step ; no x
- mov ax,cx ; get current x_pixel
- mov cx,dx ; save dx - it is trashed by idiv
- sub ax,[MouseOffsetX] ; get offset difference
- mov bx,[MouseStepX] ; get step in bx for idiv
- cwd ; extend ax -> dx:ax
- idiv bx ; divide by Step X
- imul bx ; ax = div * Step X
- add ax,[MouseOffsetX] ; normalize to region offset
- mov dx,cx ; restore dx (new MouseY)
- mov cx,ax ; set cx (new MouseX)
- ??no_x_step:
- ;------ Perform any Y movement grid adjustment.
- cmp [MouseStepY],0 ; are we stepping on the Y
- je short ??no_step ; no y
- mov ax,dx ; get current y_pixel
- sub ax,[MouseOffsetY] ; get offset difference
- mov bx,[MouseStepY] ; get step in bx for idiv
- cwd ; extend ax -> dx:ax
- idiv bx ; divide by Step Y
- imul bx ; ax = div * Step Y
- add ax,[MouseOffsetY] ; normalize to region offset
- mov dx,ax ; set dx (new MouseY)
- ??no_step:
- ;------ Here is where we store the new MouseX and MouseY values
- ; mov [MouseX],cx ; and store in mouse x
- ; mov [MouseY],dx ; store y coord in mouse y
- ;------ If the mouse is hidden or its position hasn't changed, then
- ; perform no action.
- cmp [MState],0
- jne short ??updateend
- cmp [MouseXOld],cx
- jne short ??doit
- cmp [MouseYOld],dx
- je short ??updateend
- ??doit:
- ;------ At this point we KNOW the mouse has moved.
- mov ax,[MCState]
- and ax,CONDHIDE+CONDHIDDEN
- cmp ax,CONDHIDE+CONDHIDDEN
- je short ??condcheck ; If already hidden.
- ;------ We know that the mouse is visible, we must hide it
- ; before we update its position.
- call Low_Hide_Mouse
- ;------ Conditional region check goes here. If the mouse falls within the
- ; conditional region, it gets marked as hidden and no other processing
- ; occurs.
- test [MCState],CONDHIDE
- je short ??condok
- ??condcheck:
- cmp cx,[MouseCXLeft] ; check adjusted x region
- jb short ??condok
- cmp cx,[MouseCXRight]
- ja short ??condok
- cmp dx,[MouseCYUpper] ; check adjusted y region
- jb short ??condok
- cmp dx,[MouseCYLower]
- ja short ??condok
- or [MCState],CONDHIDDEN ; flag as conditional hidden
- jmp short ??updateend
- ;------ The mouse coordinates and flags pass all of the tests, proceed
- ; with rendering the mouse.
- ??condok:
- call Low_Show_Mouse
- ;------ Final clean up and exit.
- ??updateend:
- mov [MouseXOld],cx
- mov [MouseYOld],dx
- ??exit:
- cmp [Mouse_StackPointer],0DEADh
- je ??mouse_stk_ok
- push cx
- push di
- push ax
- push es
- mov ax,0A000h
- mov es,ax
- xor di,di
- mov cx,64000
- mov ax,1
- rep stosb
- pop es
- pop ax
- pop di
- pop cx
- ??mouse_stk_ok:
- ; Restore System Stack Pointer Selector before exit Interrupt
- mov ax, [Mouse_App_Stack_SS]
- cli ; disable Interrupts
- mov ss, ax ; Get Syatem Stack Selector
- mov sp, [Mouse_App_Stack_ES] ; Get Syatem Stack offset
- sti ; Enable Interrupts
- ret
- ENDP Mouse_Int
- ;***************************************************************************
- ;***************************************************************************
- ;***************************************************************************
- ;* MOUSE_SHADOW_BUFFER -- Handles storing and restoring the mouse buffer *
- ;* *
- ;* INPUT: int store - indicates whether we are storing the buffer or *
- ;* not. *
- ;* *
- ;* OUTPUT: none *
- ;* *
- ;* PROTO: Asm callable only! *
- ;* *
- ;* HISTORY: *
- ;* 10/27/1994 PWG : Created. *
- ;*=========================================================================*
- GLOBAL C VGA_Mouse_Shadow_Buffer:FAR
- PROC VGA_Mouse_Shadow_Buffer C FAR
- USES ax,bx,cx,dx,di,si,ds,es
- ARG store:WORD
- local x0 : word
- local y0 : word
- local x1 : word
- local y1 : word
- local buffx0 : word
- local buffy0 : word
- ;*=========================================================================*
- ;* Since we are in tiny model point ds to cs
- ;*=========================================================================*
- mov ax,cs ; since we are in tiny model
- mov ds,ax ; set cs = ds
- ;*=========================================================================*
- ; Direction flag must be forward in this routine.
- ;*=========================================================================*
- cld
- ;*===================================================================
- ;* Copy of X, Y, Width and Height into local registers
- ;*===================================================================
- mov ax,[MouseBuffX]
- mov bx,[MouseBuffY]
- sub ax , [ MouseXHot ]
- sub bx , [ MouseYHot ]
- mov [ x0 ] , ax
- mov [ y0 ] , bx
- add ax , [MouseBuffW]
- add bx , [MouseBuffH]
- mov [ x1 ] , ax
- mov [ y1 ] , bx
- mov [ buffx0 ] , 0
- mov ax , [ word ptr MouseBuffer ]
- mov [ buffy0 ] , ax
- ;*===================================================================
- ;* Bounds check source X. Y.
- ;*===================================================================
- xor ax , ax
- xor dx , dx
- mov cx , [ x0 ]
- mov bx , [ x1 ]
- add cx , cx
- adc ax , ax
- add bx , bx
- adc dx , dx
- mov cx , [ x0 ]
- mov bx , [ x1 ]
- sub cx , [ MouseRight ]
- sub bx , [ MouseRight ]
- dec cx
- dec bx
- add cx , cx
- adc ax , ax
- add bx , bx
- adc dx , dx
- mov cx , [ y0 ]
- mov bx , [ y1 ]
- add cx , cx
- adc ax , ax
- add bx , bx
- adc dx , dx
- mov cx , [ y0 ]
- mov bx , [ y1 ]
- sub cx , [MouseBottom]
- sub bx , [MouseBottom]
- dec cx
- dec bx
- add cx , cx
- adc ax , ax
- add bx , bx
- adc dx , dx
- xor al , 5
- xor dl , 5
- mov ah , al
- test dl , al
- jnz ??out
- or al , dl
- jz ??acepted
- test ah , 1000b
- jz ??scr_left_ok
- mov bx , [ x0 ]
- neg bx
- mov [ buffx0 ] , bx
- mov [ x0 ] , 0
- ??scr_left_ok:
- test ah , 0010b
- jz ??scr_bottom_ok
- push dx
- mov ax , [ y0 ]
- neg ax
- mul [MouseBuffW]
- add [ buffy0 ] , ax
- mov [ y0 ] , 0
- pop dx
- ??scr_bottom_ok:
- test dl , 0100b
- jz ??scr_right_ok
- mov ax , [MouseRight] ; get width into register
- mov [ x1 ] , ax
- ??scr_right_ok:
- test dl , 0001b
- jz ??acepted
- mov ax , [MouseBottom] ; get width into register
- mov [ y1 ] , ax
- ??acepted:
- ;*===================================================================
- ;* Get the offset into the screen.
- ;*===================================================================
- mov ax,0A000h
- mov es,ax
- mov ax , [ y0 ]
- mul [ MouseRight ]
- mov dx , [MouseRight]
- mov di , ax
- add di , [ x0 ]
- ;*===================================================================
- ;* Adjust the source for the top clip.
- ;*===================================================================
- mov bx , [ MouseWidth ] ; turn this into an offset
- lds si , [ MouseBuffer ]
- mov si , [ buffy0 ] ; edx points to source
- add si , [ buffx0 ] ; plus clipped lines
- ;*===================================================================
- ;* Calculate the bytes per row add value
- ;*===================================================================
- mov ax , [ x1 ]
- mov cx , [ y1 ]
- sub ax , [ x0 ]
- jle ??out
- sub cx , [ y0 ]
- jle ??out
- sub dx , ax
- sub bx , ax
- push bp
- cmp [store],RESTORE_VISIBLE_PAGE ; are we restoring page?
- jne ??store_entry ; if not the go to store
- ;*===================================================================
- ;* Handle restoring the buffer to the visible page
- ;*===================================================================
- mov bp , cx
- ??restore_loop:
- mov cx,ax ; get number to really write
- rep movsb ; store them into the buffer
- add si,bx ; move past right clipped pixels
- add di,dx ; adjust dest to next line
- dec bp ; decrement number of rows to do
- jnz ??restore_loop ; if more to do, do it
- pop bp
- IF ECHOON
- mov ax , 0b000h
- mov di , 12 * 80 + 10
- mov es, ax
- mov al , 'V'
- mov [es:di],al
- mov al,2
- mov [es:di+1],al
- ENDIF
- ret
- ;*===================================================================
- ;* Handle soting the visible page into the Mouse Shadow Buffer
- ;*===================================================================
- ??store_entry:
- xchg si,di ; xchg the source and the dest
- mov bp , cx
- push es ; need to swap es and ds but
- push ds ; cant xchg so pop them on the
- pop es ; stack and pop them off the
- pop ds ; wrong way intentionally.
- ??store_loop:
- mov cx,ax ; get number to really write
- rep movsb ; store them into the buffer
- add si,dx ; move past right clipped pixels
- add di,bx ; adjust dest to next line
- dec bp ; decrement number of rows to do
- jnz ??store_loop ; if more to do, do it
- pop bp
- ??out:
- IF ECHOON
- mov ax , 0b000h
- mov di , 12 * 80 + 12
- mov es, ax
- mov al , 'G'
- mov [es:di],al
- mov al,2
- mov [es:di+1],al
- ENDIF
- ret
- ENDP VGA_Mouse_Shadow_Buffer
- ;***************************************************************************
- GLOBAL C VGA_Draw_Mouse:FAR
- PROC VGA_Draw_Mouse C FAR
- USES ax,bx,cx,dx,di,si,ds,es
- ARG mousex:WORD
- ARG mousey:WORD
- local x0 : word
- local y0 : word
- local x1 : word
- local y1 : word
- local buffx0 : word
- local buffy0 : word
- ;*=========================================================================*
- ;* Since we are in tiny model point ds to cs
- ;*=========================================================================*
- mov ax,cs ; since we are in tiny model
- mov ds,ax ; set cs = ds
- ;*===================================================================
- ;* Pre-initialize the left, right and topclip values to zero.
- ;*===================================================================
- mov ax, [ mousex ]
- mov bx , [ mousey ]
- sub ax , [ MouseXHot ]
- sub bx , [ MouseYHot ]
- mov [ x0 ] , ax
- mov [ y0 ] , bx
- add ax, [ MouseWidth ]
- add bx, [ MouseHeight ]
- mov [ x1 ] , ax
- mov [ y1 ] , bx
- mov [ buffx0 ] , 0
- les ax , [ MouseCursor ]
- mov [ buffy0 ] , ax
- ;*===================================================================
- ;* Bounds check source X. Y.
- ;*===================================================================
- xor ax , ax
- xor dx , dx
- mov cx , [ x0 ]
- mov bx , [ x1 ]
- add cx , cx
- adc ax , ax
- add bx , bx
- adc dx , dx
- mov cx , [ x0 ]
- mov bx , [ x1 ]
- sub cx , [ MouseRight ]
- sub bx , [ MouseRight ]
- dec cx
- dec bx
- add cx , cx
- adc ax , ax
- add bx , bx
- adc dx , dx
- mov cx , [ y0 ]
- mov bx , [ y1 ]
- add cx , cx
- adc ax , ax
- add bx , bx
- adc dx , dx
- mov cx , [ y0 ]
- mov bx , [ y1 ]
- sub cx , [MouseBottom]
- sub bx , [MouseBottom]
- dec cx
- dec bx
- add cx , cx
- adc ax , ax
- add bx , bx
- adc dx , dx
- xor al , 5
- xor dl , 5
- mov ah , al
- test dl , al
- jnz ??out
- or al , dl
- jz ??acepted
- test ah , 1000b
- jz ??scr_left_ok
- mov bx , [ x0 ]
- neg bx
- mov [ buffx0 ] , bx
- mov [ x0 ] , 0
- ??scr_left_ok:
- test ah , 0010b
- jz ??scr_bottom_ok
- push dx
- mov ax , [ y0 ]
- neg ax
- mul [MouseWidth]
- add [ buffy0 ] , ax
- mov [ y0 ] , 0
- pop dx
- ??scr_bottom_ok:
- test dl , 0100b
- jz ??scr_right_ok
- mov bx , [MouseRight] ; get width into register
- mov [ x1 ] , bx
- ??scr_right_ok:
- test dl , 0001b
- jz ??acepted
- mov bx , [MouseBottom] ; get width into register
- mov [ y1 ] , bx
- ??acepted:
- mov ax , [ y0 ]
- mul [ MouseRight ]
- mov dx , [MouseRight]
- mov di , ax
- add di , [ x0 ]
- ;*===================================================================
- ;* Adjust the source for the top clip.
- ;*===================================================================
- mov bx , [MouseWidth] ; turn this into an offset
- mov si , [ buffy0 ] ; edx points to source
- add si , [ buffx0 ] ; plus clipped lines
- ;*===================================================================
- ;* Calculate the bytes per row add value
- ;*===================================================================
- mov ax , 0a000h
- mov ds , ax
- mov ax , [ x1 ]
- mov cx , [ y1 ]
- sub ax , [ x0 ]
- jle ??out
- sub cx , [ y0 ]
- jle ??out
- sub dx , ax
- sub bx , ax
- ;*===================================================================
- ;* Handle restoring the buffer to the visible page
- ;*===================================================================
- ??top_loop:
- mov ah,al
- ??inner_loop:
- mov ch , [es:si]
- inc esi
- or ch,ch
- jz ??inc_edi
- mov [di],ch
- ??inc_edi:
- inc di
- dec ah
- jnz ??inner_loop
- add si,bx ; move past right clipped pixels
- add di,dx ; adjust dest to next line
- dec cl ; decrement number of rows to do
- jnz ??top_loop ; if more to do, do it
- ??out:
- IF ECHOON
- mov ax , 0b000h
- mov di , 12 * 80 + 14
- mov es, ax
- mov al , 'A'
- mov [es:di],al
- mov al,2
- mov [es:di+1],al
- ENDIF
- ret
- ENDP VGA_Draw_Mouse
- ;***************************************************************************
- ;***************************************************************************
- ;***************************************************************************
- ;* MOUSE_SHADOW_BUFFER -- Handles storing and restoring the mouse buffer *
- ;* *
- ;* INPUT: int store - indicates whether we are storing the buffer or *
- ;* not. *
- ;* *
- ;* OUTPUT: none *
- ;* *
- ;* PROTO: Asm callable only! *
- ;* *
- ;* HISTORY: *
- ;* 10/27/1994 PWG : Created. *
- ;*=========================================================================*
- GLOBAL C VESA_Mouse_Shadow_Buffer:FAR
- PROC VESA_Mouse_Shadow_Buffer C FAR
- USES ax,bx,cx,dx,di,si,ds,es
- ARG store:WORD
- local x0 : word
- local y0 : word
- local x1 : word
- local y1 : word
- local buffx0 : word
- local buffy0 : word
- ;*=========================================================================*
- ;* Since we are in tiny model point ds to cs
- ;*=========================================================================*
- mov ax,cs ; since we are in tiny model
- mov ds,ax ; set cs = ds
- call get_vesa_window
- mov [ app_vesa_window ] , dx
- ;*=========================================================================*
- ; Direction flag must be forward in this routine.
- ;*=========================================================================*
- cld
- ;*===================================================================
- ;* Copy of X, Y, Width and Height into local registers
- ;*===================================================================
- mov ax,[MouseBuffX]
- mov bx,[MouseBuffY]
- sub ax , [ MouseXHot ]
- sub bx , [ MouseYHot ]
- mov [ x0 ] , ax
- mov [ y0 ] , bx
- add ax , [MouseBuffW]
- add bx , [MouseBuffH]
- mov [ x1 ] , ax
- mov [ y1 ] , bx
- mov [ buffx0 ] , 0
- mov ax , [ word ptr MouseBuffer ]
- mov [ buffy0 ] , ax
- ;*===================================================================
- ;* Bounds check source X. Y.
- ;*===================================================================
- xor ax , ax
- xor dx , dx
- mov cx , [ x0 ]
- mov bx , [ x1 ]
- add cx , cx
- adc ax , ax
- add bx , bx
- adc dx , dx
- mov cx , [ x0 ]
- mov bx , [ x1 ]
- sub cx , [ MouseRight ]
- sub bx , [ MouseRight ]
- dec cx
- dec bx
- add cx , cx
- adc ax , ax
- add bx , bx
- adc dx , dx
- mov cx , [ y0 ]
- mov bx , [ y1 ]
- add cx , cx
- adc ax , ax
- add bx , bx
- adc dx , dx
- mov cx , [ y0 ]
- mov bx , [ y1 ]
- sub cx , [MouseBottom]
- sub bx , [MouseBottom]
- dec cx
- dec bx
- add cx , cx
- adc ax , ax
- add bx , bx
- adc dx , dx
- xor al , 5
- xor dl , 5
- mov ah , al
- test dl , al
- jnz ??out
- or al , dl
- jz ??acepted
- test ah , 1000b
- jz ??scr_left_ok
- mov bx , [ x0 ]
- neg bx
- mov [ buffx0 ] , bx
- mov [ x0 ] , 0
- ??scr_left_ok:
- test ah , 0010b
- jz ??scr_bottom_ok
- push dx
- mov ax , [ y0 ]
- neg ax
- mul [MouseBuffW]
- add [ buffy0 ] , ax
- mov [ y0 ] , 0
- pop dx
- ??scr_bottom_ok:
- test dl , 0100b
- jz ??scr_right_ok
- mov ax , [MouseRight] ; get width into register
- mov [ x1 ] , ax
- ??scr_right_ok:
- test dl , 0001b
- jz ??acepted
- mov ax , [MouseBottom] ; get width into register
- mov [ y1 ] , ax
- ??acepted:
- ;*===================================================================
- ;* Get the offset into the screen.
- ;*===================================================================
- mov ax,0A000h
- mov es,ax
- mov ax , [ y0 ]
- mul [ MouseRight ]
- add ax , [ x0 ]
- adc dx , 0
- mov di , ax
- call set_vesa_page
- mov dx , [MouseRight]
- ;*===================================================================
- ;* Adjust the source for the top clip.
- ;*===================================================================
- mov bx , [ MouseWidth ] ; turn this into an offset
- lds si , [ MouseBuffer ]
- mov si , [ buffy0 ] ; edx points to source
- add si , [ buffx0 ] ; plus clipped lines
- ;*===================================================================
- ;* Calculate the bytes per row add value
- ;*===================================================================
- mov ax , [ x1 ]
- mov cx , [ y1 ]
- sub ax , [ x0 ]
- jle ??out
- sub cx , [ y0 ]
- jle ??out
- sub dx , ax
- sub bx , ax
- cmp [store],RESTORE_VISIBLE_PAGE ; are we restoring page?
- jne ??store_entry ; if not the go to store
- ;*===================================================================
- ;* Handle restoring the buffer to the visible page
- ;*===================================================================
- ??restore_loop:
- mov ah,al
- ??res_inner_loop:
- mov ch , [si]
- mov [es:di],ch
- inc si
- inc di
- jnz ??res_same_page
- call next_vesa_page
- ??res_same_page:
- dec ah
- jnz ??res_inner_loop
- add si,bx ; move past right clipped pixels
- add di,dx ; adjust dest to next line
- jnc ??res_same_page1
- call next_vesa_page
- ??res_same_page1:
- dec cl ; decrement number of rows to do
- jnz ??restore_loop
- IF ECHOON
- mov ax , 0b000h
- mov di , 10 * 80 + 10
- mov es,ax
- mov al ,'v'
- mov [es:di],al
- mov al,2
- mov [es:di+1],al
- ENDIF
- jmp ??out
- ;*===================================================================
- ;* Handle soting the visible page into the Mouse Shadow Buffer
- ;*===================================================================
- ??store_entry:
- mov ah,al
- ??store_inner_loop:
- mov ch , [es:di]
- mov [si],ch
- inc si
- inc di
- jnz ??store_same_page
- call next_vesa_page
- ??store_same_page:
- dec ah
- jnz ??store_inner_loop
- add si,bx ; move past right clipped pixels
- add di,dx ; adjust dest to next line
- jnc ??store_same_page1
- call next_vesa_page
- ??store_same_page1:
- dec cl ; decrement number of rows to do
- jnz ??store_entry
- ??out:
- IF ECHOON
- mov ax , 0b000h
- mov di , 10 * 80 + 14
- mov es,ax
- mov al ,'e'
- mov [es:di],al
- mov al,2
- mov [es:di+1],al
- ENDIF
- mov dx , [ app_vesa_window ]
- call set_vesa_window
- ret
- ENDP VESA_Mouse_Shadow_Buffer
- ;***************************************************************************
- GLOBAL C VESA_Draw_Mouse:FAR
- PROC VESA_Draw_Mouse C FAR
- USES ax,bx,cx,dx,di,si,ds,es
- ARG mousex:WORD
- ARG mousey:WORD
- local x0 : word
- local y0 : word
- local x1 : word
- local y1 : word
- local buffx0 : word
- local buffy0 : word
- local app_vesa_window : word
- ;*=========================================================================*
- ;* Since we are in tiny model point ds to cs
- ;*=========================================================================*
- mov ax,cs ; since we are in tiny model
- mov ds,ax ; set cs = ds
- call get_vesa_window
- mov [ app_vesa_window ] , dx
- ;*===================================================================
- ;* Pre-initialize the left, right and topclip values to zero.
- ;*===================================================================
- mov ax, [ mousex ]
- mov bx , [ mousey ]
- sub ax , [ MouseXHot ]
- sub bx , [ MouseYHot ]
- mov [ x0 ] , ax
- mov [ y0 ] , bx
- add ax, [ MouseWidth ]
- add bx, [ MouseHeight ]
- mov [ x1 ] , ax
- mov [ y1 ] , bx
- mov [ buffx0 ] , 0
- les ax , [ MouseCursor ]
- mov [ buffy0 ] , ax
- ;*===================================================================
- ;* Bounds check source X. Y.
- ;*===================================================================
- xor ax , ax
- xor dx , dx
- mov cx , [ x0 ]
- mov bx , [ x1 ]
- add cx , cx
- adc ax , ax
- add bx , bx
- adc dx , dx
- mov cx , [ x0 ]
- mov bx , [ x1 ]
- sub cx , [ MouseRight ]
- sub bx , [ MouseRight ]
- dec cx
- dec bx
- add cx , cx
- adc ax , ax
- add bx , bx
- adc dx , dx
- mov cx , [ y0 ]
- mov bx , [ y1 ]
- add cx , cx
- adc ax , ax
- add bx , bx
- adc dx , dx
- mov cx , [ y0 ]
- mov bx , [ y1 ]
- sub cx , [MouseBottom]
- sub bx , [MouseBottom]
- dec cx
- dec bx
- add cx , cx
- adc ax , ax
- add bx , bx
- adc dx , dx
- xor al , 5
- xor dl , 5
- mov ah , al
- test dl , al
- jnz ??out
- or al , dl
- jz ??acepted
- test ah , 1000b
- jz ??scr_left_ok
- mov bx , [ x0 ]
- neg bx
- mov [ buffx0 ] , bx
- mov [ x0 ] , 0
- ??scr_left_ok:
- test ah , 0010b
- jz ??scr_bottom_ok
- push dx
- mov ax , [ y0 ]
- neg ax
- mul [MouseWidth]
- add [ buffy0 ] , ax
- mov [ y0 ] , 0
- pop dx
- ??scr_bottom_ok:
- test dl , 0100b
- jz ??scr_right_ok
- mov ax , [MouseRight] ; get width into register
- mov [ x1 ] , ax
- ??scr_right_ok:
- test dl , 0001b
- jz ??acepted
- mov ax , [MouseBottom] ; get width into register
- mov [ y1 ] , ax
- ??acepted:
- mov ax , [ y0 ]
- mul [ MouseRight ]
- add ax , [ x0 ]
- adc dx , 0
- mov di , ax
- call set_vesa_page
- mov dx , [MouseRight]
- ;*===================================================================
- ;* Adjust the source for the top clip.
- ;*===================================================================
- mov bx , [MouseWidth] ; turn this into an offset
- mov si , [ buffy0 ] ; edx points to source
- add si , [ buffx0 ] ; plus clipped lines
- ;*===================================================================
- ;* Calculate the bytes per row add value
- ;*===================================================================
- mov ax , 0a000h
- mov ds , ax
- mov ax , [ x1 ]
- mov cx , [ y1 ]
- sub ax , [ x0 ]
- jle ??out
- sub cx , [ y0 ]
- jle ??out
- sub dx , ax
- sub bx , ax
- ;*===================================================================
- ;* Handle restoring the buffer to the visible page
- ;*===================================================================
- ??top_loop:
- mov ah,al
- ??inner_loop:
- mov ch , [es:si]
- inc si
- or ch,ch
- jz ??inc_edi
- mov [di],ch
- ??inc_edi:
- inc di
- jnz ??same_page
- call next_vesa_page
- ??same_page:
- dec ah
- jnz ??inner_loop
- add si,bx ; move past right clipped pixels
- add di,dx ; adjust dest to next line
- jnc ??same_page1
- call next_vesa_page
- ??same_page1:
- dec cl ; decrement number of rows to do
- jnz ??top_loop ; if more to do, do it
- ??out:
- IF ECHOON
- mov ax , 0b000h
- mov di , 10 * 80 + 14
- mov es, ax
- mov al , 's'
- mov [es:di],al
- mov al,2
- mov [es:di+1],al
- mov di , 10 * 80 + 16
- mov al , 'a'
- mov [es:di],al
- mov al,2
- mov [es:di+1],al
- ENDIF
- mov dx , [ app_vesa_window ]
- call set_vesa_window
- ret
- ENDP VESA_Draw_Mouse
- ;************************************************************************
- PROC get_vesa_window C near
- uses ax,bx
- mov ax , 04f05h
- mov bh , 1
- mov bl , 0
- call [ dword ptr cs: VesaPtr ]
- ret
- ENDP
- ;************************************************************************
- PROC set_vesa_window C near
- uses ax,bx,dx
- mov ax , 04f05h
- mov bh , 0
- mov bl , 0
- call [ dword ptr cs: VesaPtr ]
- ret
- ENDP
- ;***************************************************************************
- PROC set_vesa_page C near
- USES ax,bx,dx
- mov bx , dx
- shl bx , 2
- mov [ cs: current_page ] , bx
- mov dx , [ word ptr cs:banktable + bx ]
- mov ax , 04f05h
- mov bh , 0
- mov bl , 0
- call [ dword ptr cs: VesaPtr ]
- ret
- ENDP set_vesa_page
- PROC next_vesa_page C near
- USES ax,bx,dx
- mov bx , [ cs: current_page ]
- add bx , 4
- mov [ cs:current_page ] , bx
- mov dx , [ word ptr cs:banktable + bx ]
- mov ax , 04f05h
- mov bh , 0
- mov bl , 0
- call [ dword ptr cs: VesaPtr ]
- ret
- ENDP next_vesa_page
- ;***********************************************************
- END
|