home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / getfield / myget.asm < prev    next >
Assembly Source File  |  1988-04-16  |  22KB  |  550 lines

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