home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / GETFLD.ZIP / GETFLD.ASM next >
Encoding:
Assembly Source File  |  1987-06-30  |  20.3 KB  |  498 lines

  1. CODE    SEGMENT BYTE PUBLIC
  2.  
  3.         ASSUME  CS:CODE
  4.  
  5.         PUBLIC  GetField
  6.  
  7.  
  8. ;--------------------------------------------------------------------------
  9. ;  Key code equates...
  10. ;--------------------------------------------------------------------------
  11. CR      equ     13              ; Carraige return
  12. Dkey    equ     339             ; Delete key code
  13. BkSpace equ     8               ; Back-space
  14. Escape  equ     27              ; Escape code
  15. UpArrw  equ     328             ; Up Arrow
  16. DnArrw  equ     336             ; Down Arrow
  17. LftArrw equ     331             ; Left Arrow
  18. RtArrw  equ     333             ; Right Arrow
  19. HmKey   equ     327             ; Home key
  20. EKey    equ     335             ; End key
  21. CBkKey  equ     127             ; Ctrl-Backspace
  22. PgUp    equ     329             ; Page Up
  23. PgDn    equ     337             ; Page Down
  24. CtrlCR  equ     10              ; Ctrl-Enter
  25.  
  26. ;--------------------------------------------------------------------------
  27. ;  The following are offsets in the stack for the input parameters:
  28. ;--------------------------------------------------------------------------
  29. Fptr    equ     word ptr [bp-4]
  30. FptrB   equ     byte ptr [bp-4]
  31.  
  32. Opts    equ     byte ptr [bp-5]
  33.  
  34. TheOpts equ     dword ptr [bp+6] ; Options[0] = length of input options
  35. UpCnv   equ     02h             ; Bit #1     = Convert input to Uppercase!
  36. AutoX   equ     20h             ; Bit #6     = Auto exit from field
  37. InitVal equ     80h             ; Bit #7     = Use initial value of Ibuf
  38. ISize   equ     10              ; Position of Size variable on stack
  39. col     equ     12              ; Position of Column value on stack
  40. row     equ     14              ; Position of Row value on stack
  41. Atrib   equ     16              ; Position of Attribute to use for field
  42. Ibuf    equ     18              ; Position of pointer to input buffer
  43. Legal   equ     22              ; Positon of legal string on stack
  44. KeyVal  equ     26              ; Position of pointer to return variable
  45.  
  46. ;--------------------------------------------------------------------------
  47. ;  Getkey function:
  48. ;    Return: AX = 0 if no key pressed
  49. ;            AX = 1..255 if standard key code
  50. ;            AX = 256..  if function key or cursor control key...
  51. ;--------------------------------------------------------------------------
  52.  
  53. GetField        PROC FAR
  54.  
  55.         push    bp              ; save the base pointer
  56.         mov     bp,sp           ; point it to the stack
  57.         push    bp              ; save new value on stack
  58.         jmp     start
  59.  
  60. GetKey  proc near
  61.         mov     bx,0            ;temporary return value
  62.         mov     ah,1            ; check kbd buffer
  63.         int     16h             ; kbd IO interrupt
  64.         jz      GetKey          ; keep waiting until key is found
  65.         mov     ah,0            ; else get kbd char
  66.         int     16h             ; kbd io interupt
  67.         mov     bl,al           ; put into return register
  68.         or      al,al           ; check for extended code
  69.         jnz     GY1             ; skip if not extended code
  70.         mov     bh,1            ; set MSByte for extended code
  71.         mov     bl,ah           ; move scan code into bl
  72. GY1:
  73.         mov     ax,bx           ; set up for return from function
  74.         ret                     ; exit module
  75.  
  76. GetKey  endp
  77.  
  78. ;--------------------------------------------------------------------------
  79. ;  Put out field with attribute specified by user
  80. ;--------------------------------------------------------------------------
  81. RevFld  proc near
  82.         mov     ax,0920h        ; get blank...& write char code
  83.         mov     bh,0            ; set for page 0
  84.         mov     bl,Atrib[bp]    ; get video attribute
  85.         mov     cx,ISize[bp]    ; get length of field
  86.         int     10h             ; go do it!
  87.         ret
  88.  
  89. revfld  endp
  90.  
  91. ;--------------------------------------------------------------------------
  92. ;  Write a character to the screen...
  93. ;--------------------------------------------------------------------------
  94. WChar   proc near
  95.  
  96.         mov     ah,10           ; write character only at current position
  97.         mov     bh,0            ; page 0 of video board!
  98.         mov     cx,1            ; only write one character...
  99.         int     10h             ; video I/O interrupt (write character)
  100.         inc     Fptr
  101.         ret
  102.  
  103. wchar   endp
  104.  
  105. ;--------------------------------------------------------------------------
  106. ;  Goto X,Y position  (dh = row, dl = column)
  107. ;--------------------------------------------------------------------------
  108. GotoXY  proc near
  109.  
  110.         dec     dh              ; Adjust row & column for BIOS
  111.         dec     dl              ; (0,0) = upper left corner!
  112.         mov     ah,2            ; set cursor function code
  113.         mov     bh,0            ; set for current page!
  114.         int     10h             ; video I/O interrupt
  115.         ret
  116.  
  117. gotoxy  endp
  118.  
  119. ;--------------------------------------------------------------------------
  120. ; Position cursor to Col+Fptr-1,Row
  121. ;--------------------------------------------------------------------------
  122. CurPos  proc near
  123.  
  124.         mov     dl,FptrB        ; get Field pointer value
  125.         dec     dl              ; subtract 1
  126.         add     dl,Col[bp]      ; dl = Fptr+Col-1
  127.         mov     dh,Row[bp]      ; get Row
  128.         call    GotoXY          ; position cursor
  129.         ret                     ; exit module
  130.  
  131. curpos  endp
  132.  
  133. ;--------------------------------------------------------------------------
  134. ;  UpCase function: convert a character to its upper-case equivalent -
  135. ;                   if it is a lowercase letter!
  136. ;--------------------------------------------------------------------------
  137. UpCase  proc near
  138.  
  139.         cmp     al,'a'          ; Check against 'a'
  140.         jb      UE1             ; nope, its below that
  141.         cmp     al,'z'          ; check against 'z'
  142.         ja      UE1             ; nope, its above that!
  143.         xor     al,20h          ; make it UPPERCASE!
  144. UE1:
  145.         ret                     ; exit module
  146.  
  147. upcase endp
  148.  
  149. ;--------------------------------------------------------------------------
  150. ; Check for legal characters in input!
  151. ;--------------------------------------------------------------------------
  152. LegalCk proc near
  153.         les     di,Legal[bp]    ; get address of legal string
  154.         mov     cl,es:[di]      ; get length of legal string
  155.         xor     ch,ch           ; zero out msb
  156.         or      cl,cl           ; check for zero length
  157.         je      LK1             ; exit if no length
  158. LK2:
  159.         inc     di              ; increment address pointer
  160.         cmp     al,es:[di]      ; is character in legal string?
  161.         loopne  LK2             ; repeat until found or end of table
  162. LK1:
  163.         ret                     ; exit from module
  164.  
  165. legalck endp
  166. ;--------------------------------------------------------------------------
  167. ; Home key function
  168. ;--------------------------------------------------------------------------
  169. HomeKey proc near
  170.         mov     Fptr,1          ; set Fptr back to start of field
  171.         ret
  172.  
  173. HomeKey endp
  174.  
  175. ;--------------------------------------------------------------------------
  176. ; End Key function
  177. ;--------------------------------------------------------------------------
  178. EndKey  proc near
  179.  
  180.         les     di,Ibuf[bp]     ; get address of Ibuf
  181.         mov     al,es:[di]      ; get length of Ibuf...
  182.         inc     al              ; Plus one!
  183.         mov     FptrB,al
  184.         ret
  185. endkey  endp
  186.  
  187. ;--------------------------------------------------------------------------
  188. ;  Right Arrow key
  189. ;--------------------------------------------------------------------------
  190. RightKey        proc near
  191.         les     di,Ibuf[bp]     ; get address of Ibuf
  192.         mov     al,es:[di]      ; get length of Ibuf
  193.         inc     al              ; plus one!
  194.         cmp     FptrB,al        ; compare with Fptr?
  195.         jnb     RY1             ; exit module if ok...
  196.         inc     Fptr            ; increment Fptr!
  197. RY1:
  198.         ret
  199. RightKey        endp
  200.  
  201. ;--------------------------------------------------------------------------
  202. ;  Left Arrow Key
  203. ;--------------------------------------------------------------------------
  204. LeftKey proc near
  205.         cmp     Fptr,1          ; Fptr > 1?
  206.         jna     LY1             ; move left if ok...
  207.         dec     Fptr            ; Fptr := Fptr - 1;
  208. LY1:
  209.         ret
  210.  
  211. LeftKey endp
  212.  
  213. ;--------------------------------------------------------------------------
  214. ;  Control-Backspace Key
  215. ;--------------------------------------------------------------------------
  216. CBackKey        proc near
  217.         call    Init            ; Erase entire field & start over!
  218.         ret
  219. cbackkey        endp
  220.  
  221. ;--------------------------------------------------------------------------
  222. ;  String Delete: delete a character from the current position of a string
  223. ;--------------------------------------------------------------------------
  224. StrDel  proc near
  225.  
  226.         les     di,Ibuf[bp]     ; get input buffer address
  227.         mov     cx,Fptr         ; get field pointer
  228.         cmp     cl,es:[di]      ; compare Ibuf[0] w/ Fptr
  229.         ja      DY1             ; Fptr > Ibuf[0]
  230.         je      DY2             ; Ibuf[0] = Fptr
  231.         mov     bx,cx           ; Fptr < Ibuf[0]
  232.         mov     cl,es:[di]      ; get length of Ibuf
  233.         sub     cl,bl           ; cx = # of char's to move
  234. DYLP1:
  235.         mov     al,es:[di+bx+1] ; get char @ next position
  236.         mov     es:[di+bx],al   ; place char @ current position
  237.         inc     bx              ; get ready for next char
  238.         loop    DYLP1           ; repeat until cx = 0
  239. DY2:
  240.         dec     byte ptr es:[di] ; decrement Ibuf length by one
  241. DY1:
  242.         ret                     ; exit from module!
  243.  
  244. strdel  endp
  245.  
  246. ;--------------------------------------------------------------------------
  247. ;  Screen delete: remove a character from the field shown on the screen!
  248. ;--------------------------------------------------------------------------
  249. ScrDel  proc near
  250.  
  251.         mov     ax,row[bp]      ; get starting row of field
  252.         dec     ax              ; set up for calc
  253.         mov     di,col[bp]      ; get starting col of field
  254.         dec     di              ; set up for calc
  255.         add     di,Fptr         ; add in Fptr offset!
  256.         dec     di              ; Col + Fptr - 1 !!!
  257.         les     bx,Ibuf[bp]     ; get address of input string
  258.         mov     cl,es:[bx]      ; get length of input string
  259.         xor     ch,ch
  260.         mov     bx,0040h        ; Calc actual address in video memory...
  261.         mov     es,bx           ; set up segment for following:
  262.         mul     es:word ptr[4ah]  ; Calc Row * current width
  263.         add     di,ax           ; add in # of col's
  264.         shl     di,1            ; multiply by two for Attrib/Value pair
  265.         mov     si,di           ; get as source address
  266.         add     si,2            ; next video loc
  267.         mov     dx,es:[63h]     ; test video board
  268.         add     dx,6            ; offset of register in video adapter
  269.         mov     ax,0b800h       ; Color ?
  270.         mov     bx,es:[10h]     ; test for Mono vs Color
  271.         and     bx,30h
  272.         cmp     bx,30h
  273.         jne     setcard         ; Board is color... else
  274.         mov     ax,0B000h       ; Mono !
  275. setcard:
  276.         mov     es,ax           ; set up segment for transfer
  277.         push    ds
  278.         mov     ds,ax
  279.         sub     cx,Fptr         ; Calc actual # of char's to move!
  280.         jb      SRExit1         ; if < 0 then skip ...
  281.         je      SRExit2 ; if = 0 then just put out space & exit!
  282. test_low:
  283.         in      al,dx           ; wait for Horizontal retrace to end
  284.         test    al,1
  285.         jnz     test_low
  286.         cli
  287. test_hi:
  288.         in      al,dx           ; wait for next one to start
  289.         test    al,1
  290.         jz      test_hi
  291.         cld                     ; set direction to forward
  292. movelp:
  293.         movsb                   ; found it! now move data!
  294.         inc     di
  295.         inc     si
  296.         loop    movelp
  297. SREXit2:
  298.         mov     byte ptr ds:[di],' ' ; blank out last position!
  299.         sti
  300. SRExit1:
  301.         pop     ds
  302.         ret
  303.  
  304. scrdel  endp
  305.  
  306. ;--------------------------------------------------------------------------
  307. ;  Delete Key
  308. ;--------------------------------------------------------------------------
  309. DelKey  proc near
  310.  
  311.         call    ScrDel          ; delete char from screen field
  312.         call    StrDel          ; delete char from string
  313.         ret
  314.  
  315. delkey  endp
  316.  
  317. ;--------------------------------------------------------------------------
  318. ; Backspace Key
  319. ;--------------------------------------------------------------------------
  320. BackKey proc near
  321.  
  322.         cmp     Fptr,1          ; Fptr > 1?
  323.         jna     BY1             ; move lef if ok
  324.         dec     Fptr            ; Fptr := Fptr - 1;
  325.         call    DelKey          ; and then delete char!!!
  326. BY1:
  327.         ret
  328. BackKey endp
  329.  
  330. ;--------------------------------------------------------------------------
  331. ;  This routine accesses all of the key subroutines!
  332. ;--------------------------------------------------------------------------
  333. Gosub   proc near
  334.  
  335.         jmp     cx              ; jump to address found from table!
  336.  
  337. Gosub   endp
  338.  
  339. ;--------------------------------------------------------------------------
  340. ;  Test content of AX against entry in JUMP Table!
  341. ;--------------------------------------------------------------------------
  342. TabTest2        proc near
  343.  
  344.         pop     bx              ; get address of Table!
  345.         mov     cx,0            ; preset ending value
  346. T2Lp1:
  347.         cmp     word ptr cs:[bx],0      ; at end of table?
  348.         je      T2Exit          ; yes, get out of subroutine!
  349.         cmp     ax,cs:[bx]      ; is char in table entry?
  350.         jne     T2Skip1
  351.         mov     cx,bx           ; get address of match position!
  352.         add     cx,2            ; increment to jump address
  353. T2Skip1:
  354.         add     bx,5            ; get to next address!
  355.         jmp     T2Lp1
  356. T2Exit:
  357.         inc     bx
  358.         inc     bx
  359.         or      ch,ch
  360.         push    bx
  361.         ret                     ; exit from module!
  362.  
  363. tabtest2 endp
  364.  
  365. ;--------------------------------------------------------------------------
  366. ; Initialize system
  367. ;--------------------------------------------------------------------------
  368. Init    proc near
  369.  
  370.         mov     Fptr,1                   ; set up Fptr for following...
  371.         les     di,TheOpts
  372.         mov     al,es:[di]
  373.         mov     Opts,al
  374.         call    CurPos                   ; position cursor to start of field
  375.         call    RevFld                   ; put out video area
  376.         test    byte ptr Opts,InitVal ; use initial value of Ibuf?
  377.         jz      IT1                      ; no, skip setup rtn
  378.         xor     byte ptr Opts,InitVal         ; reset flag!!
  379.         les     di,Ibuf[bp]              ; get address of Input buffer
  380.         cmp     byte ptr es:[di],0       ; initial value for Ibuf?
  381.         je      IT1                      ; no, skip anything else...
  382.         mov     cl,es:[di]               ; get length of Ibuf
  383.         xor     ch,ch                    ; zero out CH
  384. IT3:
  385.         inc     di                       ; increment string pointer
  386.         mov     al,es:[di]               ; get byte from Ibuf
  387.         push    cx                       ; save count!
  388.         call    WChar                    ; write character to screen
  389.         call    CurPos                   ; re-position cursor!
  390.         pop     cx                       ; restore counter
  391.         loop    IT3                      ; repeat until message is printed
  392.         mov     Fptr,1                   ; reset field pointer to field start
  393.         les     di,Ibuf[bp]              ; get address of Input buffer
  394.         jmp     IT2                      ; exit from module
  395. IT1:
  396.         mov     Fptr,1                   ; reset field pointer to field start
  397.         les     di,Ibuf[bp]              ; get address of Input buffer
  398.         mov     byte ptr es:[di],0       ; set Input length to zero
  399. IT2:
  400.         ret                              ; exit module
  401.  
  402. init    endp
  403.  
  404. ;--------------------------------------------------------------------------
  405. ; Main module
  406. ;--------------------------------------------------------------------------
  407.  
  408. Main    proc near
  409.  
  410.         call    CurPos                   ; position cursor
  411.         call    GetKey                   ; get char from kbd
  412.         cmp     ax,' '                   ; is it >= a space?
  413.         jb      MN1                      ; not a valid printable character!
  414.         cmp     ax,127                   ; is it <= chr(127)?
  415.         jnb     MN1                      ; not a valid printable character!
  416.         test    byte ptr Opts,UpCnv  ; convert to uppercase option active?
  417.         jz      MN0                      ; nope, continue...
  418.         call    UpCase                   ; else convert it!
  419. MN0:
  420.         call    LegalCk                  ; check for legal character
  421.         jnz     Main                     ; ignore if not found in legal string
  422.         mov     bl,FptrB                 ; get current field pointer
  423.         cmp     bl,ISize[bp]             ; at end of field?
  424.         ja      Main                     ; no, skip this test!
  425.         les     di,Ibuf[bp]              ; get address of input buffer
  426.         mov     bl,FptrB                 ; get input pointer value
  427.         xor     bh,bh                    ; zero out BH
  428.         mov     es:[di+bx],al            ; save char into input buffer
  429.         cmp     bl,es:[di]               ; increase return size of buffer?
  430.         jna     MN2                      ; no,
  431.         mov     es:[di],bl               ; yes, store ptr @ buffer length pos
  432. MN2:
  433.         call    WChar                    ; write character to screen
  434.         mov     bl,FptrB                 ; get current field pointer
  435.         cmp     bl,ISize[bp]             ; at end of field?
  436.         jna     Main                     ; don't worry about it!
  437.         test    byte ptr Opts,AutoX  ; auto-exit on?
  438.         jz      Main                     ; nope - try again
  439.         mov     ax,CR                    ; pretend to be a CR
  440.         jmp     Skip1                    ; go to exit from module
  441. MN1:
  442.         call    TabTest2                 ; check for address of subroutine...
  443.         dw      EKey                     ; scan code for [END] key
  444.         jmp     EndKey                   ; jump to routine
  445.         dw      LftArrw                  ; scan code for [LEFT ARROW] key
  446.         jmp     LeftKey
  447.         dw      RtArrw                   ; scan code for [RIGHT ARROW] key
  448.         jmp     RightKey
  449.         dw      CBkKey                   ; scan code for [^BACKSPACE]
  450.         jmp     CBackKey
  451.         dw      BkSpace                  ; scan code for [BACKSPACE]
  452.         jmp     BackKey
  453.         dw      HmKey                    ; scan code for [HOME] key
  454.         jmp     HomeKey
  455.         dw      DKey                     ; scan code for [DEL] key
  456.         jmp     DelKey
  457.         dw      0                        ; mark end of table
  458.         jz      Skip1
  459.         call    Gosub                    ; go do subroutine
  460.         jmp     Main
  461. Skip1:
  462.         ret                              ; exit from module!
  463.  
  464. main    endp
  465.  
  466. ;--------------------------------------------------------------------------
  467. ; Conclusion to program
  468. ;--------------------------------------------------------------------------
  469. Conc    proc near
  470.  
  471.         les     di,KeyVal[bp]            ; get address of return variable
  472.         mov     es:[di],ax               ; store keycode of last keystroke
  473.         ret                              ; exit module
  474.  
  475. Conc    endp
  476.  
  477. ;--------------------------------------------------------------------------
  478. ; Start of Program !!!!
  479. ;--------------------------------------------------------------------------
  480. start:
  481.         sub     sp,5                     ; allocate space for locals
  482.  
  483. CmdLoop:
  484.         call    Init                     ; set up for program
  485.         call    Main                     ; do main loop
  486.         call    Conc                     ; conclusion of program
  487.  
  488.         pop     ax
  489.         mov     sp,bp                    ; reset stack pointer
  490.         pop     bp                       ; reset base pointer
  491.         ret     24                       ; exit & clear stack of variables
  492.  
  493. GetField        ENDP
  494.  
  495. CODE    ENDS
  496.  
  497.         END
  498.