home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol090 / systest4.mac < prev    next >
Encoding:
Text File  |  1984-04-29  |  5.5 KB  |  245 lines

  1. ;
  2. ;  PROGRAM:  SYSTEST4
  3. ;  AUTHOR:  Richard Conn
  4. ;  PURPOSE:  To allow the user to input a list of text elements and then sort
  5. ;        that list in alphabetical order
  6. ;  NOTE:  This program demonstrates the use of SYSLIB and its Sort Routines
  7. ;
  8.  
  9. ;
  10. ;  External Routines
  11. ;
  12.     ext    ssbinit    ; Initialize Sort Specification Block (SSB)
  13.     ext    sort    ; SORT Routine
  14.     ext    crlf    ; New Line
  15.     ext    cin    ; Char In
  16.     ext    caps    ; Capitalize char
  17.     ext    print    ; Print string
  18.     ext    bbline    ; Input Line Editor
  19.     ext    cout    ; Print Char
  20.     ext    codend    ; End of code/beginning of scratch buffer
  21.  
  22. ;
  23. ;  Equates
  24. ;
  25. cr    equ    0dh
  26. lf    equ    0ah
  27.  
  28. ;
  29. ;  Start of Program
  30. ;
  31.     jmp    go
  32. done:
  33.     ret        ; placed here for testing purposes
  34.  
  35. ;
  36. ;  First we have to use the routine CODEND to determine where the first
  37. ;  free byte in the scratch data area which follows the program is.
  38. ;
  39. go:
  40.     call    print
  41.     db    'SYSTEST4 -- Sort Demonstration',cr,lf,0
  42. go1:
  43.     call    codend    ; get address of end of code
  44.     shld    start    ; save address of first byte of first record
  45.     xchg        ; ... in DE
  46. ;
  47. ;  I will use BC to contain a count of the number of records entered
  48. ;  and DE to point to the next location in memory to store the next record.
  49. ;
  50.     lxi    b,0    ; set record count
  51.  
  52. ;
  53. ;  Prompt user for input and get a line of text from him.
  54. ;
  55. loop:
  56.     call    print
  57.     db    cr,lf,'Entry (<CR>=Done)? ',0
  58.     xra    a    ; do not capitalize input line
  59.     call    bbline    ; get line from user
  60.     ora    a    ; A=char count=0 if done (just <CR> typed)
  61.     jz    sort1    ; do sort if done
  62.     inx    b    ; incr record count
  63.     push    b    ; save record count
  64.     mvi    b,40    ; copy user input into next record (pted to by DE)
  65.  
  66. ;
  67. ;  This loop copies the user's string, which was input by BBLINE and pointed
  68. ;  to by HL, into the next record position, which is pointed to by DE.
  69. ;
  70. lp1:
  71.     mov    a,m    ; get byte
  72.     ora    a    ; done if zero
  73.     jz    lp2
  74.     stax    d    ; put byte
  75.     inx    h    ; pt to next
  76.     inx    d
  77.     dcr    b    ; count down
  78.     jmp    lp1
  79.  
  80. ;
  81. ;  This loop fills the rest of the record with spaces.  This is not
  82. ;  a very good program in the sense that it does not do any error checking
  83. ;  to see if the user typed more than 40 chars, but it is OK for this demo.
  84. ;
  85. lp2:
  86.     mvi    a,' '    ; store <SP>
  87.     stax    d    ; put byte
  88.     inx    d    ; pt to next
  89.     dcr    b    ; count down
  90.     jnz    lp2
  91.  
  92. ;
  93. ;  Now we get our record count back and continue the program.
  94. ;
  95.     pop    b    ; get rec count
  96.     jmp    loop    ; continue until done
  97.  
  98. ;
  99. ;  The user has typed an empty line, and the number of records is in BC.
  100. ;
  101. sort1:
  102.  
  103. ;
  104. ;  Set up record count field of SSB
  105. ;
  106.     mov    h,b    ; save record count
  107.     mov    l,c
  108.     shld    recnt    ; save record count field of Sort Specification Block
  109.  
  110. ;
  111. ;  Test for no records and abort if so
  112. ;
  113.     mov    a,h    ; any records?
  114.     ora    l
  115.     jnz    sort2
  116.     call    print
  117.     db    cr,lf,'No Records -- Aborting Sort',0
  118.     ret        ; Return to OS
  119.  
  120. ;
  121. ;  Set up record size field of SSB
  122. ;
  123. sort2:
  124.     lxi    h,40    ; 40 bytes/record
  125.     shld    recsiz    ; save record size field of Sort Spec Block (SSB)
  126.  
  127. ;
  128. ;  Set up compare routine address field of SSB
  129. ;
  130.     lxi    h,comp    ; address of compare routine
  131.     shld    cmpadr    ; save compare address in proper field of SSB
  132.  
  133. ;
  134. ;  I shall now use SSBINIT to set up the ORDER buffer and check to see that
  135. ;  it does not overflow the TPA.  SSBINIT will also set FIRSTP to the byte
  136. ;  after the order buffer, but I will discard this and reset FIRSTP to point
  137. ;  to the first byte of my first record.
  138. ;
  139.     xchg        ; HL pts to next available entry
  140.     lxi    d,ssb    ; Pt to SSB
  141.     call    ssbinit    ; initialize the SSB FIRSTP and ORDER buffers
  142.     lhld    start    ; set start address field of SSB since ORDER buffer
  143.     shld    firstp    ;   is located AFTER the FIRSTP buffer
  144.  
  145. ;
  146. ;  Set the flag to tell SORT to use pointers to do the sort.
  147. ;
  148.     mvi    a,0ffh    ; non-zero
  149.     sta    sflag    ; set flag in SSB
  150.  
  151. ;
  152. ;  The Sort Specification Block (SSB) is now properly loaded, so let's sort!
  153. ;
  154.     call    print
  155.     db    cr,lf,'Starting Sort --',cr,lf,0
  156.     lxi    d,ssb    ; pt to ssb
  157.     call    sort    ; sort it
  158.  
  159. ;
  160. ;  Buffer is now sorted -- print out results
  161. ;
  162.     call    print
  163.     db    cr,lf,'Buffer After Sort --',cr,lf,0
  164.     call    prbuf
  165.  
  166. ;
  167. ;  Prompt the user to continue
  168. ;
  169.     call    print
  170.     db    cr,lf,'Do you wish to run this test again (Y/N)? ',0
  171.     call    cin
  172.     call    caps
  173.     call    cout
  174.     call    crlf    ; new line
  175.     cpi    'N'
  176.     jnz    go    ; rerun if not No
  177.     jmp    done
  178.  
  179. ;
  180. ;  Print the contents of the buffer containing all loaded records
  181. ;
  182. prbuf:
  183.     lhld    recnt    ; get record count
  184.     xchg        ; ... in DE
  185.     lhld    firstp    ; pt to address of first record
  186. prloop:
  187.     call    crlf    ; new line
  188.     mvi    b,40    ; print 40 chars
  189. prl1:
  190.     mov    a,m    ; get char
  191.     inx    h    ; pt to next
  192.     call    cout    ; print char
  193.     dcr    b    ; count down chars
  194.     jnz    prl1
  195.     dcx    d    ; count recs
  196.     mov    a,d
  197.     ora    e
  198.     jnz    prloop
  199.     ret
  200.  
  201. ;
  202. ;  Compare Routine for SORT
  203. ;  This is a simple byte-for-byte comparison routine, which exists as
  204. ;  soon as two bytes which are not equal are encountered.
  205. ;
  206. ;  This routine returns with the Zero Flag Set (Z) if the two records
  207. ;  pointed to by HL and DE are equal (each byte the same).  It returns
  208. ;  with the Carry Flag Set (C) if the record pointed to by DE is less
  209. ;  than the record pointed to by HL in ASCII sorting sequence.
  210. ;
  211. comp:
  212.     push    h    ; save regs
  213.     push    d
  214.     push    b
  215.     mvi    b,40    ; 40 bytes max
  216. cmpl:
  217.     ldax    d    ; get byte
  218.     cmp    m    ; compare
  219.     jz    cmpok    ; continue or fall thru with proper flags set
  220. cmpd:
  221.     pop    b    ; restore regs -- flag set
  222.     pop    d
  223.     pop    h
  224.     ret
  225. cmpok:
  226.     inx    h    ; pt to next
  227.     inx    d
  228.     dcr    b    ; count down
  229.     jnz    cmpl    ; continue
  230.     jmp    cmpd    ; done
  231.  
  232. ;
  233. ; Buffers
  234. ;
  235. start:    ds    2    ; address of 1st record
  236. ssb:            ; this is the Sort Specification Block
  237. firstp:    ds    2    ; Pointer to the first byte of first record
  238. recnt:    ds    2    ; Number of records
  239. recsiz:    ds    2    ; Size of record
  240. cmpadr:    ds    2    ; Address of comparison routine
  241. order:    ds    2    ; Address of pointer table (if used)
  242. sflag:    ds    2    ; Flag telling SORT to use pointers (0=no)
  243.  
  244.     end
  245.