home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / masm / masm6 / demos / common.asm next >
Encoding:
Assembly Source File  |  1990-10-04  |  14.1 KB  |  400 lines

  1.         .MODEL  small, pascal, os_dos
  2.         INCLUDE demo.inc
  3.  
  4.         .DATA
  5. vconfig VIDCONFIG <>           ; Global video configuration structure
  6.  
  7.         .CODE
  8.  
  9. ;* GetVidConfig - Determines current video configuration and initializes
  10. ;* the vconfig structure.
  11. ;*
  12. ;* Shows:   BIOS Interrupt - 10h, Function 0 (Set Video Mode)
  13. ;*                           10h, Function 0Fh (Get Current Video Mode)
  14. ;*                           10h, Function 1Ah (Video Display Combination)
  15. ;*
  16. ;* Uses:    vconfig - Video configuration structure, declared in the
  17. ;*          DEMO.INC include file.
  18. ;*
  19. ;* Params:  None
  20. ;*
  21. ;* Return:  None
  22.  
  23. GetVidConfig PROC
  24.  
  25.         mov     ax, 1A00h               ; Get video info for VGA
  26.         int     10h
  27. chkVGA:
  28.         cmp     al, 1Ah                 ; Is VGA or MCGA present?
  29.         jne     chkEGA                  ; No?  Then check for EGA
  30.  
  31.         cmp     bl, 2                   ; If VGA exists as secondary adapter,
  32.         je      isCGA                   ;   check for CGA and mono as primary
  33.         jb      isMONO
  34.         cmp     bl, 5                   ; If EGA is primary, do normal
  35.         jbe     chkEGA                  ;   EGA checking
  36. chkMCGA:
  37.         mov     vconfig.adapter, MCGA   ; Yes?  Assume MCGA
  38.         mov     vconfig.display, COLOR
  39.         cmp     bl, 8                   ; Correct assumption?
  40.         ja      gotmode                 ; Yes?  Continue
  41. isVGA:
  42.         mov     vconfig.adapter, VGA    ; Assume it's VGA color
  43.         je      gotmode                 ; Yes?  Continue
  44.         mov     vconfig.display, MONO   ; No?  Must be VGA mono
  45.         jmp     gotmode                 ; Finished with VGA, so jump
  46. chkEGA:
  47.         mov     ah, 12h                 ; Call EGA status function
  48.         mov     bl, 10h
  49.         sub     cx, cx                  ; Clear status bits
  50.         int     10h
  51.         jcxz    chkCGA                  ; If CX is unchanged, not EGA
  52. isEGA:
  53.         mov     vconfig.adapter, EGA    ; Set structure fields for EGA
  54.         mov     vconfig.display, MONO   ; Assume EGA mono
  55.         or      bh, bh                  ; Correct assumption?
  56.         jnz     gotmode                 ; Yes?  Continue
  57.         mov     vconfig.display, COLOR  ; No?  Must be EGA color
  58.         jmp     gotmode                 ; Finished with EGA, so jump
  59. chkCGA:
  60.         int     11h                     ; Get equipment list
  61.         and     al, 30h                 ; If bits 4-5 set, monochrome
  62.         cmp     al, 30h                 ; Monochrome text mode?
  63.         je      isMONO                  ; Yes?  Continue
  64. isCGA:
  65.         mov     vconfig.adapter, CGA    ; No?  Must be CGA
  66.         mov     vconfig.display, COLOR
  67.         jmp     gotmode
  68. isMONO:
  69.         mov     vconfig.adapter, MDA    ; Set MONO
  70.         mov     vconfig.display, MONO
  71. gotmode:
  72.         mov     ah, 0Fh
  73.         int     10h                     ; Get current mode
  74.         mov     vconfig.mode, al        ; Record mode
  75.         mov     vconfig.dpage, bh       ;   and current page
  76.         mov     al, vconfig.display     ; Multiply display value
  77.         cbw                             ;   (which is either 0 or 1)
  78.         mov     bx, 800h                ;   by 800h, then add to B000h
  79.         mul     bx                      ;   for segment address of
  80.         add     ax, 0B000h              ;   video buffer
  81.         add     ah, vconfig.dpage       ; Adding display page gives
  82.         mov     vconfig.sgmnt, ax       ;   address of current page
  83.  
  84.         sub     ax, ax
  85.         mov     es, ax
  86.         mov     al, es:[44Ah]           ; Get number of display cols
  87.         mov     vconfig.cols, al        ; Store in structure
  88.         mov     vconfig.rows, 24        ; Assume bottom row # = 24
  89.         cmp     vconfig.adapter, EGA    ; EGA or VGA?
  90.         jl      exit                    ; No?  Exit
  91.         mov     ax, 1130h               ; Yes?  Request character info
  92.         sub     bh, bh                  ; Set BH to valid value
  93.         push    bp                      ; BP will change, so save it
  94.         int     10h                     ; Get number of rows/screen
  95.         mov     vconfig.rows, dl        ; Keep in structure
  96.         pop     bp                      ; Restore BP
  97. exit:
  98.         ret
  99.  
  100. GetVidConfig ENDP
  101.  
  102.  
  103. ;* GetCurPos - Gets current cursor position.
  104. ;*
  105. ;* Uses:    vconfig - Video configuration structure (initialized
  106. ;*          by calling the GetVidConfig procedure)
  107. ;*
  108. ;* Params:  None
  109. ;*
  110. ;* Return:  Short integer with high byte = row, low byte = column
  111.  
  112. GetCurPos PROC USES bx dx
  113.  
  114.         mov     ah, 3                   ; Function 3
  115.         mov     bh, vconfig.dpage
  116.         int     10h                     ; Get cursor position
  117.         mov     ax, dx
  118.         ret
  119.  
  120. GetCurPos ENDP
  121.  
  122.  
  123. ;* SetCurPos - Sets cursor position.
  124. ;*
  125. ;* Shows:   BIOS Interrupt - 10h, Function 2 (Set Cursor Position)
  126. ;*
  127. ;* Uses:    vconfig - Video configuration structure (initialized
  128. ;*          by calling the GetVidConfig procedure)
  129. ;*
  130. ;* Params:  Row - Target row
  131. ;*          Col - Target column
  132. ;*
  133. ;* Return:  None
  134.  
  135. SetCurPos PROC USES bx dx,
  136.         Row:WORD,
  137.         Col:WORD
  138.  
  139.         mov     dh, BYTE PTR Row        ; DH = row
  140.         mov     dl, BYTE ptr Col        ; DL = column
  141.         mov     ah, 2                   ; Function 2
  142.         mov     bh, vconfig.dpage       ; Current page
  143.         int     10h                     ; Set cursor position
  144.         ret
  145.  
  146. SetCurPos ENDP
  147.  
  148.  
  149. ;* StrWrite - Writes ASCIIZ string to video memory at specified row/column.
  150. ;*
  151. ;* Shows:   Instructions - lodsb     stosb
  152. ;*
  153. ;* Uses:    vconfig - Video configuration structure (initialized
  154. ;*          by calling the GetVidConfig procedure)
  155. ;*
  156. ;* Params:  Row - Row coordinate
  157. ;*          Col - Column coordinate
  158. ;*          Sptr - Pointer to string
  159. ;*
  160. ;* Return:  None
  161.  
  162. StrWrite PROC USES ds si di,
  163.         Row:WORD,
  164.         Col:WORD,
  165.         Sptr:PTR BYTE
  166.  
  167.         GetVidOffset Row, Col           ; Get video offset for these coords
  168.         mov     di, ax                  ; Copy to DI
  169.         LoadPtr ds, si, Sptr            ; DS:SI points to string
  170.         mov     es, vconfig.sgmnt       ; ES:DI points to video RAM
  171.         .WHILE  1                       ; Loop forever (or until break)
  172.         lodsb                           ; Get 1 character from string
  173.         .BREAK .IF al == 0              ; Quit if null terminator
  174.  
  175. ; For CGA systems, StrWrite waits for the video to begin a horizontal
  176. ; retrace before writing a character to memory. This avoids the problem
  177. ; of video snow inherent with some (though not all) color/graphics adapters.
  178. ; It also demonstrates a somewhat different approach to the problem than the
  179. ; one taken in the WinOpen and WinClose procedures.
  180.  
  181.         .IF vconfig.adapter != CGA      ; If not CGA, skip this step
  182.         push    ax                      ; Save character
  183.         mov     dx, 3DAh                ; Address of status register
  184.         cli                             ; Disallow interruptions
  185.         .REPEAT
  186.         in      al, dx                  ; Read current video status
  187.         .UNTIL  !(al & 1)               ; Until horizontal retrace done
  188.  
  189.         .REPEAT
  190.         in      al, dx                  ; No?  Read status again
  191.         .UNTIL  al & 1                  ; Until retrace starts
  192.         pop     ax                      ; Recover character
  193.         .ENDIF  ; CGA only
  194.  
  195.         stosb                           ; Write char to video buffer
  196.         sti                             ; Reenable interrupts in case CGA
  197.         inc     di                      ; Skip attribute byte
  198.         .ENDW
  199.         ret
  200.  
  201. StrWrite ENDP
  202.  
  203.  
  204. ;* StrInput - Gets input string from keyboard using BIOS. Signals idle
  205. ;* state by calling interrupt 28h while polling for keypress, making
  206. ;* the procedure useful in TSR programs. Terminates when Enter or Esc
  207. ;* keys pressed.
  208. ;*
  209. ;* Shows:   DOS interrupt - Interrupt 28h (DOS Idle Interrupt)
  210. ;*
  211. ;* Params:  Row - Row coordinate
  212. ;*          Col - Column coordinate
  213. ;*          Max - Maximum allowable string length
  214. ;*          Sptr - Pointer to string
  215. ;*
  216. ;* Return:  Short integer with terminating char
  217.  
  218. StrInput PROC USES ds si,
  219.         Row:WORD,
  220.         Col:WORD,
  221.         Max:WORD,
  222.         Sptr:PBYTE
  223.  
  224.         LoadPtr ds, si, Sptr            ; DS:SI points to string
  225.         add     Max, si
  226.         dec     Max                     ; MAX now points to string limit
  227.  
  228.         .WHILE  1                       ; Get key until break or continue
  229. loop1:
  230.         INVOKE  StrWrite,               ; Display input string
  231.                 Row,
  232.                 Col,
  233.                 si
  234.  
  235.         mov     bx, si
  236.         mov     dx, Col                 ; DL = cursor column
  237.  
  238.         .WHILE  (BYTE PTR [bx] != 0)    ; Scan string for null terminator
  239.         inc     bx                      ; Else try next character
  240.         inc     dx                      ;   and increment cursor column
  241.         .ENDW
  242.  
  243.         ; Set cursor position, pass row and column (DX)
  244.         INVOKE  SetCurPos,
  245.                 Row,
  246.                 dx
  247.  
  248.         .REPEAT
  249.         int     28h                     ; Signal idle state
  250.         mov     ah, 1
  251.         int     16h                     ; Key waiting?
  252.         .CONTINUE .IF zero?
  253.         sub     ah, ah
  254.         int     16h                     ; Yes?  Get key
  255.  
  256.         cmp     ah, LEFT                ; Left arrow key?
  257.         je      backspace               ; Treat like backspace
  258.         .UNTIL  al != 0                 ; Ignore all other special keys
  259.  
  260.         .BREAK  .IF al == ESCAPE        ; Exit if Esc key
  261.         .BREAK  .IF al == CR            ; Exit if Return key
  262.  
  263.         .IF     al == BACKSP            ; If backspace or left, handle it
  264. backspace:
  265.         cmp     bx, si                  ; At first letter?
  266.         jbe     loop1                   ; Yes?  Ignore backspace
  267.         dec     bx                      ; No?  Point to preceding char
  268.         dec     dx                      ; Decrement column
  269.         mov     BYTE PTR [bx], ' '      ; Blank char
  270.         push    bx                      ; Preserve pointer
  271.         INVOKE  StrWrite,               ; Overwrite last char with blank
  272.                 Row,
  273.                 dx,
  274.                 bx
  275.  
  276.         pop     bx
  277.         mov     BYTE PTR [bx], 0        ; Make last char the new terminator
  278.         .CONTINUE
  279.         .ENDIF
  280.  
  281.         .CONTINUE .IF bx > Max          ; Ignore key if too many letters
  282.         sub     ah, ah
  283.         mov     [bx], ax                ; Store letter and null terminator
  284.         .ENDW
  285.  
  286.         ret
  287.  
  288. StrInput ENDP
  289.  
  290.  
  291. ;* ClearBox - Clears portion of screen with specified fill attribute.
  292. ;*
  293. ;* Shows:   BIOS Interrupt - 10h, Function 6 (Scroll Up)
  294. ;*
  295. ;* Params:  Attr - Fill attribute
  296. ;*          Row1 - Top screen row of cleared section
  297. ;*          Col1 - Left column of cleared section
  298. ;*          Row2 - Bottom screen row of cleared section
  299. ;*          Col2 - Right column of cleared section
  300. ;*
  301. ;* Return:  None
  302.  
  303. ClearBox PROC,
  304.         Attr:WORD,
  305.         Row1:WORD,
  306.         Col1:WORD,
  307.         Row2:WORD,
  308.         Col2:WORD
  309.  
  310.         mov     ax, 0600h               ; Scroll service
  311.         mov     bh, BYTE PTR Attr       ; BH = fill attribute
  312.         mov     ch, BYTE PTR Row1       ; CH = top row of clear area
  313.         mov     cl, BYTE PTR Col1       ; CL = left column 
  314.         mov     dh, BYTE PTR Row2       ; DH = bottom row of clear area
  315.         mov     dl, BYTE PTR Col2       ; DL = right column
  316.         int     10h                     ; Clear screen by scrolling up
  317.         ret
  318.  
  319. ClearBox ENDP
  320.  
  321.  
  322. ;* DisableCga - Disables CGA video by reprogramming the control register.
  323. ;*
  324. ;* Shows:   Instructions - cli     sti
  325. ;*
  326. ;* Params:  None
  327. ;*
  328. ;* Return:  None
  329.  
  330. DisableCga PROC USES ax cx dx           ; Preserve registers
  331.  
  332.         mov     cx, -1                  ; Set maximum loop count
  333.         mov     dx, 03DAh               ; Address of status register
  334.  
  335.         .REPEAT
  336.         in      al, dx                  ; Get video status
  337.         .UNTILCXZ !(al & 8)             ; Until retrace end/timeout
  338.         cli                             ; Disallow interruptions
  339.         mov     cx, -1                  ; Reset loop count
  340.  
  341.         .REPEAT
  342.         in      al, dx                  ; Get video status
  343.         .UNTILCXZ al & 8                ; Until retrace start/timeout
  344.  
  345.         sub     dx, 2                   ; DX = address of control reg
  346.         mov     al, 1                   ; Value to disable CGA video
  347.         out     dx, al                  ; Disable video
  348.         sti                             ; Reenable interrupts
  349.         ret
  350.  
  351. DisableCga ENDP
  352.  
  353.  
  354. ;* EnableCga - Enables CGA video by reprogramming the control register.
  355. ;*
  356. ;* Params:  None
  357. ;*
  358. ;* Return:  None
  359.  
  360. EnableCga PROC USES ax dx es                    ; Preserve registers
  361.  
  362.         sub     ax, ax
  363.         mov     es, ax                          ; Point ES to low memory
  364.         mov     al, es:[0465h]                  ; Get former mode setting
  365.         mov     dx, 03D8h                       ; Address of control register
  366.         out     dx, al                          ; Enable video
  367.         ret
  368.  
  369. EnableCga ENDP
  370.  
  371.  
  372. ;* GetVer - Gets DOS version.
  373. ;*
  374. ;* Shows:   DOS Function - 30h (Get MS-DOS Version Number)
  375. ;*
  376. ;* Params:  None
  377. ;*
  378. ;* Return:  Short integer of form (M*100)+m, where M is major
  379. ;*          version number and m is minor version, or 0 if
  380. ;*          DOS version earlier than 2.0
  381.  
  382. GetVer  PROC
  383.  
  384.         mov     ah, 30h                 ; DOS Function 30h
  385.         int     21h                     ; Get MS-DOS Version Number
  386.         .IF     al == 0                 ; If version, version 1
  387.         sub     ax, ax                  ; Set AX to 0
  388.         .ELSE                           ; Version 2.0 or higher
  389.         sub     ch, ch                  ; Zero CH and move minor
  390.         mov     cl, ah                  ;   version number into CX
  391.         mov     bl, 100
  392.         mul     bl                      ; Multiply major by 10
  393.         add     ax, cx                  ; Add minor to major*10
  394.         .ENDIF
  395.         ret                             ; Return result in AX
  396.  
  397. GetVer  ENDP
  398.  
  399.         END
  400.