home *** CD-ROM | disk | FTP | other *** search
- CODE SEGMENT BYTE PUBLIC
-
- ASSUME CS:CODE
-
- PUBLIC GetField
-
-
- ;--------------------------------------------------------------------------
- ; Key code equates...
- ;--------------------------------------------------------------------------
- CR equ 13 ; Carraige return
- Dkey equ 339 ; Delete key code
- BkSpace equ 8 ; Back-space
- Escape equ 27 ; Escape code
- UpArrw equ 328 ; Up Arrow
- DnArrw equ 336 ; Down Arrow
- LftArrw equ 331 ; Left Arrow
- RtArrw equ 333 ; Right Arrow
- HmKey equ 327 ; Home key
- EKey equ 335 ; End key
- CBkKey equ 127 ; Ctrl-Backspace
- PgUp equ 329 ; Page Up
- PgDn equ 337 ; Page Down
- CtrlCR equ 10 ; Ctrl-Enter
-
- ;--------------------------------------------------------------------------
- ; The following are offsets in the stack for the input parameters:
- ;--------------------------------------------------------------------------
- Fptr equ word ptr [bp-4]
- FptrB equ byte ptr [bp-4]
-
- Opts equ byte ptr [bp-5]
-
- TheOpts equ dword ptr [bp+6] ; Options[0] = length of input options
- UpCnv equ 02h ; Bit #1 = Convert input to Uppercase!
- AutoX equ 20h ; Bit #6 = Auto exit from field
- InitVal equ 80h ; Bit #7 = Use initial value of Ibuf
- ISize equ 10 ; Position of Size variable on stack
- col equ 12 ; Position of Column value on stack
- row equ 14 ; Position of Row value on stack
- Atrib equ 16 ; Position of Attribute to use for field
- Ibuf equ 18 ; Position of pointer to input buffer
- Legal equ 22 ; Positon of legal string on stack
- KeyVal equ 26 ; Position of pointer to return variable
-
- ;--------------------------------------------------------------------------
- ; Getkey function:
- ; Return: AX = 0 if no key pressed
- ; AX = 1..255 if standard key code
- ; AX = 256.. if function key or cursor control key...
- ;--------------------------------------------------------------------------
-
- GetField PROC FAR
-
- push bp ; save the base pointer
- mov bp,sp ; point it to the stack
- push bp ; save new value on stack
- jmp start
-
- GetKey proc near
- mov bx,0 ;temporary return value
- mov ah,1 ; check kbd buffer
- int 16h ; kbd IO interrupt
- jz GetKey ; keep waiting until key is found
- mov ah,0 ; else get kbd char
- int 16h ; kbd io interupt
- mov bl,al ; put into return register
- or al,al ; check for extended code
- jnz GY1 ; skip if not extended code
- mov bh,1 ; set MSByte for extended code
- mov bl,ah ; move scan code into bl
- GY1:
- mov ax,bx ; set up for return from function
- ret ; exit module
-
- GetKey endp
-
- ;--------------------------------------------------------------------------
- ; Put out field with attribute specified by user
- ;--------------------------------------------------------------------------
- RevFld proc near
- mov ax,0920h ; get blank...& write char code
- mov bh,0 ; set for page 0
- mov bl,Atrib[bp] ; get video attribute
- mov cx,ISize[bp] ; get length of field
- int 10h ; go do it!
- ret
-
- revfld endp
-
- ;--------------------------------------------------------------------------
- ; Write a character to the screen...
- ;--------------------------------------------------------------------------
- WChar proc near
-
- mov ah,10 ; write character only at current position
- mov bh,0 ; page 0 of video board!
- mov cx,1 ; only write one character...
- int 10h ; video I/O interrupt (write character)
- inc Fptr
- ret
-
- wchar endp
-
- ;--------------------------------------------------------------------------
- ; Goto X,Y position (dh = row, dl = column)
- ;--------------------------------------------------------------------------
- GotoXY proc near
-
- dec dh ; Adjust row & column for BIOS
- dec dl ; (0,0) = upper left corner!
- mov ah,2 ; set cursor function code
- mov bh,0 ; set for current page!
- int 10h ; video I/O interrupt
- ret
-
- gotoxy endp
-
- ;--------------------------------------------------------------------------
- ; Position cursor to Col+Fptr-1,Row
- ;--------------------------------------------------------------------------
- CurPos proc near
-
- mov dl,FptrB ; get Field pointer value
- dec dl ; subtract 1
- add dl,Col[bp] ; dl = Fptr+Col-1
- mov dh,Row[bp] ; get Row
- call GotoXY ; position cursor
- ret ; exit module
-
- curpos endp
-
- ;--------------------------------------------------------------------------
- ; UpCase function: convert a character to its upper-case equivalent -
- ; if it is a lowercase letter!
- ;--------------------------------------------------------------------------
- UpCase proc near
-
- cmp al,'a' ; Check against 'a'
- jb UE1 ; nope, its below that
- cmp al,'z' ; check against 'z'
- ja UE1 ; nope, its above that!
- xor al,20h ; make it UPPERCASE!
- UE1:
- ret ; exit module
-
- upcase endp
-
- ;--------------------------------------------------------------------------
- ; Check for legal characters in input!
- ;--------------------------------------------------------------------------
- LegalCk proc near
- les di,Legal[bp] ; get address of legal string
- mov cl,es:[di] ; get length of legal string
- xor ch,ch ; zero out msb
- or cl,cl ; check for zero length
- je LK1 ; exit if no length
- LK2:
- inc di ; increment address pointer
- cmp al,es:[di] ; is character in legal string?
- loopne LK2 ; repeat until found or end of table
- LK1:
- ret ; exit from module
-
- legalck endp
- ;--------------------------------------------------------------------------
- ; Home key function
- ;--------------------------------------------------------------------------
- HomeKey proc near
- mov Fptr,1 ; set Fptr back to start of field
- ret
-
- HomeKey endp
-
- ;--------------------------------------------------------------------------
- ; End Key function
- ;--------------------------------------------------------------------------
- EndKey proc near
-
- les di,Ibuf[bp] ; get address of Ibuf
- mov al,es:[di] ; get length of Ibuf...
- inc al ; Plus one!
- mov FptrB,al
- ret
- endkey endp
-
- ;--------------------------------------------------------------------------
- ; Right Arrow key
- ;--------------------------------------------------------------------------
- RightKey proc near
- les di,Ibuf[bp] ; get address of Ibuf
- mov al,es:[di] ; get length of Ibuf
- inc al ; plus one!
- cmp FptrB,al ; compare with Fptr?
- jnb RY1 ; exit module if ok...
- inc Fptr ; increment Fptr!
- RY1:
- ret
- RightKey endp
-
- ;--------------------------------------------------------------------------
- ; Left Arrow Key
- ;--------------------------------------------------------------------------
- LeftKey proc near
- cmp Fptr,1 ; Fptr > 1?
- jna LY1 ; move left if ok...
- dec Fptr ; Fptr := Fptr - 1;
- LY1:
- ret
-
- LeftKey endp
-
- ;--------------------------------------------------------------------------
- ; Control-Backspace Key
- ;--------------------------------------------------------------------------
- CBackKey proc near
- call Init ; Erase entire field & start over!
- ret
- cbackkey endp
-
- ;--------------------------------------------------------------------------
- ; String Delete: delete a character from the current position of a string
- ;--------------------------------------------------------------------------
- StrDel proc near
-
- les di,Ibuf[bp] ; get input buffer address
- mov cx,Fptr ; get field pointer
- cmp cl,es:[di] ; compare Ibuf[0] w/ Fptr
- ja DY1 ; Fptr > Ibuf[0]
- je DY2 ; Ibuf[0] = Fptr
- mov bx,cx ; Fptr < Ibuf[0]
- mov cl,es:[di] ; get length of Ibuf
- sub cl,bl ; cx = # of char's to move
- DYLP1:
- mov al,es:[di+bx+1] ; get char @ next position
- mov es:[di+bx],al ; place char @ current position
- inc bx ; get ready for next char
- loop DYLP1 ; repeat until cx = 0
- DY2:
- dec byte ptr es:[di] ; decrement Ibuf length by one
- DY1:
- ret ; exit from module!
-
- strdel endp
-
- ;--------------------------------------------------------------------------
- ; Screen delete: remove a character from the field shown on the screen!
- ;--------------------------------------------------------------------------
- ScrDel proc near
-
- mov ax,row[bp] ; get starting row of field
- dec ax ; set up for calc
- mov di,col[bp] ; get starting col of field
- dec di ; set up for calc
- add di,Fptr ; add in Fptr offset!
- dec di ; Col + Fptr - 1 !!!
- les bx,Ibuf[bp] ; get address of input string
- mov cl,es:[bx] ; get length of input string
- xor ch,ch
- mov bx,0040h ; Calc actual address in video memory...
- mov es,bx ; set up segment for following:
- mul es:word ptr[4ah] ; Calc Row * current width
- add di,ax ; add in # of col's
- shl di,1 ; multiply by two for Attrib/Value pair
- mov si,di ; get as source address
- add si,2 ; next video loc
- mov dx,es:[63h] ; test video board
- add dx,6 ; offset of register in video adapter
- mov ax,0b800h ; Color ?
- mov bx,es:[10h] ; test for Mono vs Color
- and bx,30h
- cmp bx,30h
- jne setcard ; Board is color... else
- mov ax,0B000h ; Mono !
- setcard:
- mov es,ax ; set up segment for transfer
- push ds
- mov ds,ax
- sub cx,Fptr ; Calc actual # of char's to move!
- jb SRExit1 ; if < 0 then skip ...
- je SRExit2 ; if = 0 then just put out space & exit!
- test_low:
- in al,dx ; wait for Horizontal retrace to end
- test al,1
- jnz test_low
- cli
- test_hi:
- in al,dx ; wait for next one to start
- test al,1
- jz test_hi
- cld ; set direction to forward
- movelp:
- movsb ; found it! now move data!
- inc di
- inc si
- loop movelp
- SREXit2:
- mov byte ptr ds:[di],' ' ; blank out last position!
- sti
- SRExit1:
- pop ds
- ret
-
- scrdel endp
-
- ;--------------------------------------------------------------------------
- ; Delete Key
- ;--------------------------------------------------------------------------
- DelKey proc near
-
- call ScrDel ; delete char from screen field
- call StrDel ; delete char from string
- ret
-
- delkey endp
-
- ;--------------------------------------------------------------------------
- ; Backspace Key
- ;--------------------------------------------------------------------------
- BackKey proc near
-
- cmp Fptr,1 ; Fptr > 1?
- jna BY1 ; move lef if ok
- dec Fptr ; Fptr := Fptr - 1;
- call DelKey ; and then delete char!!!
- BY1:
- ret
- BackKey endp
-
- ;--------------------------------------------------------------------------
- ; This routine accesses all of the key subroutines!
- ;--------------------------------------------------------------------------
- Gosub proc near
-
- jmp cx ; jump to address found from table!
-
- Gosub endp
-
- ;--------------------------------------------------------------------------
- ; Test content of AX against entry in JUMP Table!
- ;--------------------------------------------------------------------------
- TabTest2 proc near
-
- pop bx ; get address of Table!
- mov cx,0 ; preset ending value
- T2Lp1:
- cmp word ptr cs:[bx],0 ; at end of table?
- je T2Exit ; yes, get out of subroutine!
- cmp ax,cs:[bx] ; is char in table entry?
- jne T2Skip1
- mov cx,bx ; get address of match position!
- add cx,2 ; increment to jump address
- T2Skip1:
- add bx,5 ; get to next address!
- jmp T2Lp1
- T2Exit:
- inc bx
- inc bx
- or ch,ch
- push bx
- ret ; exit from module!
-
- tabtest2 endp
-
- ;--------------------------------------------------------------------------
- ; Initialize system
- ;--------------------------------------------------------------------------
- Init proc near
-
- mov Fptr,1 ; set up Fptr for following...
- les di,TheOpts
- mov al,es:[di]
- mov Opts,al
- call CurPos ; position cursor to start of field
- call RevFld ; put out video area
- test byte ptr Opts,InitVal ; use initial value of Ibuf?
- jz IT1 ; no, skip setup rtn
- xor byte ptr Opts,InitVal ; reset flag!!
- les di,Ibuf[bp] ; get address of Input buffer
- cmp byte ptr es:[di],0 ; initial value for Ibuf?
- je IT1 ; no, skip anything else...
- mov cl,es:[di] ; get length of Ibuf
- xor ch,ch ; zero out CH
- IT3:
- inc di ; increment string pointer
- mov al,es:[di] ; get byte from Ibuf
- push cx ; save count!
- call WChar ; write character to screen
- call CurPos ; re-position cursor!
- pop cx ; restore counter
- loop IT3 ; repeat until message is printed
- mov Fptr,1 ; reset field pointer to field start
- les di,Ibuf[bp] ; get address of Input buffer
- jmp IT2 ; exit from module
- IT1:
- mov Fptr,1 ; reset field pointer to field start
- les di,Ibuf[bp] ; get address of Input buffer
- mov byte ptr es:[di],0 ; set Input length to zero
- IT2:
- ret ; exit module
-
- init endp
-
- ;--------------------------------------------------------------------------
- ; Main module
- ;--------------------------------------------------------------------------
-
- Main proc near
-
- call CurPos ; position cursor
- call GetKey ; get char from kbd
- cmp ax,' ' ; is it >= a space?
- jb MN1 ; not a valid printable character!
- cmp ax,127 ; is it <= chr(127)?
- jnb MN1 ; not a valid printable character!
- test byte ptr Opts,UpCnv ; convert to uppercase option active?
- jz MN0 ; nope, continue...
- call UpCase ; else convert it!
- MN0:
- call LegalCk ; check for legal character
- jnz Main ; ignore if not found in legal string
- mov bl,FptrB ; get current field pointer
- cmp bl,ISize[bp] ; at end of field?
- ja Main ; no, skip this test!
- les di,Ibuf[bp] ; get address of input buffer
- mov bl,FptrB ; get input pointer value
- xor bh,bh ; zero out BH
- mov es:[di+bx],al ; save char into input buffer
- cmp bl,es:[di] ; increase return size of buffer?
- jna MN2 ; no,
- mov es:[di],bl ; yes, store ptr @ buffer length pos
- MN2:
- call WChar ; write character to screen
- mov bl,FptrB ; get current field pointer
- cmp bl,ISize[bp] ; at end of field?
- jna Main ; don't worry about it!
- test byte ptr Opts,AutoX ; auto-exit on?
- jz Main ; nope - try again
- mov ax,CR ; pretend to be a CR
- jmp Skip1 ; go to exit from module
- MN1:
- call TabTest2 ; check for address of subroutine...
- dw EKey ; scan code for [END] key
- jmp EndKey ; jump to routine
- dw LftArrw ; scan code for [LEFT ARROW] key
- jmp LeftKey
- dw RtArrw ; scan code for [RIGHT ARROW] key
- jmp RightKey
- dw CBkKey ; scan code for [^BACKSPACE]
- jmp CBackKey
- dw BkSpace ; scan code for [BACKSPACE]
- jmp BackKey
- dw HmKey ; scan code for [HOME] key
- jmp HomeKey
- dw DKey ; scan code for [DEL] key
- jmp DelKey
- dw 0 ; mark end of table
- jz Skip1
- call Gosub ; go do subroutine
- jmp Main
- Skip1:
- ret ; exit from module!
-
- main endp
-
- ;--------------------------------------------------------------------------
- ; Conclusion to program
- ;--------------------------------------------------------------------------
- Conc proc near
-
- les di,KeyVal[bp] ; get address of return variable
- mov es:[di],ax ; store keycode of last keystroke
- ret ; exit module
-
- Conc endp
-
- ;--------------------------------------------------------------------------
- ; Start of Program !!!!
- ;--------------------------------------------------------------------------
- start:
- sub sp,5 ; allocate space for locals
-
- CmdLoop:
- call Init ; set up for program
- call Main ; do main loop
- call Conc ; conclusion of program
-
- pop ax
- mov sp,bp ; reset stack pointer
- pop bp ; reset base pointer
- ret 24 ; exit & clear stack of variables
-
- GetField ENDP
-
- CODE ENDS
-
- END