home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ddkx86v5.zip / DDKX86 / SRC / VDH / VDHIOPL.ASM < prev    next >
Assembly Source File  |  1995-04-14  |  87KB  |  2,434 lines

  1. ;*DDK*************************************************************************/
  2. ;
  3. ; COPYRIGHT (C) Microsoft Corporation, 1989
  4. ; COPYRIGHT    Copyright (C) 1995 IBM Corporation
  5. ;
  6. ;    The following IBM OS/2 WARP source code is provided to you solely for
  7. ;    the purpose of assisting you in your development of OS/2 WARP device
  8. ;    drivers. You may use this code in accordance with the IBM License
  9. ;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
  10. ;    Copyright statement may not be removed.;
  11. ;*****************************************************************************/
  12.          PAGE    60,132
  13.         TITLE   VDHIOPL.ASM -- Video Device Handler Ring 2 Routines
  14. ;/*****************************************************************************
  15. ;*
  16. ;* SOURCE FILE NAME = VDHIOPL.asm
  17. ;*
  18. ;* DESCRIPTIVE NAME = Video device handler ring 2 routines
  19. ;*
  20. ;*
  21. ;* VERSION      V2.0
  22. ;*
  23. ;* DATE
  24. ;*
  25. ;* DESCRIPTION  This module contains routines that run at ring 2 in
  26. ;*              order to directly access the hardware ( via IN and OUT
  27. ;*              instructions ).
  28. ;*
  29. ;* FUNCTIONS    ACCESSBLINK
  30. ;*              ACCESSCLUT
  31. ;*              ACCESSCURSORPOS
  32. ;*              ACCESSCURSORTYPE
  33. ;*              ACCESSDISPLAYMASK
  34. ;*              ACCESSHARDWARE
  35. ;*              ACCESSOVERSCAN
  36. ;*              ACCESSREGISTER
  37. ;*              ACCESSUNDERSCORE
  38. ;*              ACCESSVIDEOENABLE
  39. ;*              CHARFONTEND
  40. ;*              GetMonitorID
  41. ;*              QUERY132
  42. ;*              SET132
  43. ;*              SETMAPMASK
  44. ;*              VGAWait
  45. ;*              _CharFontBegin
  46. ;*              _DPRINTF
  47. ;*              _HardwareColor
  48. ;*              _HardwareColumns
  49. ;*              _Query8514A
  50. ;*              _QueryXGA
  51. ;*              inchr
  52. ;*              putchar
  53. ;*
  54. ;* NOTES        NONE
  55. ;*
  56. ;* STRUCTURES   NONE
  57. ;*
  58. ;* EXTERNAL REFERENCES
  59. ;*
  60. ;*              NONE
  61. ;*
  62. ;* EXTERNAL FUNCTIONS
  63. ;*
  64. ;*              NONE
  65. ;*
  66. ;* CHANGE ACTIVIY =
  67. ;*   DATE      FLAG        APAR    CHANGE DESCRIPTION
  68. ;*   --------  ----------  -----   --------------------------------------
  69. ;*   mm/dd/yy  @Vr.mpppxx  xxxxx   xxxxxxx
  70. ;*   03/09/89  @D184       D184    STJ, Identify additional displays for 8514/A
  71. ;*   04/14/89  @S4         B701111 STJ, Remove negative logic,
  72. ;*   05/10/89  @C21        B701513 CJJ, Don't turn Video signal back on and reenable
  73. ;*             @C21                     reading of VideoEnable for VGA,
  74. ;*   06/29/89  @T39        B784056 TPL, Remove hardware dependencies in VDHINIT,
  75. ;*   07/31/89  @B705063    B705063 WKB, Decrease interrupt latency period as per spec
  76. ;*   08/08/89  @B19        B785016 WKB, Included OEM VGA enhancements, B785017 also.
  77. ;*   08/17/89  @S24        B706605 STJ, Restore undocumented 8514/A AI interfaces,
  78. ;*   09/11/89  @T47        B707464 TPL, Save/restore 3xBox (graphics) bit planes,
  79. ;*   09/13/89  @S28        B700010 STJ, Retain external clocking on VGA,
  80. ;*   09/14/89  @T49        B707543 TPL, Workaround for a 486 bug,
  81. ;*   10/25/89  @TL3        B708718 TPL, Setup bit mask register on restore,
  82. ;*   12/18/89  @tb25       AR05401 TLB, Don't do fixvgabug and sequencer enable unless
  83. ;*             @tb25                    in restore,
  84. ;*   04/03/90  @T57        B788756 TPL, Do not clear reserve bit when hidding cursor,
  85. ;*   06/08/90  @S28f       B789810 TPL, Do not preserve External Clock bit,
  86. ;*   06/14/90  @B72        B713826 WKB, Correct underscore problem from VioGetState,
  87. ;*   07/23/90  @T72        D1295   TPL, DCR 1295 - Support recognition of XGA device
  88. ;*   09/13/90  @D1085      D1085   WKB, DCR 1085 - Support 132 columns on appropriate h/w
  89. ;*   09/20/90  @B716255    B716255 TPL, Return XGA present for Kauai-HS
  90. ;*   10/17/90  @B717771    B717771 WKB, Reduce interrupt latency period,
  91. ;*   01/29/91  @MS00       MS00    TPL, Convert IFDEF to IF
  92. ;*   01/29/91  @MS02       MS02    TPL, OEM 132 column support (NOT ROLLOVERED YET)
  93. ;*             @MS03       MS03    TPL, Remove unused CHARFONTEND2 entry point
  94. ;*             @MS04       MS04    TPL, Paradise VGA cursor fix
  95. ;*             @MS05       MS05    TPL, Logic to switch IDC translation mode for
  96. ;*                                      cursor programming
  97. ;*             @MS06       MS06    TPL, Read-Modify-Write logic added in AccessRegister
  98. ;*             @MS07       MS07    TPL, Debug logic added
  99. ;*             @MS27       MS27    TPL, add OEM detection logic
  100. ;*   09/25/91  @B726706    B726706 WKB, OEM changes
  101. ;*             @B726719    B726719 WKB, OEM changes
  102. ;*   02/12/92  @T81        B732894 TPL, Use kernel IoDelay macro,
  103. ;*   03/01/92  @B726708    B726708 TRM, Compaq OEM fix
  104. ;*   03/25/92  @DRW                     Skip sequencer 7 'fixups' for Tseng-based adapters
  105. ;*   04/09/93  @RAD         60272  YEE, Use POS regs 108-10f for Radius
  106. ;*****************************************************************************/
  107.  
  108. .286p
  109.  
  110. ;/*
  111. ;**  Include files
  112. ;*/
  113.  
  114.         include struc.inc               ; Structured assembly macros
  115.         include vdh.inc                 ; Definitions
  116.         include vdhctl.inc              ; Conditional assembly control
  117.  
  118. ;/*
  119. ;** IF VDHCGA OR (VDHVGA AND NOT VDHINIT)                               ;@MS00
  120. ;** IF VDHCGA OR (VDHVGA AND (1 - VDHINIT))                             ;@MS00
  121. ;** OEMFlags not added to BVHINIT.                                      ;@MS00
  122. ;*/
  123.  
  124. IFE VDHINIT                             ; IF NOT VDHINIT                ;@MS00
  125.         include vdhequ.inc              ; OEMFlags bit definitions      ;@MS27
  126.         extrn   _OEMFlags:word          ; OEM specific features         ;@MS27
  127.  
  128. ENDIF   ; NOT VDHINIT                                                   ;@MS00
  129.  
  130. IF  VDHINIT                             ; IF VDHINIT                    ;@RAD
  131.         extrn   _machinetype:word                                       ;@RAD
  132. ENDIF   ; VDHINIT                                                       ;@RAD
  133.  
  134. IF VDHVGA AND (1 - VDHINIT)                                             ;@DRW
  135. TSENG_ADAPTER   EQU     3               ;                               ;@DRW
  136.         extrn   _SVGAPresent:word       ; SVGA adapter type             ;@DRW
  137. ENDIF
  138.  
  139.         include iodelay.inc             ; IODelay macro                 ;@T81
  140.  
  141. R2SEG   SEGMENT DWORD PUBLIC 'CODE'                                     ;@T81
  142.         ASSUME  CS: R2SEG, DS: DGROUP
  143.  
  144. IF VDHINIT                              ; Start of @T72                 ;@MS00
  145.  
  146. ;/***************************************************************************
  147. ;*
  148. ;* FUNCTION NAME = QueryXGA
  149. ;*
  150. ;* DESCRIPTION   = Query XGA configuration
  151. ;*                 Search until the 1st XGA adapter found beginning from
  152. ;*                 the planar and then slot 1 to 8.  Once an XGA adapter
  153. ;*                 is found, query which display is attached.
  154. ;*
  155. ;*                 LINKAGE:   CALL FAR
  156. ;*
  157. ;* INPUT         = NONE
  158. ;* OUTPUT        = NONE
  159. ;*
  160. ;* RETURN-NORMAL = AL = display type  ( Color8514, Color8512_8513, etc)
  161. ;*                 AH = memory size ( 0 - 512k, 1 - 1MB )
  162.  
  163. ;* RETURN-ERROR  = AX = VDHERROR_NO_ADAPTER
  164. ;*
  165. ;**************************************************************************/
  166.  
  167.         PUBLIC  _QueryXGA
  168. _QueryXGA PROC FAR
  169. ; STACK FRAME for saving data                                            @RAD
  170. SlotValue       EQU   <[bp-1]>                  ; BYTE                   @RAD
  171. RadiusValue     EQU   <[bp-2]>                  ; BYTE                   @RAD
  172. STACKBLOCK      EQU   2                                                 ;@RAD
  173.         push    bp                                                      ;@RAD
  174.         mov     bp,sp                                                   ;@RAD
  175.         sub     sp,STACKBLOCK           ; set up stack size              @RAD
  176.  
  177.         sub     di,di                   ; Assume XGA not present        ;@B716255
  178.         cli                             ; Disable interrupt
  179.         in      al, 94h                 ; Read planar POS
  180.         mov     bl, al                  ; Save planar setting
  181.         mov     al, 0DFh                ; 
  182.         out    94h, al                  ; Put planar into setup mode
  183.  
  184.         mov     dx, 100h                ; 
  185.         in      ax, dx                  ; Get POS ID
  186.         .if     <ax ae 8FD8h> and       ; XGA on planar?                ;D89
  187.         .if     <ax be 8FDBh>                                           ;D89
  188.             mov     di, 8000h           ; Indicate XGA found            ;@B716255
  189.             call    GetMonitorID        ; On return: AX = Monitor ID value
  190.             mov     cx, ax              ; 
  191.             mov     al, bl              ; 
  192.             out    94h, al              ; Restore planar setting
  193. ;
  194. ; Duplicate code because the else leg was getting too big for a jmp short @RAD
  195. ;
  196.             sti                         ;                                 @RAD
  197.             mov     ax, cx              ; Return VIO monitor ID value     @RAD
  198.             or      ax, di              ;   and XGA present bit           @RAD
  199.             mov     sp, bp              ; restore stack                   @RAD
  200.             pop     bp                  ; restore value                   @RAD
  201.             ret                         ; found it, now go away           @RAD
  202.         .endif                          ;                                 @RAD
  203.  
  204. ; Now look through card slots for XGA                                     @RAD
  205.         mov     al, bl                  ; 
  206.         out    94h, al                  ; Restore planar setting
  207.         kIODelay                        ; @D1085                         ;@T81
  208.         in      al, 96h                 ; Read card slot setting
  209.         mov     BYTE PTR SlotValue,al   ; Save card slot setting          @RAD
  210.         mov     cx, 08h                 ; Start with card slot 0 (bit 0-3)
  211.         .repeat                         ; Search up to 8 card slots for an
  212.             mov     al, cl              ;   XGA with a display attached
  213.             out    96h, al              ; Put card slot into setup mode
  214.             kIODelay                    ; @D1085                         ;@T81
  215.             in      ax, dx              ; Get POS ID from slot
  216.             .if    <_machinetype eq 0>  ; family 1 machine                @RAD
  217.                 .if     <ax lt 8FD8h> or    ; didn't find XGA             @RAD
  218.                 .if     <ax gt 8FDBh>       ; didn't find XGA             @RAD
  219.                     add    dx, cx       ; go to radius pos regs 108-10f   @RAD
  220.                     in     al, dx       ; Get original value              @RAD
  221.                     mov    BYTE PTR RadiusValue,al   ; save it            @RAD
  222.                     mov    al, cl       ; start again, this time for......@RAD
  223.                     out    dx, al       ; Put card into setup mode        @RAD
  224.                     kIODelay            ; @D1085                          @RAD
  225.                     mov    dx, 100h     ; restore dx                      @RAD
  226.                     in     ax, dx       ; Get POS ID from slot            @RAD
  227.                 .endif                  ; end search for Radius           @RAD
  228.             .endif                      ; end family1 machine test        @RAD
  229.  
  230.             .if     <ax ae 8FD8h> and                                    ;D89
  231.             .if     <ax be 8FDBh>                                        ;D89
  232.                 mov     di, 8000h       ; Indicate XGA found            ;@B716255
  233.                 call    GetMonitorID    ; On return: AX = Monitor ID value
  234.             .else
  235.                 sub     ax, ax                                           ;D89
  236.             .endif                      ;            AX = 0 means no display
  237.  
  238.             .if    <_machinetype eq 0>  ; we clobbered a fam1 pos register@RAD
  239.                 mov    bx, ax           ; save Monitor ID                 @RAD
  240.                 mov    al, BYTE PTR RadiusValue  ; get value to restore   @RAD
  241.                 mov    dx, 100h         ; restore dx                      @RAD
  242.                 add    dx, cx           ; get POS register to restore     @RAD
  243.                 out    dx, al           ; restore POS value               @RAD
  244.                 mov    dx, 100h         ; restore dx                      @RAD
  245.                 mov    ax, bx           ; restore Monitor ID              @RAD
  246.             .endif                      ; end test                        @RAD
  247.         .until  <nonzero ax> or         ; XGA found
  248.             inc     cx                  ; Next slot
  249.         .until  <cx a 0Fh>              ; Search all 8 slots?
  250.         mov     cx, ax                  ; 
  251.         mov     al,BYTE PTR SlotValue   ; Restore card slot setting       @RAD
  252.         out    96h, al                  ; Restore card slot setting
  253.  
  254.         sti
  255.         mov     ax, cx                  ; Return VIO monitor ID value
  256.         or      ax, di                  ;   and XGA present bit         ;@B716255
  257.         mov     sp, bp                  ; restore stack                   @RAD
  258.         pop     bp                      ; restore value                   @RAD
  259.         ret
  260. _QueryXGA ENDP
  261.  
  262. Monitor_Table   label   word
  263.                 public  Monitor_Table
  264.  
  265.         db      VDHERROR_NO_ADAPTER     ; 0000
  266.         db      VDHERROR_NO_ADAPTER     ; 0001
  267.         db      VDHERROR_NO_ADAPTER     ; 0010
  268.         db      VDHERROR_NO_ADAPTER     ; 0011
  269.         db      VDHERROR_NO_ADAPTER     ; 0100  5081
  270.         db      VDHERROR_NO_ADAPTER     ; 0101  Buffalo
  271.         db      VDHERROR_NO_ADAPTER     ; 0110
  272.         db      VDHERROR_NO_ADAPTER     ; 0111  Boston
  273.         db      VDHERROR_NO_ADAPTER     ; 1000
  274.         db      0Bh                     ; 1001  8604, 8507
  275.         db      09h                     ; 1010  8514
  276.         db      0Ch                     ; 1011  8515 (Dallas)
  277.         db      VDHERROR_NO_ADAPTER     ; 1100
  278.         db      03h                     ; 1101  8503
  279.         db      04h                     ; 1110  8513, 8512
  280.         db      VDHERROR_NO_ADAPTER     ; 1111  No monitor attached
  281.  
  282. GetMonitorID PROC NEAR
  283.         public  GetMonitorID
  284.         mov     dx, 102h                ; 
  285.         in      al, dx                  ; Read POS 102
  286.         and     ax, 0Eh                 ; IODA is located in bit 1-3
  287.         shl     ax, 03h                 ; Use bit 1-3 to form IO address
  288.         mov     dx, 210Ah               ; Base IO address
  289.         or      dx, ax                  ; Form Device IO address (21xA)
  290.         mov     al, 52h                 ; 
  291.         out     dx, al                  ; Index to Monitor ID address
  292.         inc     dx                      ; Device Data address
  293.         in      al, dx                  ; Get Monitor ID bits
  294.         and     ax, 0Fh                 ; Clear the unwanted bits
  295.         mov     si, OFFSET Monitor_Table; Setup offset to Monitor ID table
  296.         add     si, ax                  ; Form index into the Monitor ID table
  297.         mov     al, BYTE PTR cs:[si]    ; Return VIO Monitor ID
  298.         ret
  299. GetMonitorID ENDP
  300.  
  301. ENDIF   ;VDHINIT                        ; End of @T72                   ;@MS00
  302.  
  303. IF VDHVGA OR VDH8514A                                                   ;@MS00
  304.  
  305. ;/***************************************************************************
  306. ;*
  307. ;* FUNCTION NAME = Query8514A
  308. ;*
  309. ;* DESCRIPTION   = Query 8514/A configuration.
  310. ;*                 Verify presence of 8514/A adapter, query memory size,
  311. ;*                 and query display type.
  312. ;*
  313. ;*                 LINKAGE:   CALL FAR
  314. ;*
  315. ;* INPUT         = NONE
  316. ;* OUTPUT        = NONE
  317. ;*
  318. ;* RETURN-NORMAL = AL = display type  ( Color8514, Color8512_8513, etc)
  319. ;*                 AH = memory size ( 0 - 512k, 1 - 1MB )
  320. ;* RETURN-ERROR  =
  321. ;*                 AX = VDHERROR_NO_ADAPTER
  322. ;*
  323. ;**************************************************************************/
  324.  
  325.         PUBLIC  _Query8514A
  326. _Query8514A PROC FAR
  327.  
  328.         mov     cx, VDHERROR_NO_ADAPTER ; Initialize cx = 8514/A not found
  329.  
  330.         mov     dx, 9AE9h               ; High byte of status reg ;@D184
  331.         in      al, dx                  ; Read 8514 Queue Status Reg ;@D184
  332.         test    al, 20h                 ;@D184
  333.         .if     < z >                   ; Not busy
  334.             mov     dx, 92E8h
  335.             mov     ax, 5555h
  336.             out     dx, ax
  337.  
  338.             kIODelay                    ;@D1085                          ;@T81
  339.  
  340.             in      ax, dx
  341.             .if     < ax eq 5555h >     ; 8514 found
  342.                 mov     dx, 42E8h
  343.                 in      al, dx          ; Get display info
  344.  
  345.                 mov     ah, al
  346.                 and     al, 70h
  347.                 .if     < al ne 70h >   ; Display attached to 8514/A
  348.                     .if     < al eq 10h > ;@D184
  349.                         mov     cl, Mono8507_8604 ; 8514/A with 8507/8604 ;@D184
  350.                     .endif              ;@D184
  351.                     .if     < al eq 20h > ;@D184
  352.                         mov     cl, Color8514 ; 8514/A with 8514
  353.                     .endif
  354.                     .if     < al eq 30h > ;@D184
  355.                         mov     cl, Color8515 ; 8514/A with 8515 ;@D184
  356.                     .endif              ;@D184
  357.                     .if     < al eq 50h > ;@D184
  358.                         mov     cl, Mono8503 ; 8514/A with 8503
  359.                     .endif
  360.                     .if     < al eq 60h >
  361.                         mov     cl, Color8512_8513 ; 8514/A with 8512/3
  362.                     .endif
  363.  
  364.                     test    ah, 80h     ; 512k or 1MB ?
  365.                     .if     < nz >
  366.                         mov     ch, MEM_1MB
  367.                     .endif
  368.                 .endif
  369.             .endif
  370.         .endif
  371.  
  372.         mov     ax, cx
  373.         ret
  374. _Query8514A ENDP
  375.  
  376. ENDIF   ;VDHVGA OR VDH8514A                                             ;@MS00
  377.  
  378. IF VDH8514A                             ;Start of @S24 changes          ;@MS00
  379.  
  380. ;/***************************************************************************
  381. ;*
  382. ;* FUNCTION NAME = AccessDisplayMask
  383. ;*
  384. ;* DESCRIPTION   = Set or read physical display mask
  385. ;*                 AccessDisplayMask is called to query or set the physical
  386. ;*                 display mask setting.
  387. ;*
  388. ;*                 LINKAGE:   CALL FAR
  389. ;*
  390. ;* INPUT         = (Passed on stack)
  391. ;*                 WORD  Direction ( GET or SET )
  392. ;*                 DWORD DisplayMask ( far pointer to dword )
  393. ;* OUTPUT        = NONE
  394. ;*
  395. ;* RETURN-NORMAL = Display mask is set or returned
  396. ;* RETURN-ERROR  = NONE
  397. ;*
  398. ;**************************************************************************/
  399.  
  400.         PUBLIC  ACCESSDISPLAYMASK
  401. ACCESSDISPLAYMASK PROC FAR
  402.  
  403.         enter   2, 0                ; Allocate 1 word temporary storage
  404.         push    es
  405.         push    di
  406.  
  407.         les     di, ParameterPacket     ; es:di = underscore scan line
  408.  
  409.         .if     < Direction eq SET >
  410.  
  411.             mov     dx,02EAh            ; Set address
  412.             mov     al,BYTE PTR es:[di].DisplayMask
  413.             out     dx,al               ;Set the mask
  414.  
  415.         .else
  416.  
  417.             sub     ax,ax
  418.             mov     dx,02EAh            ; Set address
  419.             in      al,dx               ; Get the mask
  420.             mov     WORD PTR es:[di].DisplayMask,ax
  421.             sub     ax,ax
  422.             mov     WORD PTR es:[di].DisplayMask+2,ax
  423.  
  424.         .endif
  425.  
  426.         pop     di
  427.         pop     es
  428.         leave
  429.         ret     6
  430.  
  431. ACCESSDISPLAYMASK ENDP
  432.  
  433. ;/***************************************************************************
  434. ;*
  435. ;* FUNCTION NAME = AccessCLUT for 8514/A
  436. ;*
  437. ;* DESCRIPTION   = Set or read physical color lookup table.
  438. ;*                 AccessCLUT is called to query or set the physical
  439. ;*                 color lookup table.
  440. ;*
  441. ;*                 LINKAGE:   CALL FAR
  442. ;*
  443. ;* INPUT         = (Passed on stack)
  444. ;*                 WORD   Direction ( GET or SET )
  445. ;*                 DWORD  ColorLookupTable  ( far pointer to structure )
  446. ;*                          DWORD DataArea ( far pointer to table )
  447. ;*                          WORD  FirstEntry
  448. ;*                          WORD  NumEntries
  449. ;*
  450. ;* OUTPUT        = NONE
  451. ;*
  452. ;* RETURN-NORMAL = Color lookup table is altered or queried
  453. ;* RETURN-ERROR  = NONE
  454. ;*
  455. ;**************************************************************************/
  456.  
  457. paldata     equ     02EDh               ; Palette data Register ;@S24
  458. paladdr     equ     02ECh               ; Palette Address Register ;@S24
  459. rpaladdr    equ     02EBh               ; Palette Address Register ;@S24
  460.  
  461.         PUBLIC  ACCESSCLUT
  462. ACCESSCLUT  PROC    FAR
  463.  
  464.         push    bp
  465.         mov     bp, sp
  466.         push    es
  467.         push    di
  468.  
  469.         les     di, ParameterPacket     ; es:di = palette packet
  470.  
  471.         mov     cx,WORD PTR es:[di].NumEntries  ; # of RBGx entries
  472.         mov     ax, WORD PTR es:[di].FirstEntry ; starting reg
  473.         les     di, DWORD PTR es:[di].DataArea
  474.         cld
  475.  
  476.         .if     < Direction eq SET >
  477.             push    ds
  478.             push    si
  479.             mov     si,es
  480.             mov     ds,si
  481.             mov     si,di
  482.  
  483.             .repeat
  484.                 mov     dx,paladdr      ; Palette address reg
  485.                 cli
  486.                 out     dx,al           ; Put out address
  487.                 mov     dx,paldata      ; Point to data reg for RGB triplet
  488.                 inc     ax              ; set next palette address
  489.                 push    ax
  490.                 lodsb
  491.                 shr     al,1
  492.                 shr     al,1            ; Reduce to hardware range
  493.                 out     dx,al           ; Put out the red
  494.                 lodsb
  495.                 shr     al,1
  496.                 shr     al,1            ; Reduce to hardware range
  497.                 xchg    AH,AL           ; Blue is first in the definition
  498.                 lodsb
  499.                 shr     al,1
  500.                 shr     al,1            ; Reduce to hardware range
  501.                 out     dx,al           ; Put out the green
  502.                 xchg    ah,al           ; Get the blue back
  503.                 out     dx,al           ; Put out the blue
  504.                 sti
  505.                 lodsb                   ; Discard extra byte
  506.                 pop     ax
  507.             .loop                       ; Go back for more
  508.  
  509.             pop     si
  510.             pop     ds
  511.         .else                           ; Read the color registers
  512.  
  513.             .repeat
  514.                 mov     dx,rpaladdr     ; Palette read address reg
  515.                 cli
  516.                 out     dx,al           ; Put out address
  517.                 mov     dx,paldata      ; Point to data reg for RGB triplet
  518.                 inc     ax              ; set next palette address
  519.                 push    ax              ; save palette address
  520.                 in      al,dx           ; do triplet - get RED
  521.                 shl     al,1            ; Align Data
  522.                 shl     al,1            ; Align Data
  523.                 stosb                   ; save RED
  524.                 in      al,dx           ; - get GREEN
  525.                 shl     al,1            ; Align Data
  526.                 shl     al,1            ; Align Data
  527.                 xchg    ah,al           ; keep GREEN
  528.                 in      al,dx           ; - get BLUE
  529.                 sti
  530.                 shl     al,1            ; Align Data
  531.                 shl     al,1            ; Align Data
  532.                 stosb                   ; save BLUE
  533.                 xchg    ah,al           ; restore GREEN
  534.                 stosb                   ; save GREEN
  535.                 mov     al,0            ; Setup 4th byte
  536.                 stosb
  537.                 pop     ax              ; restore palette address
  538.             .loop
  539.  
  540.         .endif
  541.  
  542.         pop     di
  543.         pop     es
  544.         pop     bp
  545.         ret     6
  546.  
  547. ACCESSCLUT  ENDP
  548.  
  549. ELSE    ;VDH8514A                       ; End of @S24 changes           ;@MS00
  550.  
  551. IF VDHVGA                               ; Read/write hardware           ;@MS00
  552.  
  553. ;/***************************************************************************
  554. ;*
  555. ;* FUNCTION NAME = _HardwareColumns
  556. ;*
  557. ;* DESCRIPTION   = Get number of text columns in current mode
  558. ;*                 _HardwareColumns is called by routines who need to know
  559. ;*                 whether the current mode has 40, 80 or 132 character
  560. ;*                 columns.
  561. ;*
  562. ;* INPUT         = NONE
  563. ;* OUTPUT        = NONE
  564. ;*
  565. ;* RETURN-NORMAL = AX = Number of character columns ( 40, 80 or 132 )
  566. ;* RETURN-ERROR  = NONE
  567. ;*
  568. ;**************************************************************************/
  569.  
  570.         PUBLIC  _HardwareColumns
  571. _HardwareColumns PROC   FAR
  572.  
  573. ;/*
  574. ;** Determine number of character columns by reading Sequencer register
  575. ;** Dot Clock bit (b3) of Clocking Mode Register: 0 = 80 col, 1 = 40 col
  576. ;*/
  577.  
  578.         mov     dx, SeqAddressPort      ;Sequencer address register
  579.         mov     al, IndClockModeReg     ;Clocking Mode index
  580.         cli
  581.         out     dx, al
  582.  
  583.         mov     dx, SeqDataPort         ;Sequencer data register
  584.         in      al, dx
  585.         test    al, 8                   ;Check Dot Clock bit
  586.         .if     < z >
  587.  
  588. IFE VDHINIT     ; NOT VDHINIT                                   ;MS?? - BEGIN
  589.  
  590.  
  591.                 sti                                            
  592.                 mov     dx, MiscOutputRegRead                  
  593.                 in      al, dx                                 
  594.  
  595.                 mov     dx, CRTCtlAddressReg
  596.                 .if     <BIT al and NOT_MONO>    ; Color VGA?
  597.                     add     dx, ColorAdjustment
  598.                 .endif
  599.                 cli
  600.                 mov     ax, 01h         ; Index to the Horizontal Display
  601.                 out     dx, al          ;   Enable End Register
  602.  
  603.                 kIODelay                ;                               ;@T81
  604.  
  605.                 inc     dx              ; Read the Horizontal Display
  606.                 in      al, dx          ;   Enable End Register content
  607.                 inc     al              ; Convert to 1 base
  608.  
  609. ELSE
  610.             mov     ax, 80
  611.  
  612. ENDIF   ;NOT VDHINIT                                            ;MS?? - END
  613.  
  614.         .else
  615.             mov     ax, 40              ;40 column mode
  616.         .endif
  617.  
  618.         sti
  619.         ret
  620.  
  621. _HardwareColumns ENDP
  622.  
  623. ;/***************************************************************************
  624. ;*
  625. ;*  SUBROUTINE NAME: _HardwareColor
  626. ;*
  627. ;*  DESCRIPTIVE NAME: Determine if current mode is color or monochrome
  628. ;*
  629. ;*  FUNCTION: _HardwareColor is called by routines who need to know
  630. ;*            whether the current mode is color or monochrome.
  631. ;*
  632. ;*  ENTRY POINT: _HardwareColor
  633. ;*    LINKAGE:   CALL FAR
  634. ;*
  635. ;*  INPUT: NONE
  636. ;*
  637. ;*  EXIT-NORMAL: AX = 1 - color, 0 - monochrome
  638. ;*
  639. ;*  INTERNAL REFERENCES:
  640. ;*    ROUTINES: NONE
  641. ;*
  642. ;*  EXTERNAL REFERENCES:
  643. ;*    ROUTINES: NONE
  644. ;*
  645. ;****************************************************************************/
  646.         PUBLIC  _HardwareColor
  647. _HardwareColor  PROC    FAR
  648.  
  649. ;/*
  650. ;** Determine whether color or monochrome mode to determine which
  651. ;** ports should be used.  This is done by checking the
  652. ;** I/O Address Select bit (b0) of the Miscellaneous Output Register:
  653. ;**     b0: 0 = Monochrome emulation mode, 1 = Color emulation mode
  654. ;*/
  655.  
  656.         mov     dx, MiscOutputRegRead   ; Read Miscellaneous Output Register
  657.         in      al, dx
  658.         and     ax, 1                   ; Return 1 - color, 0 - monochrome
  659.  
  660.         ret
  661.  
  662. _HardwareColor  ENDP
  663.  
  664. ;/**************************************************************************
  665. ;*
  666. ;*  SUBROUTINE NAME: SET132
  667. ;*
  668. ;*  DESCRIPTIVE NAME: Enable display adapter for 132 column mode.
  669. ;*
  670. ;*  FUNCTION: SET132 is called by routines who need to set the
  671. ;*            state of the display adapter into 132 column mode.
  672. ;*
  673. ;*  ENTRY POINT: SET132
  674. ;*    LINKAGE:   CALL FAR
  675. ;*
  676. ;*  INPUT: NONE
  677. ;*  INPUT: (Passed on stack)
  678. ;*             WORD   Comp_reg (POS ID)
  679. ;*             WORD   Direction ( 1 = SET, 0 = CLEAR )
  680. ;*
  681. ;*  EXIT-NORMAL: Display adapter enabled for 132 column mode.
  682. ;*
  683. ;*  INTERNAL REFERENCES:
  684. ;*    ROUTINES: NONE
  685. ;*
  686. ;*  EXTERNAL REFERENCES:
  687. ;*    ROUTINES: NONE
  688. ;*
  689. ;****************************************************************************/
  690.  
  691.  
  692.         PUBLIC  SET132                                                  ;@D1085
  693. SET132  PROC    FAR                                                     ;@D1085
  694.                                                                         ;@D1085
  695.         enter   4,0                                                     ;@D1085
  696.                                                                         ;@D1085
  697.         mov     ax, ss:[bp+6]                                           ;@D1085
  698.         mov     dx, ss:[bp+8]                                           ;@D1085
  699.         .if     < ax eq 1 >                                             ;@D1085
  700.             mov     al,11h                                              ;@D1085
  701.         .else                                                           ;@D1085
  702.             mov     al,1h                                               ;@D1085
  703.         .endif                                                          ;@D1085
  704.                                                                         ;@D1085
  705.         out     dx, al                                                  ;@D1085
  706.                                                                         ;@D1085
  707.         leave                                                           ;@D1085
  708.         ret     4                                                       ;@D1085
  709.                                                                         ;@D1085
  710. SET132  ENDP                                                            ;@D1085
  711.  
  712. ;/****************************************************************************
  713. ;*
  714. ;*  SUBROUTINE NAME: QUERY132
  715. ;*
  716. ;*  DESCRIPTIVE NAME: Inspect Adapter for ability to support 132
  717. ;*                    column mode.
  718. ;*
  719. ;*  FUNCTION: QUERY132 is called by routines who need know
  720. ;*            whether 132 column mode is supported.
  721. ;*
  722. ;*  ENTRY POINT: QUERY132
  723. ;*    LINKAGE:   CALL FAR
  724. ;*
  725. ;*  INPUT: NONE
  726. ;*
  727. ;*  EXIT-NORMAL: AX = Address of instance data register.
  728. ;*
  729. ;*  INTERNAL REFERENCES:
  730. ;*    ROUTINES: NONE
  731. ;*
  732. ;*  EXTERNAL REFERENCES:
  733. ;*    ROUTINES: NONE
  734. ;*
  735. ;****************************************************************************/
  736.  
  737.         PUBLIC  QUERY132                                                ;@D1085
  738. QUERY132        PROC    FAR                                             ;@D1085
  739.                                                                         ;@D1085
  740.         push    bx                                                      ;@T81
  741.         mov     dx, 2170h                       ; start from the 8th    ;@D1085
  742.                                                 ; instance OpMode Reg.  ;@D1085
  743.         .repeat                                                         ;@D1085
  744.            in      al, dx                       ; get the OpMode setting;@D1085
  745.            .if     < al b 0F0h >                ; valid value?          ;@D1085
  746.                                                                         ;@D1085
  747.               xchg    ah, al                    ; save it in AH         ;@D1085
  748.                                                                         ;@D1085
  749.               mov     al, 1h                    ; now enable it for     ;@D1085
  750.               out     dx, al                    ;   VGA decode          ;@D1085
  751.                                                                         ;@D1085
  752.               kIODelay bx                                         ;@D1085,@T81
  753.                                                                         ;@D1085
  754.               in      al, dx                    ; read the value back   ;@D1085
  755.                                                                         ;@D1085
  756.               .if     < al eq 1 >               ; VGA mode set?         ;@D1085
  757.                   mov     al, 11h               ; now enable SVGA to    ;@D1085
  758.                   out     dx, al                ; 132 column mode       ;@D1085
  759.                                                                         ;@D1085
  760.                   kIODelay bx                                     ;@D1085,@T81
  761.                                                                         ;@D1085
  762.                   in      al, dx                ; read mode setting     ;@D1085
  763.                   xchg    ah, al                ; AL = original value   ;@D1085f
  764.                   .if     < ah eq 11h >         ; 132 col mode is set?  ;@D1085f
  765.                       out     dx, al            ; restore original SVGA ;@D1085
  766.                       mov     ax, dx            ; setting and return    ;@D1085
  767.                                                 ; SVGA found            ;@D1085f
  768.                   .else                                                 ;@D1085
  769.                       out     dx, al            ; restore original XGA  ;@D1085f
  770.                       sub     ax, ax            ; setting and return    ;@D1085f
  771.                   .endif                        ; non-found             ;@D1085
  772.               .else                                                     ;@D1085
  773.                   sub     ax, ax                ; indicate non-found    ;@D1085
  774.               .endif                                                    ;@D1085
  775.            .else                                                        ;@D1085
  776.               sub     ax, ax                    ; indicate non-found    ;@D1085
  777.            .endif                                                       ;@D1085
  778.                                                                         ;@D1085
  779.         sub     dx, 10h                         ; next configuration    ;@D1085
  780.         .until  <nonzero ax> or                                         ;@D1085
  781.         .until  <dx b 2100h>                                            ;@D1085
  782.                                                                         ;@D1085
  783.         pop     bx                                                      ;@T81
  784.         ret                                                             ;@D1085
  785.                                                                         ;@D1085
  786. QUERY132        ENDP                                                    ;@D1085
  787.  
  788. ENDIF   ;VDHVGA                                                         ;@MS00
  789.  
  790. IF VDHEGA OR VDHVGA                                                ;@T72,@MS00
  791.  
  792. ;/****************************************************************************
  793. ;*
  794. ;*  SUBROUTINE NAME: SetMapMask
  795. ;*
  796. ;*  DESCRIPTIVE NAME: Address select a bit plane to read or write
  797. ;*
  798. ;*  FUNCTION: SetMapMask is called by SaveRestorePVB in order to address
  799. ;*            a specific bit plane in graphics mode during a 3xBox
  800. ;*            display buffer save or restore
  801. ;*
  802. ;*  ENTRY POINT: SetMapMask
  803. ;*    LINKAGE:   CALL FAR
  804. ;*
  805. ;*  INPUT: (Passed on stack)
  806. ;*             WORD ReadMapMask  ( 0 - 3, 4 = write )
  807. ;*             WORD WriteMapMask ( 1, 2, 4, or 8 )
  808. ;*
  809. ;*  EXIT-NORMAL: Bit plane selected for read or write
  810. ;*
  811. ;*  INTERNAL REFERENCES:
  812. ;*    ROUTINES: NONE
  813. ;*
  814. ;*  EXTERNAL REFERENCES:
  815. ;*    ROUTINES: NONE
  816. ;*
  817. ;*****************************************************************************/
  818.         PUBLIC  SETMAPMASK
  819. SETMAPMASK  PROC    FAR
  820.  
  821. ;/*
  822. ;** ENTRY: SS:SP = offset selector mas
  823. ;*/
  824.         push    bp
  825.         mov     bp, sp
  826.         push    dx
  827.         push    ax
  828.  
  829.         cli
  830.  
  831.         .if     < ReadMap eq 0 > or
  832.         .if     < MapMask eq 1 >
  833.  
  834. ;/*
  835. ;**  Set graphics mode register just for the first bit plane
  836. ;*/
  837.  
  838.             mov     dx, GraphAddressPort
  839.             mov     ax, 0001h           ; Start from Set/Reset regs.    ;@T47
  840.             .repeat                     ;                               ;@T47
  841.                 out     dx, al          ; Setup address port            ;@T47
  842.                 inc     dx              ; Index to data port            ;@T47
  843.                 inc     ax              ; Index to next address port    ;@T47
  844.                 xchg    al,ah           ;                               ;@T47
  845.                 out     dx,al           ; Clear Graphics register       ;@T47
  846.                 dec     dx              ; Back to address port          ;@T47
  847.                 xchg    al,ah           ;                               ;@T47
  848.                 cmp     al,6            ;                               ;@T47
  849.             .until  <z>                 ;                               ;@T47
  850.  
  851.             .if     < MapMask eq 1 >    ; 1st write request?            ;@TL3
  852.                 mov     al,8            ;                               ;@TL3
  853.                 out     dx,al           ; Index to Bit Mask register    ;@TL3
  854.                 inc     dx              ;                               ;@TL3
  855.                 mov     al,0ffh         ;                               ;@TL3
  856.                 out     dx,al           ; Allow write to all bits       ;@TL3
  857.             .endif                      ;                               ;@TL3
  858.         .endif                          ;                               ;@T47
  859.  
  860.         .if     < ReadMap ne WriteFunction >
  861.  
  862. ;/*
  863. ;**  Reading from display buffer, address select specified bit plane
  864. ;*/
  865.  
  866.             mov     dx, SeqAddressPort
  867.             mov     al, 02h             ; Memory map register in sequencer
  868.             out     dx, al
  869.             inc     dx
  870.             mov     al, 0Fh
  871.             out     dx, al              ; Memory map = 00001111
  872.  
  873. ;/*
  874. ;**  Address select specified bit plane to read
  875. ;*/
  876.  
  877.             mov     dx, GraphAddressPort
  878.             mov     al, 04h             ; Read map select register
  879.             out     dx, al
  880.             inc     dx
  881.             mov     al, ReadMap
  882.             out     dx, al              ; Read map select  = 0, 1, 2, 3
  883.         .else
  884.  
  885. ;/*
  886. ;**  Writing to display buffer, address select specified bit plane
  887. ;*/
  888.  
  889.             mov     dx, SeqAddressPort
  890.             mov     al, 02h             ; Memory map register in sequencer
  891.             out     dx, al
  892.             inc     dx
  893.             mov     al, MapMask
  894.             out     dx, al              ; Memory map
  895.         .endif
  896.  
  897.         sti
  898.  
  899.         pop     ax
  900.         pop     dx
  901.         pop     bp
  902.         ret     4                       ; Remove 2 words from stack
  903.  
  904. SETMAPMASK  ENDP
  905.  
  906. ENDIF   ; VDHEGA OR VDHVGA                                          ;@T72,@MS00
  907.  
  908. ;@T39       IFDEF  FONT_SUPPORT         ;@S4
  909.  
  910. ;/*****************************************************************************
  911. ;*
  912. ;*  SUBROUTINE NAME: _CharFontBegin
  913. ;*
  914. ;*  DESCRIPTIVE NAME: Address the font buffer
  915. ;*
  916. ;*  FUNCTION: _CharFontBegin is called by routines in order to address
  917. ;*            the font buffer for writing or reading
  918. ;*
  919. ;*  ENTRY POINT: _CharFontBegin
  920. ;*    LINKAGE:   CALL FAR
  921. ;*
  922. ;*  INPUT: NONE
  923. ;*
  924. ;*  EXIT-NORMAL: Font buffer is address selected at A0000
  925. ;*
  926. ;*  INTERNAL REFERENCES:
  927. ;*    ROUTINES: NONE
  928. ;*
  929. ;*  EXTERNAL REFERENCES:
  930. ;*    ROUTINES: NONE
  931. ;*
  932. ;*****************************************************************************/
  933.  
  934.         PUBLIC  _CharFontBegin
  935. _CharFontBegin PROC FAR
  936.  
  937.         push    dx
  938.         mov     dx, GraphAddressPort
  939.         mov     ax, 0204h
  940.  
  941.         cli
  942.         out     dx, ax                  ; Read Map Select register
  943.  
  944.         mov     ax, 0005h
  945.         out     dx, ax                  ; Graphics Mode register
  946.  
  947.         mov     ax, 0406h
  948.         out     dx, ax                  ; Graphics Misc register
  949.  
  950.         mov     dx, SeqAddressPort
  951.         mov     ax, 0402h               ; write font to bp only bit plane 0
  952.         out     dx, ax                  ; Write Map Select
  953.  
  954.         mov     ax, 0404h
  955.         out     dx, ax                  ; Turn on odd/even
  956.  
  957.         sti
  958.  
  959.         pop     dx
  960.         ret
  961.  
  962. _CharFontBegin ENDP
  963.  
  964. ;/*****************************************************************************
  965. ;*
  966. ;*  SUBROUTINE NAME:  CharFontEnd
  967. ;*
  968. ;*  DESCRIPTIVE NAME: Deselect font buffer
  969. ;*
  970. ;*  FUNCTION:  CharFontEnd and  CharFontEnd2 are called following
  971. ;*            completion of accessing the font buffer.
  972. ;*
  973. ;*  ENTRY POINTS:  CharFontEnd,  CharFontEnd2
  974. ;*    LINKAGE:   CALL FAR
  975. ;*
  976. ;*  INPUT: NONE
  977. ;*
  978. ;*  EXIT-NORMAL: font buffer address is deselected
  979. ;*
  980. ;*  INTERNAL REFERENCES:
  981. ;*    ROUTINES: NONE
  982. ;*
  983. ;*  EXTERNAL REFERENCES:
  984. ;*    ROUTINES: NONE
  985. ;*
  986. ;*****************************************************************************/
  987.         PUBLIC  CHARFONTEND
  988. CHARFONTEND PROC    FAR
  989.         push    bp
  990.         mov     bp, sp
  991.         mov     cx, 0A06h               ; Setup mono buffer with chaining
  992.         .if     < ColorMonoMode eq COLOR >
  993.             or      cx, 0400h           ; Setup color buffer
  994.         .endif
  995.         pop     bp
  996.  
  997.         push    ax
  998.  
  999.         mov     dx, GraphAddressPort
  1000.         mov     ax, 0004h
  1001.  
  1002.         cli
  1003.         out     dx, ax                  ; Read Map Select register
  1004.  
  1005.         mov     ax, 1005h
  1006.         out     dx, ax                  ; Graphics Mode register
  1007.  
  1008.         mov     ax, cx
  1009.         out     dx, ax                  ; Graphics Misc register
  1010.  
  1011.  
  1012.         mov     dx, SeqAddressPort
  1013.         mov     ax, 0302h
  1014.         out     dx, ax                  ; Write Map Select
  1015.  
  1016.         mov     ax, 0004h
  1017.         out     dx, ax                  ; Turn off odd/even
  1018.  
  1019.         sti
  1020.         pop     ax
  1021.  
  1022.         ret     2
  1023.  
  1024. CHARFONTEND ENDP
  1025.  
  1026. ;@T39       ENDIF  FONT_SUPPORT
  1027.  
  1028. ;/*****************************************************************************
  1029. ;*
  1030. ;*  SUBROUTINE NAME: AccessCursorPos
  1031. ;*
  1032. ;*  DESCRIPTIVE NAME: Set or read physical cursor position
  1033. ;*
  1034. ;*  FUNCTION: AccessCursorPos is called to determine or set the
  1035. ;*            physical cursor location
  1036. ;*
  1037. ;*  ENTRY POINT: AccessCursorPos
  1038. ;*    LINKAGE:   CALL FAR
  1039. ;*
  1040. ;*  INPUT: (Passed on stack)
  1041. ;*             WORD  Direction ( GET or SET )
  1042. ;*             DWORD CursorPositiion ( far pointer to structure )
  1043. ;*                      WORD Row
  1044. ;*                      WORD Column
  1045. ;*
  1046. ;*  EXIT-NORMAL: Cursor position set or returned
  1047. ;*
  1048. ;*  INTERNAL REFERENCES:
  1049. ;*    ROUTINES: NONE
  1050. ;*
  1051. ;*  EXTERNAL REFERENCES:
  1052. ;*    ROUTINES: NONE
  1053. ;*
  1054. ;*****************************************************************************/
  1055.  
  1056.         PUBLIC  ACCESSCURSORPOS
  1057. ACCESSCURSORPOS PROC FAR
  1058.  
  1059.         enter   2, 0                    ; Allocate 1 word temporary storage
  1060.         push    es
  1061.         push    di
  1062.  
  1063.         les     di, ParameterPacket     ; es:di = cursor position packet
  1064.  
  1065.         .if     < ColorMode eq TRUE >   ; Determine port address fixup
  1066.             mov     ColorMonoFixup, ColorAdjustment
  1067.         .else
  1068.             mov     ColorMonoFixup, MonoAdjustment
  1069.         .endif
  1070.  
  1071. ;/*
  1072. ;**  Address Cursor Location Low Register in CRT Controller Registers
  1073. ;*/
  1074.  
  1075.         mov     dx, CRTCtlAddressReg    ; CRT Controller Address Register
  1076.         add     dx, ColorMonoFixup
  1077.  
  1078.         mov     al, IndCursorLowLoc     ; Address Cursor Location Low Register
  1079.         cli
  1080.         out     dx, al
  1081.         push    dx                      ; Remember CRT Controller Address
  1082.                                         ;   Register Port
  1083.  
  1084. ;/*
  1085. ;**  Set/Read Cursor Location Low Register
  1086. ;*/
  1087.  
  1088.         mov     dx, CRTCtlDataReg       ; CRT Controller Data Register
  1089.         add     dx, ColorMonoFixup      ; Port address fixup
  1090.  
  1091.         .if     < Direction eq SET >
  1092.             push    dx
  1093.             mov     ax, CharacterColumns ; Number of columns this mode
  1094.             mul     WORD PTR es:[di].CursorRow ; Row * # of screen columns
  1095.             add     ax, WORD PTR es:[di].CursorColumn ; (Row * # of screen columns)+Column
  1096.             pop     dx
  1097.             out     dx, al              ; Cursor Location Low value in AL
  1098.         .else
  1099.             in      al, dx              ; Cursor Location Low value in AL
  1100.             mov     cl, al              ; Save low byte of cursor location
  1101.         .endif
  1102.  
  1103.         pop     dx                      ; Get CRT Controller Address
  1104.                                         ;   Register Port
  1105.         .if     < Direction eq SET >
  1106.             push    ax                  ; Save the cursor location
  1107.         .endif
  1108.  
  1109.  
  1110. ;/*
  1111. ;**  Address Cursor Location High Register in CRT Controller Registers
  1112. ;*/
  1113.  
  1114.         mov     al, IndCursorHighLoc    ; Address Cursor Location High Register
  1115.         out     dx, al
  1116.  
  1117. ;/*
  1118. ;**  Set/Read Cursor Location High Register
  1119. ;*/
  1120.  
  1121.         mov     dx, CRTCtlDataReg       ; CRT Controller Data Register
  1122.         add     dx, ColorMonoFixup      ; Port address fixup
  1123.  
  1124.         .if     < Direction eq SET >
  1125.             pop     ax                  ; Retrieve the location
  1126.             xchg    al, ah              ; Put high byte into low byte
  1127.             out     dx, al              ; Cursor Location High value in AL
  1128.         .else
  1129.             in      al, dx              ; Cursor Location High value in AL
  1130.  
  1131. ;/*
  1132. ;**  Calculate the cursor position parameters using the register value
  1133. ;*/
  1134.  
  1135.             mov     ah, al              ; Put high byte in AH
  1136.             mov     al, cl              ; Put low byte in AL
  1137.             xor     dx, dx              ; Word division
  1138.             div     CharacterColumns    ; # of screen columns
  1139.             mov     WORD PTR es:[di].CursorRow, ax
  1140.             mov     WORD PTR es:[di].CursorColumn, dx
  1141.         .endif
  1142.  
  1143.         sti
  1144.  
  1145.         pop     di
  1146.         pop     es
  1147.  
  1148.         leave                           ; Deallocate temorary storage
  1149.         ret     10
  1150.  
  1151. ACCESSCURSORPOS ENDP
  1152.  
  1153. ;/*****************************************************************************
  1154. ;*
  1155. ;*  SUBROUTINE NAME: AccessCursorType
  1156. ;*
  1157. ;*  DESCRIPTIVE NAME: Set or read physical cursor type
  1158. ;*
  1159. ;*  FUNCTION: AccessCursorType is called to determine or set the
  1160. ;*            physical cursor type
  1161. ;*
  1162. ;*  ENTRY POINT: AccessCursorType
  1163. ;*    LINKAGE:   CALL FAR
  1164. ;*
  1165. ;*  INPUT: (Passed on stack)
  1166. ;*             WORD  Direction ( GET or SET )
  1167. ;*             DWORD CursorType ( far pointer to structure )
  1168. ;*                       WORD TopScanLine
  1169. ;*                       WORD BottomScanLine
  1170. ;*                       WORD Width
  1171. ;*                       WORD Attribute
  1172. ;*
  1173. ;*  EXIT-NORMAL: Cursor type is set or returned
  1174. ;*
  1175. ;*  INTERNAL REFERENCES:
  1176. ;*    ROUTINES: NONE
  1177. ;*
  1178. ;*  EXTERNAL REFERENCES:
  1179. ;*    ROUTINES: NONE
  1180. ;*
  1181. ;*****************************************************************************/
  1182.  
  1183.         PUBLIC  ACCESSCURSORTYPE
  1184. ACCESSCURSORTYPE PROC FAR
  1185.  
  1186.         enter   2, 0                    ; Allocate 1 word temporary storage
  1187.         push    es
  1188.         push    di
  1189.  
  1190.         les     di, ParameterPacket     ; es:di = cursor type packet
  1191.  
  1192.         .if     < ColorMode eq TRUE >   ; Determine port address fixup
  1193.             mov     ColorMonoFixup, ColorAdjustment
  1194.         .else
  1195.             mov     ColorMonoFixup, MonoAdjustment
  1196.         .endif
  1197.  
  1198. ;/*
  1199. ;**  Address Cursor Start Register in CRT Controller Registers
  1200. ;*/
  1201.  
  1202.         mov     dx, CRTCtlAddressReg    ; CRT Controller Address Register
  1203.         add     dx, ColorMonoFixup
  1204.  
  1205. IF VDHVGA AND (1 - VDHINIT)     ; VDHVGA AND NOT VDHINIT                ;@MS04
  1206.  
  1207.  
  1208.         .if     < Direction eq SET >                                    ;@MS04
  1209.             push    ds                                                  ;@MS04
  1210.             mov     ax,seg _OEMFlags                                    ;@MS04
  1211.             mov     ds,ax                                               ;@MS04
  1212.             mov     al,BYTE PTR es:[di].CursorTopScanLine               ;@MS04
  1213.             test    ds:word ptr[_OEMFlags],PARADISE_VGA                 ;@MS04
  1214.             pop     ds                                                  ;@MS04
  1215.             .if     < nz > and                                          ;@MS04
  1216.             .if     < al ne 0 >                                         ;@MS04
  1217.                 mov     al,IndMaxScanLine                               ;@MS04
  1218.                 out     dx,al                                           ;@MS04
  1219.                 inc     dx                                              ;@MS04
  1220.                 in      al,dx                   ; Get char cell size    ;@MS04
  1221.                 and     al,CHAR_SCANLINES                               ;@MS04
  1222.                 dec     dx                                              ;@MS04
  1223.                 mov     ah,BYTE PTR es:[di].CursorBottomScanLine        ;@MS04
  1224.                 .if < al eq ah >                                        ;@MS04
  1225.                     dec     BYTE PTR es:[di].CursorBottomScanLine       ;@MS04
  1226.                     dec     BYTE PTR es:[di].CursorTopScanLine          ;@MS04
  1227.                 .endif                                                  ;@MS04
  1228.             .endif                                                      ;@MS04
  1229.         .endif                                                          ;@MS04
  1230.  
  1231. ENDIF   ;VDHVGA AND NOT VDHINIT
  1232.  
  1233.         mov     al, IndCursorStart      ; Address Cursor Start Register
  1234.         cli
  1235.  
  1236.  
  1237.         out     dx, al
  1238.         push    dx              ; Remember CRT Controller Address Register port
  1239.  
  1240.  
  1241. ;/*
  1242. ;**  Set/Read Cursor Start Register
  1243. ;*/
  1244.  
  1245.         mov     dx, CRTCtlDataReg       ; CRT Controller Data Register
  1246.         add     dx, ColorMonoFixup      ; Port address fixup
  1247.  
  1248. IF VDHVGA                               ; Read/write hardware           ;@MS00
  1249.  
  1250.         in      al, dx                  ; Read reserved bits
  1251.  
  1252. ELSE
  1253.                                                                         ;@MS00
  1254.         xor     al, al                  ; Zero reserved bits
  1255.  
  1256. ENDIF   ;VDHVGA                                                         ;@MS00
  1257.  
  1258.         .if     < Direction eq SET >
  1259.  
  1260.             and     al, 11000000B       ; Clear bits we will set
  1261.  
  1262.             or      al, BYTE PTR es:[di].CursorTopScanLine ; Get value
  1263.  
  1264.             .if     <<WORD PTR es:[di].CursorAttribute> eq -1 > ; Hidden cursor?
  1265.  
  1266. IF VDHVGA   ;VGA: b5 turns off cursor, OTHERS: b5 & b6 turns off cursor ;@MS00
  1267.  
  1268.                 or      al, 00100000B   ; Flip cursor off bit
  1269.  
  1270. ELSE                                                                    ;@MS00
  1271.  
  1272.                 or      al, 00111111B   ; Flip cursor off bits    ;@T57
  1273.  
  1274. ENDIF   ;VDHVGA                                                         ;@MS00
  1275.  
  1276.             .endif
  1277.  
  1278.             out     dx, al              ; Cursor Start value in AL
  1279.         .else
  1280.  
  1281. IF VDHVGA                               ; Read/write hardware           ;@MS00
  1282.  
  1283.             test    al, 00100000B       ; Check cursor off bit
  1284.             .if     < nz >
  1285.                 mov     WORD PTR es:[di].CursorAttribute, -1 ; Cursor is hidden
  1286.             .else
  1287.                 mov     WORD PTR es:[di].CursorAttribute, 0 ; Cursor is not hidden
  1288.             .endif
  1289.  
  1290.             mov     WORD PTR es:[di].CursorWidth, 1 ; Cursor width is always 1 column
  1291.  
  1292.             and     ax, 00011111B       ; Isolate scan line begin (top)
  1293.             mov     WORD PTR es:[di].CursorTopScanLine, ax
  1294.  
  1295. ENDIF   ;VDHVGA                                                         ;@MS00
  1296.  
  1297.         .endif
  1298.  
  1299.         pop     dx              ; Get CRT Controller Address Register port
  1300.  
  1301.  
  1302. ;/*
  1303. ;**  Address Cursor End Register in CRT Controller Registers
  1304. ;*/
  1305.  
  1306.         mov     al, IndCursorEnd        ; Address Cursor End Register
  1307.         out     dx, al
  1308.  
  1309.  
  1310. ;/*
  1311. ;**  Set/Read Cursor End Register
  1312. ;*/
  1313.  
  1314.         mov     dx, CRTCtlDataReg       ; CRT Controller Data Register
  1315.         add     dx, ColorMonoFixup      ; Port address fixup
  1316.  
  1317. IF VDHVGA                               ; Read/write hardware           ;@MS00
  1318.  
  1319.         in      al, dx                  ; Read reserved bits
  1320.  
  1321. ELSE                                                                    ;@MS00
  1322.  
  1323.         xor     al, al                  ; Zero reserved bits
  1324.  
  1325. ENDIF   ;VDHVGA                                                         ;@MS00
  1326.  
  1327.         .if     < Direction eq SET >
  1328.  
  1329.             and     al, 11100000B       ; Clear bits we will set
  1330.  
  1331.             or      al, BYTE PTR es:[di].CursorBottomScanLine
  1332.             out     dx, al              ; Cursor End value in AL
  1333.         .else
  1334.  
  1335. IF VDHVGA                               ; Read/write hardware           ;@MS00
  1336.  
  1337.             and     ax, 00011111B       ; Isolate scan line end (bottom)
  1338.             mov     WORD PTR es:[di].CursorBottomScanLine, ax
  1339.  
  1340. ENDIF   ;VDHVGA                                                         ;@MS00
  1341.  
  1342.         .endif
  1343.  
  1344.  
  1345.         sti
  1346.  
  1347.         pop     di
  1348.         pop     es
  1349.  
  1350.         leave                   ; Deallocate temorary storage
  1351.         ret     8
  1352.  
  1353. ACCESSCURSORTYPE ENDP
  1354.  
  1355. IF BLINK_SUPPORT                        ;@S4                            ;@MS00
  1356.  
  1357. ;/*****************************************************************************
  1358. ;*
  1359. ;*  SUBROUTINE NAME: AccessBlink
  1360. ;*
  1361. ;*  DESCRIPTIVE NAME: Set or read physical blink vs. BG intensity
  1362. ;*
  1363. ;*  FUNCTION: AccessBlink is called to query or set the physical
  1364. ;*            blink versus background intensity setting
  1365. ;*
  1366. ;*  ENTRY POINT: AccessBlink
  1367. ;*    LINKAGE:   CALL FAR
  1368. ;*
  1369. ;*  INPUT: (Passed on stack)
  1370. ;*             WORD  Direction ( GET or SET )
  1371. ;*             DWORD Blink ( far pointer to word )
  1372. ;*
  1373. ;*  EXIT-NORMAL: Blink vs. BG intensity is set or returned
  1374. ;*
  1375. ;*  INTERNAL REFERENCES:
  1376. ;*    ROUTINES: NONE
  1377. ;*
  1378. ;*  EXTERNAL REFERENCES:
  1379. ;*    ROUTINES: NONE
  1380. ;*
  1381. ;*****************************************************************************/
  1382.  
  1383.         PUBLIC  ACCESSBLINK
  1384. ACCESSBLINK     PROC    FAR
  1385.  
  1386.         push    bp
  1387.         mov     bp, sp
  1388.         push    es
  1389.         push    di
  1390.  
  1391.         les     di, ParameterPacket     ;es:di = Blink setting
  1392.  
  1393. ;/*
  1394. ;**  Address Attribute Mode Control Register in Attribute Controller Registers
  1395. ;*/
  1396.  
  1397.         @SetAttAddressPort              ; Attribute Address Register
  1398.         mov     al, IndAttModeCtl       ; Address Attribute Mode Control Reg.
  1399.         out     dx, al                  ; Set up for get mode ctl color
  1400.  
  1401. ;/*
  1402. ;**  Set/Read Attribute Mode Control Register
  1403. ;*/
  1404.  
  1405.         mov     dx, AttDataReadPort     ; Read current mode ctl setting
  1406.  
  1407. IF VDHVGA                               ; Read/write hardware           ;@MS00
  1408.  
  1409.         in      al, dx                  ; Read reserved bits
  1410.  
  1411. ELSE                                                                    ;@MS00
  1412.  
  1413.         xor     al, al                  ; Zero reserved bits
  1414.  
  1415. ENDIF   ;VDHVGA                                                         ;@MS00
  1416.  
  1417.         .if     < Direction eq SET >
  1418.  
  1419.             and     al, 11110111B       ; Select background intensity
  1420.             .if     < <WORD PTR es:[di].Blink> eq 0 >
  1421.                 or      al, 00001000B   ; Enable blink
  1422.             .endif
  1423.  
  1424.             mov     dx, AttDataWritePort ; Set the hardware
  1425.             out     dx, al
  1426.  
  1427. IF VDHVGA                               ; Read/write hardware           ;@MS00
  1428.  
  1429.         .else
  1430.             test    al, 00001000B       ; Check setting
  1431.             .if     < z >
  1432.                 mov     WORD PTR es:[di].Blink, 1 ; Report background intensity
  1433.             .else
  1434.                 mov     WORD PTR es:[di].Blink, 0 ; Report blink enable
  1435.             .endif
  1436.  
  1437. ENDIF   ;VDHVGA                                                         ;@MS00
  1438.  
  1439.         .endif
  1440.  
  1441.         @VideoOn
  1442.  
  1443.         sti
  1444.  
  1445.         pop     di
  1446.         pop     es
  1447.         pop     bp
  1448.         ret     8
  1449.  
  1450. ACCESSBLINK     ENDP
  1451.  
  1452. ENDIF   ;BLINK SUPPORT                                                  ;@MS00
  1453.  
  1454. IF OVERSCAN_SUPPORT                     ;@S4                            ;@MS00
  1455.  
  1456. ;/*****************************************************************************
  1457. ;*
  1458. ;*  SUBROUTINE NAME: AccessOverscan
  1459. ;*
  1460. ;*  DESCRIPTIVE NAME: Set or read physical border color
  1461. ;*
  1462. ;*  FUNCTION: AccessOverscan is called to query or set the physical
  1463. ;*            overscan color
  1464. ;*
  1465. ;*  ENTRY POINT: AccessOverscan
  1466. ;*    LINKAGE:   CALL FAR
  1467. ;*
  1468. ;*  INPUT: (Passed on stack)
  1469. ;*             WORD  Direction ( GET or SET )
  1470. ;*             DWORD Overscan ( far pointer to word )
  1471. ;*
  1472. ;*  EXIT-NORMAL: Overscan color is set or returned
  1473. ;*
  1474. ;*  INTERNAL REFERENCES:
  1475. ;*    ROUTINES: NONE
  1476. ;*
  1477. ;*  EXTERNAL REFERENCES:
  1478. ;*    ROUTINES: NONE
  1479. ;*
  1480. ;*****************************************************************************/
  1481.  
  1482.         PUBLIC  ACCESSOVERSCAN
  1483. ACCESSOVERSCAN  PROC    FAR
  1484.  
  1485.         push    bp
  1486.         mov     bp, sp
  1487.         push    es
  1488.         push    di
  1489.  
  1490.         les     di, ParameterPacket     ; es:di = Overscan color
  1491.  
  1492. ;/*
  1493. ;**  Address Overscan Color Register in Attribute Controller Registers
  1494. ;*/
  1495.  
  1496.         @SetAttAddressPort              ; Attribute Address Register
  1497.         mov     al, IndOverscanColor    ; Address Overscan Color Register
  1498.         out     dx, al                  ; Set up for get mode ctl color
  1499.  
  1500. ;/*
  1501. ;**   Set/Read Overscan Color Register
  1502. ;*/
  1503.  
  1504.         .if     < Direction eq SET >
  1505.  
  1506.             mov     al, BYTE PTR es:[di].Overscan
  1507.  
  1508.             mov     dx, AttDataWritePort ; Set the hardware
  1509.             out     dx, al
  1510.  
  1511. IF VDHVGA                               ; Read/write hardware           ;@MS00
  1512.  
  1513.         .else
  1514.             mov     dx, AttDataReadPort ; Read current setting
  1515.             in      al, dx
  1516.  
  1517.             xor     ah,ah                                               ;@B72
  1518.             mov     WORD PTR es:[di].Overscan, ax                       ;@B72
  1519.  
  1520. ENDIF   ;VDHVGA                                                         ;@MS00
  1521.  
  1522.         .endif
  1523.  
  1524.         @VideoOn
  1525.  
  1526.         sti
  1527.  
  1528.         pop     di
  1529.         pop     es
  1530.         pop     bp
  1531.         ret     8
  1532.  
  1533. ACCESSOVERSCAN  ENDP
  1534.  
  1535. ENDIF   ;OVERSCAN_SUPPORT                                               ;@MS00
  1536.  
  1537. IF UNDERSCORE_SUPPORT                   ;@S4                            ;@MS00
  1538.  
  1539. ;/*****************************************************************************
  1540. ;*
  1541. ;*  SUBROUTINE NAME: AccessUnderscore
  1542. ;*
  1543. ;*  DESCRIPTIVE NAME: Set or read physical underscore scan line no.
  1544. ;*
  1545. ;*  FUNCTION: AccessUnderscore is called to query or set the physical
  1546. ;*            underscore scan line
  1547. ;*
  1548. ;*  ENTRY POINT: AccessUnderscore
  1549. ;*    LINKAGE:   CALL FAR
  1550. ;*
  1551. ;*  INPUT: (Passed on stack)
  1552. ;*             WORD  Direction ( GET or SET )
  1553. ;*             DWORD Underscore ( far pointer to word )
  1554. ;*
  1555. ;*  EXIT-NORMAL: Underscore scan line is set or returned
  1556. ;*
  1557. ;*  INTERNAL REFERENCES:
  1558. ;*    ROUTINES: NONE
  1559. ;*
  1560. ;*  EXTERNAL REFERENCES:
  1561. ;*    ROUTINES: NONE
  1562. ;*
  1563. ;*****************************************************************************/
  1564.  
  1565.         PUBLIC  ACCESSUNDERSCORE
  1566. ACCESSUNDERSCORE PROC   FAR
  1567.  
  1568.         enter   2, 0                    ; Allocate 1 word of temporary storage
  1569.         push    es
  1570.         push    di
  1571.  
  1572.         les     di, ParameterPacket     ; es:di = underscore scan line
  1573.  
  1574.         .if     < ColorMode eq TRUE >   ; Determine port address fixup
  1575.             mov     ColorMonoFixup, ColorAdjustment
  1576.         .else
  1577.             mov     ColorMonoFixup, MonoAdjustment
  1578.         .endif
  1579.  
  1580.  
  1581. ;/*
  1582. ;**   Address Underline Location Register in CRT Controller Registers
  1583. ;*/
  1584.  
  1585.         mov     dx, CRTCtlAddressReg    ; CRT Controller Address Register
  1586.         add     dx, ColorMonoFixup      ; Port address fixup
  1587.         mov     al, IndUnderlineLoc     ; Address Underline Location Register
  1588.         cli
  1589.         out     dx, al
  1590.  
  1591.  
  1592. ;/*
  1593. ;**   Set/Read Underline Location Register
  1594. ;*/
  1595.  
  1596.         mov     dx, CRTCtlDataReg       ; CRT Controller Data Register
  1597.         add     dx, ColorMonoFixup      ; Port address fixup            ;@B72
  1598.  
  1599. IF VDHVGA                               ; Read/write hardware           ;@MS00
  1600.  
  1601.         in      al, dx                  ; Read reserved bits
  1602.  
  1603. ELSE                                                                    ;@MS00
  1604.  
  1605.         xor     al, al                  ; Zero reserved bits
  1606.  
  1607. ENDIF   ;VDHVGA                                                         ;@MS00
  1608.  
  1609.         .if     < Direction eq SET >
  1610.  
  1611.             and     al, 11100000B       ; Clear bits we will set
  1612.  
  1613.             or      al, BYTE PTR es:[di].Underscore ; Set the hardware
  1614.             out     dx, al
  1615.  
  1616. IF VDHVGA                               ; Read/write hardware           ;@MS00
  1617.  
  1618.         .else
  1619.             and     al, 00011111B       ; Isolate underscore scan line
  1620.             xor     ah,ah                                               ;@B72
  1621.             mov     WORD PTR es:[di].Underscore, ax                     ;@B72
  1622.  
  1623. ENDIF   ;VDHVGA                                                         ;@MS00
  1624.  
  1625.         .endif
  1626.  
  1627.         sti
  1628.  
  1629.         pop     di
  1630.         pop     es
  1631.         leave                           ; Deallocate temporary storage
  1632.         ret     8
  1633.  
  1634. ACCESSUNDERSCORE ENDP
  1635.  
  1636. ENDIF   ;UNDERSCORE_SUPPORT                                             ;@MS00
  1637.  
  1638. ;/*****************************************************************************
  1639. ;*
  1640. ;*  SUBROUTINE NAME: AccessVideoEnable
  1641. ;*
  1642. ;*  DESCRIPTIVE NAME: Set or read physical video enable
  1643. ;*
  1644. ;*  FUNCTION: AccessVideoEnable is called to query or set the physical
  1645. ;*            video enable setting.
  1646. ;*
  1647. ;*  ENTRY POINT: AccessVideoEnable
  1648. ;*    LINKAGE:   CALL FAR
  1649. ;*
  1650. ;*  INPUT: (Passed on stack)
  1651. ;*             WORD  Direction ( GET or SET )
  1652. ;*             DWORD VideoEnable ( far pointer to word )
  1653. ;*
  1654. ;*  EXIT-NORMAL: Video enable is set or returned
  1655. ;*
  1656. ;*  INTERNAL REFERENCES:
  1657. ;*    ROUTINES: NONE
  1658. ;*
  1659. ;*  EXTERNAL REFERENCES:
  1660. ;*    ROUTINES: NONE
  1661. ;*
  1662. ;*****************************************************************************/
  1663.  
  1664.         PUBLIC  ACCESSVIDEOENABLE
  1665. ACCESSVIDEOENABLE PROC FAR
  1666.  
  1667.         push    bp
  1668.         mov     bp, sp
  1669.         push    es
  1670.         push    di
  1671.  
  1672.         les     di, ParameterPacket     ; es:di = underscore scan line
  1673.  
  1674.         cli                             ; clear interrupts
  1675.  
  1676.  
  1677. IF VDHEGA OR VDHVGA                                                     ;@MS00
  1678.  
  1679.         @SetAttAddressPort              ; Set the Attribute Address Port
  1680.  
  1681. IF VDHVGA                               ;@C21                           ;@MS00
  1682.  
  1683.         .if     < Direction eq GET >    ;@C21
  1684.             mov     dx,AttDataReadPort  ;@C21
  1685.             in      al,dx               ;@C21
  1686.             mov     WORD PTR es:[di].VideoEnable, 0 ;Disabled  @C21
  1687.             test    al, 20h             ;@C21
  1688.             .if     < nz >              ;@C21
  1689.                 inc     WORD PTR es:[di].VideoEnable ;Enabled   @C21
  1690.             .endif                      ;@C21
  1691.         .else                           ;@C21
  1692.  
  1693. ENDIF   ;VDHVGA                         ;@C21                           ;@MS00
  1694.  
  1695.             sub     ax,ax               ; Preset Disable video
  1696.             .if     < <WORD PTR es:[di].VideoEnable> ne ax >
  1697.                 mov     al, 20h         ; Set Enable video
  1698.             .endif
  1699.             out     dx, al              ; Write to the port
  1700.  
  1701. IF VDHVGA                               ;@C21                           ;@MS00
  1702.         .endif                          ;@C21
  1703. ENDIF   ;VDHVGA                         ;@C21                           ;@MS00
  1704.  
  1705. ENDIF   ;VDHEGA OR VDHVGA                                               ;@MS00
  1706.  
  1707.         sti
  1708.         pop     di
  1709.         pop     es
  1710.         pop     bp
  1711.         ret     8
  1712.  
  1713. ACCESSVIDEOENABLE ENDP
  1714.  
  1715. IF VDHVGA                                                               ;@MS00
  1716.  
  1717. ;/*****************************************************************************
  1718. ;*
  1719. ;*  SUBROUTINE NAME: AccessCLUT for VGA
  1720. ;*
  1721. ;*  DESCRIPTIVE NAME: Set or read physical color lookup table
  1722. ;*
  1723. ;*  FUNCTION: AccessCLUT is called to query or set the physical
  1724. ;*            color lookup table.
  1725. ;*
  1726. ;*  ENTRY POINT: AccessCLUT
  1727. ;*    LINKAGE:   CALL FAR
  1728. ;*
  1729. ;*  INPUT: (Passed on stack)
  1730. ;*             WORD   Direction ( GET or SET )
  1731. ;*             DWORD  ColorLookupTable  ( far pointer to structure )
  1732. ;*                      DWORD DataArea ( far pointer to table )
  1733. ;*                      WORD  FirstEntry
  1734. ;*                      WORD  NumEntries
  1735. ;*
  1736. ;*  EXIT-NORMAL: Color lookup table is altered or queried
  1737. ;*
  1738. ;*  INTERNAL REFERENCES:
  1739. ;*    ROUTINES: NONE
  1740. ;*
  1741. ;*  EXTERNAL REFERENCES:
  1742. ;*    ROUTINES: NONE
  1743. ;*
  1744. ;*****************************************************************************/
  1745.  
  1746.  
  1747.         PUBLIC  ACCESSCLUT
  1748. ACCESSCLUT      PROC    FAR
  1749.  
  1750.         push    bp
  1751.         mov     bp, sp
  1752.         push    es
  1753.         push    di
  1754.  
  1755.         les     di, ParameterPacket     ; es:di = palette packet
  1756.  
  1757.         mov     cx,WORD PTR es:[di].NumEntries ; # of triplets  ;@B705063
  1758.         mov     ax, WORD PTR es:[di].FirstEntry ; starting reg  ;@B705063
  1759.         les     di, DWORD PTR es:[di].DataArea
  1760.  
  1761.         .if     < Direction eq SET >    ;@B705063
  1762.             mov     dx, PELAddressWrite ;@B705063
  1763.             cli                         ;@B705063
  1764.             out     dx, al              ;@B705063
  1765.             mov     dx, PELDataRegister ; Get data register ;@B705063
  1766.             .repeat                     ;@B705063
  1767.                 cli                     ;@B705063
  1768.                 mov     al, BYTE PTR es:[di] ;@B705063
  1769.                 out     dx, al          ; Set register value ;@B705063
  1770.                 inc     di              ;@B705063
  1771.                 mov     al, BYTE PTR es:[di] ;@B705063
  1772.                 out     dx, al          ; Set register value ;@B705063
  1773.                 inc     di              ;@B705063
  1774.                 mov     al, BYTE PTR es:[di] ;@B705063
  1775.                 out     dx, al          ; Set register value ;@B705063
  1776.                 sti                     ;@B705063
  1777.                 inc     di              ;@B705063
  1778.             .loop                       ;@B705063
  1779.         .else                           ;@B705063
  1780.             cld                         ;@B705063
  1781.             mov     dx, PELAddressRead  ;@B705063
  1782.             cli                         ;@B705063
  1783.             out     dx, al              ;@B705063
  1784.             mov     dx, PELDataRegister ; Get data register ;@B705063
  1785.  
  1786. IFE VDHINIT
  1787.             push    ds
  1788.             mov     ax, seg _OEMFlags
  1789.             mov     ds, ax
  1790.             mov     ah, 3Fh             ; Default 6-bit DAC
  1791.             .if     <bit [_OEMFlags] and STARDUST_VGA>
  1792.                 mov     ah, 0FFh        ; VGA has 8-bit DAC
  1793.             .endif
  1794.             pop     ds
  1795. ELSE
  1796.             mov     ah, 3Fh
  1797. ENDIF
  1798.             .repeat                     ;@B705063
  1799.                 cli                     ;@B705063
  1800.                 in      al, dx          ; Set register value ;@B705063
  1801.                 and     al, ah          ; Isolate color ( x bits ) ;@B705063
  1802.                 stosb                   ;@B705063
  1803.                 in      al, dx          ; Set register value ;@B705063
  1804.                 and     al, ah          ; Isolate color ( x bits ) ;@B705063
  1805.                 stosb                   ;@B705063
  1806.                 in      al, dx          ; Set register value ;@B705063
  1807.                 sti                     ;@B705063
  1808.                 and     al, ah          ; Isolate color ( x bits ) ;@B705063
  1809.                 stosb                   ;@B705063
  1810.             .loop                       ;@B705063
  1811.         .endif
  1812.  
  1813.         pop     di
  1814.         pop     es
  1815.         pop     bp
  1816.         ret     6
  1817.  
  1818. ACCESSCLUT      ENDP
  1819.  
  1820. ENDIF   ;VDHVGA                                                         ;@MS00
  1821.  
  1822. ;/*****************************************************************************
  1823. ;*
  1824. ;*  SUBROUTINE NAME: AccessHardware
  1825. ;*
  1826. ;*  DESCRIPTIVE NAME: Set or read physical indexed registers
  1827. ;*
  1828. ;*  FUNCTION: AccessHardware is called to query or set the physical
  1829. ;*            indexed registers - Sequencers, Attributes, CRTs, or
  1830. ;*            Graphics
  1831. ;*
  1832. ;*  ENTRY POINT: AccessHardware
  1833. ;*    LINKAGE:   CALL FAR
  1834. ;*
  1835. ;*  INPUT: (Passed on stack)
  1836. ;*             DWORD  RegAddress ( far pointer to structure )
  1837. ;*                       WORD RegAddressPort
  1838. ;*                       WORD RegDataPort
  1839. ;*                       WORD RegColorAdjust
  1840. ;*                       WORD RegFlags
  1841. ;*             WORD   DataType ( BYTES or WORDS )
  1842. ;*             WORD   Direction ( GET or SET )
  1843. ;*             DWORD  RegData ( far pointer to structure )
  1844. ;*                       DWORD DataArea  ( far pointer to data table )
  1845. ;*                       WORD  FirstEntry
  1846. ;*                       WORD  NumEntries
  1847. ;*
  1848. ;*  EXIT-NORMAL: Indexed registers are altered or queried
  1849. ;*
  1850. ;*  INTERNAL REFERENCES:
  1851. ;*    ROUTINES: NONE
  1852. ;*
  1853. ;*  EXTERNAL REFERENCES:
  1854. ;*    ROUTINES: NONE
  1855. ;*
  1856. ;*****************************************************************************/
  1857.  
  1858.         PUBLIC  ACCESSHARDWARE
  1859. ACCESSHARDWARE PROC FAR
  1860.  
  1861.         push    bp
  1862.         mov     bp, sp
  1863.         push    es
  1864.         push    di
  1865.         push    ds
  1866.         push    si
  1867.  
  1868.         les     di, ParameterPacket     ; es:di = data packet
  1869.         lds     si, AddressPacket       ; ds:di = address packet
  1870.  
  1871.         mov     bx, WORD PTR  es:[di].FirstEntry ; Get starting reg
  1872.         mov     cx, WORD PTR  es:[di].NumEntries ; Get number of regs
  1873.         les     di, DWORD PTR es:[di].DataArea
  1874.  
  1875.  
  1876.         .if     < ds:[si].RegFlags eq Attributes_CMD >
  1877.  
  1878. ;/*
  1879. ;**  To access the attribute address register, an 'in' must be issued to
  1880. ;**  the Attribute Controller at address 03BA for mono or 03DA for color.
  1881. ;*/
  1882.  
  1883.             mov     dx, AttCtlInitializeReg ; Feature Control Register - init AttCtl flip-flop
  1884.             .if     < ColorMode eq TRUE >
  1885.                 add     dx, ColorAdjustment
  1886.             .endif
  1887.         .endif
  1888.  
  1889.         push    dx                      ;@B19
  1890.  
  1891. HARDWARE_REG:
  1892.         cli                             ;@B717771
  1893.         .if     < ds:[si].RegFlags eq Attributes_CMD >
  1894.             pop     dx                  ;@B19
  1895.             in      al, dx              ; Read port to reset flip-flop
  1896.             push    dx                  ;@B19
  1897.         .endif
  1898.  
  1899.  
  1900.         mov     dx, ds:[si].RegAddressPort ; Address Register
  1901.         .if     < ColorMode eq TRUE >
  1902.             add     dx, ds:[si].RegColorAdjust
  1903.         .endif
  1904.         mov     al, bl                  ; Address Palette Reg ( 00 - 0F )
  1905.  
  1906.  
  1907. IF VDHVGA                               ;@B19                           ;@MS00
  1908.         ; wait for vertical retrace to avoid glitching VRAM ;@B19
  1909.         .if     <al EQ 10h> AND         ;@B19
  1910.         .if     <dx EQ AttAddressPort>  ;@B19
  1911.             call    VGAWait             ;@B19
  1912.         .endif                          ;@B19
  1913. ENDIF   ;VDHVGA                         ;@B19                           ;@MS00
  1914.  
  1915.  
  1916.         out     dx, al                  ; Set up for get palette reg
  1917.  
  1918.         mov     dx, ds:[si].RegDataPort ; Address Register
  1919.         .if     < ColorMode eq TRUE >
  1920.             add     dx, ds:[si].RegColorAdjust
  1921.         .endif
  1922.  
  1923.         .if     < Direction eq SET >
  1924.             mov     al, BYTE PTR es:[di]
  1925.             out     dx, al
  1926.         .else
  1927.  
  1928. IF VDHVGA                               ; Read/write hardware           ;@MS00
  1929.  
  1930.             in      al, dx
  1931.             .if     < WordByte eq WORDS >
  1932.                 xor     ah, ah
  1933.                 mov     WORD PTR es:[di], ax
  1934.             .else
  1935.                 mov     BYTE PTR es:[di], al
  1936.             .endif
  1937.  
  1938. ENDIF   ;VDHVGA                                                         ;@MS00
  1939.  
  1940.         .endif
  1941.  
  1942.         inc     bx
  1943.         .if     < WordByte eq WORDS >
  1944.             inc     di                  ; Point to next byte
  1945.         .endif
  1946.         inc     di                      ; Point to next byte
  1947.  
  1948.         sti                             ;@B717771
  1949.         loop    HARDWARE_REG
  1950.  
  1951.         pop     dx                      ;@B19
  1952.  
  1953.         cli                             ;@B717771
  1954.  
  1955.         .if     < ds:[si].RegFlags eq Sequencers_CMD > AND  ; @tb25
  1956.         .if     < Direction eq SET >                        ; @tb25
  1957.  
  1958. IF VDHVGA AND (1 - VDHINIT)                                             ;@DRW
  1959.             push    ds                                                  ;@DRW
  1960.             mov     ax, seg _SVGAPresent
  1961.             mov     ds, ax
  1962.             cmp     _SVGAPresent, TSENG_ADAPTER                         ;@DRW
  1963.             pop     ds                                                  ;@DRW
  1964.             je      @F                                                  ;@DRW
  1965.             @FixVGABug
  1966. @@:
  1967. ENDIF   ;VDHVGA                                                         ;@MS00
  1968.  
  1969.             mov     dx, SeqAddressPort  ; Sequencer address port
  1970.             mov     al, 0               ; Reset register index
  1971.             out     dx, al
  1972.             mov     dx, SeqDataPort     ; Sequencer data port
  1973.             mov     al, 3               ; Enable Sequencers again
  1974.             out     dx, al
  1975.         .endif
  1976.  
  1977.         sti
  1978.  
  1979.         pop     si
  1980.         pop     ds
  1981.         pop     di
  1982.         pop     es
  1983.         pop     bp
  1984.         ret     14
  1985.  
  1986. ACCESSHARDWARE ENDP
  1987.  
  1988. IF VDHVGA                                                               ;@MS00
  1989.  
  1990. ;/*****************************************************************************
  1991. ;*
  1992. ;*  SUBROUTINE NAME: VGAWait
  1993. ;*
  1994. ;*  DESCRIPTIVE NAME: wait for video retrace before a write to port
  1995. ;*                    3C0h, register 10h
  1996. ;*
  1997. ;*  FUNCTION:
  1998. ;*
  1999. ;*  ENTRY POINT: VGAWait
  2000. ;*    LINKAGE:   CALL NEAR
  2001. ;*
  2002. ;*  INPUT: none
  2003. ;*  INTERNAL REFERENCES:
  2004. ;*    ROUTINES: NONE
  2005. ;*
  2006. ;*  EXTERNAL REFERENCES:
  2007. ;*    ROUTINES: NONE
  2008. ;*
  2009. ;*****************************************************************************/
  2010.  
  2011.         PUBLIC  VGAWait
  2012. VGAWait PROC    NEAR                    ;@B19
  2013.         sti
  2014.         push    ax
  2015.         push    cx
  2016.         push    dx
  2017.         mov     dx, FeatureControlWrite
  2018.         .if     < ColorMode eq TRUE >
  2019.             add     dx, 20h             ; use color ports
  2020.         .endif
  2021.         xor     cx,cx           ; time out in case a card never sets this bit
  2022. VGAWait1:
  2023.         in      al,dx
  2024.         test    al,8            ; look for retrace bit
  2025.         loopnz  VGAWait1        ; wait for retrace to end
  2026.         xor     cx,cx           ; time out in case a card never sets this bit
  2027. VGAWait2:
  2028.         sti
  2029.         nop
  2030.         nop                     ; 486     work around            ;@T49
  2031.         cli
  2032.         in      al,dx
  2033.         test    al,8            ; look for retrace bit
  2034.         loopz   VGAWait2        ;wait for retrace to begin again
  2035.  
  2036.         pop     dx
  2037.         pop     cx
  2038.         pop     ax
  2039.         ret
  2040. VGAWait ENDP
  2041.  
  2042. ENDIF   ;VDHVGA                                                         ;@MS00
  2043.  
  2044.  
  2045. ENDIF   ;VDH8514A                                                       ;@MS00
  2046.  
  2047.  
  2048. ;/*****************************************************************************
  2049. ;*
  2050. ;*  SUBROUTINE NAME: AccessRegister
  2051. ;*
  2052. ;*  DESCRIPTIVE NAME: Set or read physical non-indexed register
  2053. ;*
  2054. ;*  FUNCTION: AccessRegister is called to query or set the physical
  2055. ;*            non-indexed register specified
  2056. ;*
  2057. ;*  ENTRY POINT: AccessRegister
  2058. ;*    LINKAGE:   CALL FAR
  2059. ;*
  2060. ;*  INPUT: (Passed on stack)
  2061. ;*             DWORD  RegAddress ( far pointer to structure )
  2062. ;*                       WORD RegAddressPort
  2063. ;*                       WORD RegDataPort
  2064. ;*                       WORD RegColorAdjust
  2065. ;*                       WORD RegFlags
  2066. ;*             WORD   Direction ( GET or SET or SETWORD )
  2067. ;*             DWORD  RegData ( far pointer to data )
  2068. ;*
  2069. ;*  EXIT-NORMAL: Non-indexed register is altered or queried
  2070. ;*
  2071. ;*  INTERNAL REFERENCES:
  2072. ;*    ROUTINES: NONE
  2073. ;*
  2074. ;*  EXTERNAL REFERENCES:
  2075. ;*    ROUTINES: NONE
  2076. ;*
  2077. ;*****************************************************************************/
  2078.  
  2079.         PUBLIC  ACCESSREGISTER
  2080. ACCESSREGISTER PROC FAR
  2081.  
  2082.         push    bp
  2083.         mov     bp, sp
  2084.         push    es
  2085.         push    di
  2086.         push    ds
  2087.         push    si
  2088.  
  2089.         les     di, ParameterPacket     ; es:di = data packet
  2090.         lds     si, AddressPkt          ; ds:si = address packet
  2091.  
  2092.         mov     dx, ds:[si].RegDataPort ; Register port
  2093.  
  2094.         cli
  2095.  
  2096.         .if     < Direction eq SET >
  2097.  
  2098. IF VDHEGA OR VDHVGA                                                     ;@MS00
  2099.  
  2100.             .if     < ds:[si].RegDataPort eq MiscOutputRegWrite >
  2101.                 push    dx              ; Save register address
  2102.                 mov     dx, SeqAddressPort ; Sequencer address port
  2103.                 mov     al, 0           ; Reset register index
  2104.                 out     dx, al
  2105.                 mov     dx, SeqDataPort ; Sequencer data port
  2106.                 inc     al              ; Synchronous reset
  2107.                 out     dx, al
  2108.  
  2109.                 pop     dx              ; Retrieve register address
  2110.                 mov     al, BYTE PTR es:[di] ; Set miscoutput register
  2111.  
  2112.                 out     dx, al
  2113.  
  2114. IF VDHVGA AND (1 - VDHINIT)                                             ;@DRW
  2115.                 push    ds                                              ;@DRW
  2116.                 mov     ax, seg _SVGAPresent                            ;@DRW
  2117.                 mov     ds, ax                                          ;@DRW
  2118.                 cmp     _SVGAPresent, TSENG_ADAPTER                     ;@DRW
  2119.                 pop     ds                                              ;@DRW
  2120.                 je      @F                                              ;@DRW
  2121.                 @FixVGABug
  2122. @@:
  2123. ENDIF   ;VDHVGA                                                         ;@MS00
  2124.  
  2125.                 mov     dx, SeqAddressPort ; Sequencer address port
  2126.                 mov     al, 0           ; Reset register index
  2127.                 out     dx, al
  2128.                 mov     dx, SeqDataPort ; Sequencer data port
  2129.                 mov     al, 3           ; Normal operation
  2130.                 out     dx, al
  2131.             .else
  2132.  
  2133. ENDIF   ;VDHEGA OR VDHVGA                                               ;@MS00
  2134.  
  2135.                 mov     al, BYTE PTR es:[di]
  2136.                 out     dx, al
  2137.  
  2138. IF VDHEGA OR VDHVGA                                                     ;@MS00
  2139.  
  2140.             .endif
  2141.  
  2142. ENDIF   ;VDHEGA OR VDHVGA                                               ;@MS00
  2143.  
  2144.         .else
  2145.             .if     < Direction eq SETWORD >
  2146.  
  2147.                 mov     ax, word ptr es:[di]
  2148.                 out     dx,ax
  2149.  
  2150.             .else                       ; < Direction eq GET >
  2151.  
  2152.                 in      al, dx
  2153.                 stosb
  2154.  
  2155.             .endif
  2156.         .endif
  2157.  
  2158.         sti
  2159.  
  2160.         pop     si
  2161.         pop     ds
  2162.         pop     di
  2163.         pop     es
  2164.         pop     bp
  2165.         ret     10
  2166.  
  2167. ACCESSREGISTER ENDP
  2168.  
  2169. IF DEBUG                                                        ;@MS07 - BEGIN
  2170.  
  2171.  
  2172. ;/*
  2173. ;** Equates for com port
  2174. ;*/
  2175.  
  2176. COM1_DAT=       03f8H           ; base for COM1
  2177. COM2_DAT=       02f8H           ; base for COM2
  2178. R_IEN   =       1               ; Interrupt enable
  2179. R_IER   =       2               ; interrupt ID
  2180. R_LCR   =       3               ; line control registers
  2181. R_MCR   =       4               ; modem control register
  2182. R_LSR   =       5               ; line status register
  2183. R_MSR   =       6               ; modem status regiser
  2184. R_DLL   =       0               ; divisor latch least sig
  2185. R_DLM   =       1               ; divisor latch most sig
  2186.  
  2187. ;/*
  2188. ;** Exactly one of the next two lines should be uncommented to select por
  2189. ;*/
  2190.  
  2191. ;UR_DAT =       COM2_DAT        ; select COM2 = 02f8H
  2192. UR_DAT  =       COM1_DAT        ; select COM1 = 03f8H
  2193. UR_IEN  =       UR_DAT+1        ; Interrupt enable
  2194. UR_IER  =       UR_DAT+2        ; interrupt ID
  2195. UR_LCR  =       UR_DAT+3        ; line control registers
  2196. UR_MCR  =       UR_DAT+4        ; modem control register
  2197. UR_LSR  =       UR_DAT+5        ; line status register
  2198. UR_MSR  =       UR_DAT+6        ; modem status regiser
  2199. UR_DLL  =       UR_DAT          ; divisor latch least sig
  2200. UR_DLM  =       UR_DAT+1        ; divisor latch most sig
  2201.  
  2202. ;/***************************************************************************
  2203. ;*
  2204. ;* FUNCTION NAME = DPRINTF - Debug Printf
  2205. ;*
  2206. ;* DESCRIPTION   =
  2207. ;*
  2208. ;*      Dprintf is a kernel debug print formatting package.
  2209. ;*      This version is a hastily stripped version of another routine
  2210. ;*      with the same name.
  2211. ;*
  2212. ;*      Due to difficulties passing variable length argument lists
  2213. ;*      through a call gate transition, only one argument, a zero
  2214. ;*      terminated string is passed to this routine.  The string
  2215. ;*      will be sent to either COM1 or COM2 depending on the definition
  2216. ;*      of UR_DAT.
  2217.  *
  2218. ;*      About the only intelligent thing this routine can do is process
  2219. ;*      XON/XOFF characters from the equipment attached to the debug
  2220. ;*      port so that the output will not overrun the recieving device.
  2221. ;*      However after recieving an XOFF, this routine will simply spin
  2222. ;*      in a loop waiting for XON.  Using equipment/software on that
  2223. ;*      can keep up on the debug port is recommended.
  2224. ;*
  2225. ;*      The format string is an ASCIZ string which can contain
  2226. ;*      literal characters.
  2227. ;*
  2228. ;*      Literal characters
  2229. ;*          - any character not part of a format specification.  Special
  2230. ;*            non-printing characters are:
  2231. ;*              \n      - CRLF
  2232. ;*              \t      - tab
  2233. ;*              \b      - bell
  2234. ;*              \\      - \
  2235. ;*
  2236. ;*      WARNINGS
  2237. ;*          As befitting a debug routine, DPRINTF does not have a whole lot
  2238. ;*          of "failsafe" code in it.
  2239. ;*
  2240. ;* INPUT         = (sp+6  ) = segment of string
  2241. ;*                 (sp+4  ) = offset of string
  2242. ;*                 (sp+2  ) = seg of return address
  2243. ;*                 (sp    ) = offset of return address
  2244. ;*
  2245. ;* OUTPUT        = NONE
  2246. ;*
  2247. ;* RETURN-NORMAL = NONE
  2248. ;* RETURN-ERROR  = NONE
  2249. ;*
  2250. ;**************************************************************************/
  2251.  
  2252.         Public _DPRINTF
  2253. _DPRINTF PROC    far
  2254.  
  2255.         push    bp
  2256.         mov     bp,sp
  2257.         push    ds
  2258.         push    es
  2259.         push    di
  2260.         push    si
  2261.         push    dx
  2262.         push    cx
  2263.         push    bx
  2264.         push    ax
  2265.         cld
  2266.  
  2267. ;/*
  2268. ;** Change string address to far ptr on stac
  2269. ;*/
  2270.  
  2271.         add     bp,6
  2272.         mov     si,[bp]
  2273.         add     bp,2
  2274.         mov     ax,[bp]
  2275.         push    ax
  2276.         pop     ds
  2277.  
  2278. ;/*
  2279. ;**       Scan format string for next character
  2280. ;**
  2281. ;**       (ds:si) = address of format string
  2282. ;**       (ss:bp) = address of next argument
  2283. ;*/
  2284.  
  2285. public dpf1
  2286. dpf1:   lodsb                   ; (al) = format string byte
  2287.         and     al,al
  2288.         je      dpf3            ; all done
  2289.         cmp     al,'\'
  2290.         jnz     dpf2            ; got the character
  2291.  
  2292.  
  2293. ;/*
  2294. ;**       it's an "\" escape code - crack the argument characte
  2295. ;*/
  2296.  
  2297.         lodsb
  2298.         and     al,al
  2299.         je      dpf3            ; all done, ignore hanging \
  2300.         xchg    ah,al
  2301.         mov     al,0Ch
  2302.         cmp     ah,'n'
  2303.         jne     dpf1$5          ; not \n
  2304.         mov     al,0dH
  2305.         call    putchar
  2306.         mov     al,0aH
  2307.         jmp     SHORT dpf2      ; print LF
  2308.  
  2309. dpf1$5: cmp     ah,'t'
  2310.         mov     al,9
  2311.         je      dpf2            ; is \t
  2312.         cmp     ah,'b'
  2313.         mov     al,7
  2314.         je      dpf2            ; is \b
  2315.         xchg    ah,al
  2316. dpf2:   call    putchar
  2317.         jmp     dpf1
  2318.  
  2319.  
  2320. ;/*
  2321. ;**     have the end of the format string - exit
  2322. ;*/
  2323.  
  2324. dpf3:   pop     ax
  2325.         pop     bx
  2326.         pop     cx
  2327.         pop     dx
  2328.         pop     si
  2329.         pop     di
  2330.         pop     es
  2331.         pop     ds
  2332.         pop     bp
  2333.         ret     4       ; pop 4 bytes after return address
  2334.  
  2335. _DPRINTF ENDP
  2336.  
  2337.  
  2338. ;/***************************************************************************
  2339. ;*
  2340. ;* FUNCTION NAME = inchr
  2341. ;*
  2342. ;* DESCRIPTION   = input character
  2343. ;*
  2344. ;* INPUT         = NONE
  2345. ;* OUTPUT        = 'z' set if no character
  2346. ;*                 'z' clear if char
  2347. ;*                   (al) = char
  2348. ;* RETURN-NORMAL = NONE
  2349. ;* RETURN-ERROR  = NONE
  2350. ;*
  2351. ;**************************************************************************/
  2352.  
  2353. inchr   PROC NEAR
  2354.         mov     dx,UR_LSR
  2355.         in      al,dx
  2356.         and     al,1
  2357.         jz      inchr1
  2358.         mov     dx,UR_DAT
  2359.         in      al,dx
  2360.         and     al,07fh
  2361. inchr1: ret
  2362. inchr   ENDP
  2363.  
  2364.  
  2365. ;/***************************************************************************
  2366. ;*
  2367. ;* FUNCTION NAME = putchar
  2368. ;*
  2369. ;* DESCRIPTION   = put a character on the console
  2370. ;*
  2371. ;* INPUT         = (al) = character
  2372. ;* OUTPUT        = NONE
  2373. ;*
  2374. ;* RETURN-NORMAL = NONE
  2375. ;* RETURN-ERROR  = NONE
  2376. ;*
  2377. ;**************************************************************************/
  2378.  
  2379. putchar PROC    NEAR
  2380.         pushf
  2381.         cli
  2382.         push    dx
  2383.         push    cx
  2384.         push    bx
  2385.         push    ax              ; (al) = character
  2386.  
  2387. ;/*
  2388. ;**     see if CTL-Q or CTL-S
  2389. ;*/
  2390.  
  2391.         pushf
  2392.         cli
  2393.         call    inchr
  2394.         jz      putc3           ; no characters incomming
  2395.         cmp     al,19           ; ctl-S?
  2396.         jnz     putc3           ; no, ignore
  2397.  
  2398. ;/*
  2399. ;**     have ctl-s.  wait till we see ctl-Q
  2400. ;*/
  2401.  
  2402. putc2:  call    inchr
  2403.         jz      putc2
  2404.         cmp     al,17
  2405.         jnz     putc2
  2406.  
  2407. putc3:  popf
  2408.         mov     dx,UR_LSR
  2409. putc4:  in      al,dx
  2410.         test    al,020h
  2411.         jz      putc4
  2412.  
  2413. ;/*
  2414. ;**     ready.  crank it out!
  2415. ;*/
  2416.  
  2417.         mov     dx,UR_DAT
  2418.  
  2419.         pop     ax
  2420.         out     dx,al
  2421.  
  2422.         pop     bx
  2423.         pop     cx
  2424.         pop     dx
  2425.         popf
  2426.         ret
  2427. putchar ENDP
  2428.  
  2429. ENDIF   ;DEBUG                                                  ;@MS07 - END
  2430.  
  2431. R2SEG   ENDS
  2432. END
  2433.  
  2434.