; ; PROGRAM: SYSTEST4 ; AUTHOR: Richard Conn ; PURPOSE: To allow the user to input a list of text elements and then sort ; that list in alphabetical order ; NOTE: This program demonstrates the use of SYSLIB and its Sort Routines ; ; ; External Routines ; ext ssbinit ; Initialize Sort Specification Block (SSB) ext sort ; SORT Routine ext crlf ; New Line ext cin ; Char In ext caps ; Capitalize char ext print ; Print string ext bbline ; Input Line Editor ext cout ; Print Char ext codend ; End of code/beginning of scratch buffer ; ; Equates ; cr equ 0dh lf equ 0ah ; ; Start of Program ; jmp go done: ret ; placed here for testing purposes ; ; First we have to use the routine CODEND to determine where the first ; free byte in the scratch data area which follows the program is. ; go: call print db 'SYSTEST4 -- Sort Demonstration',cr,lf,0 go1: call codend ; get address of end of code shld start ; save address of first byte of first record xchg ; ... in DE ; ; I will use BC to contain a count of the number of records entered ; and DE to point to the next location in memory to store the next record. ; lxi b,0 ; set record count ; ; Prompt user for input and get a line of text from him. ; loop: call print db cr,lf,'Entry (=Done)? ',0 xra a ; do not capitalize input line call bbline ; get line from user ora a ; A=char count=0 if done (just typed) jz sort1 ; do sort if done inx b ; incr record count push b ; save record count mvi b,40 ; copy user input into next record (pted to by DE) ; ; This loop copies the user's string, which was input by BBLINE and pointed ; to by HL, into the next record position, which is pointed to by DE. ; lp1: mov a,m ; get byte ora a ; done if zero jz lp2 stax d ; put byte inx h ; pt to next inx d dcr b ; count down jmp lp1 ; ; This loop fills the rest of the record with spaces. This is not ; a very good program in the sense that it does not do any error checking ; to see if the user typed more than 40 chars, but it is OK for this demo. ; lp2: mvi a,' ' ; store stax d ; put byte inx d ; pt to next dcr b ; count down jnz lp2 ; ; Now we get our record count back and continue the program. ; pop b ; get rec count jmp loop ; continue until done ; ; The user has typed an empty line, and the number of records is in BC. ; sort1: ; ; Set up record count field of SSB ; mov h,b ; save record count mov l,c shld recnt ; save record count field of Sort Specification Block ; ; Test for no records and abort if so ; mov a,h ; any records? ora l jnz sort2 call print db cr,lf,'No Records -- Aborting Sort',0 ret ; Return to OS ; ; Set up record size field of SSB ; sort2: lxi h,40 ; 40 bytes/record shld recsiz ; save record size field of Sort Spec Block (SSB) ; ; Set up compare routine address field of SSB ; lxi h,comp ; address of compare routine shld cmpadr ; save compare address in proper field of SSB ; ; I shall now use SSBINIT to set up the ORDER buffer and check to see that ; it does not overflow the TPA. SSBINIT will also set FIRSTP to the byte ; after the order buffer, but I will discard this and reset FIRSTP to point ; to the first byte of my first record. ; xchg ; HL pts to next available entry lxi d,ssb ; Pt to SSB call ssbinit ; initialize the SSB FIRSTP and ORDER buffers lhld start ; set start address field of SSB since ORDER buffer shld firstp ; is located AFTER the FIRSTP buffer ; ; Set the flag to tell SORT to use pointers to do the sort. ; mvi a,0ffh ; non-zero sta sflag ; set flag in SSB ; ; The Sort Specification Block (SSB) is now properly loaded, so let's sort! ; call print db cr,lf,'Starting Sort --',cr,lf,0 lxi d,ssb ; pt to ssb call sort ; sort it ; ; Buffer is now sorted -- print out results ; call print db cr,lf,'Buffer After Sort --',cr,lf,0 call prbuf ; ; Prompt the user to continue ; call print db cr,lf,'Do you wish to run this test again (Y/N)? ',0 call cin call caps call cout call crlf ; new line cpi 'N' jnz go ; rerun if not No jmp done ; ; Print the contents of the buffer containing all loaded records ; prbuf: lhld recnt ; get record count xchg ; ... in DE lhld firstp ; pt to address of first record prloop: call crlf ; new line mvi b,40 ; print 40 chars prl1: mov a,m ; get char inx h ; pt to next call cout ; print char dcr b ; count down chars jnz prl1 dcx d ; count recs mov a,d ora e jnz prloop ret ; ; Compare Routine for SORT ; This is a simple byte-for-byte comparison routine, which exists as ; soon as two bytes which are not equal are encountered. ; ; This routine returns with the Zero Flag Set (Z) if the two records ; pointed to by HL and DE are equal (each byte the same). It returns ; with the Carry Flag Set (C) if the record pointed to by DE is less ; than the record pointed to by HL in ASCII sorting sequence. ; comp: push h ; save regs push d push b mvi b,40 ; 40 bytes max cmpl: ldax d ; get byte cmp m ; compare jz cmpok ; continue or fall thru with proper flags set cmpd: pop b ; restore regs -- flag set pop d pop h ret cmpok: inx h ; pt to next inx d dcr b ; count down jnz cmpl ; continue jmp cmpd ; done ; ; Buffers ; start: ds 2 ; address of 1st record ssb: ; this is the Sort Specification Block firstp: ds 2 ; Pointer to the first byte of first record recnt: ds 2 ; Number of records recsiz: ds 2 ; Size of record cmpadr: ds 2 ; Address of comparison routine order: ds 2 ; Address of pointer table (if used) sflag: ds 2 ; Flag telling SORT to use pointers (0=no) end