TITLE "SSORT0 - SYSLIB 4.3" NAME ('SSBINI') ;================================================================= ; The Libraries, Version 4, (C) 1989 by Alpha Systems Corp. ;----------------------------------------------------------------- ; Author : Joe Wright with touches by Harold F. Bower ; Date : 19 Oct 90 ; Version : 2.0 ; Module : SSORT0 ; Abstract: This module contains the routine SSBINIT which sets the ; initial values for a Sort Specification Block, and initializes ; pointers for a subsequent sort. The routine can optionally be used ; to establish a memory area for record storage upon which to sort, ; and performs extensive checks for memory overflow. ; ; The Sort Specification Block (SSB) has the following format: ; ; Bytes 0&1: (SORDER) Starting Address of File (1st byte of 1st record) ; Bytes 2&3: (SNREC) Number of Records in the File ; Bytes 4&5: (SSIZE) Size of Each Record (in Bytes) ; Bytes 6&7: (SCOMP) Address of a Compare Routine Provided by the User ; This routine compares two records, one addressed ; by HL and the other addressed by DE; if the record ; addressed by DE is less in sorting order than that ; addressed by HL, this routine returns with Carry ; Set (C); if the records are equal in sorting order, ; this routine returns with Zero Set (Z); no registers ; other than the PSW may be affected by this routine. ; Bytes 8&9: (SORDER) Address of ORDER Buffer (SNREC*2 in size) ; Byte 10: (SPOINT) 0FFH = Use pointers, 0 = Don't use pointers ; Byte 11: (SNOREC) If Byte 10<>0, 0 means Reorder records after sort ; FF means do Not reorder after sort ; Revision: ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Module Entry Points PUBLIC SSBINIT ; Externals EXT SFIRST, SNREC, SSIZE, SORDER ; Variables EXT LOGSSB, RETSSB ; In SORT1 ; Definitions BDOS EQU 5 ; Bdos Entry Point .Z80 CSEG ;=============================================================== ; NAME - SSBINIT ; Entry: HL - Points to first available byte after User's pgm ; This value is placed in the SSB bytes 8&9 (SORDER) ; DE - points to an SSB ; Exit : HL - Points to first byte for user's data file ; A = 0FFH, Zero flag Reset (NZ) if Ok ; A = 0, Zero Flag Set (Z) if Error ; Uses : AF,HL ;NOTE: If the user has already loaded his data and just wants to ; allocate an ORDER table, then he should save HL before calling ; SSBINI, restore HL upon return from SSBINI, and then store HL ; into his FIRST entry before calling SORT. ; If bytes 0&1 (SFIRST) contain 0000H, SSBINIT will use the next ; free memory address [N*2+ORDER] to initialize the Order table ; and set FIRST to this value. If the user has passed an address ; in FIRST, then that value will be used to seed the Order table. ;=============================================================== SSBINIT: PUSH BC ; Save BC PUSH DE ; .ptr to User's SSB PUSH HL ; ..next available byte address CALL LOGSSB ; Copy Caller's SSB to us POP DE ; Get next available byte address LD (SORDER),DE ; Set ptr to it LD HL,(SNREC) ; Get number of records LD A,H ; Check for Non-Zero OR L JR Z,SSBERR ; ..don't even try if Zero LD B,H ; Count to BC for Ptr Build LD C,L ADD HL,HL ; Double it with error checking JR C,SSBERR ; ..error exit if Overflow ADD HL,DE ; Add Start to Length with Error Checking JR C,SSBERR ; ..error if Overflow (>64k) EX DE,HL ; Potential FIRST to DE LD HL,(BDOS+1) ; .get protect address SBC HL,DE ; Are we safe? JR C,SSBERR ; ..jump if Order table would Kill System ; Everything seems Ok to here. Let's build the Order table now. We need ; the seed address for the Order table. If the user has passed us one in ; SSB+0, use his, else use the first address at the end of the Order table. LD HL,(SFIRST) ; SSB+0 from the User LD A,H OR L ; Check for Zero JR Z,BUILD ; Use end of Order table as seed ; Caller has passed his own FIRST pointer in the SSB EX DE,HL ; User's FIRST in DE ; Set up Order Table; DE points to first record in File (FIRST), ; BC = Number of recs remaining (N) BUILD: PUSH DE ; Save calculated FIRST for exit LD HL,(SORDER) ; First pointer at Order Table beginning SSBINL: LD (HL),E ; Store Low-order address INC HL ; .Pt to next order byte LD (HL),D ; ..Store High-order address INC HL ; ...Pt to next order entry PUSH HL ; Save ptr LD HL,(SSIZE) ; Get number of Bytes/Entry ADD HL,DE EX DE,HL ; Point DE to next Record entry POP HL ; .restore ptr to Order Table DEC BC ; ..count down LD A,B ; Done? OR C JR NZ,SSBINL ; ..loop til done if not POP HL ; FIRST to HL LD (SFIRST),HL ; ..saving in SSB PUSH HL CALL RETSSB ; Updated SSB to Caller POP HL ; Restore Pointer to First Rec (FIRST) DEC A ; 0 -> FFh and NZ (Success) SSBER0: POP DE ; Restore regs POP BC RET SSBERR: XOR A ; Failure LD HL,(SORDER) ; Restore ptr to user's Buffer JR SSBER0 ; ..and exit w/error code END ;..of SSORT0.Z80