home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / ansi / avatar1.arj / AVATERM.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-08-16  |  22.5 KB  |  761 lines

  1. page    55, 132
  2. .model  SMALL
  3. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  4. ;;
  5. ;;      Copyright (C) 1990 G. Adam Stanislav
  6. ;;      All Rights Reserved
  7. ;;
  8. ;;      Purpose:
  9. ;;
  10. ;;      To show how AVATAR console can be accessed and used by
  11. ;;      communications programs.
  12. ;;
  13. ;;      AVATAR and AVATAR console are trademarks of
  14. ;;      G. Adam Stanislav and Stanislav Publishing
  15. ;;
  16. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  17.  
  18. ; Equates
  19.  
  20. FOSSIL          equ     14h
  21. MULTIVIDEO      equ     1Ah     ; Video function of MULTIPLEX
  22. DOS             equ     21h
  23. MULTIPLEX       equ     2Fh
  24. VIDEO           equ     29h
  25. KEYBOARD        equ     79h     ; AVATAR fastread interrupt
  26.  
  27. CURSOR          equ     08h     ; ^H
  28. CLS             equ     0Ch     ; ^L
  29. DLE             equ     10h     ; ^P
  30. AVTCODE         equ     16h     ; ^V
  31. WINSWITCH       equ     17h     ; ^W
  32. QUERY           equ     11h     ; ^Q
  33. RESETWINDOWS    equ     12h     ; ^R
  34. WAKE            equ     1Dh     ; GS
  35.  
  36. BEL             equ     07h     ; beep
  37. LF              equ     0Ah     ; line feed
  38. CR              equ     0Dh     ; carriage return
  39. EOS             equ     24h     ; end of string ('$')
  40.  
  41. SHIFT_F1        equ     54h     ; Shift-F1 scan code
  42.  
  43. ; macros
  44.  
  45. VERSION         macro
  46.  
  47.         db      "1.03"
  48.  
  49. endm
  50.  
  51. page
  52. .data
  53.  
  54. comport         dw      0       ; This is COM1. Change it as needed.
  55.  
  56. notice          db      LF, "AVATERM, version "
  57.                 VERSION
  58.                 db      CR, LF
  59.                 db      "Copyright (C) 1990 G. Adam Stanislav.", CR, LF
  60.                 db      "All Rights Reserved.", CR, LF, LF
  61.                 db      "AVATAR and AVATAR console are trademarks of", CR, LF
  62.                 db      "G. Adam Stanislav and Stanislav Publishing."
  63.                 db      CR, LF, LF, EOS
  64. fatalmsg        db      "Fatal error: ", BEL, EOS
  65. nofosmsg        db      "FOSSIL not loaded or accessible.", CR, LF, EOS
  66. noavtcon        db      "AVATAR console not loaded.", CR, LF, EOS
  67.  
  68. ; Save the original state of AVATAR console in a buffer, so you can restore
  69. ; it when exiting.
  70. origcount       dw      oslen
  71. origstate       db      32 dup (0)
  72. oslen           equ     $-origstate
  73. origcursor      db      8  dup(0)
  74. ocurlen         equ     $-origcursor
  75.  
  76. ; This is what we want to set the driver to: 'a'ctive and converting 'g'ray
  77. ; keys all the time.
  78.  
  79. activate        db      'ag'   ; Activate, gray-keys on.
  80. actlen          equ     $-activate
  81.  
  82. ; Query the original wake state of the AVATAR console.
  83.  
  84. wakequery       db      AVTCODE, QUERY, WAKE
  85. wqlen           equ     $-wakequery
  86.  
  87. ; Save the original wake state
  88.  
  89. origwake        db      AVTCODE, WAKE   ; Just in case there is no reply.
  90. owlen           equ     $-origwake
  91.  
  92. ; Ask the cursor position
  93. cursorquery     db      AVTCODE, QUERY, CURSOR
  94. curqlen         equ     $-cursorquery
  95.  
  96. ; Wake up the interpreter, reset the windows, clear the screen.
  97. wakeupmsg       db      AVTCODE, WAKE
  98.                 db      AVTCODE, RESETWINDOWS
  99.                 db      CLS
  100. wumlen          equ     $-wakeupmsg
  101.  
  102. ; Query the driver for its version.
  103. versionquery    db      AVTCODE, QUERY, QUERY
  104. vqlen           equ     $-versionquery
  105.  
  106. ; Reset all AVATAR windows to their default values.
  107. resetmsg        db      AVTCODE, RESETWINDOWS
  108. resetlen        equ     $-resetmsg
  109.  
  110. ; Help message
  111. helpmsg         db      CR, LF, LF
  112.                 db      "Press Shift-F1 to hang up", CR, LF
  113.                 db      "or to quit.", CR, LF, LF, EOS
  114.  
  115. ; Switch to raw parser mode. If we call an AVT/0 system,
  116. ; that is the state we need to be in. If, on the other hand,
  117. ; we call an AVT/1 system, chances are it will start by issuing the
  118. ; reset command which will switch us to cooked mode.
  119. ;
  120. ; By the same token, we emulate an AVT/0 window. Let's call it
  121. ; window 'E' for Emulate. Remember that 'E' is really an ASCII
  122. ; number somewhere between 0-255, so it is an acceptable window
  123. ; handle. We will make it default to cyan color attribute as
  124. ; required by AVT/0 specs. We will make it cover the entire screen.
  125. ; An apparent problem is that we do not know what size the screen is.
  126. ; We could figure it out by querying window 0, which is always full
  127. ; screen. But there is an easier way. Obviously, upper left corner
  128. ; is at 1, 1. It is the lower right corner we do not know.
  129. ;
  130. ; But AVATAR console always compares the requested window size with
  131. ; the actual physical size of the screen. If the requested size is too
  132. ; big, AVATAR console will automatically shrink the request to fit
  133. ; within the available screen size.
  134. ;
  135. ; Thus, if we request the lower left corner to be -1, -1 (which is the
  136. ; same as the highest possible unsigned integer, as far as the computer
  137. ; is concerned), we will be well past the limit. AVATAR console will
  138. ; shrink our request. The result: Window 'E' covers the full screen.
  139. ;
  140. ; Once we have defined 'E' window, we switch in it. With raw parser
  141. ; mode, cyan default attribute and full screen, we are AVT/0 compatible.
  142. ; If we happen to be calling an AVT/1 system, this one will issue the
  143. ; reset command, and presto we are operating at AVT/1 level.
  144.  
  145. rawmode         db      AVTCODE, "=R"
  146.                 db      AVTCODE, AVTCODE, 'E'   ; define window 'E'
  147.                 db      3                       ; cyan
  148.                 db      1, 1                    ; upper left corner
  149.                 db      -1, -1                  ; lower left corner
  150.                 db      AVTCODE, WINSWITCH, 'E'
  151. rawmodelen      equ     $-rawmode
  152.  
  153. ; Hang up message.
  154. hangupmsg       db      CR, LF, CR, LF
  155.                 db      "Hanging up. Do you also want to quit? [y/N] ", EOS
  156.  
  157. yesmsg          db      "Yes.", CR, LF, LF
  158.                 db      "Bye-bye.", CR, LF, LF, EOS
  159.  
  160. nomsg           db      "No, not yet!", CR, LF, LF, EOS
  161.  
  162. page
  163. .code
  164.  
  165. ; Routines to check/set the state of AVATAR console, either via
  166. ; AVATAR codes or direct driver manipulation:
  167.  
  168.  
  169. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  170. ;;
  171. ;;      Check for the presence of AVATAR console.
  172. ;;      If found, save its current state and return no carry.
  173. ;;      Else, return carry.
  174. ;;
  175. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  176. AVT_check:
  177.  
  178.         ; First, check if the driver is loaded at all
  179.         mov     ax, 1A00h
  180.         mov     bx, 'AV'
  181.         mov     cx, 'AT'
  182.         mov     dx, 'AR'
  183.         int     MULTIPLEX
  184.  
  185.         ; See if there is *any* CON driver at all. If so, AL = -1
  186.         inc     al
  187.         jne     AVT_check_CY    ; Probably no CON driver loaded.
  188.                                 ; Definitely no AVATAR CON driver.
  189.  
  190.         ; There is something there, see if it is AVATAR console
  191.         cmp     dx, AVTCODE
  192.         jne     AVT_check_CY    ; Nope, it is some other driver.
  193.  
  194.         ; AVATAR console is there. Save its original state.
  195.         mov     cx, origcount
  196.         lea     di, origstate
  197.  
  198.         mov     ax, (MULTIVIDEO shl 8) or '?'   ; Query the device driver
  199.         int     MULTIPLEX
  200.         jc      AVT_check_CY    ; Something's wrong!
  201.         mov     origcount, cx   ; save the size of the reply
  202.  
  203.         ; Activate the driver. Make it convert gray keys to 0 plus scan code.
  204.         mov     ax, (MULTIVIDEO shl 8) or '!'   ; Command the driver
  205.         mov     cx, actlen
  206.         lea     si, activate
  207.         int     MULTIPLEX
  208.         jc      AVT_check_CY    ; Something's wrong again
  209.  
  210.         clc                     ; clear carry flag
  211.         ret
  212.  
  213.  
  214. AVT_check_CY:
  215.         stc
  216.         ret
  217.  
  218. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  219. ;;
  220. ;;      Restore the state of AVATAR con as it was before we came in.
  221. ;;
  222. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  223. AVT_restore:
  224.         mov     cx, origcount
  225.         lea     si, origstate
  226.  
  227.         mov     ax, (MULTIVIDEO shl 8) or '!'   ; send a command to driver
  228.         int     MULTIPLEX
  229.  
  230.         ret
  231.  
  232. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  233. ;;
  234. ;;      Wake up the AVT interpreter, if asleep, after saving its state.
  235. ;;      Also reset all windows to their defaults and clear the screen.
  236. ;;
  237. ;;      If the AVATAR keyboard is functional, read and display
  238. ;;      the driver version.
  239. ;;
  240. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  241. AVT_wakeup:
  242.         ; First query its sleep state
  243.         mov     cx, wqlen
  244.         lea     si, wakequery
  245.         call    AVT_print
  246.  
  247.         ; Read and save the reply.
  248.         int     KEYBOARD        ; This is a faster alternative to DOS.
  249.                                 ; It returns carry and AX=FFFF if no char is
  250.                                 ; pending for input. Otherwise, it returns
  251.                                 ; no carry and character in AX (AH=0).
  252.         jc      AVT_wakeup_RET  ; Nothing there, return to caller.
  253.  
  254.         cmp     al, AVTCODE     ; Make sure it is a reply.
  255.         jne     AVT_wakeup_RET  ; An artifact. Ignore it.
  256.  
  257.         int     KEYBOARD        ; Read the state.
  258.         mov     origwake[1], al ; Save it.
  259.  
  260.         call    driver_version
  261.  
  262. AVT_wakeup_RET:
  263.         ret
  264.  
  265. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  266. ;;
  267. ;;      Restore the original state of the interpreter.
  268. ;;
  269. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  270. int_restore:
  271.         mov     cx, owlen
  272.         lea     si, origwake    ; Write the string returned by initial query.
  273.         call    AVT_print
  274.         ret
  275.  
  276. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  277. ;;
  278. ;;      Query the driver for its version. Display the reply.
  279. ;;
  280. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  281. driver_version:
  282.         ; First, send the query to the driver.
  283.         mov     cx, vqlen
  284.         lea     si, versionquery
  285.         call    AVT_print
  286.  
  287.         ; Now read the reply and print it. Do so until the character
  288.         ; read and printed is a CR.
  289. dr_ver_print:
  290.         int     KEYBOARD        ; Read a character,
  291.         int     VIDEO           ; write it,
  292.         cmp     al, CR          ; check if it is the last one.
  293.         jne     dr_ver_print    ; If it is not, read some more.
  294.  
  295.         ; Print two line feeds.
  296.         mov     al, LF
  297.         int     VIDEO
  298.         mov     al, LF
  299.         int     VIDEO
  300.  
  301.         ; Return to the caller.
  302.         ret
  303.  
  304. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  305. ;;
  306. ;;      Emulate AVT/0. See detailed discussion in DATA section above.
  307. ;;
  308. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  309. emulate:
  310.         mov     cx, curqlen
  311.         lea     si, cursorquery
  312.         call    AVT_print               ; find cursor position
  313.         sub     cx, cx                  ; initialize counter
  314.         lea     di, origcursor
  315.  
  316. emuloop:
  317.         int     KEYBOARD
  318.         jc      outofemuloop
  319.         stosb
  320.         inc     cx
  321.         cmp     cx, ocurlen
  322.         jb      emuloop
  323.  
  324. outofemuloop:
  325.         push    cx
  326.  
  327.         mov     cx, rawmodelen
  328.         lea     si, rawmode
  329.         call    AVT_print
  330.  
  331.         pop     cx
  332.         jcxz    emuret
  333.         lea     si, origcursor
  334.         ; At this point *we* are in raw mode, but the information at
  335.         ; origcursor is pre-cooked. We have to un-cook it if need be.
  336.         lodsb
  337.         int     VIDEO   ; presumably AVTCODE
  338.         dec     cx
  339.         jcxz    emuret
  340.         lodsb
  341.         int     VIDEO   ; presumably CURSOR
  342.         dec     cx
  343.         jcxz    emuret
  344.         lodsb
  345.         dec     cx
  346.         cmp     al, DLE
  347.         jne     emu_1
  348.         jcxz    emuret
  349.         lodsb
  350.         and     al, 1Fh ; turn to raw code
  351.  
  352. emu_1:
  353.         int     VIDEO
  354.         dec     cx
  355.         jcxz    emuret
  356.         lodsb
  357.         cmp     al, DLE
  358.         jne     emu_2
  359.         lodsb
  360.         and     al, 1Fh
  361.  
  362. emu_2:
  363.         int     VIDEO
  364.  
  365. emuret:
  366.         ret
  367.  
  368. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  369. ;;
  370. ;;      Reset all AVATAR windows to their default values.
  371. ;;
  372. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  373. AVT_reset:
  374.         mov     cx, resetlen
  375.         lea     si, resetmsg
  376.         call    AVT_print
  377.         ret
  378.  
  379. page
  380. ; Console (via AVATAR) input and output routines:
  381.  
  382.  
  383. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  384. ;;
  385. ;;      Print a string at DS:SI of CX bytes to AVATAR console
  386. ;;
  387. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  388. AVT_print:
  389.         ; Get the first (or next) character.
  390.         lodsb                   ; Load byte from buffer.
  391.         int     VIDEO           ; print character
  392.  
  393.         ; Continue printing in a loop until all characters of the
  394.         ; string are printed.
  395.         loop    AVT_print
  396.  
  397.         ; When you come here, the printing is done. Return to the caller.
  398.         ret
  399.  
  400. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  401. ;;
  402. ;;      Print an individual character in AL. Cook it if necessary.
  403. ;;
  404. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  405. putchar:
  406.         int     VIDEO
  407.         ret
  408.  
  409. page
  410. ; Communications routines via FOSSIL driver:
  411.  
  412. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  413. ;;
  414. ;;      Check for the presence of a FOSSIL driver. Raise DTR.
  415. ;;
  416. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  417. find_fossil:
  418.         mov     ah, 04h
  419.         mov     dx, comport
  420.         int     FOSSIL
  421.  
  422.         cmp     ax, 1954h       ; This will be there if FOSSIL is loaded.
  423.         jne     find_fossil_CY
  424.  
  425.         clc                     ; return success as no carry
  426.         ret
  427.  
  428. find_fossil_CY:
  429.         stc                     ; return failure in carry flag
  430.         ret
  431.  
  432. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  433. ;;
  434. ;;      Tell the FOSSIL we are leaving
  435. ;;
  436. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  437. bye_fossil:
  438.         mov     ah, 05h
  439.         mov     dx, comport
  440.         int     FOSSIL
  441.         ret
  442.  
  443. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  444. ;;
  445. ;;      Check if a byte arrived at the modem
  446. ;;
  447. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  448. mdmcheck:
  449.         mov     ah, 0Ch
  450.         mov     dx, comport
  451.         int     FOSSIL
  452.  
  453.         ; returns AX = -1 if nothing available
  454.         inc     ax
  455.         ret
  456.  
  457. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  458. ;;
  459. ;;      Read a byte from modem.
  460. ;;
  461. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  462. getbyte:
  463.         mov     ah, 02h
  464.         int     FOSSIL
  465.         ret
  466.  
  467. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  468. ;;
  469. ;;      Send a byte in AL to the modem.
  470. ;;
  471. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  472. putbyte:
  473.         mov     ah, 01h
  474.         mov     dx, comport
  475.         int     FOSSIL
  476.         ret
  477.  
  478. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  479. ;;
  480. ;;      Hang up the phone.
  481. ;;
  482. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  483. hang_up:
  484.         ; Lower DTR.
  485.         mov     ax, 0600h
  486.         mov     dx, comport
  487.         int     FOSSIL
  488.  
  489.         ; Create a minimal delay.
  490.         jmp     $+2
  491.  
  492.         ; Check for CD
  493.         mov     ah, 03h
  494.         mov     dx, comport
  495.         int     FOSSIL
  496.         test    al, 80h
  497.         jne     hang_up
  498.  
  499.         ; Raise DTR again.
  500.         mov     ax, 0601h
  501.         mov     dx, comport
  502.         int     FOSSIL
  503.  
  504.         ; Reset the Avatar driver.
  505.         call    AVT_reset
  506.  
  507.         ; Switch to AVT/0 emulation.
  508.         call    emulate
  509.  
  510.         ; Return to the caller.
  511.         ret
  512.  
  513. page
  514. ; The main section of the program
  515.  
  516. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  517. ;;
  518. ;;      This is where the program starts its execution. Check and
  519. ;;      set up everything conceivable.
  520. ;;
  521. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  522. begin:
  523.         call    disable_ctlC
  524.  
  525.         mov     ax, _data
  526.         mov     ds, ax
  527.         mov     es, ax
  528.  
  529.         ; We are calling AVT_check before saying hello. Otherwise,
  530.         ; AVT_check would erase our greetings. So, we call this first,
  531.         ; save the result (PUSHF) and restore it (POPF) after hello
  532.  
  533.         call    AVT_check
  534.         pushf
  535.  
  536.         ; say hello
  537.         mov     ah, 09h
  538.         lea     dx, notice
  539.         int     DOS
  540.  
  541.         popf
  542.         jc      no_AVATAR
  543.  
  544.         call    find_fossil
  545.         jc      no_fossil
  546.  
  547.         call    AVT_wakeup
  548.  
  549.         call    help
  550.  
  551.         call    emulate
  552.  
  553.         call    terminal
  554.  
  555.         call    cleanup
  556.  
  557.         ; exit to DOS with errorlevel = 0
  558.         mov     ax, 4C00h
  559.         int     DOS
  560.  
  561. no_fossil:
  562.         call    fatal
  563.         mov     ah, 09h         ; print warning message
  564.         lea     dx, nofosmsg
  565.         int     DOS
  566.  
  567.         ; exit with errorlevel = 1
  568.         mov     ax, 4C01h
  569.         int     DOS
  570.  
  571. no_AVATAR:
  572.         call    fatal
  573.         mov     ah, 09h         ; print warning message
  574.         lea     dx, noavtcon
  575.         int     DOS
  576.  
  577.         ; exit with errorlevel =2
  578.         mov     ax, 4C02h
  579.         int     DOS
  580.  
  581. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  582. ;;
  583. ;;      This is the terminal itself. It is a simple loop which checks
  584. ;;      the keyboard for any keystrokes and modem input.
  585. ;;
  586. ;;      The keystrokes are sent to the modem with the exception of
  587. ;;      Shift-F1 which AVATAR PC keyboard emulator saves for the use
  588. ;;      of the terminal. We use it to hang up and to quit.
  589. ;;
  590. ;;      The modem input is sent to the console.
  591. ;;
  592. ;;      Obviously, in a full-fledged communications program you need
  593. ;;      much more activity to be going on. But this program is here
  594. ;;      only to demonstrate the use of AVATAR console with a terminal
  595. ;;      program.
  596. ;;
  597. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  598. terminal:
  599.  
  600.         int     KEYBOARD        ; See if a key was pressed. If so, read it.
  601.         jc      terminal_3
  602.  
  603.         ; A key was pressed. See what it is.
  604.         or      al, al          ; This means: if AL <> 0
  605.         jne     terminal_2
  606.  
  607.         ; A function key was received. Need further checking.
  608.         call    function_key
  609.         jc      terminal_out    ; This was the "quit" key.
  610.         jmp     short terminal_3
  611.  
  612. terminal_2:
  613.         call    putbyte         ; Send the character received out.
  614.  
  615. terminal_3:
  616.         call    mdmcheck        ; Anything in the modem?
  617.         jz      terminal        ; No, continue the loop
  618.  
  619.         ; Yes, receive and print it.
  620.         call    getbyte
  621.         call    putchar
  622.         jmp     terminal        ; Continue the loop.
  623.  
  624. terminal_out:                   ; Quit.
  625.         ret
  626.  
  627. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  628. ;;
  629. ;;      A function key was received. If it is Shift-F1, process it.
  630. ;;      Else, send it out.
  631. ;;
  632. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  633. function_key:
  634.         ; Receive the scan code from the AVATAR console /stdin
  635.         int     KEYBOARD
  636.         cmp     al, SHIFT_F1
  637.         je      function_key_1
  638.  
  639.         ; It is not a shift-F1. Send out a 0 followed by the scan code.
  640.         push    ax
  641.         sub     al, al          ; AL = AL - AL = 0 (These assembly language
  642.                                 ; programmers are weird. :-)
  643.         call    putbyte
  644.         pop     ax
  645.         call    putbyte
  646.         clc
  647.         ret
  648.  
  649. function_key_1:
  650.         ; A shift-F1 was pressed. First hang up.
  651.         call    hang_up
  652.  
  653.         ; Now ask if we should quit
  654.         mov     ah, 09
  655.         lea     dx, hangupmsg
  656.         int     DOS
  657.  
  658.         ; Get the answer. Loop if necessary.
  659. function_key_2:
  660.         mov     ax, 0C07h       ; Clear the input buffer. Then read.
  661.         int     DOS
  662.  
  663.         ; See what you got
  664.         cmp     al, CR
  665.         je      function_key_NO
  666.  
  667.         cmp     al, 'n'
  668.         je      function_key_NO
  669.  
  670.         cmp     al, 'N'
  671.         je      function_key_NO
  672.  
  673.         cmp     al, 'y'
  674.         je      function_key_YES
  675.  
  676.         cmp     al, 'Y'
  677.         je      function_key_YES
  678.  
  679.         ; Check for smart allecks here:
  680.         cmp     al, LF
  681.         jne     function_key_2          ; Try again
  682.  
  683. function_key_NO:
  684.         ; print "No", clear carry and return
  685.         mov     ah, 09h
  686.         lea     dx, nomsg
  687.         int     DOS
  688.         clc
  689.         ret
  690.  
  691. function_key_YES:
  692.         ; Print "Yes", set carry and return
  693.         mov     ah, 09h
  694.         lea     dx, yesmsg
  695.         int     DOS
  696.         stc
  697.         ret
  698.  
  699. page
  700. ; System support routines
  701.  
  702. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  703. ;;
  704. ;;      Disable ^C break.
  705. ;;
  706. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  707. disable_ctlC:
  708.         mov     ax, 2523h       ; set vector for int 23h
  709.         lea     dx, dummy_interrupt
  710.         push    cs
  711.         pop     ds
  712.         int     DOS
  713.         ret
  714.  
  715. dummy_interrupt:
  716.         iret
  717.  
  718. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  719. ;;
  720. ;;      Print fatal error message
  721. ;;
  722. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  723. fatal:
  724.         mov     ah, 09h
  725.         lea     dx, fatalmsg
  726.         int     DOS
  727.         ret
  728.  
  729. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  730. ;;
  731. ;;      Print initial help message
  732. ;;
  733. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  734. help:
  735.         mov     ah, 09h
  736.         lea     dx, helpmsg
  737.         int     DOS
  738.         ret
  739.  
  740. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  741. ;;
  742. ;;      Restore all defaults
  743. ;;
  744. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  745. cleanup:
  746.         call    AVT_reset               ; This will also set the cooked mode.
  747.         call    int_restore
  748.         call    AVT_restore
  749.         call    bye_fossil
  750.         ret
  751.  
  752.         ; N.B. There is no need to restore the original ^C handler.
  753.         ; DOS will take care of it for us.
  754.  
  755. .stack
  756.  
  757.         dw      512 dup(1990h)
  758.  
  759. end     begin
  760.  
  761.