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