; SORTV.ASM VER 1.2 ; BY WARD CHRISTENSEN ; (REVISED 1/3/81) ; ;SIMPLE SORT PROGRAM FOR SORTING LISTS OF NAMES, ;OR ANY OTHER VARIABLE LENGTH FILE, WITH CR/LF ;DELIMITED RECORDS. ; ;THIS IS A "SIMPLE" PROGRAM: FILE MUST FIT IN MEMORY. ; ;--->NEEDS MAC TO ASSEMBLE<--- ; ;01/03/81 CHANGE STACK INIT. BY KEITH PETERSEN, W8SDZ ; ;11/15/80 ADD @ COMMAND (WLC) ; ;10/24/80 ORIGINALLY WRITTEN BY WARD CHRISTENSEN ; ;FORMAT: ; SORTV INPUT-NAME OUTPUT-NAME ; OR SORTV NAME ; ;IF THE SECOND FORMAT IS USED, THE FILE IS READ INTO ;MEMORY, SORTED, ERASED, CREATED, AND WRITTEN BACK. ; ; THE SORT WILL BE BASED ON THE FIRST CHARACTERS ; IN THE FILE, UNLESS THE COMMAND IS FOLLOWED BY ; AN "@" SIGN, THEN A STRING (1 OR MORE CHARACTERS) ; TO SKIP. ; ;EX: SORTV NAMES.SUB @. ; ;WILL SORT NAMES.SUB BY FILETYPE, SINCE IT SKIPS PAST ;THE "." BEFORE DOING THE COMPARE. ; 001A = EOF EQU 1AH 000D = CR EQU 0DH 000A = LF EQU 0AH ; ;(FROM EQU10.LIB...) ; 0000 # MF SET 0 ;SHOW MOVE NOT REQUESTED 0000 # CF SET 0 ;SHOW COMP NOT REQUESTED ; ;DEFINE SOME MACROS TO MAKE THINGS EASIER ; ;DEFINE DATA MOVE MACRO: MOVE FROM,TO,LENGTH ; FROM MAY BE ADDR, OR QUOTED STRING ; MOVE MACRO ?F,?T,?L MCSUB ?F,?T,?L ;;HANDLE ARGS CALL MOVER MF SET -1 ;;SHOW EXPANSION ENDM ; ;COMPARE MACRO COMP MACRO ?F,?T,?L MCSUB ?F,?T,?L ;;HANDLE ARGS CALL COMPR CF SET -1 ;;SHOW EXPANSION ENDM ; ;MCSUB - HANDLES MOVE, COMPARE ARGUMENTS MCSUB MACRO ?F,?T,?L IF NOT NUL ?F IRPC ?C,?F ?Q SET '&?C&?C' ;;TEST FOR QUOTE EXITM ENDM IF ?Q EQ '''' LOCAL ?B,?Z CALL ?Z ?B DB ?F ?Z POP H ;GET FROM LXI B,?Z-?B ;GET LEN ELSE LXI H,?F ENDIF ENDIF IF NOT NUL ?T LXI D,?T ENDIF IF NOT NUL ?L LXI B,?L ENDIF ENDM ; ;DEFINE CP/M MACRO - CPM FNC,PARM [,NOSAVE] ; CPM MACRO ?F,?P,?N IF NUL ?N PUSH B PUSH D PUSH H ENDIF IF NOT NUL ?F MVI C,?F ENDIF IF NOT NUL ?P LXI D,?P ENDIF CALL BDOS IF NUL ?N POP H POP D POP B ENDIF ENDM ; RDB MACRO ?F PUSH D PUSH H LXI H,?F CALL RDBYTE POP H POP D ENDM ; WRB MACRO ?F PUSH H LXI H,?F CALL WRBYTE POP H ENDM ; EFCB MACRO ?B,?P,?F DW ?B DW 0 DB ?P DW ?F ENDM ; 0100 ORG 100H ; ;INIT LOCAL STACK ; 0100 31CB05 LXI SP,STACK ; 0103 CD1601 CALL START 0106 534F525456 DB 'SORTV rev 1.2' 0113 0D0A24 DB CR,LF,'$' ; 0116 D1 START POP D ;GET ID 0117 0E09 MVI C,PRINT 0119 CD0500 CALL BDOS ;PRINT ID ; ;START OF PROGRAM EXECUTION ; 011C CD3A01 CALL SVSKIP ;SAVE SKIP INFO 011F CD5201 CALL CKNAMES ;SEE THAT 2 NAMES ARE THERE 0122 CDCB01 CALL OPENIN ;OPEN INPUT FILE 0125 CDF501 CALL READN ;READ THE NAMES 0128 CDA502 CALL SORTN ;SORT THE NAMES 012B CD3303 CALL WRITEN ;WRITE THE NAMES 012E CD4C05 CALL ERXIT 0131 2B2B444F4E DB '++DONE++$' ; ;====> SUBROUTINES ; ---------------- ; ;====> SAVE "SKIP TO" INFORMATION ; 013A 218100 SVSKIP LXI H,81H ; 013D 7E SVSKL MOV A,M 013E B7 ORA A 013F C8 RZ ;NO 'SKIP TO' 0140 FE40 CPI '@' ;SKIP DELIMITER? 0142 23 INX H 0143 C23D01 JNZ SVSKL 0146 115E05 LXI D,SKIPC ;CHARS TO SKIP ; 0149 7E SVSKL2 MOV A,M 014A 12 STAX D 014B 23 INX H 014C 13 INX D 014D B7 ORA A 014E C24901 JNZ SVSKL2 0151 C9 RET ; ;====> CHECK THAT 2 NAMES WERE SUPPLIED ; 0152 3A5D00 CKNAMES LDA FCB+1 0155 FE20 CPI ' ' 0157 CA8101 JZ NONAME 015A 3A6D00 LDA FCB2+1 015D FE20 CPI ' ' 015F CA7401 JZ SAMENAM 0162 FE40 CPI '@' ;SKIP PARM? 0164 CA7401 JZ SAMENAM MOVE FCB2,OUTNAME,12 0167+216C00 LXI H,FCB2 016A+11CB05 LXI D,OUTNAME 016D+010C00 LXI B,12 0170+CDEF03 CALL MOVER 0173 C9 RET ; ;OUTPUT NAME = INPUT NAME ; SAMENAM MOVE FCB,OUTNAME,12 0174+215C00 LXI H,FCB 0177+11CB05 LXI D,OUTNAME 017A+010C00 LXI B,12 017D+CDEF03 CALL MOVER 0180 C9 RET ; 0181 CD4C05 NONAME CALL ERXIT 0184 2B2B457272 DB '++Error - ',CR,LF 0190 436F6D6D61 DB 'Command format requires an ' 01AB 696E707574 DB 'input name, and an output name.$' ; ;====> OPEN THE INPUT FILE ; OPENIN CPM OPEN,FCB 01CB+C5 PUSH B 01CC+D5 PUSH D 01CD+E5 PUSH H 01CE+0E0F MVI C,OPEN 01D0+115C00 LXI D,FCB 01D3+CD0500 CALL BDOS 01D6+E1 POP H 01D7+D1 POP D 01D8+C1 POP B 01D9 3C INR A 01DA C0 RNZ ;SUCCESSFUL? RETURN 01DB CD4C05 CALL ERXIT 01DE 2B2B496E70 DB '++Input file not found$' ; ;====> READ IN THE NAMES ; 01F5 21000A READN LXI H,BUFF ;TO FIRST NAME ; 01F8 CD0202 READNL CALL READL ;READ ONE LINE 01FB D8 RC ;GOT EOF, RETURN 01FC CD9402 CALL CHAIN ;CHAIN THINGS TOGETHER 01FF C3F801 JMP READNL ; ;====> READ ONE LINE ; 0202 22D805 READL SHLD CURR ;SAVE CURR LINE PTR 0205 AF XRA A ;GET 0 0206 77 MOV M,A ;INIT FORWARD 0207 23 INX H ; POINTER 0208 77 MOV M,A ; TO 0209 23 INX H ; 0 020A 115E05 LXI D,SKIPC ;TO CK SKIP CHARS PRESENT ; 020D 3A0700 READLLP LDA BDOS+2 ;ARE WE 0210 3D DCR A ; OVER- 0211 BC CMP H ; FLOW- 0212 CA7602 JZ OFLO ; ING? RDB EXTFCB ;READ A BYTE 0215+D5 PUSH D 0216+E5 PUSH H 0217+215505 LXI H,EXTFCB 021A+CDFA03 CALL RDBYTE 021D+E1 POP H 021E+D1 POP D 021F FE1A CPI EOF ;SET CARRY 0221 37 STC ; AND RETURN 0222 C8 RZ ; IF EOF 0223 77 MOV M,A ;STORE CHAR ;TEST FOR SKIP CHAR FOUND 0224 47 MOV B,A ;SAVE FOR COMPARE 0225 1A LDAX D 0226 B7 ORA A ;NO MORE SKIP CHARS? 0227 CA2F02 JZ READLNS ;NO MORE 022A B8 CMP B ;A SKIP CHAR? 022B C22F02 JNZ READLNS ;NO, KEEP TRYIN. 022E 13 INX D ;TO NEXT SKIP CHAR ; 022F 23 READLNS INX H ;POINT TO NEXT 0230 78 MOV A,B ;GET CHAR 0231 FE0D CPI CR ;END OF LINE? 0233 C20D02 JNZ READLLP ; NO, LOOP. RDB EXTFCB ;GOBBLE UP LF 0236+D5 PUSH D 0237+E5 PUSH H 0238+215505 LXI H,EXTFCB 023B+CDFA03 CALL RDBYTE 023E+E1 POP H 023F+D1 POP D 0240 1A LDAX D ;GET SKIP CHAR END 0241 B7 ORA A ;TEST IT AND SET "NO EOF" 0242 C8 RZ ;ERROR - NO SKIP CHAR 0243 2AD805 LHLD CURR 0246 23 INX H ;SKIP 0247 23 INX H ; POINTER ; 0248 5E ERPLP MOV E,M CPM WRCON 0249+C5 PUSH B 024A+D5 PUSH D 024B+E5 PUSH H 024C+0E02 MVI C,WRCON 024E+CD0500 CALL BDOS 0251+E1 POP H 0252+D1 POP D 0253+C1 POP B 0254 7E MOV A,M 0255 23 INX H 0256 FE0D CPI CR 0258 C24802 JNZ ERPLP 025B CD4C05 CALL ERXIT 025E 0A2B2B4E4F DB LF,'++NO SKIP CHAR FOUND++$' ; 0276 CD4C05 OFLO CALL ERXIT 0279 2B2B46696C DB '++File won''t fit in memory$' ; ;====> CHAIN RECORDS TOGETHER ; 0294 E5 CHAIN PUSH H ;SAVE POINTER 0295 2AD805 LHLD CURR ;GET CURRENT 0298 EB XCHG ; TO DE 0299 2A5C05 LHLD PREV ;PREV TO HL 029C 73 MOV M,E ;MOVE CURR 029D 23