home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / UTILITY / SCREEN / ZAVT11.ZIP / ZAVT_K.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-05-28  |  12.7 KB  |  505 lines

  1. ;------ zavt_k.asm ----------------------------------------------
  2. ; Zephyr Avatar terminal driver.
  3. ;    Copyright (C) 1989-1990, Luns Tee, Toronto ON.
  4. ;    Based on original code by Charles Petzold
  5. ;
  6. ; Revision History:
  7. ;------------------------------------------------------------------------
  8. ;  Luns Tee, Toronto, Ontario
  9. ;  28 Feb 1990;    Personal hack of DOS-EDIT taken and modified for use
  10. ;        in ZAVT.
  11. ;
  12. ;  12 May 1990; Pseudocursor support extended here
  13. ;------------------------------------------------------------------------
  14.  
  15.     include    zavt_d.asm        ; get equates
  16.  
  17.  
  18.     ; to zavt.asm
  19.     public    getchar, peekchar
  20.  
  21.     ; from zavt.asm
  22.  
  23. if    fullscreen            ; nothing needed if no full-screen ed.
  24.     extrn    scrnbuf:keybuf, linebufend:abs, linebuf:abs
  25.     extrn    max_x:byte, cur_coords:word
  26.     extrn    cur_x:byte, cur_y:byte
  27.     extrn    gmode_flag:byte
  28.     extrn    cur_attrib:byte
  29.     extrn    pseudo_flag:byte
  30. endif
  31.     extrn    fnkey:keybuf, fnkeybuf:byte
  32. if    xlate
  33.     extrn    xlatseq:keybuf
  34.     extrn    redef_end:abs, param_end:word
  35. endif
  36.  
  37. code    segment byte public 'CODE'
  38.     assume    cs:code, ds:code, es:code
  39.  
  40.  
  41. if    fullscreen            ; nothing needed if no full-screen ed.
  42.  
  43. ;    All Data
  44. ;    --------
  45.  
  46. InsertOn    db    0        ; Insert mode flag
  47. KeyRoutine    dw    Home,Up,PgUp,Dummy,Left,Dummy,Right
  48.         dw    Dummy,End,Down,PgDn,Insert,Delete
  49. endif
  50.  
  51. ;---- lookup -----------------------------------------------
  52. ; Called by getchar, peekchar, and key to see if a given key has
  53. ; been redefined.
  54. ; Sets AH to zero if AL is not zero (i.e. if AX is not a function key).
  55. ; Returns with Z cleared if no redefinition; otherwise,
  56. ; Z is set, SI points to redefinition string, CX is its length.
  57. ; Preseves AL, all but CX and SI.
  58. ; Redefinition table organization:
  59. ; redef_end points to the last word used by the redef table.
  60. ;  the highest word is the length of the string sans header;
  61. ;  the word following is the character to be replaced;
  62. ;  the string follows with the last character highest;
  63. ; param_end points to the last byte used by the parameter buffer.
  64.  
  65.     if    xlate
  66.     public    lookup
  67.  
  68. lookup    proc    near
  69.     mov    si, redef_end        ; Start at end of table, move down.
  70.     or    al, al
  71.     jz    lu_lp
  72.     xor    ah, ah            ; clear extraneous scan code
  73. lu_lp:    cmp    si, param_end
  74.     jbe    lu_notfound        ; If below redef table, exit.
  75.     mov    cx, [si]
  76.     cmp    ax, [si-2]        ; are you my mommy?
  77.     jz    lu_gotit
  78.     sub    si, 4
  79.     sub    si, cx            ; point to next header
  80.     jmp    lu_lp
  81. lu_notfound:
  82.     or    si, si            ; clear Z
  83.     ret
  84.  
  85. lu_gotit:
  86.     sub    si, 3            ; point to last char of string
  87.     cmp    al, al            ; set Z
  88.     ret
  89. lookup    endp
  90.  
  91.     endif
  92.  
  93. ;---- searchbuf --------------------------------------------
  94. ; Called by getchar and peekchar to see if any characters are
  95. ; waiting to be gotten from sources other than BIOS.
  96. ; Returns with Z set if no chars found, BX=keybuf & SI=keybuf.len otherwise.
  97. assume    ds:code
  98. searchbuf    proc    near
  99.     ; Search the stuffahead buffers.
  100.     mov    cx,3 - fullscreen - xlate ; number of buffers to check for chars
  101.     mov    bx,offset fnkey - 4
  102. sbloop: add    bx,4            ; point to next buffer record
  103.     mov    si,[bx].len
  104.     or    si,si            ; empty?
  105.     loopz    sbloop            ; if so, loop.
  106.     ret
  107. searchbuf    endp
  108.  
  109.  
  110. ;---- peekchar -----------------------------------------------
  111. ; Returns Z if no character ready, AL=char otherwise.
  112. ; Trashes AX, BX, CX, SI.
  113. peekchar    proc    near
  114.     call    searchbuf
  115.     jz    pc_trykbd        ; No chars?  Try the keyboard.
  116.     ; A nonempty buffer was found.
  117.     dec    si
  118. pcdone:    neg    si
  119.     add    si, [bx].adr        ; get pointer to string
  120.     lodsb                ; get the char
  121.     ret
  122.  
  123. pc_brk: int    16h            ; get rid of control-break in buffer
  124.  
  125. pc_trykbd:
  126.     mov    ah,1
  127.     int    16h            ; BIOS returns with char in AX
  128.     jz    pcexit
  129.     or    ax,ax
  130.     jz    pc_brk    ; If ctl-brk, it's already been taken care of- kill it.
  131.  
  132.     if    xlate
  133.     ; Look in the reassignment table to see if it needs translation.
  134.     call    lookup            ; Z=found; CX=length; SI=ptr
  135.     jnz    pcexit            ; Nope; just return the char.
  136.     ; Okay; get the first code to be returned.
  137.     sub    si,cx
  138.     inc    si
  139.     lodsb
  140.     endif
  141.  
  142. pcexit: ret    ; with character in AL, Z true if no char waiting.
  143. peekchar    endp
  144.  
  145. ;---- getchar -----------------------------------------------
  146. ; Returns AL = next char.
  147. ; Trashes AX, BX, CX, SI.
  148.  
  149. getchar proc    near
  150.     ; See if any chars are waiting in stuffahead buffers.
  151.     call    searchbuf
  152.     jz    gc_trykbd        ; No chars?  Try the keyboard.
  153.     ; A nonempty buffer was found.
  154.     dec    si
  155.     mov    [bx].len,si
  156.  
  157.     if    xlate
  158.     neg    si
  159.     mov    bp, [bx].adr        ; get pointer to string
  160.     mov    ax, ds:[bp][si]        ; get the char
  161.     ; Recognize function key sequences, move them to highest priority
  162.     ; queue.
  163.     or    al, al
  164.     jnz    gcdone            ; nonzero first byte -> not fnkey.
  165.     or    si,si            ; set Z if si=0
  166.     jz    gcdone            ; no chars left -> nothing to protect.
  167.     dec    [bx].len
  168.  
  169.     if    fullscreen
  170.     or    ax,ax            ; full-screen routine wanted?
  171.     jz    screenedit        ; yes? no?
  172.     endif
  173.  
  174.     ; Valid char from buffer in AL.  Return with it through
  175.     ; code shared with peekchar
  176.     else
  177.     jmp    short pcdone
  178.     endif
  179.  
  180. gc_fnkey:                ;   yep, special treatment
  181.     mov    fnkey.len, 1
  182.     mov    fnkeybuf, ah        ; save it.
  183.  
  184. gcdone: ret    ; with character in AL.
  185.  
  186. gc_trykbd:
  187.     xor    ah,ah
  188.     int    16h            ; BIOS returns with char in AX
  189.     ; If it's Ctrl-Break, it has already been taken care of.
  190.     or    ax,ax
  191.     jz    gc_trykbd
  192.  
  193. gcbark:
  194.     if    xlate
  195.     ; Look in the reassignment table to see if it needs translation.
  196.     call    lookup            ; Z=found; CX=length; SI=ptr
  197.     jnz    gc_noredef
  198.     ; Okay; set up the reassignment, and run thru the translation code.
  199.     mov    xlatseq.len, cx
  200.     mov    xlatseq.adr, si
  201.     jmp    getchar
  202.     endif
  203. gc_noredef:
  204.     or    al,al            ; Is it a function key?
  205.     jnz    gcdone
  206.  
  207.     if    fullscreen and not xlate
  208.     cmp    ah,84h            ; Check if up cursor
  209.     jnz    gc_fnkey            ; If so, get something from screen
  210.     else
  211.     jmp    gc_fnkey
  212.     endif
  213. getchar endp
  214.  
  215. if    fullscreen            ; nothing needed if no full-screen ed.
  216.  
  217. ;    Full Screen Routine
  218. ;    -------------------
  219.  
  220. ScreenEdit    proc    near
  221.         push    es
  222.         push    di
  223.  
  224.         push    cs            ; Set ax to this segment
  225.         pop    es            ; And es is also
  226.  
  227.         mov    ah,0Fh            ; Get Video State
  228.         int    10h            ;   through BIOS
  229.         dec    ah            ; Number of columns on screen
  230.         mov    [max_x],ah        ; Save maximum column
  231.  
  232.         cbw
  233.         cmp    al,4
  234.         jb    text_mode
  235.         cmp    al,7
  236.         jz    text_mode
  237.         not    ah        
  238.  
  239. text_mode:    mov    gmode_flag,ah        ; BH = Page Number throughout
  240.         mov    ah, 3            ; Get cursor in dx
  241.         int    10h            ;   through BIOS
  242.         mov    [cur_coords],dx        ; And save the cursor position
  243.  
  244.         call    cursor            ; delete old pseudocursor
  245.         call    Up            ; Move cursor up    
  246.     
  247. MainLoop:    cmp    dh,[cur_y]        ; If at line
  248.         jz    TermFullScreen        ; we started from, terminate
  249.  
  250. GetKeyboard:    call    cursor            ; redraw pseudocursor
  251.         mov    ah,ch            ; Get the next key
  252.         int    16h
  253.  
  254.         push    ax
  255.         call    cursor            ; delete pseudocursor
  256.         pop    ax
  257.  
  258.         mov    bl,[cur_attrib]
  259.  
  260.         or    ah,ah            ; Alt-<num> input?
  261.         jz    PutOnScreen
  262.  
  263.         cmp    al,1Bh            ; See if Escape key
  264.         jz    TermFullScreen        ; If so, terminate full screen
  265.  
  266. ;    Back Space
  267. ;    ----------
  268.  
  269.         cmp    al,08h            ; See if back space
  270.         jnz    NotBackSpace        ; If not, continue test
  271.  
  272.         or    dl,dl            ; Check if cursor at left
  273.         jz    MainLoop        ; If so, do nothing    
  274.  
  275.         dec    dx            ; Otherwise, move cursor back
  276.         call    ShiftLeft        ; And shift line to the left
  277.  
  278.         jmp    MainLoop        ; And continue for next key
  279.  
  280. ;    Carriage Return
  281. ;    ---------------
  282.  
  283. NotBackSpace:    cmp    al,0Dh            ; See if Carriage Return
  284.         jnz    PutOnScreen        ; If not, continue test
  285.  
  286.         call    TransferLine        ; Move line into buffer
  287.  
  288.         inc    scrnbuf.len        ; Put trailing CR into
  289.         inc    scrnbuf.adr        ; buffer as well
  290.  
  291. ;    Terminate Full Screen Movement
  292. ;    ------------------------------
  293.  
  294. TermFullScreen:    mov    dx,[cur_coords]        ; Set cursor to original
  295.         call    cursor            ; draw pseudocursor
  296.  
  297.         pop    di
  298.         pop    es
  299.  
  300.         jmp    getchar
  301.  
  302. ;    Normal Character
  303. ;    ----------------
  304.  
  305. PutOnScreen:    or    al,al            ; See if normal character
  306.         jz    NotNormalChar        ; If not, continue test
  307.  
  308.         mov    ah,0Ah            ; By calling BIOS
  309.         add    ah,gmode_flag
  310.  
  311.         cmp    [InsertOn],ch        ; Check for Insert mode
  312.         jz    OverWrite        ; If not, overwrite 
  313.  
  314.         call    ShiftRight        ; Shift line right for insert
  315.         jmp    Short NormalCharEnd    ; And get ready to print
  316.  
  317. OverWrite:    int    10h
  318.     
  319. NormalCharEnd:    mov    ax,4d00h        ; stuff in a cursor-right
  320.                         ; and fall through
  321.  
  322. ;    Cursor Key, Insert, or Delete Subroutine
  323. ;    ----------------------------------------
  324.  
  325. NotNormalChar:    xchg    al,ah            ; Put extended code in al
  326.         sub    al,71            ; See if it's a cursor key
  327.         jc    GetKeyboard        ; If not, no good
  328.  
  329.         cmp    al,12            ; Another check for cursor
  330.         ja    GetKeyboard        ; If not, skip it 
  331.  
  332.         shl    ax,1            ; Double for index
  333.         mov    di,ax            ;   into vector table
  334.  
  335.         call    [KeyRoutine + di]    ; Do the routine
  336.  
  337.         jmp    MainLoop        ; Back for another key    
  338.  
  339.  
  340. ;    Cursor Movement
  341. ;    ---------------
  342.  
  343. End:        call    TransferLine        ; Move line to buffer
  344.         mov    dh,[cur_y]        ; Set cursor to original
  345.  
  346. PgUp:        mov    dl,[cur_x]        ; Move cursor to
  347.         ret                ; to original column
  348.  
  349. Left:        sub    dl,cl            ; Check if cursor at far left
  350.         jc    GoNorth            ; If so, move it up
  351.         ret
  352.  
  353. GoNorth:    or    dh,dh            ; Top of screen?
  354.         jz    UpEnd            ; then don't move
  355.         mov    dl,[max_x]        ; Move cursor to right margin
  356.  
  357. Up:        sub    dh,cl            ; Decrement row (CX=1)
  358.         adc    dh,ch            ; if carry, restore to zero
  359.         ret
  360.  
  361. Right:        cmp    dl,[max_x]        ; Check if cursor at far right
  362.         jae    GoSouth            ; If not, move it right
  363. UpEnd:        inc    dl
  364.         ret
  365.  
  366. Home:        dec    dh            ; Move cursor up a row
  367.  
  368. GoSouth:    mov    dl,ch            ; Set cursor to left of screen
  369.  
  370. Down:        inc    dh            ; Move cursor down one row
  371.         ret
  372.  
  373. PgDn:        mov    cl,[max_x]        ; Get last column on screen
  374.         sub    cl,dl            ; Subtract current column
  375.         inc    cx            ; Kick it up by one
  376.         mov    ax,' '+0Ah*256        ; Write blanks to screen
  377.         int    10h            ;   through BIOS
  378. Dummy:        ret
  379.  
  380. ;    Insert and Delete
  381. ;    -----------------
  382.  
  383. Insert:        not    [InsertOn]        ; Toggle the InsertOn flag
  384.         ret                ;   and return    
  385.  
  386. Delete:        ; fall through to ShiftLeft routine
  387.  
  388.  
  389. ;    Shift Line One Space Left (For Delete)
  390. ;    --------------------------------------
  391.  
  392. ShiftLeft:    mov    di,0020h        ; Blank at end
  393.         mov    bl,0Ah            ; first write is char. only
  394.         mov    cl,[max_x]        ; How far to go to
  395.         sub    cl,dl            ; from where
  396.         inc    cx
  397.         add    dl,cl            ; And put cursor at EOL
  398. ShiftLeftLoop:    dec    dx            ; Kick down cursor column
  399.         call    ReadAndWrite        ; Copy a character
  400.         loop    ShiftLeftLoop        ; And repeat as necessary
  401.         ret
  402.  
  403.  
  404. ;    Shift Line One Space Right (For Insert, called like Int 10h)
  405. ;    ------------------------------------------------------------
  406.  
  407. ShiftRight:    push    dx            ; Save original cursor
  408.         xchg    bl,ah            ; Write character and attribute
  409.  
  410.         mov    di,ax            ; Character to insert
  411.         mov    cl,[max_x]
  412.         sub    cl,dl
  413.         inc    cx
  414.  
  415. ShiftRightLoop:    call    ReadAndWrite        ; Read character and write
  416.         inc    dx            ; Kick up cursor column 
  417.         loop    ShiftRightLoop
  418.  
  419.         pop    dx            ; Get back original cursor
  420.         ret                ; And return from routine
  421.  
  422. ;    Read and Write Character for Line Shifts
  423. ;    ----------------------------------------
  424.  
  425. ReadAndWrite:    push    cx
  426.         mov    ah,2            ; Set Cursor from dx
  427.         int    10h            ;   through BIOS
  428.  
  429.         mov    ah,8            ; Read Character and Attribute
  430.         int    10h            ;   through BIOS
  431.  
  432.         xchg    ax,di            ; Switch with previous char
  433.  
  434.         mov    cl,1            ; One character to write
  435.         xchg    bl,ah            ; Write character and attribute
  436.         int    10h            ;   through BIOS
  437.         mov    bl,9            ; next write is with attribute
  438.         pop    cx
  439.         ret                ; Return from Routine
  440.  
  441. ;    Transfer Line on Screen to Keyboard Buffer
  442. ;    ------------------------------------------
  443.  
  444. TransferLine:    mov    cl,ch            ; Count characters in line
  445.         mov    di, linebuf        ; Place to store 'em
  446.  
  447. GetCharLoop:    mov    ah,02h            ; Set Cursor at dx
  448.         int    10h            ;   through BIOS
  449.  
  450.         mov    ah,08h            ; Read Character & Attribute
  451.         int    10h            ;   through BIOS
  452.         or    al,al            ; Space in graphics mode?
  453.         jnz    StashIt            ;  if no, save it
  454.         mov    al,' '            ; else use a space
  455. StashIt:    stosb                ; Save the character
  456.  
  457.         inc    cx            ; Increment the counter
  458.         inc    dx            ; Increment the cursor column
  459.         cmp    dl,[max_x]        ; See if at end of line yet
  460.         jbe    GetCharLoop        ; If not, continue
  461.  
  462.         sub    dx,cx            ; go home
  463.  
  464.         dec    di            ; Points to end of string
  465.         mov    al,' '            ; Character to search through
  466.         std                ; Searching backwards
  467.         repz    scasb            ; Search for first non-blank
  468.         cld
  469.         jz    SetBufferCount        ; If all blanks, skip down
  470.  
  471.         inc    cx
  472.         inc    di            ; At last character
  473.  
  474. SetBufferCount:    mov    scrnbuf.adr, di        ; save pointer to last char in string
  475.         mov    scrnbuf.len,cx        ; pass info to the getchar routine
  476.         mov    al,13
  477.         inc    di            ; After last character
  478.         stosb                ; send a carriage return, too
  479.  
  480.         ret                ; Return from routine
  481.  
  482. ;    Draw or erase pseudocursor in graphics mode or set text mode cursor
  483. ;    -------------------------------------------------------------------
  484.  
  485. Cursor:        mov    ah,2
  486.         int    10h
  487.         mov    cx,1            ; just one
  488.         cmp    gmode_flag,ch        ; if we're in text mode
  489.         jz    Set_Text
  490.         cmp    pseudo_flag,ch        ; or don't want a pseudocursor
  491.         jz    Set_Text        ; don't draw it
  492.  
  493.         mov    ax,0916h        ; write a ^V
  494.         mov    bl,8fh            ; XOR mode
  495.         int    10h
  496.  
  497. Set_Text:    ret
  498.  
  499. ScreenEdit    endp
  500.  
  501. endif
  502.  
  503. code    ends
  504.     end                ; of zavt_k.asm
  505.