home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / MISC / NETWORK / TEL23SRC.ZIP / ENGINE / NCSAIO.ASM < prev    next >
Encoding:
Assembly Source File  |  1991-08-20  |  42.6 KB  |  2,012 lines

  1. ;
  2. ;  ncsaio.asm
  3. ;  Support for BIOS calls in NCSA Telnet
  4. ;****************************************************************************
  5. ;*                                                                            *
  6. ;*                                                                            *
  7. ;*      part of NCSA Telnet                                                    *
  8. ;*      by Tim Krauskopf, VT100 by Gaige Paulsen, Tek by Aaron Contorer        *
  9. ;*                                                                            *
  10. ;*      National Center for Supercomputing Applications                        *
  11. ;*      152 Computing Applications Building                                    *
  12. ;*      605 E. Springfield Ave.                                                *
  13. ;*      Champaign, IL  61820                                                    *
  14. ;*                                                                            *
  15. ;*                                                                            *
  16. ;****************************************************************************
  17.  
  18.     TITLE    NCSAIO    -- LOW-LEVEL I/O FOR SANE HARDWARE HANDLING
  19. ;Microsoft EQU 1
  20. ;Lattice EQU 1
  21. ifndef Microsoft
  22.     ifndef Lattice
  23.         if2
  24.             %out
  25.             %out ERROR: You have to specify "/DMicrosoft" OR "/DLattice" on the
  26.             %out        MASM command line to determine the type of assembly.
  27.             %out
  28.         endif
  29.         end
  30.     endif
  31. endif
  32.  
  33. ;
  34. ;   From original code by Tim Krauskopf    1984-1985
  35. ;
  36. ;   Modified and ported to Lattice C, Sept. 1986
  37. ;   ifdefs for Microsoft C, June 1987
  38. ;   Tim Krauskopf
  39. ;
  40. ;   Modified for version 2.3 release May 1990 by Heeren Pathak
  41. ;
  42. ;   National Center for Supercomputing Applications
  43. ;
  44.     NAME    NIO
  45.  
  46. ;
  47. ;  Macros for reading and writing I/O ports
  48. ;
  49. MOUT    MACRO    REG,STUFF       ; one byte to the given I/O register
  50.     MOV        DX,REG
  51.     MOV        AL,STUFF
  52.     OUT        DX,AL
  53.     ENDM
  54. ;
  55. MIN    MACRO    REG                 ; get one byte to al
  56.     MOV        DX,REG
  57.     IN        AL,DX
  58.     ENDM
  59. ;
  60. ;  Internal data 
  61. ;
  62. X     EQU    6                    ;  for the large model programs
  63.  
  64. EXTRN _malloc:FAR
  65. ifdef Microsoft
  66. DGROUP    group    _DATA
  67. _DATA    segment    public 'DATA'
  68.     assume    DS:DGROUP
  69.  
  70.     PUBLIC _DTAPTR                ; pointer to dta location
  71. _DTAPTR     DW    0000H            ; DTA address for me
  72. _DTADS        DW    0000H            ; DS for DTA
  73. _KEYBOARD_TYPE    DB    ?            ; KEYBOARD TYPE (0) - is standard
  74.                                 ; (0x10) is enhanced
  75. else
  76.     INCLUDE    DOS.MAC
  77.     DSEG
  78.     PUBLIC    DTAPTR                ; pointer to dta location
  79. DTAPTR        DW    0000H            ; dta ADDRESS FOR ME
  80. DTADS        DW    0000H            ; ds FOR dta
  81. KEYBOARD_TYPE    DB    ?            ; KEYBOARD TYPE (0) - is standard
  82.                                 ; (0x10) is enhanced
  83. endif
  84.  
  85. ATT            DB    7                ; CURRENT DEFAULT ATTRIBUTE
  86. TOPL        DB    00                ; TOP LINE OF CURRENT WINDOW
  87. BOTL        DB    24                ; BOTTOM LINE OF CURRENT WINDOW
  88. LEFTC        DB    00                ; LEFT SIDE OF CURRENT WINDOW
  89. RIGHTC        DB    79                ; RIGHT SIDE OF CURRENT WINDOW
  90. ROW            DB    00                ; CURSOR POSITION ROW
  91. COL            DB    00                ; CURSOR POSITION COL
  92. WRAP        DB    00                ; WRAP AT END OR NOT
  93. REGEN        DW    0B000H            ; DEFAULT TO COLOR SCREEN
  94. CURSOR      DW  0607H            ; DEFAULT CURSOR SHAPE
  95. CURSOR_SAVE    DW    ?                ; PLACE TO SAVE THE USER'S CURSOR IN
  96. BREAK_STATE    DB    ?                ; WHETHER THE BREAK IS SET TO ON OR OFF
  97. EGAMODE     DB  ?                ; DEFAULT EGA MODE
  98. VID_MODE    DB  ?               ; video mode
  99. VIDSTATE    DD  0
  100.  
  101. ifdef Microsoft
  102. _DATA    ends
  103. else
  104.     ENDDS
  105. endif
  106. ;
  107. ;
  108. ;
  109. ;   The subroutines to call from C
  110. ;
  111. ifdef Microsoft
  112. _TEXT    segment    public    'CODE'
  113.     assume CS:_TEXT
  114.     PUBLIC    _n_color,_n_upscroll,_n_dnscroll,_n_wrap,_n_erase,_n_getchar
  115.     PUBLIC  _n_cur,_n_row,_n_col,_n_clear,_n_window,_n_putchar,_n_chkchar
  116.     PUBLIC  _n_savewin,_n_restwin,_n_puts,_n_sound,_n_findfirst,_n_findnext
  117.     PUBLIC  _n_draw,_n_scrup,_n_scrdn,_n_cheat,_n_clicks,_n_biosattr
  118.     PUBLIC  _getdsk, _chgdsk, _ega43,_n_flags,_set_cur,_ega24,_n_scrlck
  119.     PUBLIC    _save_break,_restore_break,_n_gmode,_save_cursor,_restore_cursor
  120.     PUBLIC  _install_cursor, _n_attr, _install_keyboard
  121.     PUBLIC  _fix_vid, _get_mode, _set_mode, _get_size
  122. else
  123.     PSEG
  124.     PUBLIC    n_color,n_upscroll,n_dnscroll,n_wrap,n_erase,n_getchar
  125.     PUBLIC  n_cur,n_row,n_col,n_clear,n_window,n_putchar,n_chkchar
  126.     PUBLIC  n_savewin,n_restwin,n_puts,n_sound,n_findfirst,n_findnext
  127.     PUBLIC  n_draw,n_scrup,n_scrdn,n_cheat,n_clicks,n_biosattr,n_srclck
  128.     PUBLIC  ega43,n_flags,set_cur,ega24,save_break,restore_break,g_mode
  129.     PUBLIC    save_cursor,restore_cursor,install_cursor,n_attr,install_keyboard
  130.     PUBLIC  fix_vid, get_mode, set_mode
  131. endif
  132.  
  133.  
  134. ;****************************************************************
  135. ; install_keyboard
  136. ;
  137. ; check for enhanced keyboard, and set keyboard type variable
  138. ;
  139. ;
  140. ifdef Microsoft
  141. _install_keyboard    proc     far
  142. else
  143. install_keyboard    proc    far
  144. endif
  145.     PUSH    DS
  146.     PUSH    SI
  147.     MOV        AX,040H                ; load the address of the keyboard flag
  148.     MOV        DS,AX
  149.     MOV        SI,096H
  150.     LODSB                        ; get the keyboard flag
  151.     POP        SI
  152.     POP        DS
  153.     AND        AL,10H                ; mask off all bits except the enhanced flag
  154. ifdef Microsoft
  155.     MOV        _KEYBOARD_TYPE,AL    ; store the keyboard type
  156. else
  157.     MOV        KEYBOARD_TYPE,AL    ; store the keyboard type
  158. endif
  159.     RET
  160. ifdef Microsoft
  161. _install_keyboard    endp
  162. else
  163. install_keyboard    endp
  164. endif
  165.  
  166. ;****************************************************************
  167. ; install cursor
  168. ;
  169. ; put in user defined cursor settings
  170. ;
  171. ;
  172. ifdef Microsoft
  173. _install_cursor    proc     far
  174. else
  175. install_cursor    proc    far
  176. endif
  177.         push    bp         ; save the base pointer
  178.         mov    bp,sp        ; point to the stack
  179.         mov    AX,[bp+x]    ; read our first parameter
  180.         mov    CURSOR, AX    ; save into the cursor variable
  181.         pop    bp        ; get the old base
  182.         ret            ; exit
  183. ifdef Microsoft
  184. _install_cursor    endp
  185. else
  186. install_cursor    endp
  187. endif
  188.  
  189. ;/***************************************************************/
  190. ; scrlck
  191. ;   returns whether scroll lock is on or not
  192. ;
  193. ifdef Microsoft
  194. _n_scrlck    proc    far
  195. else
  196. n_scrlck    proc    far
  197. endif
  198.         push bp
  199.         mov        ax,0200h        ; get shift states
  200.         int        16h                ; keyboard int
  201.         and        al,010h            ; scroll lock state bit
  202.         xor        ah,ah
  203.         pop bp
  204.         ret    
  205. ifdef Microsoft
  206. _n_scrlck    endp
  207. else
  208. n_scrlck    endp
  209. endif
  210.  
  211. ;*********************************************************************
  212. ;*      save_break
  213. ;*      record the state of the DOS BREAK status, and turn BREAK ON
  214. ;*
  215. ifdef Microsoft
  216. _save_break    proc    far
  217. else
  218. save_break    proc     far
  219. endif
  220.     PUSH    BP
  221.  
  222.     MOV        AX,3300H            ; request current break state
  223.     INT        21H                    ;
  224.     MOV        BREAK_STATE,DL        ; preserve the break state
  225.  
  226.     MOV        AX,3301H            ; set break state
  227.     MOV        DL,1                ; turn break on
  228.     INT        21H                    ;
  229.  
  230.     POP     BP
  231.     RET
  232. ifdef Microsoft
  233. _save_break     endp
  234. else
  235. save_break    endp
  236. endif    
  237.  
  238. ;*********************************************************************
  239. ;*      restore_break
  240. ;*      restore the previous state of the DOS BREAK state
  241. ;*
  242. ifdef Microsoft
  243. _restore_break    proc    far
  244. else
  245. restore_break    proc     far
  246. endif
  247.     PUSH    BP
  248.  
  249.     MOV        AX,3301H            ; set break state
  250.     MOV        DL,BREAK_STATE        ; return break state to previous value
  251.     INT        21H                    ;
  252.  
  253.     POP     BP
  254.     RET
  255. ifdef Microsoft
  256. _restore_break     endp
  257. else
  258. restore_break    endp
  259. endif    
  260.  
  261. ;*********************************************************************
  262. ;*      save_cursor
  263. ;*      record the state of the DOS keyboard cursor for page 0
  264. ;*
  265. ifdef Microsoft
  266. _save_cursor    proc    far
  267. else
  268. save_cursor    proc     far
  269. endif
  270.     PUSH    BP
  271.  
  272.     MOV        AX,0300h            ; GET THE CURRENT CURSOR TYPE
  273.     MOV        BX,0000h            ; INFO FOR PAGE 0
  274.     INT    10h
  275.     MOV        CURSOR_SAVE,CX
  276.  
  277.     POP     BP
  278.     RET
  279. ifdef Microsoft
  280. _save_cursor     endp
  281. else
  282. save_cursor    endp
  283. endif    
  284.  
  285. ;*********************************************************************
  286. ;*      restore_cursor
  287. ;*      restore the previous state of the DOS keyboard cursor
  288. ;*
  289. ifdef Microsoft
  290. _restore_cursor    proc    far
  291. else
  292. restore_cursor    proc     far
  293. endif
  294.     PUSH    BP
  295.  
  296.     MOV        AH,01H            ; set the keyboard cursor
  297.     MOV        CX,CURSOR_SAVE    ; get the user's keyboard cursor
  298.     INT        10H                ; set the cursor
  299.  
  300.     POP     BP
  301.     RET
  302. ifdef Microsoft
  303. _restore_cursor     endp
  304. else
  305. restore_cursor    endp
  306. endif    
  307.  
  308. ;*********************************************************************
  309. ;*      n_gmode
  310. ;*      change the type of video display being used
  311. ;*
  312. ifdef Microsoft
  313. _n_gmode    PROC    FAR
  314. else
  315. n_gmode        PROC    FAR
  316. endif
  317.     PUSH    BP
  318.     MOV        BP,SP
  319.     
  320.     MOV        AX,[BP+X]        ;GET SCREEN MODE TO SWITCH TO
  321.     XOR        AH,AH            ;ENTER VIDEO_IO ROUTINE (SET MODE=0)
  322.     INT        10H                ;VIDEO INTERUPT
  323.  
  324.     POP    BP
  325.     RET
  326. ifdef Microsoft    
  327. _n_gmode    ENDP
  328. else
  329. n_gmode    ENDP
  330. endif
  331.  
  332. ;*********************************************************************
  333. ;*      ega24
  334. ;*      set char set for 24 line mode
  335. ;*
  336.  
  337. ifdef Microsoft
  338. _ega24    proc    far
  339. else
  340. ega24    proc     far
  341. endif
  342.     PUSH    BP
  343.     MOV        BP, SP
  344. ifdef not_used
  345.     PUSH     DS
  346.     PUSH     SI
  347.     PUSH     DI
  348. endif
  349.  
  350.     MOV         AL,3                ; reset egamode
  351.     XOR      AH,AH
  352.     INT     10H
  353.  
  354.     MOV        AX,0100H            ; SET CURSOR
  355.     MOV        CX,CURSOR            ; TURN ON
  356.     INT     10H
  357.  
  358. ifdef not_used
  359.     POP     DI
  360.     POP     SI
  361.     POP        DS
  362. endif
  363.     POP     BP
  364.     RET
  365. ifdef Microsoft
  366. _ega24     endp
  367. else
  368. ega24    endp
  369. endif    
  370.  
  371. ;****************************************************************
  372. ;*   set_cur
  373. ;*   sets cursor
  374. ;*
  375.  
  376. ifdef Microsoft
  377. _set_cur     proc    far
  378. else
  379. set_cur        proc    far
  380. endif
  381.     PUSH     BP
  382.     MOV        BP,SP
  383.     MOV        AL,[BP+X]            ;get var
  384.     OR        AL,AL
  385.     JNZ        CUR                    ; MAKE CURSOR
  386.     MOV        AX,0100H            ; TURN OFF
  387.     MOV        CX,2000H            ; BEGIN END OF CURSOR
  388.     INT     10h
  389.     JMP     SHORT EXIT                ; we are done
  390. CUR:    
  391.     MOV        CX,CURSOR            ; get cursOR type
  392.     MOV        AX,0100h            ; reset cursOR
  393.     INT     10h
  394. EXIT:
  395.     POP     BP
  396.     RET
  397.  
  398. ifdef Microsoft
  399. _set_cur endp
  400. else
  401. set_cur endp
  402. endif
  403.  
  404. ;****************************************************************
  405. ;*   n_flags
  406. ;*     returns the keyboard status flags
  407. ;*
  408.  
  409. ifdef Microsoft
  410. _n_flags    proc    far
  411. else
  412. n_flags     proc    far
  413. endif
  414.     PUSH     BP
  415.     MOV        AX,0200h            ; get shift states
  416.     INT        16h                    ; keyboard INT
  417.     XOR        AH,AH
  418.     POP     BP
  419.     RET    
  420. ifdef Microsoft
  421. _n_flags    endp
  422. else
  423. n_flags    endp
  424. endif
  425.  
  426. ;****************************************************************
  427. ;*   ega43
  428. ;*   code fOR 43 line ega mode
  429. ;*     
  430.  
  431. ifdef Microsoft
  432. _ega43 proc far
  433. else
  434. ega43 proc far
  435. endif
  436.     PUSH     BP
  437. ifdef not_used
  438.     PUSH     SI
  439.     PUSH     DI
  440.     PUSH     DS
  441. endif
  442.  
  443.     MOV        AH,00H                ; SET TO 80X25 CHAR MODE
  444.     MOV        AL,03H
  445.     INT        10H
  446.  
  447.     MOV        AX,1112H            ; CHAR. GENERATOR BIOS ROUTINUE
  448.     MOV        BL,00H                ; LOAD 8 BY 8 DOUBLE DOT CHARACTER FONT
  449.     INT     10H                    ; VIDEO CALL
  450.  
  451.     MOV        AX,1200H            ; ALTERNATE SCREEN ROUTINE
  452.     MOV        BL,20H                ; SELECT ALTERNATE PRint SCREEN ROUTINE
  453.     INT     10H                    ; VIDEO CALL
  454.  
  455.     MOV        AX,0007H    
  456.     MOV        CURSOR,AX            ; full cursOR
  457.  
  458. ifdef not_used
  459.     POP     DS
  460.     POP     DI
  461.     POP        SI
  462. endif
  463.     POP     BP
  464.     RET    
  465. ifdef Microsoft
  466. _ega43     endp
  467. else
  468. ega43    endp
  469. endif
  470.     
  471. ;*****************************************************************
  472. ;*   getDSk
  473. ;*   gets the active drive
  474. ;*     
  475. ifdef Microsoft
  476. _getdsk proc    far
  477.     PUSH     BP
  478.     MOV        AH,19H
  479.     INT        21h
  480.     POP     BP
  481.     RET
  482. _getdsk     endp    
  483. endif         
  484.  
  485. ;*****************************************************************
  486. ;*     chgdsk
  487. ;*   changes current drive
  488. ;*
  489.  
  490. ifdef Microsoft
  491. _chgdsk    proc    far
  492.     PUSH    BP
  493.     MOV        AH,0Eh
  494.     MOV        DL,[BP+X]
  495.     INT        21H
  496.     POP        BP
  497.     RET
  498. _chgdsk    endp
  499. endif
  500.  
  501. ;*****************************************************************
  502. ;*  n_attr
  503. ;*  replaces char. attribute
  504. ;*
  505.  
  506. ifdef Microsoft
  507. _n_attr    proc    far
  508. else 
  509. n_attr    proc    far
  510. endif
  511.  
  512.     PUSH     BP
  513.     MOV        BP,SP
  514.     PUSH     ES
  515.     PUSH    DI
  516. ;
  517. ;  fOR now, assume that the cursOR location has ALready been set
  518. ;  (cursOR is there)
  519. ;
  520.     MOV        AX,REGEN
  521.     MOV        ES,AX                ; set up fOR segment where screen is
  522.  
  523.     MOV        AL,ROW                ; row where chars go
  524.     XOR        AH,AH
  525.     MOV        BL,160
  526.     MUL        BL                    ; AX now equALs start of row
  527.     XOR        BH,BH
  528.  
  529.     MOV        BL,COL
  530.     SHL        BL,1                ; COL*2
  531.     ADD        AX,BX                ; add in column offset
  532.     INC        AX
  533.     MOV     DI,AX
  534.     MOV        AL,[BP+X]            ; ATTRIBUTE For CHARS
  535.     STOSB                        ; STorE aTTR
  536.  
  537.     POP        DI
  538.     POP        ES
  539.     POP        BP
  540.     RET
  541.  
  542.  
  543. ifdef Microsoft
  544. _n_attr     endp
  545. else
  546. n_attr      endp
  547. endif
  548.         
  549. ;*****************************************************************
  550. ;*  n_biosattr
  551. ;*  replaces char. attribute
  552. ;*  uses bios instead of directly screen write
  553. ;*
  554.  
  555. ifdef Microsoft
  556. _n_biosattr    proc    far
  557. else 
  558. n_biosattr    proc    far
  559. endif
  560.     PUSH     BP
  561.     MOV        BP,SP    
  562.     MOV         AH,8h                ; we want to read
  563.     MOV         BH,0H                ; GET FROM PAGE ZERO
  564.     INT     10H
  565.     MOV        BL,[BP+X]            ; GET CHANGED ATTRIBUTE
  566.     MOV        AH,9H                 ; WE WANT TO WRITE
  567.     MOV        CX,1H                ; ONLY ONCE
  568.     INT     10H
  569.     POP     BP
  570.     RET
  571. ifdef Microsoft
  572. _n_biosattr     endp
  573. else
  574. n_biosattr      endp
  575. endif
  576.  
  577. ;/***************************************************************/
  578. ;
  579. ;   Change the vALue of my current colOR
  580. ;
  581. ifdef Microsoft
  582. _n_color    proc    far
  583. else
  584. n_color    proc    far
  585. endif
  586.     PUSH    BP
  587.     MOV        BP,SP
  588.  
  589.     XOR        AX,AX
  590.     MOV        DL,[BP+X]            ; PARAMETER, ONE BYTE
  591.     MOV        AL,ATT                ; RETURN OLD COLor
  592.     MOV        ATT,DL
  593.  
  594.     POP        BP
  595.     RET
  596. ifdef Microsoft
  597. _n_color    endp
  598. else
  599. n_color    endp
  600. endif
  601.  
  602. ;/*****************************************************************/
  603. ;   Determine the current type of DISPlay
  604. ;
  605. ;   ask the BIOS which screen is currently active
  606. ;
  607. ifdef Microsoft
  608. _n_which    proc    far
  609. else
  610. n_which    proc    far
  611. endif
  612.     PUSH     BP
  613.     MOV        AH,0Fh                ; get screen mode
  614.     INT        10h                    ; cALl video BIOS
  615.     CMP        AL,7                ; is it mono?
  616.     JZ        K1                    ; yes
  617.     MOV        AX,0B800H            ; NO, SET For COLor
  618.     JMP     SHORT K2
  619. K1: 
  620.     MOV        AX,0B000H
  621. K2: 
  622.         MOV         REGEN,AX            ; SAVE SCREEN REGION
  623.  
  624.     MOV        AX,0300h            ; GET THE CURRENT
  625.     MOV        BX,0000h            ; INFO FOR PAGE 0
  626.     INT    10h
  627.     MOV        CURSOR,CX
  628.  
  629.     POP     BP
  630.     RET
  631. ifdef Microsoft
  632. _n_which    endp
  633. else
  634. n_which    endp
  635. endif
  636.  
  637. ;
  638. ;/***************************************************************/
  639. ;
  640. ;   Set whether wORd wrap will be on OR not
  641. ;   usage:  n_wrap(flag);
  642. ;
  643. ifdef Microsoft
  644. _n_wrap    proc    far
  645. else
  646. n_wrap    proc    far
  647. endif
  648.     PUSH    BP
  649.     MOV        BP,SP
  650.     MOV        DL,[BP+X]            ; PARAMETER, ONE BYTE FLAG
  651.     MOV        AL,WRAP                ; RETURN OLD COLor
  652.     MOV        WRAP,DL
  653.     POP        BP
  654.     RET
  655. ifdef Microsoft
  656. _n_wrap    endp
  657. else
  658. n_wrap    endp
  659. endif
  660.  
  661. ;/***************************************************************/
  662. ;
  663. ;   Move the cursOR somewhere
  664. ;
  665. ifdef Microsoft
  666. _n_cur    proc    far
  667. else
  668. n_cur    proc    far
  669. endif
  670.     PUSH    BP
  671.     MOV        BP,SP
  672.  
  673.     MOV        DH,[BP+X]            ; row poSItion
  674.     MOV        DL,[BP+X+2]            ; column poSItion
  675.     MOV        ROW,DH                ; save a copy fOR me
  676.     MOV        COL,DL                ; save column too
  677.     MOV         AX,0200h            ; ah=2 FUNCTION CalL
  678.     XOR     BX,BX                ; video page 0
  679.     INT      10H                  ; set cursOR poSItion
  680.  
  681.     POP        BP
  682.     RET
  683. ifdef Microsoft
  684. _n_cur    endp
  685. else
  686. n_cur    endp
  687. endif
  688.  
  689. ;/***************************************************************/
  690. ;
  691. ;  set the window boundaries
  692. ;
  693. ;  usage:  n_window(ulrow,ulcol,lrrow,lrcol);
  694. ;     sets window SIze fOR future operations.
  695. ;
  696. ;
  697. ifdef Microsoft
  698. _n_window    proc    far
  699. else
  700. n_window    proc    far
  701. endif
  702.     PUSH        BP
  703.     MOV            BP,SP
  704.     MOV            AL,[BP+X]        ; UPPER LEFT Y
  705.     MOV            TOPL,AL
  706.     MOV            AL,[BP+X+2]        ; COLUMN POsiTION
  707.     MOV            LEFTC,AL        ; save a copy fOR me
  708.     MOV            AL,[BP+X+4]
  709.     MOV            BOTL,AL            ; bottom row
  710.     MOV            AL,[BP+X+6]
  711.     MOV            RIGHTC,AL        ; keep this one too
  712. ifdef Microsoft
  713.     CALL        _N_WHICH        ; what kind of screen?
  714. else
  715.     CALL        N_WHICH            ; WHAT KIND OF SCREEN?
  716. endif
  717.     POP            BP
  718.     RET
  719. ifdef Microsoft
  720. _n_window    endp
  721. else
  722. n_window    endp
  723. endif
  724.  
  725. ;/***************************************************************/
  726. ;
  727. ;  erase pORtion of the screen
  728. ;
  729. ;  usage:  n_erase(ulrow,ulcol,lrrow,lrcol);
  730. ;
  731. ;
  732. ifdef Microsoft
  733. _n_erase    proc    far
  734. else
  735. n_erase    proc    far
  736. endif
  737.     PUSH    BP
  738.     MOV        BP,SP
  739.     MOV        CH,[BP+X]            ; UPPER LEFT X
  740.     MOV        CL,[BP+X+2]            ; COLUMN POsiTION
  741.     MOV        DH,[BP+X+4]
  742.     MOV        DL,[BP+X+6]
  743.     XOR        AX,AX                ; clear area
  744.     MOV        AH,6                ; scroll up function
  745.     MOV        BH,ATT                ; ATTRIBUTE For ERAsiNG IS SAME AS PRint
  746.     INT        10H                    ; CalL bios
  747.     POP        BP
  748.     RET
  749. ifdef Microsoft
  750. _n_erase    endp
  751. else
  752. n_erase    endp
  753. endif
  754.  
  755. ;/***************************************************************/
  756. ;  scroll up and down
  757. ;  given the number of lines to scroll and the DImenSIons of the
  758. ;  box to scroll.
  759. ;  
  760. ifdef Microsoft
  761. _n_scrup    proc    far
  762. else
  763. n_scrup    proc    far
  764. endif
  765.     PUSH    BP
  766.     MOV        BP,SP
  767.  
  768.     MOV        CH,[BP+X+2]            ; UPPER LEFT X
  769.     MOV        CL,[BP+X+4]            ; COLUMN POsiTION
  770.     MOV        DH,[BP+X+6]
  771.     MOV        DL,[BP+X+8]
  772.     MOV        AL,[BP+X]            ; NUMBER OF LINES TO SCROLL
  773.     MOV        AH,6                ; scroll up function
  774.     MOV        BH,ATT                ; ATTRIBUTE For BLANK LINE IS SAME AS PRint
  775.     INT        10H                    ; CalL bios
  776.  
  777.     POP        BP
  778.     RET
  779. ifdef Microsoft
  780. _n_scrup    endp
  781. else
  782. n_scrup    endp
  783. endif
  784.  
  785. ifdef Microsoft
  786. _n_scrdn    proc    far
  787. else
  788. n_scrdn    proc    far
  789. endif
  790.     PUSH    BP
  791.     MOV        BP,SP
  792.     MOV        CH,[BP+X+2]            ; upper left x
  793.     MOV        CL,[BP+X+4]            ; column poSItion
  794.     MOV        DH,[BP+X+6]
  795.     MOV        DL,[BP+X+8]
  796.     MOV        AL,[BP+X]            ; number of lines to scroll
  797.     MOV        AH,7                ; scroll down function
  798.     MOV        BH,ATT                ; attribute fOR blank line is same as prINT
  799.     INT        10H                    ; CalL bios
  800.     POP        BP
  801.     RET
  802. ifdef Microsoft
  803. _n_scrdn    endp
  804. else
  805. n_scrdn    endp
  806. endif
  807.  
  808. ;/***************************************************************/
  809. ;  Find the cursOR poSItion, return the row vALue
  810. ;  
  811. ifdef Microsoft
  812. _n_row    proc    far
  813. else
  814. n_row    proc    far
  815. endif
  816.     PUSH     BP
  817.  
  818.     MOV        AX,0300H            ;video find cursOR function
  819.     XOR     BX,BX
  820.     INT     10H                  ; find cursOR
  821.     MOV        ROW,DH
  822.     MOV        COL,DL                ; save col fOR next routine
  823.     XOR        AX,AX
  824.     MOV        AL,DH                ; return row location
  825.  
  826.     POP     BP
  827.     RET
  828. ifdef Microsoft
  829. _n_row    endp
  830. else
  831. n_row    endp
  832. endif
  833.  
  834. ;/****************************************************************************/
  835.   ;-----------------------------------------------------------
  836.   ;  This routine was submitted by David T. Burhans, Jr.
  837.   ;  It was obtained from an RBBS-PC electronic bulleton board 
  838.   ;  deDIcated to the "C" language [(703) 321-7003].
  839.   ;-----------------------------------------------------------
  840.   ;
  841.   ; SOUND - This routine produces a tone of a SPecified frequency 
  842.   ; and duration on the SPeaker.
  843.   ; The frequency in Hertz is moved INTo DI (21 to 65535 Hertz) 
  844.   ; and the duration in hundredths of a second, is moved INTo BX 
  845.   ; (0 to 65535).
  846.   ; The routine is cALled with the following sequence:
  847.   ;
  848.   ;        UnSIgned        frequency, duration;
  849.   ;
  850.   ;       n_sound(frequency, duration);
  851.   ;
  852. ifdef Microsoft
  853. _n_sound    proc    far
  854. else
  855. n_sound    proc    far
  856. endif
  857.     PUSH    BP
  858.     MOV        BP,SP
  859.     PUSH    DI
  860.  
  861.     MOV         DI,[BP+X]          ; Frequency
  862.     MOV         BX,[BP+X+2]        ; Duration
  863.     CMP      DI, 21H            ; See if freq. is below minimum
  864.     JB       DONE               ; iF LESS THAN LIMIT, THEN
  865.                                 ; clean up and return
  866.     MOV         AL,0B6H            ; Write timer mode register
  867.     OUT      43H, AL
  868.     MOV         DX, 14H            ; Timer DIvisOR =
  869.     MOV         AX, 4F38H          ; 1331000/Frequency
  870.     DIV      DI 
  871.     OUT      42H,AL             ; Write timer 2 count low byte
  872.     MOV         AL,AH
  873.     OUT      42H,AL             ; Write timer 2 count high byte
  874.     IN       AL,61H             ; Get current PORt B setting
  875.     MOV         AH,AL              ; and save it in AH
  876.     OR       AL,3               ; Turn SPeaker on
  877.     OUT      61H,AL
  878. HOLD:
  879.     MOV         CX, 2801
  880. SPKR_ON: 
  881.     LOOP   SPKR_ON
  882.     DEC      BX                ; Speaker-on count expired?
  883.     JNZ      HOLD              ; iF NOT, KEEP spEAKER ON
  884.     MOV         AL,AH             ; Otherwise, recover vALue of pORt
  885.     OUT      61H,AL
  886. DONE:
  887.     POP        DI
  888.     MOV        SP,BP             ; RestORe locALs from stack.
  889.     POP        BP                ; RestORe cALler's BP
  890.     RET                        ; rETURN TO CalLER
  891. ifdef Microsoft
  892. _n_sound    endp
  893. else
  894. n_sound    endp
  895. endif
  896.  
  897. ;/***************************************************************/
  898. ;
  899. ;  Find the column poSItion of the cursOR.
  900. ;  Must be preceded by a n_row cALl!!!!
  901. ;  Will wORk when these routines ALready know the cursOR poSItion
  902. ;
  903. ifdef Microsoft
  904. _n_col    proc    far
  905. else
  906. n_col    proc    far
  907. endif
  908.     XOR        AH,AH
  909.     MOV        AL,COL                ; RETURN COL LOCATION
  910.     RET
  911. ifdef Microsoft
  912. _n_col    endp
  913. else
  914. n_col    endp
  915. endif
  916.  
  917. ;/***************************************************************/
  918. ;  n_clear
  919. ;  Clear what we think is the current window
  920. ;
  921. ifdef Microsoft
  922. _n_clear    proc    far
  923. else
  924. n_clear    proc    far
  925. endif
  926.     PUSH     BP
  927.     MOV        AL,0            ; clear window
  928.     MOV        AH,6            ; scroll up function
  929.     MOV        CH,TOPL            ; TOP ROW TO CLEAR
  930.     MOV        CL,LEFTC        ; LEFT COLUMN
  931.     MOV        DH,BOTL            ; BOTTOM ROW TO CLEAR
  932.     MOV        DL,RIGHTC        ; RIGHT siDE TO CLEAR
  933.     MOV        BH,ATT            ; ATTRIBUTE TO USE For BLANKS
  934.     INT        10H                ; CalL bios
  935.     POP     BP
  936.     RET
  937. ifdef Microsoft
  938. _n_clear    endp
  939. else
  940. n_clear    endp
  941. endif
  942.  
  943. ;/***************************************************************/
  944. ;  n_upscroll
  945. ;  Scroll up what we think is the current window, n lines
  946. ;
  947. ifdef Microsoft
  948. _n_upscroll    proc    far
  949. else
  950. n_upscroll    proc    far
  951. endif
  952.     PUSH    BP
  953.     MOV        BP,SP
  954.  
  955.     MOV        AL,[BP+X]            ; number of lines to scroll
  956.     MOV        AH,6                ; scroll up function
  957.     MOV        CH,TOPL                ; top row to clear
  958.     MOV        CL,LEFTC            ; left column
  959.     MOV        DH,BOTL                ; bottom row to clear
  960.     MOV        DL,RIGHTC            ; RIGHT siDE TO CLEAR
  961.     MOV        BH,ATT                ; attribute to use
  962.     INT        10H                    ; cALl BIOS
  963.  
  964.     POP        BP
  965.     RET
  966. ifdef Microsoft
  967. _n_upscroll    endp
  968. else
  969. n_upscroll    endp
  970. endif
  971.  
  972. ;/***************************************************************/
  973. ;  n_dnscroll
  974. ;  Scroll up what we think is the current window, n lines
  975. ;
  976. ifdef Microsoft
  977. _n_dnscroll    proc    far
  978. else
  979. n_dnscroll    proc    far
  980. endif
  981.     PUSH    BP
  982.     MOV        BP,SP
  983.     MOV        AL,[BP+X]            ; number of lines to scroll
  984.     MOV        AH,7                ; scroll down function
  985.     MOV        CH,TOPL                ; top row to clear
  986.     MOV        CL,LEFTC            ; left column
  987.     MOV        DH,BOTL                ; bottom row to clear
  988.     MOV        DL,RIGHTC            ; right SIde to clear
  989.     MOV        BH,ATT                ; attribute to use fOR blank lines
  990.     INT        10h                    ; CalL bios
  991.     POP        BP
  992.     RET
  993. ifdef Microsoft
  994. _n_dnscroll    endp
  995. else
  996. n_dnscroll    endp
  997. endif
  998.  
  999. ;/***************************************************************/
  1000. ;  n_putchar(letter)
  1001. ;      puts onto screen at current cursOR location
  1002. ;
  1003. ifdef Microsoft
  1004. _n_putchar    proc    far
  1005. else
  1006. n_putchar    proc    far
  1007. endif
  1008.     PUSH     BP
  1009.     MOV        BP,SP
  1010.  
  1011.     MOV        AL,[BP+X]           ; char to write
  1012.     XOR      BX,BX               ;  set page number fOR ALl cursOR addresses
  1013.     CMP      AL,10               ; line feed
  1014.     JNZ     NXT
  1015.     MOV        AL,ROW                ; get current cursOR row poSItion
  1016.     CMP        AL,BOTL    
  1017.     JL        NOSCR                ; within window area
  1018.     MOV        AX,1                ; scroll up one line
  1019.     PUSH    AX
  1020. ifdef Microsoft
  1021.     CALL    _N_UPSCROLL            ; scrolls it up one
  1022. else
  1023.     CALL    N_UPSCROLL            ; scrolls it up one
  1024. endif
  1025.     POP        AX                    ; take parameter off of stack
  1026. ;    MOV        AL,LEFTC            ; get left SIde vALue
  1027. ;    MOV        COL,AL                ; set cursOR to left
  1028.     JMP        PUTCUR
  1029. NOSCR:
  1030. ;    MOV        AL,LEFTC            ; return cursOR to left SIde
  1031. ;    MOV        COL,AL
  1032.     INC        ROW
  1033.     JMP        PUTCUR                ; set new cursOR poSItion, return
  1034. NXT:
  1035.     CMP      AL,7                 ; ctrl-G, bell
  1036.     JNZ      NXT2
  1037. ;
  1038. ;  handle bell with a cALl to a SPeciAL routine
  1039. ;
  1040.     MOV        AX,12                ; duration of tone
  1041.     PUSH    AX
  1042.     MOV        AX,1000              ; frequency of tone
  1043.     PUSH     AX
  1044. ifdef Microsoft
  1045.     CALL _N_SOUND
  1046. else
  1047.     CALL N_SOUND
  1048. endif
  1049.     ADD     SP,4                 ; remove params from stack
  1050. HERE2:
  1051.     POP        BP
  1052.     RET
  1053. NXT2:
  1054.     CMP        AL,13               ; cr,  home the cursOR
  1055.     JNZ        TRYTAB
  1056.     MOV        AL,LEFTC            ; new cursOR poSItion
  1057.     MOV        COL,AL
  1058.     JMP        PUTCUR
  1059. TRYTAB:
  1060.     CMP      AL,9                ; tab character
  1061.     JNZ      NOTCRLF               ; ready fOR regular character
  1062. ;  expand tabs
  1063.     MOV        DL,COL                ; get cursOR poSItion
  1064.     MOV        CL,3
  1065.     SHR     DL,CL                ; DIvide cursOR poSItion by 8
  1066.     INC        DL                    ; increment cursOR poSItion
  1067.     SHL        DL,CL                ; multiply back by 8
  1068.     MOV        COL,DL
  1069.                                 ; check to see if past right SIde
  1070.     MOV        DL,COL                ; get where the cursOR has moved to
  1071.     CMP        DL,RIGHTC            ; over the SIde yet?
  1072.     JA        TABOVER                ; set the new poSItion
  1073.     JMP        PUTCUR
  1074. TABOVER:
  1075.     MOV        DL,LEFTC
  1076.     MOV        COL,DL
  1077.     INC        ROW                    ; TO NEXT ROW
  1078.     MOV        DL,ROW                ; WHAT ROW?
  1079.     CMP        DL,BOTL
  1080.     JG        TABNOS                ; we are okay
  1081.     JMP     SHORT PUTCUR
  1082. TABNOS:
  1083.     DEC        ROW                    ; need to scroll
  1084.     MOV        AX,1
  1085.     PUSH    AX
  1086. ifdef Microsoft
  1087.     CALL    _N_UPSCROLL            ; scroll window up one line
  1088. else
  1089.     CALL    N_UPSCROLL            ; scroll window up one line
  1090. endif
  1091.     POP        AX
  1092.     MOV        AL,LEFTC            ; reset cursOR poSItion to left
  1093.     MOV        COL,AL
  1094.     JMP     SHORT PUTCUR
  1095. NOTCRLF:
  1096.        CMP      AL,8                   ; backSPace
  1097.     JNZ     REGCHAR
  1098.     MOV        AL,COL                ; where is cursOR?
  1099.     CMP        AL,LEFTC            ; is at left of screen?
  1100.     JZ        HERE2
  1101.     DEC        COL                    ; decrement cursOR poSItion
  1102.     JMP     SHORT PUTCUR              ; okay, move cursOR where it belongs
  1103. REGCHAR:
  1104.     MOV         CX,1H                 ; number of repetitions = 1
  1105.     MOV         BL,ATT                 ; attribute of char
  1106.     MOV        BH,0                ; write to page zero
  1107.     MOV         AH,9                 ; write char
  1108.     INT      10H
  1109.  
  1110.     INC      COL                 ; move cursOR over one. 
  1111.     MOV        DL,COL                ; get current poSItion
  1112.        CMP      DL,RIGHTC            ; is at right SIde of screen?
  1113.     JLE       PUTCUR                 ; no, char can just be put out, cursOR moved.
  1114. ;
  1115. ;  check wORd-wrap because we are at edge of window
  1116. ;
  1117.     MOV        DL,WRAP
  1118.     OR        DL,DL                ; 0 = NO WRAP, 1 = WRAP
  1119.     JZ        NOWRAP
  1120.        MOV         DL,LEFTC            ; cursOR will wrap around
  1121.     MOV        COL,DL                ; save the new column poSItion
  1122.     INC        ROW                    ; to next row
  1123.     MOV        DL,BOTL
  1124.     CMP      ROW,DL                ; do we need to scroll?
  1125.     JNG      PUTCUR                ; no, okay fOR next row, nORmAL wrap
  1126. ; scroll screen up one 
  1127.     MOV        AX,1
  1128.     PUSH    AX
  1129. Ifdef Microsoft
  1130.     CALL    _N_UPSCROLL            ; scroll window up one line
  1131. else
  1132.     CALL    N_UPSCROLL            ; scroll window up one line
  1133. endif
  1134.     POP        AX
  1135.     DEC        ROW                    ; scrolled up one
  1136.     JMP     SHORT PUTCUR              ; don't wrap
  1137. NOWRAP:
  1138.     DEC        COL
  1139. PUTCUR:
  1140.     MOV        DH,ROW
  1141.     MOV        DL,COL
  1142.        MOV         AH,2h
  1143.        XOR     BX,BX
  1144.     INT      10H                 ; set cursOR poSItion
  1145.  
  1146. ESCAPEHERE:
  1147.     POP     BP
  1148.     RET
  1149. ifdef not_used
  1150. TELE:
  1151.     MOV        BL,3                  ; SEND WHATEVER CHAR
  1152.     MOV        AH,14
  1153.     INT     10H
  1154.  
  1155.     POP        BP
  1156.     RET
  1157. endif
  1158. ifdef Microsoft
  1159. _n_putchar    endp
  1160. else
  1161. n_putchar    endp
  1162. endif
  1163.  
  1164. ;/**********************************************************************/
  1165. ;  draw
  1166. ;  place characters on the screen-- checking fOR bounDS, etc.  ALl done
  1167. ;  at a higher level.
  1168. ;
  1169. ;  n_draw(s,len)
  1170. ;    char*s ; INT len;
  1171. ;
  1172. ifdef Microsoft
  1173. _n_draw proc far
  1174. else
  1175. n_draw proc far
  1176. endif
  1177.     PUSH     BP
  1178.     MOV        BP,SP
  1179.     PUSH     ES
  1180.     PUSH    SI
  1181.     PUSH    DI
  1182. ;
  1183. ;  fOR now, assume that the cursOR location has ALready been set
  1184. ;  (cursOR is there)
  1185. ;
  1186. ;    MOV        SI,[BP+X]            ; poINTer to string
  1187. ;    MOV        AX,[BP+X+2]            ; ds OF STRING
  1188. ;    MOV        ES,AX
  1189.     LES        SI,[BP+X]            ; get the segment and offset of the string
  1190.     MOV        DI,[BP+X+4]            ; # OF CHARACTERS
  1191. ;    OR        DI,DI                ; check for no characters to draw
  1192. ;    JZ        ENDDRAW                ; exit if no characters to draw
  1193.     MOV        DH,ROW                ; row where cursOR is
  1194. LOOPDRAW:
  1195.     MOV        AL,ES:[SI]            ; get character to write from es:SI
  1196.     INC        SI
  1197.     MOV         CX,1H                  ; number of repetitions = 1
  1198.     XOR      BH,BH                ; dispLAY PAGE 0
  1199.        MOV         BL,ATT                 ; attribute of char
  1200.     MOV         AH,9                   ; write char
  1201.        INT      10h
  1202.     INC        COL                    ; MOVE THE CURSor OVER
  1203.     MOV        DL,COL
  1204.        MOV         AH,2H
  1205.     XOR        BX,BX
  1206.     INT      10H                     ; SET CURSor POsiTION
  1207.     DEC     DI                    ; check counter
  1208.     JNZ     LOOPDRAW            ; GO THROUGH TO REQUIRED COUNT
  1209.  
  1210. ENDDRAW:
  1211.     POP        DI
  1212.     POP        SI
  1213.     POP     ES
  1214.     POP        BP
  1215.     RET
  1216. ifdef Microsoft
  1217. _n_draw endp
  1218. else
  1219. n_draw endp
  1220. endif
  1221.  
  1222. ;/**********************************************************************/
  1223. ;  cheat
  1224. ;  put characters on the screen as per n_draw, but write DIrectly
  1225. ;  to DISPlay memORy.  Don't even check fOR retrace
  1226. ;
  1227. ifdef Microsoft
  1228. _n_cheat proc    far
  1229. else
  1230. n_cheat proc    far
  1231. endif
  1232.     PUSH     BP
  1233.     MOV        BP,SP
  1234.     PUSH     ES
  1235.     PUSH     DS
  1236.     PUSH    SI
  1237.     PUSH    DI
  1238. ;
  1239. ;  fOR now, assume that the cursOR location has ALready been set
  1240. ;  (cursOR is there)
  1241. ;
  1242.     MOV        AX,REGEN
  1243.     MOV        ES,AX                ; set up fOR segment where screen is
  1244.     MOV        AL,ROW                ; row where chars go
  1245.     XOR        AH,AH
  1246.     MOV        BL,160
  1247.     MUL        BL                    ; AX now equALs start of row
  1248.     XOR        BH,BH
  1249.     MOV        BL,COL
  1250.     SHL        BL,1                ; COL*2
  1251.     ADD        AX,BX                ; add in column offset
  1252.     MOV        DI,AX                ; stORe in DI (es:DI)
  1253.     MOV        CX,[BP+X+4]            ; # of characters
  1254. ;    OR        CX,CX                ; check whether we really have ANY characters
  1255. ;    JZ        ENDCHEAT            ; exit if we have no characters
  1256.     ADD        COL,CL                ; COLUMN POsiTION OF CURSor
  1257.     MOV        AH,ATT                ; ATTRIBUTE For CHARS
  1258. ;    MOV        SI,[BP+X]            ; POintER TO STRING
  1259. ;    MOV        BX,[BP+X+2]            ; ds OF STRING
  1260. ;    MOV        DS,BX
  1261.     LDS        SI,[BP+X]            ; get the segment and offset of the string
  1262. ;
  1263. ;  do the move
  1264. ;
  1265.     CLD
  1266. LPCHEAT:
  1267.     LODSB                        ; GET NEXT BYTE
  1268.     STOSW                        ; STorE BYTE AND ATTRIBUTE
  1269.     LOOP     LPCHEAT
  1270.  
  1271. ENDCHEAT:
  1272.     POP        DI
  1273.     POP        SI
  1274.     POP        DS
  1275.     POP        ES
  1276.     POP        BP
  1277.     RET
  1278. ifdef Microsoft
  1279. _n_cheat    endp
  1280. else
  1281. n_cheat    endp
  1282. endif
  1283.  
  1284. ;/**********************************************************************/
  1285. ;
  1286. ;  New keyboard handling
  1287.  
  1288. ;    the interrupt and codes for the keyboard interface.
  1289.  
  1290. KEYBOARD    EQU    16H            ; interrupt 16 to deal with keyboard
  1291. GETC          EQU    0            ; code for reading a character
  1292. CHECKC        EQU    1            ; code for keyboard status
  1293. SHIFTSTAT    EQU    2            ; code for shift key status
  1294. SCAN        EQU    00100H        ; scan code
  1295. SHIFT        EQU    00200H        ; left or right shift key pressed
  1296. CONTROL        EQU    00400H        ; control key pressed
  1297. ALT            EQU    00800H        ; alt key pressed
  1298. ENHANCE        EQU    01000H        ; enhanced keyboard special key
  1299.  
  1300. ;**********************************************************************
  1301. ;
  1302. ;  Get a translated character from the keyboard.
  1303. ;
  1304. ;    Return the next character pressed with the new translation method for
  1305. ;        kermit compatibility.
  1306. ;    Quincey Koziol
  1307. ;
  1308. ;    Usage:
  1309. ;        unsigned int n_newgetchar(void);
  1310. ;
  1311. ifdef Microsoft
  1312. _n_getchar    proc    far
  1313. else
  1314. n_getchar    proc    far
  1315. endif
  1316.     PUSH      BP
  1317. ifdef Microsoft
  1318.     MOV     AH,_KEYBOARD_TYPE   ; ask for a keyboard character
  1319. else
  1320.     MOV           AH,_KEYBOARD_TYPE    ; ask for a keyboard character
  1321. endif
  1322.     INT        KEYBOARD
  1323.     MOV        BX,AX                ; store the scan code character
  1324.     MOV        AH,SHIFTSTAT        ; get the shift keys' status
  1325.     INT        KEYBOARD            ; shift status returned in AX
  1326.     XOR        AH,AH                ; clear the top part of the shift status
  1327.     XOR        DX,DX                ; set local variables to zero
  1328.     XOR        CX,CX                ; 
  1329.     CMP        BH,0                ; check for enhanced key
  1330.     JE        NOT_ENHANCED1        ; jump around first enchanced key checks
  1331.     CMP        BH,0E0H                ; check for other part of enhanced key
  1332.     JNE        NOT_ENHANCED2
  1333.     XCHG    BH,BL                ; shift key from bios left 8 bits
  1334.     XOR        BL,BL                ; 
  1335.     OR        DX,ENHANCE            ; set the enhanced bit
  1336. NOT_ENHANCED2:
  1337.     CMP        BL,0E0H                ; check for second part of enhanced key
  1338.     JNE        NOT_ENHANCED1
  1339.     XOR        BL,BL                ; clear the character code from the bios key
  1340.     OR        DX,ENHANCE            ; set the enhanced bit
  1341. NOT_ENHANCED1:
  1342.     CMP        BL,0                ; check for not scan code only being zero
  1343.     JE        NOT_ALIAS            ; not one of the alias'ed keys from BIOS
  1344.     CMP        BX,(14*SCAN)+8        ; check for Backspace
  1345.     JE        ALIAS_KEY
  1346.     CMP        BX,(55*SCAN)+'*'    ; check for '*'
  1347.     JE        ALIAS_KEY
  1348.     CMP        BX,(74*SCAN)+'-'    ; check for '-'
  1349.     JE        ALIAS_KEY
  1350.     CMP        BX,(78*SCAN)+'+'    ; check for '+'
  1351.     JE        ALIAS_KEY
  1352.     CMP        BX,(71*SCAN)+'7'    ; check for '7'
  1353.     JE        ALIAS_KEY
  1354.     CMP        BX,(72*SCAN)+'8'    ; check for '8'
  1355.     JE        ALIAS_KEY
  1356.     CMP        BX,(73*SCAN)+'9'    ; check for '9'
  1357.     JE        ALIAS_KEY
  1358.     CMP        BX,(75*SCAN)+'4'    ; check for '4'
  1359.     JE        ALIAS_KEY
  1360.     CMP        BX,(76*SCAN)+'5'    ; check for '5'
  1361.     JE        ALIAS_KEY
  1362.     CMP        BX,(77*SCAN)+'6'    ; check for '6'
  1363.     JE        ALIAS_KEY
  1364.     CMP        BX,(79*SCAN)+'1'    ; check for '1'
  1365.     JE        ALIAS_KEY
  1366.     CMP        BX,(80*SCAN)+'2'    ; check for '2'
  1367.     JE        ALIAS_KEY
  1368.     CMP        BX,(81*SCAN)+'3'    ; check for '3'
  1369.     JE        ALIAS_KEY
  1370.     CMP        BX,(82*SCAN)+'0'    ; check for '0'
  1371.     JE        ALIAS_KEY
  1372.     CMP        BX,(83*SCAN)+'.'    ; check for '.'
  1373.     JE        ALIAS_KEY
  1374.     CMP        BX,(83*SCAN)+','    ; check for ','
  1375.     JE        ALIAS_KEY
  1376.     CMP        BX,(15*SCAN)+9        ; check for Tab
  1377.     JE        ALIAS_KEY
  1378.     JMP     SHORT NOT_ALIAS           ; key didn't match one of the alias'ed keys
  1379. ALIAS_KEY:
  1380.     XOR        BL,BL                ; clear ascii code for alias'ed keys
  1381. NOT_ALIAS:
  1382.     CMP        BL,0                ; no ascii value, get a kermit scan code
  1383.     JNE        REGULAR_KEY
  1384.     MOV        DL,BH                ; get the scancode
  1385.     OR        DX,SCAN                ; set the SCAN flag
  1386.     TEST    AX,3                ; check for shift key down
  1387.     JE        NOT_SHIFT            ; shift key not down
  1388.     OR        CX,SHIFT            ; set the SHIFT help flag
  1389. NOT_SHIFT:
  1390.     TEST    AL,20h                ; check for NumLock set
  1391.     JE        NOT_NUMLOCK            ; NumLock not down
  1392.     CMP        DX,71+SCAN            ; on numeric keypad?
  1393.     JB        NOT_NUMLOCK
  1394.     CMP        DX,83+SCAN
  1395.     JA        NOT_NUMLOCK
  1396.     CMP        DX,74+SCAN            ; not the grey - key
  1397.     JE        NOT_NUMLOCK
  1398.     CMP        DX,78+SCAN            ; not the grey + key
  1399.     JE        NOT_NUMLOCK
  1400.     XOR        CX,SHIFT            ; all true, xor the shift help
  1401. NOT_NUMLOCK:
  1402.     OR        DX,CX                ; set the correct shift status
  1403.     TEST    AL,4                ; check for the CONTROL key down
  1404.     JE        NOT_CONTROL
  1405.     OR        DX,CONTROL            ; set the control flag
  1406. NOT_CONTROL:
  1407.     TEST    AX,8                ; check for the ALT key down
  1408.     JE        NOT_ALT
  1409.     OR        DX,ALT                ; set the alt flag
  1410. NOT_ALT:
  1411.     MOV        AX,DX                ; set the return value
  1412.     JMP     SHORT END_NEWGETCHAR
  1413.     
  1414. REGULAR_KEY:                    ; we have an ascii value, return that
  1415.     XOR        BH,BH                ;
  1416.     MOV        AX,BX                ; return the key id
  1417.  
  1418. END_NEWGETCHAR:
  1419.     POP    BP
  1420.     RET
  1421. ifdef Microsoft
  1422. _n_getchar    endp
  1423. else
  1424. n_getchar    endp
  1425. endif
  1426.  
  1427. ;**********************************************************************
  1428. ;  Check for character present at the keyboard
  1429. ;  If there is one available, return it, if not, return -1
  1430. ;
  1431. ;  translate any extended characters
  1432. ;
  1433. ifdef Microsoft
  1434. _n_chkchar    proc    far
  1435. else
  1436. n_chkchar    proc    far
  1437. endif
  1438.     PUSH     BP
  1439. ifdef Microsoft
  1440.     MOV        AH,_KEYBOARD_TYPE    ; get the correct BIOS setting for the keyboard
  1441. else
  1442.     MOV        AH,KEYBOARD_TYPE    ; get the correct BIOS setting for the keyboard
  1443. endif
  1444.     INC        AH                    ; increment for the setting to check the keyboard
  1445.     INT         KEYBOARD
  1446.     MOV        AX,-1
  1447.     JZ        NEW_NOKEY
  1448. ifdef Microsoft
  1449.     CALL    _N_GETCHAR            ;get the coded character
  1450. else
  1451.     CALL    N_GETCHAR            ;get the coded character
  1452. endif
  1453. NEW_NOKEY:
  1454.        POP    BP
  1455.     RET
  1456. ifdef Microsoft
  1457. _n_chkchar    endp
  1458. else
  1459. n_chkchar    endp
  1460. endif
  1461.  
  1462. ;/***************************************************************/
  1463. ;  savewin
  1464. ;    copy the current window INTo a buffer
  1465. ;
  1466. ;   usage:  n_savewindow(buffer);
  1467. ;
  1468. ifdef Microsoft
  1469. _n_savewin    proc    far
  1470. else
  1471. n_savewin    proc    far
  1472. endif
  1473.     PUSH    BP
  1474.     MOV        BP,SP
  1475.     PUSH    ES
  1476.     PUSH    DS
  1477.     PUSH    SI
  1478.     PUSH    DI
  1479.  
  1480.     MOV        AX,[BP+X+2]            ; DS of buffer
  1481.     MOV        ES,AX
  1482.     MOV        DI,[BP+X]            ; poINTer to buffer
  1483.     CLD
  1484. ;
  1485. ;  stORe parameters in first, fOR recALl later
  1486. ;
  1487.     MOV        AL,ROW                ; cursOR poSItion: row,col
  1488.     STOSB
  1489.     MOV        AL,COL
  1490.     STOSB
  1491.     MOV        AL,TOPL                ; window boundaries
  1492.     STOSB
  1493.     MOV        AL,LEFTC
  1494.     STOSB
  1495.     MOV        AL,BOTL
  1496.     STOSB
  1497.     MOV        AL,RIGHTC
  1498.     STOSB                        ; STorE IN BUFFER TOO
  1499. ;
  1500. ;  cALculate amount to move
  1501. ;
  1502. ;
  1503. ;  cALculate number of lines to move
  1504. ;
  1505.     MOV         AL,TOPL             ; X1
  1506.     MOV         BL,BOTL                ; X2
  1507.     SUB      BL,AL               ; x2 = x2-x1
  1508.     INC      BL                  ; ADD 1 LINE
  1509.     MOV         [BP+X],BL            ; KEEP IT SOMEWHERE SAFE
  1510. ;
  1511. ;  cALculate screen offset  = 160*x1+2*y1;
  1512. ;
  1513. ;   AL has topl in it
  1514.     XOR      AH,AH
  1515.     MOV         BL,160
  1516.     MUL      BL                    ; how many chars in x1 lines, in AX
  1517.     XOR      CH,CH
  1518.     MOV         CL,LEFTC            ; chars to left SIde
  1519.     SHL      CL,1                ; *2 counts attributes
  1520.     ADD      AX,CX               ; add them
  1521.     MOV         SI,AX               ; place INTo source index
  1522. ;
  1523. ;  find number of characters to move each time
  1524. ;
  1525.     MOV         CL,RIGHTC
  1526.     SUB      CL,LEFTC               ; Y2 = Y2-Y1
  1527.     INC      CL                     ;  ADD 1
  1528.     MOV         [BP+X+1],CL            ; SAFE PLACE AGAIN
  1529. ;
  1530. ;  find number to add to wrap around fOR each line
  1531. ;
  1532.     MOV         BL,CL                  ; # OF CHARS MOVED EACH TIME
  1533.     SHL      BL,1                   ; CHARS*2
  1534.     MOV         AL,160
  1535.     SUB      AL,BL                  ; 160-chars*2
  1536.     MOV         [BP+X+2],AL            ; safe place to keep it
  1537. ;
  1538. ;
  1539.     MOV         AX,REGEN               ; where source segment is (screen)
  1540.     MOV         DS,AX
  1541.     MOV         DX,03dAH            ; colOR card status pORt
  1542.     XOR      BH,BH
  1543.     MOV         BL,[BP+X]           ; howmany lines to move
  1544.     CMP      AX,0B000H           ; CHECK For MONO CARD
  1545.     JNZ     GETLINE
  1546.     MOV         DX,03BAH            ; change status pORt vALue
  1547. GETLINE:
  1548.     MOV         CL,[BP+X+1]         ; # OF CHARS TO MOVE
  1549. GETCHAR:
  1550. ;   IN       AL,DX               ; GET STATUS BYTE
  1551.     TEST     AL,1                ; hORizontAL retrace
  1552. ;   JNZ      GETCHAR             ; not there yet
  1553. ;ISON:
  1554.     IN       AL,DX
  1555. ;   TEST     AL,1
  1556. ;   JZ       ISON                ; STILL ON, TRY AGAIN
  1557.     MOVSW                         ; NOW IS TIME, MOVE THE WorD
  1558.     LOOP     GETCHAR             ; DO ANOTHER UNTIL THIS LINE IS DONE
  1559. ;
  1560.     DEC     BX
  1561.     JZ      ENDKEEP             ; DONE, WE ARE OUT OF HERE
  1562.     MOV        AL,[BP+X+2]
  1563.     XOR        AH,AH
  1564.     ADD     SI,AX               
  1565. ; go to next line, skip 160-n*2 bytes
  1566.     JMP     GETLINE
  1567. ENDKEEP:
  1568.     POP        DI
  1569.     POP        SI
  1570.     POP      DS
  1571.     POP      ES
  1572.     POP      BP
  1573.     RET
  1574. ifdef Microsoft
  1575. _n_savewin    endp
  1576. else
  1577. n_savewin    endp
  1578. endif
  1579.  
  1580. ;/***************************************************************/
  1581. ;  restwindow
  1582. ;    restORe the contents of the window to the screen
  1583. ;
  1584. ifdef Microsoft
  1585. _n_restwin    proc    far
  1586. else
  1587. n_restwin    proc    far
  1588. endif
  1589.     PUSH    BP
  1590.     MOV        BP,SP
  1591.     PUSH    ES
  1592.     PUSH    DS
  1593.     PUSH    SI
  1594.     PUSH    DI
  1595.  
  1596.     MOV        AX,[BP+X+2]            ; ds OF BUFFER
  1597.     PUSH    AX                    ; will POP to DS later 
  1598.     MOV        ES,AX                ; used to restORe variable vALues
  1599.     MOV        SI,[BP+X]            ; POintER TO BUFFER
  1600.     CLD
  1601. ;
  1602. ;  get back stORed variables
  1603. ;
  1604.     MOV        AL,ES:[SI]            ; get cursOR row
  1605.     MOV        ROW,AL
  1606.     INC        SI
  1607.     MOV        AL,ES:[SI]
  1608.     MOV        COL,AL
  1609.     INC        SI
  1610.     MOV        AL,ES:[SI]            ; window boundaries
  1611.     MOV        TOPL,AL
  1612.     INC        SI
  1613.     MOV        AL,ES:[SI]
  1614.     MOV        LEFTC,AL
  1615.     INC        SI
  1616.     MOV        AL,ES:[SI]
  1617.     MOV        BOTL,AL
  1618.     INC        SI
  1619.     MOV        AL,ES:[SI]
  1620.     MOV        RIGHTC,AL
  1621.     INC        SI                    ; now we are ready fOR data
  1622. ;
  1623. ;  cALculate amount to move
  1624. ;
  1625. ;
  1626. ;  cALculate number of lines to move
  1627. ;
  1628.     MOV        AL,TOPL             ; X1
  1629.     MOV        BL,BOTL                ; X2
  1630.     SUB      BL,AL               ; x2 = x2-x1
  1631.     INC      BL                  ; ADD 1 LINE
  1632.     MOV         [BP+X],BL            ; KEEP IT SOMEWHERE SAFE
  1633. ;
  1634. ;  cALculate screen offset  = 160*x1+2*y1;
  1635. ;
  1636. ;   AL has topl in it
  1637.     XOR     AH,AH
  1638.     MOV        BL,160
  1639.     MUL     BL                    ; HOW MANY CHARS IN X1 LINES, IN ax
  1640.     XOR     CH,CH
  1641.     MOV        CL,LEFTC            ; CHARS TO LEFT siDE
  1642.     SHL     CL,1                ; *2 COUNTS ATTRIBUTES
  1643.     ADD     AX,CX               ; add them
  1644.     MOV        DI,AX               ; place INTo source index
  1645. ;
  1646. ;  find number of characters to move each time
  1647. ;
  1648.     MOV         CL,RIGHTC
  1649.     SUB      CL,LEFTC            ; Y2 = Y2-Y1
  1650.     INC      CL                  ;  add 1
  1651.     MOV         [BP+X+1],CL            ; safe place again
  1652. ;
  1653. ;  find number to add to wrap around fOR each line
  1654. ;
  1655.     MOV     BL,CL               ; # of chars moved each time
  1656.     SHL     BL,1                ; chars*2
  1657.     MOV     AL,160
  1658.     SUB     AL,BL               ; 160-chars*2
  1659.     MOV     [BP+X+2],AL         ; safe place to keep it
  1660. ;
  1661. ;
  1662. ifdef CHECK_FOR_REFRESH
  1663.     MOV         AX,REGEN            ; screen will receive this data
  1664.     MOV         ES,AX
  1665.     POP      DS                    ; set DS to where data is coming from 
  1666.     MOV         DX,03DAH            ; COLor CARD STATUS PorT
  1667.     XOR      BH,BH
  1668.     MOV         BL,[BP+X]           ; howmany lines to move
  1669.     CMP      AX,0B000H           ; check fOR mono card
  1670.     JNZ     RGETLINE
  1671.     MOV         DX,03BAH              ; change status pORt vALue
  1672. RGETLINE:
  1673.     MOV         CL,[BP+X+1]            ; # of chars to move
  1674. RGETCHAR:
  1675.     IN       AL,DX               ; GET STATUS BYTE
  1676.     TEST     AL,1                ; hORizontAL retrace
  1677.     JNZ      RGETCHAR            ; NOT THERE YET
  1678. RISON:
  1679.     IN       AL,DX
  1680.     TEST     AL,1
  1681.     JZ       RISON               ; STILL ON, TRY AGAIN
  1682.     MOVSW                       ; NOW IS TIME, MOVE THE WorD
  1683.     LOOP     RGETCHAR            ; DO ANOTHER UNTIL THIS LINE IS DONE
  1684. else
  1685.     MOV         AX,REGEN            ; screen will receive this data
  1686.     MOV         ES,AX
  1687.     POP      DS                    ; set DS to where data is coming from 
  1688. ;    MOV         DX,03DAH            ; COLor CARD STATUS PorT
  1689.     XOR      BH,BH
  1690.     MOV         BL,[BP+X]           ; howmany lines to move
  1691. ;    CMP      AX,0B000H           ; check fOR mono card
  1692. ;    JNZ     RGETLINE
  1693. ;    MOV         DX,03BAH              ; change status pORt vALue
  1694. RGETLINE:
  1695.     XOR        CH,CH
  1696.     MOV         CL,[BP+X+1]            ; # of chars to move
  1697. RGETCHAR:
  1698. ;   IN       AL,DX               ; GET STATUS BYTE
  1699. ;   TEST     AL,1                ; hORizontAL retrace
  1700. ;   JNZ      RGETCHAR            ; NOT THERE YET
  1701. ;RISON:
  1702. ;    IN       AL,DX
  1703. ;   TEST     AL,1
  1704. ;   JZ       RISON               ; STILL ON, TRY AGAIN
  1705. ;    MOVSW                       ; NOW IS TIME, MOVE THE WorD
  1706. ;    LOOP     RGETCHAR            ; DO ANOTHER UNTIL THIS LINE IS DONE
  1707.     REP        MOVSW                ; move all the words
  1708. endif
  1709. ;
  1710.     DEC     BX
  1711.     JZ      RENDKEEP            ; DONE, WE ARE OUT OF HERE
  1712.     MOV        AL,[BP+X+2]
  1713.     XOR        AH,AH
  1714.     ADD     DI,AX               ; go to next line, skip 160-n*2 bytes
  1715.     JMP     RGETLINE
  1716. RENDKEEP:
  1717.     POP        DI
  1718.     POP        SI
  1719.     POP      DS
  1720.     MOV        DH,ROW                ; LOAD STorED CURSor POsiTION
  1721.     MOV        DL,COL
  1722.        MOV         AH,2H
  1723.        XOR     BX,BX
  1724.     INT      10H                 ; SET CURSor POsiTION TO SAVED ValUE
  1725.     POP      ES
  1726.     POP      BP
  1727.     RET
  1728. ifdef Microsoft
  1729. _n_restwin    endp
  1730. else
  1731. n_restwin    endp
  1732. endif
  1733.  
  1734. ;************************************************************************
  1735. ;  n_puts
  1736. ;  Window-compatible puts, uses n_putchar and ALso translates
  1737. ;  \n to CRLF
  1738. ;
  1739. ;     usage:  identicAL to puts()
  1740. ;
  1741. ifdef Microsoft
  1742. _n_puts    proc    far
  1743. else
  1744. n_puts    proc    far
  1745. endif
  1746.     PUSH    BP
  1747.     MOV        BP,SP
  1748. NEXTC:
  1749.     PUSH    DS
  1750.     MOV        DX,[BP+X+2]            ; ds OF STRING
  1751.     MOV        DS,DX
  1752.     MOV        BX,[BP+X]            ; PTR TO STRING
  1753.     MOV        AL,[BX]                ; GET CHARACTER
  1754.     XOR        AH,AH                ; clear AH
  1755.     POP        DS
  1756.     OR        AL,AL                ; is it end of string?
  1757.     JZ        DONEST
  1758.     INC        WORD PTR [BP+X]        ; INCREMENT POintER For NEXT ONE
  1759.     CMP        AL,10                ; newline?
  1760.     JNZ        DOCHAR
  1761.     MOV        AL,13
  1762.     PUSH    AX
  1763. Ifdef Microsoft
  1764.     CALL    _N_PUTCHAR
  1765. Else
  1766.     CALL    N_PUTCHAR
  1767. endif
  1768.     POP        AX
  1769.     MOV        AX,10
  1770. DOCHAR:
  1771.     PUSH    AX
  1772. ifdef Microsoft
  1773.     CALL    _N_PUTCHAR
  1774. else
  1775.     CALL    N_PUTCHAR
  1776. endif
  1777.     POP        AX                    ; take off of the stack
  1778.     JMP        NEXTC
  1779. DONEST:
  1780.     MOV        AX,13                ; CR
  1781.     PUSH    AX
  1782. ifdef Microsoft
  1783.     CALL    _N_PUTCHAR
  1784. else
  1785.     CALL    N_PUTCHAR
  1786. endif
  1787.     POP        AX
  1788.     MOV        AX,10                ; LF
  1789.     PUSH    AX
  1790. ifdef Microsoft
  1791.     CALL    _N_PUTCHAR
  1792. else
  1793.     CALL    N_PUTCHAR
  1794. endif
  1795.     POP        AX
  1796.     POP        BP
  1797.     RET
  1798. ifdef Microsoft
  1799. _n_puts    endp
  1800. else
  1801. n_puts    endp
  1802. endif
  1803.  
  1804. ;**********************************************************************
  1805. ;
  1806. ;  find first
  1807. ;    make dos find file names accORDIng to wildcarDS
  1808. ;  n_findfirst(filename,attr)
  1809. ;    char *filename; INT attr;
  1810. ;
  1811. ifdef Microsoft
  1812. _n_findfirst    proc    far
  1813. else
  1814. n_findfirst        proc    far
  1815. endif
  1816.     PUSH    BP
  1817.     MOV        BP,SP
  1818.     PUSH    ES
  1819.     PUSH    DS
  1820.     MOV        AH,02FH                ; dos FUNCTION GET dta
  1821.     INT        21H
  1822. ifdef Microsoft
  1823.     MOV     _DTAPTR,BX            ; SQUIRREL A COPY For ME
  1824.     MOV        AX,ES
  1825.     MOV     _DTADS,AX
  1826. else
  1827.     MOV        DTAPTR,BX            ; SQUIRREL A COPY For ME
  1828.     MOV        AX,ES
  1829.     MOV        DTADS,AX
  1830. endif
  1831.     MOV        AX,[BP+X+2]            ; ds OF FILENAME PTR
  1832.     MOV        DS,AX
  1833.     MOV        DX,[BP+X]            ; PTR PART OF FILENAME
  1834.     MOV        CX,[BP+X+4]            ; ATTRIBUTE TO SEARCH For
  1835.     MOV        AH,04EH                ; FIND MATCHING FILE dos CalL
  1836.     INT        21H
  1837.     JC        BADRET                ; ax alREADY CONTAINS ERRor CODE
  1838.     XOR        AX,AX
  1839. BADRET:
  1840.     POP        DS
  1841.     POP        ES
  1842.     POP        BP
  1843.     RET
  1844. ifdef Microsoft
  1845. _n_findfirst    endp
  1846. else
  1847. n_findfirst    endp
  1848. endif
  1849. ;
  1850. ;  n_findnext()
  1851. ;  will find entries that follow findfirst
  1852. ;  no need to respecify file name
  1853. ;
  1854. ifdef Microsoft
  1855. _n_findnext    proc    far
  1856. else
  1857. n_findnext    proc    far
  1858. endif
  1859.     PUSH    BP
  1860.     MOV        AH,04FH                ; FIND NEXT dos CalL
  1861.     INT        21H
  1862.     JC        NBADRET
  1863.     XOR        AX,AX
  1864. NBADRET:
  1865.     POP        BP
  1866.     RET
  1867. ifdef Microsoft
  1868. _n_findnext    endp
  1869. else
  1870. n_findnext    endp
  1871. endif
  1872. ;
  1873. ;  get the number of timer clicks from BIOS
  1874. ;
  1875. ifdef Microsoft
  1876. _n_clicks  proc    far             ; must be declared long n_clicks()
  1877. else
  1878. n_clicks  proc    far             ; must be declared long n_clicks()
  1879. endif
  1880.     MOV        AH,0
  1881.     INT        1AH
  1882. ifdef Microsoft
  1883.     MOV        AX,DX                ; msc USES ax-LO, dx-HI
  1884.     MOV        DX,CX                ; return vALues from INTerrupt 1A
  1885. else
  1886.     MOV        AX,CX                ; Lattice uses AX-hi, BX-lo
  1887.     MOV        BX,DX                ; Lattice returns in BX, MSC in DX and switched
  1888. endif
  1889.     RET
  1890. ifdef Microsoft
  1891. _n_clicks endp
  1892. else
  1893. n_clicks endp
  1894. endif
  1895.  
  1896. ;
  1897. ;    void fix_vid(void)
  1898. ;
  1899. ifdef Microsoft
  1900. _fix_vid proc far
  1901. else
  1902. fix_vid proc far
  1903. endif
  1904.  
  1905.     push es
  1906.  
  1907.     mov ax,0
  1908.     push ax
  1909.     pop es
  1910.     mov bx,410h
  1911.     mov al,es:[bx]        ; get equipment flags
  1912.     and al,0ch
  1913.     cmp al,3
  1914.     je done_vid_fix                ; if mono, we don't do anything
  1915.  
  1916.     mov ax,40h
  1917.     push ax
  1918.     pop es
  1919.     mov bx,89h
  1920.     mov al,es:[bx]        ; get VDD flag byte
  1921.     and al,0fdh            ; Make sure bit 1 (gray scale summing enable)
  1922.                                 ;   is UNSET
  1923.     mov es:[bx],al    ; put new flag byte in VDD 
  1924.  
  1925.     mov ah,0fh
  1926.     int 10h                        ; get current mode
  1927.     xor ah,ah
  1928.     int 10h                        ; reset current mode (new flags take affect)
  1929.  
  1930. done_vid_fix:
  1931.     pop es
  1932.     ret
  1933.  
  1934. ifdef Microsoft
  1935. _fix_vid endp
  1936. else
  1937. fix_vid endp
  1938. endif
  1939.  
  1940. ifdef Microsoft
  1941. _get_mode proc far
  1942. else
  1943. get_mode proc far
  1944. endif
  1945.  
  1946.     push bp
  1947.     mov bp,sp
  1948.  
  1949.     les bx,dword ptr [bp+6]
  1950.  
  1951.     mov word ptr [VIDSTATE],bx
  1952.     mov word ptr [VIDSTATE+2],es
  1953.     mov cx,7
  1954.     mov ax,1c01h
  1955.     int 10h
  1956.  
  1957.     pop bp
  1958.     ret
  1959.  
  1960. ifdef Microsoft
  1961. _get_mode endp
  1962. else
  1963. get_mode endp
  1964. endif
  1965.  
  1966.  
  1967. ifdef Microsoft
  1968. _set_mode proc far
  1969. else
  1970. set_mode proc far
  1971. endif
  1972.  
  1973.     mov es,word ptr [VIDSTATE+2]
  1974.     mov bx,word ptr [VIDSTATE];
  1975.     mov ax,1c02h
  1976.     int 10h
  1977.  
  1978.     ret
  1979.  
  1980. ifdef Microsoft
  1981. _set_mode endp
  1982. else
  1983. set_mode endp
  1984. endif
  1985.  
  1986. ifdef Microsoft
  1987. _get_size proc far
  1988. else
  1989. get_size proc far
  1990. endif
  1991.  
  1992.     mov ax,1c00h;
  1993.     mov cx,7
  1994.     int 10h
  1995.     mov ax,bx
  1996.     ret
  1997.  
  1998. ifdef Microsoft
  1999. _get_size endp
  2000. else
  2001. get_size endp
  2002. endif
  2003. ;-----------------------------------------------------------------
  2004.  
  2005. ifdef Microsoft
  2006. _TEXT    ENDS
  2007. else
  2008.     endps
  2009. endif
  2010.     end
  2011.