home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / utils / asmutl / asmlib.lbr / FORMIN.AZM / FORMIN.ASM
Encoding:
Assembly Source File  |  1991-06-25  |  12.3 KB  |  400 lines

  1. ;----------------------------------------------------------------
  2. ;        This is a module in the ASMLIB library.
  3. ;
  4. ; This program uses DE -> a data structure to read formatted
  5. ; screen input forms. The user must generate a set of menu strings
  6. ; which will be displayed and a set of data areas which will be
  7. ; filled by this program with user input. An example is....
  8. ;
  9. ;     lxi    d,menu
  10. ;    call    formin            ; display menu and read data. SIMPLE
  11. ;    jmp    wherever        ; continue on, no error returns
  12. ;
  13. ; menu    db    x1,y1,'String 1$'
  14. ;    dw    data1            ; address of data string 1
  15. ;    db    x2,y2,'String 2$'
  16. ;    dw    data2            ; address of data string 2
  17. ;    db    Xn,Yn,'String N$'
  18. ;    dw    datan
  19. ;    db    0ffh            ; end of table
  20. ;
  21. ; data1    db    6,0,0,0,0,0,0,0        ; 6 character CP/M console buffer
  22. ; data2 db    3,0,0,0,0        ; 3
  23. ; datan    db    5,3,'Hey',0,0        ; Preinitialized 5 character buffer
  24. ;
  25. ; The user is limited to a maximum of 255 items in the menu maximum.
  26. ; Note that this module uses internal I/O and is completely self contained.
  27. ; All console I/O is done via direct console I/O function 6 due to the
  28. ; nature of the software. If the address of the console buffer is 00 then the
  29. ; program only prints the string so that menu items can be used as 
  30. ; non-accepting prompts.
  31. ;
  32. ;        Written        R.C.H.        20/8/83
  33. ;        Last Update    R.C.H.        22/10/83
  34. ;
  35. ; Added 00 console address code.            R.C.H.  21/9/83
  36. ; Added I/O driver linkages.                R.C.H.  22/10/83
  37. ; Fixed silly ^X bug                    R.C.H.  06/03/84
  38. ;----------------------------------------------------------------
  39. ;
  40. ; All I/O is internal to this module other than primitive character i/o
  41. ;
  42.     name    'formin'
  43.     public    formin
  44.     extrn    cie,coe
  45. ;
  46.     maclib    z80
  47. ;
  48. ;
  49. filchr    equ    '_'            ; prompt characters
  50. esc    equ    01bh            ; end of job
  51. del    equ    07fh            ; delete key
  52. erlin    equ    24             ; erase whole line (control X)
  53. uplin    equ    11            ; up a line in the display
  54. dlin    equ    10            ; down a line
  55. lchr    equ    08            ; left a character
  56. ;
  57. ; The program will display all the strings then display string 1 and wait
  58. ; for console input. When the strings are displayed the program checks if
  59. ; the console buffer is empty and if so will send a set of dashes and if
  60. ; not will display the characters along with any make-up dashes required.
  61. ;
  62. formin:    ; Note that the address of the menu is passed in register DE
  63.     sded    mnuadr            ; save the menu address.
  64.     shld    hlsave            ; save the registers
  65.     sbcd    bcsave
  66. ;
  67. print$menu:
  68.     call    disp$item        ; display a menu string and data area
  69.     ldax    d            ; get a byte
  70.     cpi    0ffh             ; end ?
  71.     jrnz    print$menu        ; if not the keep on till end
  72. ;
  73. ;----------------------------------------------------------------
  74. ; This routine is responsible for handling the displaying and
  75. ; reading of input lines. It must ...
  76. ;
  77. ; 1) Display the current menu item & console buffer
  78. ; 2) Read characters into the console buffer and acting on them...
  79. ;   a.  Save in the buffer
  80. ;   b.  Goto next line and buffer
  81. ;   c.  Goto last line and buffer
  82. ;   d.  Goback a character in the line (destructively)
  83. ;   e.  Go forward in the line (non destructively)
  84. ;   f.  Return to the main handler to exit or whatever
  85. ;----------------------------------------------------------------
  86. ;
  87. get$input:
  88.     lded    mnuadr            ; Get the menu address
  89.     xra    a
  90.     sta    itmnum            ; save the menu item number
  91. ;
  92. get$item:
  93. ; Now display the item DE points to.
  94.     call    disp$item        ; display menu & console buffer
  95. ; After DISP$ITEM DE -> the start of the NEXT item in the list.
  96.     sded    nxtadr            ; indicate the start of next item
  97. ; Next we must cursor position to the screen X and Y position of the data field
  98.     lxi    d,bufx            ; point to data buffer X, Y screeb addr
  99.     call    setde            ; position cursor using DE -> XY
  100. ; Now point to the buffer. We must re-print it if characters in it.
  101.     lhld    conadr            ; HL -> start of console buffer
  102.     mov    a,l
  103.     ora    h            ; Is H = L = 0 ??
  104.     jz    nxt$lin            ; If so then process the next line
  105.     mov    c,m            ; C = maximum characters allowed
  106.     inx    h            ; HL -> characters in the buffer
  107.     mov    e,l
  108.     mov    d,h            ; copy address of length into DE
  109.     inx    h            ; now hl -> first character in string.
  110. ;
  111. ;Now we detect if there are already characters there. If so print them.
  112.     ldax    d            ; get the number
  113.     ora    a
  114.     jrz    no$chars
  115.     mov    b,a            ; set up a loop counter
  116. pcl:
  117.     mov    a,m            ; fetch a character
  118.     inx    h            ; point to next character
  119.     call    coe
  120.     djnz    pcl            ; print characters till b = 0
  121. ;
  122. ; This section of code assumes that C = maximum characters allowed and 
  123. ; DE -> characters in the buffer already. HL must point to characters in 
  124. ; the buffer and DE points to the character in the buffer actual length.
  125. ;
  126. no$chars:    ; Read console for characters.
  127.     call    cie              ; get the character via direct input
  128. ; check if a terminator
  129.     cpi    erlin
  130.     jz    erase$line
  131.     cpi    esc
  132.     jz    fin$get            ; finish of the get then
  133.     cpi    0dh            ; carriage return ?
  134.     jz    nxt$lin
  135.     cpi    uplin            ; go up a line
  136.     jz    prv$lin
  137.     cpi    dlin
  138.     jz    nxt$lin
  139.     cpi    lchr
  140.     jz    lft$chr
  141.     cpi    del
  142.     jz    lft$chr
  143.     cpi    020h            ; check if less than a space
  144.     jrc    ign$chr                ; ignore them
  145. ; If it is not a formatting character then save it then check if the
  146. ; buffer is full before inserting it. C = max allowed, B = current size
  147.     sta    temp
  148.     ldax    d            ; get character read counter
  149.     cmp    c            ; compare to maximum allowed
  150.     jrz    ign$chr            ; ignore if exactly full
  151.     jrnc    ign$chr            ; no carry if too full
  152. ; If not full or overfull then we merely bump the count and save it back
  153.     inr    a
  154.     stax    d            ; saved
  155. ; All else means that we can insert the character into the buffer
  156.     lda    temp            ; fetch
  157.     mov    m,a            ; save
  158.     call    coe            ; echo the character now
  159.     inx    h            ; point to next memory address
  160.     jr    no$chars        ; keep reading characters
  161. ;
  162. ; This trivial bit of code rings the bell then jumps to get another char.
  163. ; We usually get here due to an illegal control code or buffer full.
  164. ;
  165. ign$chr:    ; Ignore the character in a and ring bell then return to loop
  166.     mvi    a,07            ; bell code
  167.     call    coe
  168.     jr    no$chars        ; get next character
  169. ;
  170. ; This piece of code handles the end of input due to carriage return or
  171. ; down a line code inputs. We must assume that all parameters are up to
  172. ; date so we only have to address the next line of the menu then return
  173. ; to the start of the get section to continue.
  174. ;
  175. nxt$lin:
  176.     lda    itmnum
  177.     inr    a            ; load.bump.save item number
  178.     sta    itmnum
  179. ;
  180.     lded    nxtadr            ; get address of next item
  181.     ldax    d
  182.     cpi    0ffh            ; is it the end of the menu ??
  183.     jnz    get$item        ; use it if it is NOT
  184.     lded    mnuadr            ; all else we get the start address
  185.     xra    a
  186.     sta    itmnum            ; indicate first item number
  187.     jmp    get$item        ; restart from scratch
  188. ;
  189. ; This section of code must go back a line. It does this by backing up
  190. ; using $ characters as indicators. Note that if ITMNUM = 1 then
  191. ; no action is taken and we return to the read loop.
  192. ;
  193. prv$lin:
  194.     lda    itmnum            ; get line number
  195.     ora    a
  196.     jz    no$chars        ; ignore all this if line 1
  197.     dcr    a
  198.     sta    itmnum            ; decrement and save
  199.     ora    a
  200.     jrnz    prv$lin1
  201.     lded    mnuadr            ; point to item 1 
  202.     jmp    get$item
  203. ; If here then we must goto the (ITMNUM)'th dollar address + 3 in the menu
  204. prv$lin1:
  205.     lded    mnuadr            ; point to start of menu
  206.     mov    b,a            ; save the counter
  207. ;
  208. prv$lin2:
  209.     ldax    d
  210.     inx    d
  211.     cpi    '$'
  212.     jrnz    prv$lin2
  213.     djnz    prv$lin2        ; keep on till all found
  214.     inx    d            ; points to address byte 2
  215.     inx    d            ; points to start of string
  216.     jmp    get$item        ; get the data now
  217. ;
  218. ; Here we erase the whole line back to the start.
  219. ; b = number of characters in the buffer.
  220. erase$line:
  221.     ldax    d            ; get the # character there
  222.     ora    a            ; See if none there yet
  223.     jz    no$chars        ; If none, skip the backspacing
  224.     mov    b,a
  225. eol2:
  226.     call    back$char
  227.     djnz    eol2
  228.     xra    a            ; get a zero into character count
  229.     stax    d            ; save line length
  230.     jmp    no$chars
  231. ;
  232. ; Here we back the cursor up a character so long as there are characters 
  233. ; to back up in the buffer. If the buffer is empty then we ring the bell.
  234. ;
  235. ; DE -> characters in the buffer
  236. ; HL -> ascii characters in the buffer
  237. ;
  238. lft$chr:
  239.     ldax    d            ; get the character count
  240.     ora    a            ; empty ??
  241.     jz    ign$chr            ; ring bell and continue
  242.     dcr    a
  243.     stax    d            ; save the decremented count
  244.     call    back$char        ; do the backing up of the cursor
  245.     jmp    no$chars
  246. ;
  247. ; Back the cursor up 1 character and write a null to the buffer.
  248. ;
  249. back$char:
  250.     dcx    h            ; back up the memory pointer too
  251.     mvi    m,00            ; clear the buffer byte
  252. ; Send now a backspace, underline, backspace
  253.     mvi    a,8
  254.     call    coe
  255.     mvi    a,filchr        ; the fill character
  256.     call    coe
  257.     mvi    a,08
  258.     call    coe
  259.     ret
  260. ;
  261. ;----------------------------------------------------------------
  262. ; This is jumped to when the user enters an ESCAPE to quit the input
  263. ; to the data fields.
  264. ;----------------------------------------------------------------
  265. ;
  266. fin$get:
  267.     lded    mnuadr
  268.     lhld    hlsave
  269.     lbcd    bcsave
  270.     ret
  271. ;
  272. ;----------------------------------------------------------------
  273. ; This large routine must use DE to print the menu item it points
  274. ; to and also print the console buffer the menu item points to. 
  275. ; If the console buffer has an address of 00 then it is ignored.
  276. ; On return DE must point to the next menu item or end of menu.
  277. ;----------------------------------------------------------------
  278. ;
  279. disp$item:
  280.     call    setde            ; set up cursor DE-> address
  281.     call    print            ; print DE-> string
  282. ;
  283. ; Now we need to save the current screen address since this is where
  284. ; the console buffer is being printed so we need it for later homing to.
  285.     lda    curx
  286.     sta    bufx
  287.     lda    cury
  288.     sta    bufy            ; saved
  289. ;
  290. ; Now load the address of the console buffer string
  291.     xchg                ; HL -> the address now
  292.     mov    e,m
  293.     inx    h
  294.     mov    d,m
  295.     inx    h
  296. ; Now HL -> next menu string, DE -> console buffer for this string. 
  297. ; This extensive section of code will print the console buffer or prompt
  298. ;
  299.     sded    conadr            ; save CONSOLE BUFFER address
  300. ; See if this menu string has no console buffer
  301.     mov    a,e
  302.     ora    d            ; Is D = E = 0 ?
  303.     jrz    fin$disp        ; put address of menu into de then ret.
  304.     ldax    d            ; get its maximum length
  305.     mov    b,a            ; Save as a counter
  306.     inx    d            ; DE -> characters in the buffer
  307.     inx    d            ; DE -> first buffer character
  308. print$con$buf:
  309.     ldax    d
  310.     inx    d            ; point to next character
  311.     ora    a            ; is this character a null ?
  312.     jrnz    pconbuf2
  313.     mvi    a,filchr        ; if it was load a default
  314. pconbuf2:
  315.     call    coe            ; print it
  316.     djnz    print$con$buf        ; print next string
  317. ; Restore DE as pointer to the menu then do the next item / buffer
  318. ; Note that the address of the console buffer is saved in CONADR.
  319. fin$disp:
  320.     xchg                ; DE -> next string start
  321.     ret
  322. ;
  323. ;----------------------------------------------------------------
  324. ; Set up the screen address -> by DE stored in memory.
  325. ; The address is saved in curx, cury. Note that the offset (32) 
  326. ; is added to both x and y.
  327. ;----------------------------------------------------------------
  328. ;
  329. setde:
  330.     ldax    d            ; get the X address
  331.     sta    curx
  332.     inx    d
  333.     ldax    d
  334.     sta    cury
  335.     inx    d            ; DE now -> past end
  336. ;
  337. ; Flow onto the next part which uses curx and cury to set up the cursor
  338. ;
  339. ;----------------------------------------------------------------
  340. ; Use the values in curx and cury for the cursor position to
  341. ; be used to set the cursor.
  342. ;----------------------------------------------------------------
  343. ;
  344. setcur:
  345.     mvi    a,esc
  346.     call    coe
  347.     mvi    a,'='
  348.     call    coe
  349. ; Now the Y value
  350.     lda    cury
  351.     adi    32
  352.     call    coe
  353. ; X address
  354.     lda    curx
  355.     adi    32
  356.     jmp    coe             ; all done
  357. ;
  358. ;----------------------------------------------------------------
  359. ; Print the string -> by DE. Return with DE pointing past the 
  360. ; string end so as to point to the start of the next string.
  361. ; NOTE that this routine updates the CURX screen address. This is
  362. ; vital for all printing functions.
  363. ;----------------------------------------------------------------
  364. ;
  365. print:
  366.     ldax    d
  367.     inx    d
  368.     ora    a
  369.     rz
  370.     cpi    '$'            ; END ?
  371.     rz
  372.     call    coe
  373.     lda    curx
  374.     inr    a
  375.     sta    curx            ; loaded.updated.saved
  376.     jr    print
  377. ;
  378. ; Data storage of string addresses and cursor addresses.
  379. ;
  380.     dseg
  381. ;
  382. nxtadr    db    00,00                ; current string address
  383. conadr    db    00,00                ; address of a console buffer
  384. mnuadr    db    00,00                ; address of a menu string
  385. itmnum    db    00                ; menu item number counter
  386. ;
  387. bufx    db    00                ; buffer start screen x value
  388. bufy    db    00                ; buffer start screen y value
  389. ;
  390. curx:    db    00            ; loaded by setxy
  391. cury:    db    00            ; as above
  392. ;
  393. hlsave    db    00,00
  394. bcsave    db    00,00                ; preserver registers in these
  395. temp    db    00                ; save cons. character temp.
  396. ;
  397.     end
  398.  
  399.