;      /*****************************************************************/
;      /*                                                               */
;      /*           Copyright (c) IBM Corporation  1987, 1992           */
;      /*                     All Rights Reserved                       */
;      /*                                                               */
;      /*****************************************************************/
;      /******************* START OF SPECIFICATIONS *********************/
;      /*                                                               */
;      /*  SOURCE FILE NAME: VMC.ASM                                    */
;      /*                                                               */
;      /*  DESCRIPTIVE NAME: Video change extents adjustments           */
;      /*                                                               */
;      /*  COPYRIGHT:  IBM Corp. 1992                                   */
;      /*                                                               */
;      /*  STATUS:  Version 1.0                                         */
;      /*                                                               */
;      /*  NOTES: This module provides routines to service changes      */
;      /*         in vido mode.                                         */
;      /*  ENTRY POINTS:                                                */
;      /*      See public statements                                    */
;      /*  EXTERNAL REFERENCES:                                         */
;      /*      See extrn statements                                     */
;      /*                                                               */
;      /******************* END  OF  SPECIFICATIONS *********************/
.xlist
  include pensegs.inc
  include pen.inc
  include penei.inc
  include penidc.inc
  include struc.inc
.list

.286p

;------------------------------------------------------------------------------
; external routines
;------------------------------------------------------------------------------

extrn Idc_UpdateCaps:near
extrn skip_to_white :near
extrn skip_white    :near
extrn str_i_cmp     :near

;------------------------------------------------------------------------------
; external data
;------------------------------------------------------------------------------


;------------------------------------------------------------------------------
; local data
;------------------------------------------------------------------------------
DSEG segment
public Vmc_PMYRes,Vmc_Type
  Vmc_PMYRes     dw 01E0h   ; default Y pixel resolution for this device
                            ; can be changed by device dependent routine
  Vmc_Type db VMC_TYPE_NONE ; Type of video mode processing

DSEG ends

DSEGI segment
  opt_ltypeC    db  'LTYPE=C',0
  opt_ltypeT    db  'LTYPE=T',0
  opt_ltypeN    db  'LTYPE=N',0
DSEGI ends

CSEG SEGMENT
     ASSUME    CS:CGROUP, SS:nothing, ES:nothing, DS:DGROUP

;------------------------------------------------------------------------------
; process Vidie Mode changes. Call from IDC as result of notification by
; pen device driver services.
;    es:di = vinfo structure
;------------------------------------------------------------------------------
Public Vmc_Change
Vmc_Change     Proc  Near
  .if  <Vmc_Type ne VMC_TYPE_NONE>
     CALL_TYPE fixExtents,DT_LOCATOR  ;call fixExtents for all locator DCBs
  .endif
  xor  ax,ax
  ret

; do this for each locator device
; bx = DCB
fixExtents:
  .386p
  push es
  push di

  mov  eax, [bx].dcb_Ytrans.trn_ext_adj_calibrated
  xor  edx,edx
  mov  dx, es:[di].vinfo_GRow_res

; for non-PM screen group video modes, scale the translation adjustments
; for the new screen dimensions

  .if  <dx ne Vmc_PMYRes>
     imul edx                                 ; eax*edx = EDX:EAX
     xor  ecx,ecx
     mov  cx, Vmc_PMYRes
     idiv ecx                                 ; edx:eax / ecx = EAX.EDX
     .if  <nonzero edx>                       ; if remainder
        inc  eax
     .endif
     mov  [bx].dcb_Ytrans.trn_ext_adj, eax    ; set up extents ratio
     mov  [bx].dcb_Ytrans.trn_ext_max, eax    ; and use for maximum also

     .if  <Vmc_Type eq VMC_TYPE_CENTER>       ; need to modify the origin
        mov edx, eax                          ; (don't mess up eax)
        sub edx, [bx].dcb_Ytrans.trn_ext_adj_calibrated
        sar edx, 1
        add edx, [bx].dcb_Ytrans.trn_org_calibrated
        mov [bx].dcb_Ytrans.trn_org_adj, edx
     .endif

; for PM screen group video modes, restore the PM calibrated values
  .else
     mov  [bx].dcb_Ytrans.trn_ext_adj, eax       ; restore PM extents ratio

     mov  eax,[bx].dcb_Ytrans.trn_org_calibrated ; and origin adjustment
     mov  [bx].dcb_Ytrans.trn_org_adj, eax       ; (in case LTYPE=C changed it)

     mov  eax,[bx].dcb_Ytrans.trn_ext_max_PM     ; and maximum extent
     mov  [bx].dcb_Ytrans.trn_ext_max, eax
  .endif

; need to update capabilities
; eax = maximum Y extent

  mov  si, [bx].dcb_@RegCaps
  .if  <[si].lcap_dev_y_extent ne eax>       ; extents have changed
     mov  [si].lcap_dev_y_extent,eax         ; update it and update caps
     call Idc_UpdateCaps
  .endif

  pop di
  pop es
  .286p
  ret

Vmc_Change     EndP

;------------------------------------------------------------------------------
; Interface to set the LCD type. Set the type based on how the LCD hardware
; behaves when in less than full video mode (squeeze to top, center)
; al = VMC_TYPE_xxx
;------------------------------------------------------------------------------
Public Vmc_LcdType
Vmc_LcdType proc
  mov  Vmc_Type,al
  ret
Vmc_LcdType endp

;------------------------------------------------------------------------------
; Interface to set the LCD Y (vertical) resolution in PM screen group.
; ax = resolution
;------------------------------------------------------------------------------
Public Vmc_LcdPMRes
Vmc_LcdPMRes proc
  mov  Vmc_PMYRes,ax
  ret
Vmc_LcdPMRes endp

;------------------------------------------------------------------------------
; Set style bit to receive video mode notification
; dx = style bits from READ_ENABLE
;------------------------------------------------------------------------------
Public Vmc_ReadEnable
Vmc_ReadEnable proc
  .if  <Vmc_Type ne VMC_TYPE_NONE>
     and  dx,NOT STYLE_NOTIFY_VMCHANGE
  .endif
  ret
Vmc_ReadEnable endp

CSEG ends

CSEGI SEGMENT
     ASSUME    CS:CGROUP, SS:nothing, ES:nothing, DS:DGROUP

;------------------------------------------------------------------------------
; look for command line overrides for video type
;    es:di = config.sys line
;------------------------------------------------------------------------------
CR equ 0Dh
LF equ 0Ah

Public Vmc_Init
Vmc_Init proc
  call    skip_to_white             ; Skip driver name
  .repeat
     call    skip_white
     mov     al, es:[di]
     .leave  <al eq CR>
     .leave  <al eq LF>
     .leave  <al eq 0>
; look for full screen LTYPE option
     push    di
     mov     si, offset opt_ltypeN
     call    str_i_cmp
     pop     di
     .if     <zero ax> ; found it, set default values
        mov ax, VMC_TYPE_NONE
        call Vmc_LCDType
        .leave
     .endif
     push    di
     mov     si, offset opt_ltypeC
     call    str_i_cmp
     pop     di
     .if     <zero ax> ; found it, set default values
        mov ax,VMC_TYPE_CENTER
        call Vmc_LCDType
        .leave
     .endif
     mov     si, offset opt_ltypeT
     call    str_i_cmp
     .if     <zero ax> ; found it, set default values
        mov ax,VMC_TYPE_TOP
        call Vmc_LCDType
        .leave
     .endif
     call  skip_to_white           ; Skip to next parameter
  .until
  ret
Vmc_Init endp

CSEGI ends
end
