home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / CASM.ARJ / DISP.ASM < prev    next >
Encoding:
Assembly Source File  |  1988-07-19  |  15.7 KB  |  757 lines

  1. ;_ disp.asm   Wed Mar 23 1988   Modified by: Walter Bright */
  2. ; Copyright (C) 1986-1988 by Northwest Software
  3. ; All Rights Reserved
  4. ; Written by Walter Bright
  5.  
  6. ; Fast screen display package
  7.  
  8. include    macros.asm
  9.  
  10. video_io macro
  11.     int    10h
  12.     endm
  13.  
  14. ;ASCII values
  15. DEL    equ    07Fh        ;DEL character
  16.  
  17.     begdata
  18.  
  19.     public    _disp_numrows,_disp_numcols
  20. _disp_numrows    dw    25    ;# of rows in display
  21. _disp_numcols    dw    0    ;# of columns in display
  22.  
  23. scrnrowcol    label    word    ;row,col of actual screen cursor
  24. scrncol    db    ?
  25. scrnrow    db    ?
  26.  
  27.     public    _disp_cursorrow,_disp_cursorcol
  28. _disp_cursorrow    dw    ?    ;row,col of where we want the cursor to be
  29. _disp_cursorcol    dw    ?
  30.  
  31. normatt    equ    07h    ;white chars on black background
  32. stndatt    equ    070h    ;inverse video
  33. att    db    normatt    ;current attribute
  34.  
  35.     public    _disp_mono,_disp_base,_disp_snowycga,_disp_mode,_disp_inited
  36.     public    _disp_ega,_disp_activepage
  37. _disp_mono    db    1    ;0 for color, 1 for monochrome
  38. _disp_snowycga    db    1    ;if 1, then the display is an IBM snowy CGA
  39. _disp_mode    db    ?    ;what is the current display mode?
  40. _disp_inited    db    0    ;1 if display package is opened
  41. _disp_ega    db    0    ;1 if IBM EGA
  42. _disp_activepage db    0    ;which page to read/write
  43. _disp_displaypage db    0    ;which page is displayed
  44. _disp_base    dw    0B000h    ;segment of base of video screen
  45.                 ; (default is mono)
  46.                 ;if 0, then not available (use BIOS)
  47.  
  48. cursortype    dw    ?    ;where we save the cursor type
  49.  
  50.     enddata
  51.  
  52.     begcode    disp
  53.  
  54.  
  55. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  56. ; Set things up. That is, determine what display we've got.
  57.  
  58.     c_public    disp_open
  59. func    disp_open
  60.     .if    _disp_inited e 0, Q4    ;if not already initialized
  61.     ret
  62.  
  63. Q4:    mov    _disp_inited,1
  64.     push    BP
  65.     .save    DI
  66.     pushES
  67.  
  68.     ;Determine number of rows, also if we have an EGA
  69.     clr    DX        ;default value
  70.     clr    BH
  71.     mov    AX,01130h    ;inquire info from EGA BIOS
  72.     video_io
  73.     tst    DL        ;Check if DL is still zero
  74.     jz    L3        ;if so, no EGA
  75.     mov    _disp_ega,1    ;flag that we have an EGA
  76.     mov    _disp_snowycga,0    ;EGAs don't snow
  77.     inc    DL
  78.     mov    _disp_numrows,DX    ;number of rows
  79. L3:
  80.  
  81.     mov    AH,15
  82.     video_io
  83.     mov    byte ptr _disp_numcols,AH    ;set number of columns
  84.     mov    _disp_mode,AL        ;save display mode
  85.     .if    AL ne 7, Q2        ;if not mono mode
  86.     mov    _disp_snowycga,0        ;mono displays don't snow
  87.  
  88.     ;Do an equipment check to see if this is really a mono card.
  89.     ;Note that the COMPAQ can be in mode 7, but still be a color card!
  90.     int    11h            ;Equipment Determination BIOS call
  91.     and    AX,  00110000b        ;isolate initial video mode bits
  92.     .if    AX e 00110000b, L1    ;yes, it is a real mono card
  93.     mov    AL,7            ;mode 7
  94.     jmps    L51
  95.  
  96. Q2:    .if    AL e 15, L51        ;if EGA monochrome graphics mode
  97.     mov    _disp_mono,0        ;else color display
  98. L51:    mov    _disp_base,0B800h    ;base of color adapter
  99.     .if    AL be 3, L1    ;if color text mode
  100.     .if    AL e 7, L1    ; or mono text mode
  101.     mov    _disp_base,0    ;use BIOS instead of direct access to video ram
  102.                 ; for all graphics and other unrecognized modes
  103.     jmps    L50
  104. L1:
  105.     ;Find out if we are running under DESQview.
  106.     ;This section provided by Erik Lindberg.
  107.     mov    AX,2B01h    ; Get DESQview version (set date)
  108.     mov    CX,'DE'        ;     if CX,DX = 'DESQ', is invalid
  109.     mov    DX,'SQ'        ;     setdate call.
  110.     int    21h        ; DOS interrupt.
  111.     cmp    AL,0FFh        ; check for invalid return.
  112.     jz    L2        ;   then DESQview is not running.
  113.     mov    ES,_disp_base    ; get pre-determined buffer address (_disp_base:0)
  114.     clr    DI        ;   into ES:DI
  115.     mov    AH,0FEh        ; load function code into AH
  116.     video_io        ; to request alternate buffer address.
  117.     mov    _disp_base,ES    ; and save it.
  118. L2:
  119.  
  120.     ;determine where cursor is
  121. L50:    mov    AH,3
  122.     video_io
  123.     mov    cursortype,CX    ;save original cursor type
  124.     mov    scrnrow,DH
  125.     mov    scrncol,DL
  126.     mov    AL,DH
  127.     cbw
  128.     mov    _disp_cursorrow,AX
  129.     clr    DH
  130.     mov    _disp_cursorcol,DX
  131.  
  132.     popES
  133.     .restore DI
  134.     pop    BP
  135.     ret
  136. c_endp    disp_open
  137.  
  138. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  139. ; Close things up
  140.  
  141.     c_public    disp_close
  142. func    disp_close
  143.     .if    _disp_inited e 0, Q3    ;quit if never opened
  144.     push    BP
  145.     callm    disp_flush    ;flush all output
  146.     mov    AH,1
  147.     mov    CX,cursortype    ;restore original cursor type
  148.     video_io
  149.     mov    _disp_inited,0
  150.     pop    BP
  151. Q3:    ret
  152. c_endp    disp_close
  153.  
  154. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  155. ; Be BIOS compatible, instead of poking directly into the screen
  156. ; memory.
  157.  
  158.     c_public    disp_usebios
  159. func    disp_usebios
  160.     mov    _disp_base,0
  161.     ret
  162. c_endp    disp_usebios
  163.  
  164. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  165. ; Set cursor type.
  166. ; Use:
  167. ;    disp_setcursortype(startline*256 + endline);
  168.  
  169.     c_public    disp_setcursortype
  170. func    disp_setcursortype
  171.     push    BP
  172.     mov    BP,SP
  173.     mov    CX,P[BP]
  174.     mov    AH,1
  175.     video_io
  176.     pop    BP
  177.     ret
  178. c_endp    disp_setcursortype
  179.  
  180. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  181. ; Put a character into the display.
  182. ; Behave as a dumb terminal.
  183. ; Returns character passed.
  184.  
  185.     c_public    disp_putc
  186. func    disp_putc
  187.     push    BP
  188.     mov    BP,SP
  189.     mov    AL,P[BP]        ;char
  190.     .if    AL b ' ', docntl    ;control char
  191.     .if    AL z DEL, zip1        ;ignore rubouts
  192. doout:    call    near ptr outchr        ;display character
  193.     mov    AX,_disp_cursorcol
  194.     inc    AX            ;next column
  195.     .if    AX ae _disp_numcols, L19    ;if on or past right edge
  196. L20:    mov    _disp_cursorcol,AX
  197. zip1:    clr    AH
  198.     mov    AL,P[BP]
  199.     pop    BP
  200.     ret
  201.  
  202.  
  203. L19:    clr    AX
  204.     mov    BX,_disp_cursorrow        ;get row and column
  205.     inc    BX            ;start of next row
  206.     .if    BX b _disp_numrows, L18    ;if not past bottom
  207.     call    near ptr scrollup    ;scroll up 1 line
  208.     clr    AX
  209.     mov    BX,_disp_numrows        ;lower left corner
  210.     dec    BX
  211. L18:    mov    _disp_cursorrow,BX
  212.     jmp    L20
  213.  
  214. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  215. ; Handle control characters
  216.  
  217. docntl:    clr    AH
  218.     mov    BX,AX
  219.     add    BX,AX
  220.     jmp    CS:word ptr (offset cntltab)[BX]
  221.  
  222. cntltab:
  223.     if LCODE
  224.     dw    doout
  225.     dw    doout
  226.     dw    doout
  227.     dw    doout
  228.     dw    doout
  229.     dw    doout
  230.     dw    doout
  231.     dw    beep,dobs,dotab,donl        ;BEL,BS,TAB,LF
  232.     dw    donl,donl            ;VT,FF
  233.     dw    docr                ;CR
  234.     dw    doout,doout,doout,doout        ;P,XON,R,XOFF
  235.     dw    doout,doout,doout,doout,doout,doout,doout
  236.     dw    doout                ;escape
  237.     dw    doout,doout,doout,doout,doout,doout
  238.     else
  239.     dw    offset _TEXT:doout
  240.     dw    offset _TEXT:doout
  241.     dw    offset _TEXT:doout
  242.     dw    offset _TEXT:doout
  243.     dw    offset _TEXT:doout
  244.     dw    offset _TEXT:doout
  245.     dw    offset _TEXT:doout
  246.     dw    offset _TEXT:beep,offset _TEXT:dobs    ;BEL,BS
  247.     dw    offset _TEXT:dotab,offset _TEXT:donl    ;TAB,LF
  248.     dw    offset _TEXT:donl,offset _TEXT:donl    ;VT,FF
  249.     dw    offset _TEXT:docr            ;CR
  250.     dw    offset _TEXT:doout,offset _TEXT:doout
  251.     dw    offset _TEXT:doout,offset _TEXT:doout        ;P,XON,R,XOFF
  252.     dw    offset _TEXT:doout
  253.     dw    offset _TEXT:doout
  254.     dw    offset _TEXT:doout
  255.     dw    offset _TEXT:doout
  256.     dw    offset _TEXT:doout
  257.     dw    offset _TEXT:doout
  258.     dw    offset _TEXT:doout
  259.     dw    offset _TEXT:doout                ;escape
  260.     dw    offset _TEXT:doout
  261.     dw    offset _TEXT:doout
  262.     dw    offset _TEXT:doout
  263.     dw    offset _TEXT:doout
  264.     dw    offset _TEXT:doout
  265.     dw    offset _TEXT:doout
  266.     endif
  267.  
  268. ;;;;;;;;;;;;;;;;;;;;;;
  269. ; Bell
  270.  
  271. beep:    mov    DL,7
  272.     bdos    2            ;send a bell to DOS
  273.     mov    AX,7
  274.     pop    BP
  275.     ret
  276.  
  277. ;;;;;;;;;;;;;;;;;;;;
  278. ; Backspace (non-destructive)
  279.  
  280. dobs:    mov    BX,_disp_cursorcol
  281.     dec    BX            ;backup 1 column
  282.     js    L140            ;oops! already in column 0
  283.     mov    _disp_cursorcol,BX
  284. L140:    pop    BP
  285.     ret
  286.  
  287. ;;;;;;;;;;;;;;;;;;;;
  288. ; Carriage return
  289.  
  290. docr:    mov    _disp_cursorcol,0        ;reset column
  291.     pop    BP
  292.     ret
  293.  
  294. ;;;;;;;;;;;;;;;;;;;
  295. ; Line feed
  296.  
  297. donl:    mov    _disp_cursorcol,0        ;reset column to start of line
  298.  
  299. dolf:    mov    DX,_disp_cursorrow
  300.     inc    DX
  301.     .if    DX b _disp_numrows, L101
  302.     call    near ptr scrollup
  303.     mov    AX,0Ah
  304.     pop    BP
  305.     ret
  306.  
  307. L101:    mov    _disp_cursorrow,DX
  308.     pop    BP
  309.     ret
  310.  
  311. ;;;;;;;;;;;;;;;;;;;
  312. ; Tab (non-destructive)
  313.  
  314. dotab:
  315.     mov    AX,_disp_cursorcol
  316.     or    AX,7
  317.     inc    AX        ;advance to next tab stop
  318.     .if    AX b _disp_numcols, D1
  319.     mov    AX,_disp_numcols
  320.     dec    AX
  321. D1:    mov    _disp_cursorcol,AX
  322.     mov    AX,9
  323.     pop    BP
  324.     ret
  325.  
  326. c_endp    disp_putc
  327.  
  328. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  329. ; Scroll a region of the display.
  330. ;    void disp_scroll(lines,ulrow,ulcol,lrrow,lrcol,att);
  331. ;    lines > 0:    scroll up
  332. ;    lines == 0:    blank window
  333. ;    lines < 0:    scroll down
  334.  
  335.     c_public    disp_scroll
  336. func    disp_scroll
  337.     push    BP
  338.     mov    BP,SP
  339.     mov    AL,P[BP]
  340.     mov    CH,P+2[BP]
  341.     mov    CL,P+4[BP]
  342.     mov    DH,P+6[BP]
  343.     mov    DL,P+8[BP]
  344.     mov    BH,P+10[BP]
  345.     mov    AH,6
  346.     tst    AL
  347.     jns    scroll1
  348.     neg    AL
  349.     inc    AH
  350. scroll1:
  351.     video_io
  352.     pop    BP
  353.     ret
  354. c_endp    disp_scroll
  355.  
  356. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  357. ; Poke att/char into display at row,column.
  358. ;    void disp_pokew(row,col,attchr);
  359.  
  360.     c_public    disp_pokew
  361. func    disp_pokew
  362.     push    BP
  363.     mov    BP,SP
  364.  
  365.     mov    CX,P+4[BP]    ;save att/char
  366.     mov    DH,P[BP]    ;row
  367.     mov    DL,P+2[BP]    ;column
  368.     .if    _disp_base e 0, W7
  369.  
  370.     pushES
  371.     mov    AX,_disp_numcols
  372.     mul    DH
  373.     clr    DH
  374.     add    AX,DX        ;add in column
  375.     shl    AX,1        ;compute offset into screen
  376.     mov    BX,AX
  377.     mov    ES,_disp_base
  378.     .if    _disp_snowycga e 0, W1    ;if skip snow check
  379.  
  380.     mov    DX,03DAh        ;color card status port
  381.     mov    AH,1
  382.  
  383. W5:    in    AL,DX            ;wait for retrace low
  384.     test    AL,AH
  385.     jnz    W5
  386.     cli                ;turn off interrupts
  387. W6:    in    AL,DX            ;wait for retrace high
  388.     test    AL,AH
  389.     jz    W6
  390.  
  391.     mov    ES:[BX],CX        ;poke it
  392.     sti                ;enable interrupts
  393.     popES
  394.     pop    BP
  395.     ret
  396.  
  397. W1:    mov    ES:[BX],CX        ;poke it
  398.     popES
  399.     pop    BP
  400.     ret
  401.  
  402. W7:    mov    scrnrow,DH
  403.     mov    scrncol,DL
  404.     mov    BH,_disp_activepage    ;page number
  405.     mov    AH,2
  406.     video_io        ;set cursor position (BP is destroyed)
  407.     mov    AL,CL        ;char
  408.     mov    BL,CH        ;attribute to use
  409.     mov    AH,9        ;write att/char at current cursor position
  410.     mov    CX,1        ;write one character
  411.     video_io
  412.     pop    BP
  413.     ret
  414.  
  415. c_endp    disp_pokew
  416.  
  417. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  418. ; Read att/char from display at row,column.
  419. ;    unsigned disp_peekw(row,col);
  420.  
  421.     c_public    disp_peekw
  422. func    disp_peekw
  423.     push    BP
  424.     mov    BP,SP
  425.  
  426.     mov    DH,P[BP]    ;row
  427.     mov    DL,P+2[BP]    ;column
  428.     mov    scrnrowcol,DX
  429.     mov    BH,_disp_activepage    ;page number
  430.     mov    AH,2
  431.     video_io        ;set cursor position (BP is destroyed)
  432.     mov    AH,8        ;read att/char at current cursor position
  433.     video_io
  434.     pop    BP
  435.     ret
  436. c_endp    disp_peekw
  437.  
  438. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  439. ; Display character in AL.
  440.  
  441. outchr    proc    near
  442.     .if    _disp_base e 0, P7
  443.  
  444.     pushES
  445.     mov    CL,AL
  446.     mov    CH,att        ;attribute to use
  447.     mov    AX,_disp_numcols
  448.     mul    _disp_cursorrow
  449.     add    AX,_disp_cursorcol
  450.     shl    AX,1        ;compute offset into screen
  451.     mov    BX,AX
  452.     mov    ES,_disp_base
  453.     .if    _disp_snowycga e 0, P1    ;if skip snow check
  454.  
  455.     mov    DX,03DAh        ;color card status port
  456.     mov    AH,1
  457. P5:    in    AL,DX            ;wait for retrace low
  458.     test    AL,AH
  459.     jnz    P5
  460.     cli                ;turn off interrupts
  461. P6:    in    AL,DX            ;wait for retrace high
  462.     test    AL,AH
  463.     jz    P6
  464.  
  465.     mov    ES:[BX],CX        ;poke it
  466.     sti                ;enable interrupts
  467.     popES
  468.     ret
  469.  
  470. P1:    mov    ES:[BX],CX        ;poke it
  471.     popES
  472.     ret
  473.  
  474. P7:    push    AX
  475.     callm    disp_flush    ;bring cursor up to date
  476.     pop    AX
  477.     mov    AH,9        ;write att/char at current cursor position
  478.     mov    BH,_disp_activepage    ;page number
  479.     mov    BL,att        ;attribute to use
  480.     mov    CX,1        ;write one character
  481.     video_io
  482.     ret
  483. outchr    endp
  484.  
  485.  
  486. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  487. ; Set cursor position
  488.  
  489.     c_public    disp_move
  490. func    disp_move
  491.     push    BP
  492.     mov    BP,SP
  493.     mov    AX,P[BP]
  494.     mov    _disp_cursorrow,AX
  495.     mov    AX,P+2[BP]
  496.     mov    _disp_cursorcol,AX
  497.     pop    BP
  498.     ret
  499. c_endp    disp_move
  500.  
  501. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  502. ; Flush output.
  503. ; What this does is set the hardware cursor (scrnxxx) to be where
  504. ; the software cursor (disp_cursorxxx) is. This is only done when
  505. ; disp_flush() is called because it is a relatively slow operation.
  506.  
  507.     c_public    disp_flush
  508. func    disp_flush
  509.     mov    DH,byte ptr _disp_cursorrow
  510.     mov    DL,byte ptr _disp_cursorcol
  511.     .if    DX e scrnrowcol, F1
  512.     mov    scrnrowcol,DX
  513.     mov    BH,_disp_activepage
  514.     mov    AH,2        ;set cursor function
  515.     push    BP
  516.     video_io
  517.     pop    BP
  518. F1:    ret
  519. c_endp    disp_flush
  520.  
  521.  
  522. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  523. ; Delete to end of line (including cursor position)
  524.  
  525.     c_public    disp_eeol
  526. func    disp_eeol
  527.     mov    CX,_disp_numcols
  528.     sub    CX,_disp_cursorcol    ;CX = # of spaces left in line
  529.     mov    AX,_disp_numcols
  530.     mul    _disp_cursorrow
  531.     add    AX,_disp_cursorcol
  532.     jmps    clear1
  533. c_endp    disp_eeol
  534.  
  535. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  536. ; Delete to end of screen (including cursor position)
  537.  
  538.     c_public    disp_eeop
  539. func    disp_eeop
  540.     mov    AX,_disp_numcols
  541.     mul    _disp_numrows
  542.     mov    CX,AX        ;CX = # of chars on screen
  543.     mov    AX,_disp_numcols
  544.     mul    _disp_cursorrow
  545.     add    AX,_disp_cursorcol
  546.     sub    CX,AX
  547. clear1:
  548.     .save    DI
  549.     shl    AX,1
  550.     mov    DI,AX
  551. ;    jmps    clear
  552. c_endp    disp_eeop
  553.  
  554. ;;;;;;;;;;;;;;;;;;;;;;;;
  555. ; Send CX spaces to screen starting at DI.
  556.  
  557. func    clear
  558.     .if    _disp_base e 0, C7
  559.  
  560.     pushES
  561.     mov    ES,_disp_base
  562.     cld
  563.     mov    AL,' '
  564.     mov    AH,att
  565.     .if    _disp_snowycga ne 0, C1
  566.     rep    stosw
  567.     popES
  568.     .restore DI
  569.     ret
  570.  
  571. C1:    mov    DX,03DAh        ;color card status port
  572.     mov    BX,AX
  573.  
  574. C5:    in    AL,DX            ;wait for retrace low
  575.     test    AL,1
  576.     jnz    C5
  577.     cli                ;turn off interrupts
  578. C6:    in    AL,DX            ;wait for retrace high
  579.     test    AL,1
  580.     jz    C6
  581.  
  582.     mov    AX,BX
  583.     stosw                ;poke it
  584.     sti                ;enable interrupts
  585.     loop    C5
  586.  
  587.     popES
  588.     .restore DI
  589.     ret
  590.  
  591. C7:    callm    disp_flush    ;bring cursor up to date
  592.     mov    AX,9*256+' '    ;write att/char at current cursor position
  593.     mov    BH,_disp_activepage    ;page number
  594.     mov    BL,att        ;attribute to use
  595.     push    BP
  596.     video_io
  597.     pop    BP
  598.     .restore DI
  599.     ret
  600. c_endp    clear
  601.  
  602. ;;;;;;;;;;;;;;;;;;;;;;;;
  603. ; Start/end standout mode.
  604. ; Set attribute for subsequent writes.
  605.  
  606.     c_public    disp_startstand,disp_endstand,disp_setattr
  607.  
  608. func    disp_startstand
  609.     mov    att,stndatt
  610.     ret
  611. c_endp    disp_startstand
  612.  
  613. func    disp_endstand
  614.     mov    att,normatt
  615.     ret
  616. c_endp    disp_endstand
  617.  
  618. func    disp_setattr
  619.     push    BP
  620.     mov    BP,SP
  621.     mov    AL,P[BP]
  622.     mov    att,AL
  623.     pop    BP
  624.     ret
  625. c_endp    disp_setattr
  626.  
  627. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  628. ; Scroll up 1 line
  629.  
  630. scrollup proc    near
  631.     .if    _disp_snowycga ne 0, biosway    ;give up and use bios
  632.     .if    _disp_base e 0, biosway
  633.     push    DS
  634.     pushES
  635.     .save    <SI,DI>
  636.     mov    AX,_disp_numcols
  637.     mov    SI,AX
  638.     mov    BX,AX
  639.     mul    _disp_numrows
  640.     sub    AX,SI
  641.     mov    CX,AX            ;CX = # of words to scroll
  642.     shl    SI,1            ;source is 1 row in
  643.     clr    DI
  644.     mov    AL,' '            ;char for blank row
  645.     mov    AH,att            ;attribute for blank row
  646.     mov    ES,_disp_base        ;point to video segment
  647.     mov    DS,_disp_base
  648.     cld                ;increment
  649.     rep movsw            ;do the scroll
  650.     mov    CX,BX            ;# of words in bottom row
  651.     rep stosw            ;blank bottom row
  652.     .restore <DI,SI>
  653.     popES
  654.     pop    DS
  655.     ret
  656.  
  657. biosway:
  658.     clr    CX            ;row,col of upper left corner
  659.     mov    DX,_disp_numcols    ;col of lower right corner
  660.     dec    DX
  661.     mov    DH,24
  662.     mov    BH,att            ;att for blank
  663.     mov    AX,0601h        ;scroll up 1 line
  664.     video_io
  665.     ret
  666. scrollup endp
  667.  
  668. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  669. ; Get and return the current video mode.
  670.  
  671.     c_public    disp_getmode
  672. func    disp_getmode
  673.     push    BP
  674.     mov    AH,15
  675.     video_io
  676.     clr    AH
  677.     pop    BP
  678.     ret
  679. c_endp    disp_getmode
  680.  
  681. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  682. ; Set the video mode.
  683. ; Do not use while disp package is open.
  684.  
  685.     c_public    disp_setmode
  686. func    disp_setmode
  687.     push    BP
  688.     mov    BP,SP
  689.     clr    AH
  690.     mov    AL,P[BP]
  691.     video_io
  692.     pop    BP
  693.     ret
  694. c_endp    disp_setmode
  695.  
  696. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  697. ; Set into 43 line mode.
  698. ; Do not use while disp package is open.
  699.  
  700.     c_public    disp_set43
  701. func    disp_set43
  702.     .if    _disp_ega ne 1, S1
  703.     .if    _disp_numrows ne 25, S1
  704.     push    BP
  705.     mov    AX,0003h    ;set color mode, 80x43
  706.     .if    _disp_mono e 0, S2
  707.     mov    AX,0007h    ;set monochrome mode, 80x43
  708. S2:    mov    _disp_mode,AL        ;save display mode
  709.     video_io
  710.     mov    AX,01112h    ;character generator BIOS routine
  711.     mov    BL,0        ;8x8 double dot character font
  712.     video_io
  713.     mov    AX,01200h    ;alternate screen routine
  714.     mov    BL,020h        ;alternate print screen routine
  715.     video_io
  716.     ;Must set cursor to be a block else it will disappear
  717.     mov    AX,0100h
  718.     mov    CX,0007h    ;block cursor
  719.     video_io        ;set cursor type
  720.  
  721. S3:    mov    AX,01130h    ;inquire info from EGA BIOS
  722.     video_io
  723.     clr    DH
  724.     .if    DX ae _disp_cursorrow, S4
  725.     mov    _disp_cursorrow,DX    ;reset cursor so it's on the screen
  726. S4:    inc    DL
  727.     mov    _disp_numrows,DX    ;set new # of rows
  728.     pop    BP
  729. S1:    ret
  730. c_endp    disp_set43
  731.  
  732. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  733. ; Switch from 43 line mode back to 25 line mode.
  734.  
  735.     c_public    disp_reset43
  736. func    disp_reset43
  737.     .if    _disp_ega ne 1, S1
  738.     .if    _disp_numrows be 25, S1
  739.     push    BP
  740.     mov    AX,0003        ;color, 80x25
  741.     .if    _disp_mono e 0, R2
  742.     mov    AX,0007        ;mono, 80x25
  743. R2:    mov    _disp_mode,AL    ;save display mode
  744.     video_io
  745.     mov    AX,01101h    ;character generator BIOS routine
  746.     mov    BL,0
  747.     video_io
  748.     mov    AX,01200h
  749.     mov    BL,020h
  750.     video_io
  751.     jmp    S3        ;determine # of rows
  752. c_endp    disp_reset43
  753.  
  754.     endcode    disp
  755.  
  756.     end
  757.