home *** CD-ROM | disk | FTP | other *** search
- ;----------------------------------------------------------------
- ; This is a module in the ASMLIB library.
- ;
- ; This program uses DE -> a data structure to read formatted
- ; screen input forms. The user must generate a set of menu strings
- ; which will be displayed and a set of data areas which will be
- ; filled by this program with user input. An example is....
- ;
- ; lxi d,menu
- ; call formin ; display menu and read data. SIMPLE
- ; jmp wherever ; continue on, no error returns
- ;
- ; menu db x1,y1,'String 1$'
- ; dw data1 ; address of data string 1
- ; db x2,y2,'String 2$'
- ; dw data2 ; address of data string 2
- ; db Xn,Yn,'String N$'
- ; dw datan
- ; db 0ffh ; end of table
- ;
- ; data1 db 6,0,0,0,0,0,0,0 ; 6 character CP/M console buffer
- ; data2 db 3,0,0,0,0 ; 3
- ; datan db 5,3,'Hey',0,0 ; Preinitialized 5 character buffer
- ;
- ; The user is limited to a maximum of 255 items in the menu maximum.
- ; Note that this module uses internal I/O and is completely self contained.
- ; All console I/O is done via direct console I/O function 6 due to the
- ; nature of the software. If the address of the console buffer is 00 then the
- ; program only prints the string so that menu items can be used as
- ; non-accepting prompts.
- ;
- ; Written R.C.H. 20/8/83
- ; Last Update R.C.H. 22/10/83
- ;
- ; Added 00 console address code. R.C.H. 21/9/83
- ; Added I/O driver linkages. R.C.H. 22/10/83
- ; Fixed silly ^X bug R.C.H. 06/03/84
- ;----------------------------------------------------------------
- ;
- ; All I/O is internal to this module other than primitive character i/o
- ;
- name 'formin'
- public formin
- extrn cie,coe
- ;
- maclib z80
- ;
- ;
- filchr equ '_' ; prompt characters
- esc equ 01bh ; end of job
- del equ 07fh ; delete key
- erlin equ 24 ; erase whole line (control X)
- uplin equ 11 ; up a line in the display
- dlin equ 10 ; down a line
- lchr equ 08 ; left a character
- ;
- ; The program will display all the strings then display string 1 and wait
- ; for console input. When the strings are displayed the program checks if
- ; the console buffer is empty and if so will send a set of dashes and if
- ; not will display the characters along with any make-up dashes required.
- ;
- formin: ; Note that the address of the menu is passed in register DE
- sded mnuadr ; save the menu address.
- shld hlsave ; save the registers
- sbcd bcsave
- ;
- print$menu:
- call disp$item ; display a menu string and data area
- ldax d ; get a byte
- cpi 0ffh ; end ?
- jrnz print$menu ; if not the keep on till end
- ;
- ;----------------------------------------------------------------
- ; This routine is responsible for handling the displaying and
- ; reading of input lines. It must ...
- ;
- ; 1) Display the current menu item & console buffer
- ; 2) Read characters into the console buffer and acting on them...
- ; a. Save in the buffer
- ; b. Goto next line and buffer
- ; c. Goto last line and buffer
- ; d. Goback a character in the line (destructively)
- ; e. Go forward in the line (non destructively)
- ; f. Return to the main handler to exit or whatever
- ;----------------------------------------------------------------
- ;
- get$input:
- lded mnuadr ; Get the menu address
- xra a
- sta itmnum ; save the menu item number
- ;
- get$item:
- ; Now display the item DE points to.
- call disp$item ; display menu & console buffer
- ; After DISP$ITEM DE -> the start of the NEXT item in the list.
- sded nxtadr ; indicate the start of next item
- ; Next we must cursor position to the screen X and Y position of the data field
- lxi d,bufx ; point to data buffer X, Y screeb addr
- call setde ; position cursor using DE -> XY
- ; Now point to the buffer. We must re-print it if characters in it.
- lhld conadr ; HL -> start of console buffer
- mov a,l
- ora h ; Is H = L = 0 ??
- jz nxt$lin ; If so then process the next line
- ;
- mov c,m ; C = maximum characters allowed
- inx h ; HL -> characters in the buffer
- mov e,l
- mov d,h ; copy address of length into DE
- inx h ; now hl -> first character in string.
- ;
- ;Now we detect if there are already characters there. If so print them.
- ldax d ; get the number
- ora a
- jrz no$chars
- mov b,a ; set up a loop counter
- pcl:
- mov a,m ; fetch a character
- inx h ; point to next character
- call coe
- djnz pcl ; print characters till b = 0
- ;
- ; This section of code assumes that C = maximum characters allowed and
- ; DE -> characters in the buffer already. HL must point to characters in
- ; the buffer and DE points to the character in the buffer actual length.
- ;
- no$chars: ; Read console for characters.
- call cie ; get the character via direct input
- ; check if a terminator
- cpi erlin
- jz erase$line
- cpi esc
- jz fin$get ; finish of the get then
- cpi 0dh ; carriage return ?
- jz nxt$lin
- cpi uplin ; go up a line
- jz prv$lin
- cpi dlin
- jz nxt$lin
- cpi lchr
- jz lft$chr
- cpi del
- jz lft$chr
- cpi 020h ; check if less than a space
- jrc ign$chr ; ignore them
- ; If it is not a formatting character then save it then check if the
- ; buffer is full before inserting it. C = max allowed, B = current size
- sta temp
- ldax d ; get character read counter
- cmp c ; compare to maximum allowed
- jrz ign$chr ; ignore if exactly full
- jrnc ign$chr ; no carry if too full
- ; If not full or overfull then we merely bump the count and save it back
- inr a
- stax d ; saved
- ; All else means that we can insert the character into the buffer
- lda temp ; fetch
- mov m,a ; save
- call coe ; echo the character now
- inx h ; point to next memory address
- jr no$chars ; keep reading characters
- ;
- ; This trivial bit of code rings the bell then jumps to get another char.
- ; We usually get here due to an illegal control code or buffer full.
- ;
- ign$chr: ; Ignore the character in a and ring bell then return to loop
- mvi a,07 ; bell code
- call coe
- jr no$chars ; get next character
- ;
- ; This piece of code handles the end of input due to carriage return or
- ; down a line code inputs. We must assume that all parameters are up to
- ; date so we only have to address the next line of the menu then return
- ; to the start of the get section to continue.
- ;
- nxt$lin:
- lda itmnum
- inr a ; load.bump.save item number
- sta itmnum
- ;
- lded nxtadr ; get address of next item
- ldax d
- cpi 0ffh ; is it the end of the menu ??
- jnz get$item ; use it if it is NOT
- lded mnuadr ; all else we get the start address
- xra a
- sta itmnum ; indicate first item number
- jmp get$item ; restart from scratch
- ;
- ; This section of code must go back a line. It does this by backing up
- ; using $ characters as indicators. Note that if ITMNUM = 1 then
- ; no action is taken and we return to the read loop.
- ;
- prv$lin:
- lda itmnum ; get line number
- ora a
- jz no$chars ; ignore all this if line 1
- dcr a
- sta itmnum ; decrement and save
- ora a
- jrnz prv$lin1
- lded mnuadr ; point to item 1
- jmp get$item
- ; If here then we must goto the (ITMNUM)'th dollar address + 3 in the menu
- prv$lin1:
- lded mnuadr ; point to start of menu
- mov b,a ; save the counter
- ;
- prv$lin2:
- ldax d
- inx d
- cpi '$'
- jrnz prv$lin2
- djnz prv$lin2 ; keep on till all found
- inx d ; points to address byte 2
- inx d ; points to start of string
- jmp get$item ; get the data now
- ;
- ; Here we erase the whole line back to the start.
- ; b = number of characters in the buffer.
- erase$line:
- ldax d ; get the # character there
- ora a ; See if none there yet
- jz no$chars ; If none, skip the backspacing
- mov b,a
- eol2:
- call back$char
- djnz eol2
- xra a ; get a zero into character count
- stax d ; save line length
- jmp no$chars
- ;
- ; Here we back the cursor up a character so long as there are characters
- ; to back up in the buffer. If the buffer is empty then we ring the bell.
- ;
- ; DE -> characters in the buffer
- ; HL -> ascii characters in the buffer
- ;
- lft$chr:
- ldax d ; get the character count
- ora a ; empty ??
- jz ign$chr ; ring bell and continue
- dcr a
- stax d ; save the decremented count
- call back$char ; do the backing up of the cursor
- jmp no$chars
- ;
- ; Back the cursor up 1 character and write a null to the buffer.
- ;
- back$char:
- dcx h ; back up the memory pointer too
- mvi m,00 ; clear the buffer byte
- ; Send now a backspace, underline, backspace
- mvi a,8
- call coe
- mvi a,filchr ; the fill character
- call coe
- mvi a,08
- call coe
- ret
- ;
- ;----------------------------------------------------------------
- ; This is jumped to when the user enters an ESCAPE to quit the input
- ; to the data fields.
- ;----------------------------------------------------------------
- ;
- fin$get:
- lded mnuadr
- lhld hlsave
- lbcd bcsave
- ret
- ;
- ;----------------------------------------------------------------
- ; This large routine must use DE to print the menu item it points
- ; to and also print the console buffer the menu item points to.
- ; If the console buffer has an address of 00 then it is ignored.
- ; On return DE must point to the next menu item or end of menu.
- ;----------------------------------------------------------------
- ;
- disp$item:
- call setde ; set up cursor DE-> address
- call print ; print DE-> string
- ;
- ; Now we need to save the current screen address since this is where
- ; the console buffer is being printed so we need it for later homing to.
- lda curx
- sta bufx
- lda cury
- sta bufy ; saved
- ;
- ; Now load the address of the console buffer string
- xchg ; HL -> the address now
- mov e,m
- inx h
- mov d,m
- inx h
- ; Now HL -> next menu string, DE -> console buffer for this string.
- ; This extensive section of code will print the console buffer or prompt
- ;
- sded conadr ; save CONSOLE BUFFER address
- ; See if this menu string has no console buffer
- mov a,e
- ora d ; Is D = E = 0 ?
- jrz fin$disp ; put address of menu into de then ret.
- ldax d ; get its maximum length
- mov b,a ; Save as a counter
- inx d ; DE -> characters in the buffer
- inx d ; DE -> first buffer character
- print$con$buf:
- ldax d
- inx d ; point to next character
- ora a ; is this character a null ?
- jrnz pconbuf2
- mvi a,filchr ; if it was load a default
- pconbuf2:
- call coe ; print it
- djnz print$con$buf ; print next string
- ; Restore DE as pointer to the menu then do the next item / buffer
- ; Note that the address of the console buffer is saved in CONADR.
- fin$disp:
- xchg ; DE -> next string start
- ret
- ;
- ;----------------------------------------------------------------
- ; Set up the screen address -> by DE stored in memory.
- ; The address is saved in curx, cury. Note that the offset (32)
- ; is added to both x and y.
- ;----------------------------------------------------------------
- ;
- setde:
- ldax d ; get the X address
- sta curx
- inx d
- ldax d
- sta cury
- inx d ; DE now -> past end
- ;
- ; Flow onto the next part which uses curx and cury to set up the cursor
- ;
- ;----------------------------------------------------------------
- ; Use the values in curx and cury for the cursor position to
- ; be used to set the cursor.
- ;----------------------------------------------------------------
- ;
- setcur:
- mvi a,esc
- call coe
- mvi a,'='
- call coe
- ; Now the Y value
- lda cury
- adi 32
- call coe
- ; X address
- lda curx
- adi 32
- jmp coe ; all done
- ;
- ;----------------------------------------------------------------
- ; Print the string -> by DE. Return with DE pointing past the
- ; string end so as to point to the start of the next string.
- ; NOTE that this routine updates the CURX screen address. This is
- ; vital for all printing functions.
- ;----------------------------------------------------------------
- ;
- print:
- ldax d
- inx d
- ora a
- rz
- cpi '$' ; END ?
- rz
- call coe
- lda curx
- inr a
- sta curx ; loaded.updated.saved
- jr print
- ;
- ; Data storage of string addresses and cursor addresses.
- ;
- dseg
- ;
- nxtadr db 00,00 ; current string address
- conadr db 00,00 ; address of a console buffer
- mnuadr db 00,00 ; address of a menu string
- itmnum db 00 ; menu item number counter
- ;
- bufx db 00 ; buffer start screen x value
- bufy db 00 ; buffer start screen y value
- ;
- curx: db 00 ; loaded by setxy
- cury: db 00 ; as above
- ;
- hlsave db 00,00
- bcsave db 00,00 ; preserver registers in these
- temp db 00 ; save cons. character temp.
- ;
- end
-