IMD 1.16: 8/06/2007 14:24:54 ebmmug.024 eastbay micromate users' group utilities: du89, dirban&label, deskmaster,time,za80asm,certify disk issued: july 11, 1985 DIRLABELASM9DESKMASTLBR DESKMASTLBRFORSALE JUL PRINT COM&!"#DIRBANERASM@$%&'DIRLABELCOM(DIRBANERCOM)PDUMP COM)*+,SAP COM-.DDEU COMd/012345CERTIFY COM 6789:;<=>DU-V87 DOCY?@ABCDDU-V89 COMNU$ THEN PRINT ME$:REM Error message if any 335 IF OU=PR AND ME$<>NU$ THEN LPRINT ME$ 336 ME$=NU$ 337 PRINT:PRINT ": ";: REM prompt for input 338 IF OU=PR THEN LPRINT:LPRINT ": "; 340 LN=80:FC=32:LC=127:GOSUB 20000:REM GET LINE 350 IF EC$="ESC" THEN GOTO 800 360 IF T$=NU$ THEN GOTO 300: REM re-prompt 399 REM **************************************** 400 REM PARSE INFIX EXPRESSION INTO TOKENS 410 REM IMPORT: T$ 420 REM EXPORT: I$(),I 430 REM 450 N$="NOTVAL":IN$="NOTID":REM value,identifier flags 455 I=0 460 FOR C=1 TO LEN(T$):REM For each char in expression 470 C$=MID$(T$,C,1) 475 IF C$=BL$ THEN GOTO 570 480 GOSUB 5000: REM GET CHARACTER TYPE (TP$) 485 IF TP$="Bad character" THEN ME$=TP$:GOTO 300 486 IF TP$<>"NUMERIC" AND N$="VAL" THEN N$="NOTVAL" 490 IF TP$="OPERATOR" AND IN$="ID" AND C$<>"=" THEN ID$=I$(I):GOSUB 1400:I$(I)=RIGHT$(STR$(NU),LEN(STR$(NU))-1):IF ME$<>NU$ THEN GOTO 300 491 IF TP$="OPERATOR" AND IN$="ID" THEN IN$="NOTID":GOTO 508 493 IF TP$="NUMERIC" AND N$="VAL" THEN GOTO 570 499 IF TP$="ALPHA" AND IN$="NOTID" THEN I=I+1:I$(I)=C$:IN$="ID":GOTO 570 502 IF TP$<>"OPERATOR" AND IN$="ID" THEN I$(I)=I$(I)+C$:GOTO 570 505 IF TP$="NUMERIC" AND N$="NOTVAL" THEN I=I+1:I$(I)=RIGHT$(STR$(VAL(RIGHT$(T$,LEN(T$)-C+1))),LEN(STR$(VAL(RIGHT$(T$,LEN(T$)-C+1))))-1):N$="VAL":GOTO 570 508 IF TP$="OPERATOR" THEN I=I+1:I$(I)=C$:GOTO 570 570 NEXT 580 IF IN$="ID" AND I>1 THEN ID$=I$(I):GOSUB 1400:I$(I)=RIGHT$(STR$(NU),LEN(STR$(NU))-1):IF ME$<>NU$ THEN GOTO 300 599 REM ******************************************* 600 REM INTERPRET EXPRESSION 610 REM IMPORT: I$(I) 611 REM 612 IF I=0 THEN GOTO 300 613 LW$=I$(1):GOSUB 900:I1$=UP$ 615 C$=LEFT$(I$(1),1):GOSUB 5000 617 IF TP$="NUMERIC" AND I$(2)="=" THEN ME$="Can't assign a value to a number":GOTO 300 620 IF I$(2)="=" AND I>=2 THEN GOSUB 1500:GOTO 300 621 IF I1$="HELP" THEN GOSUB 6000:GOTO 300 REM LIST COMMANDS 623 IF I1$="LIST" THEN GOSUB 1600:GOTO 300 REM LIST VARIABLE VALUES 625 IF I1$="CLEAR" THEN L3=0:FOR N=1 TO MV:N$(N)=NU$:NEXT:GOTO 300 630 IF I1$="PON" THEN OU=PR:GOTO 300:REM Output to printer 640 IF I1$="POFF" THEN OU=SC:GOTO 300 650 IF I1$="EXAMPLES1" THEN RESTORE:PRINT CL$:FOR X=1 TO 11:READ X$:PRINT X$:NEXT:GOTO 300 660 IF I1$="EXAMPLES2" THEN RESTORE:PRINT CL$:FOR X=1 TO 11:READ X$:NEXT:FOR X=12 TO 23:READ X$:PRINT X$:NEXT:GOTO 300 670 IF I=1 THEN ID$=I$(1):GOSUB 1400:IF ME$=NU$ THEN GOTO 690 671 IF ME$<>NU$ THEN GOTO 300 680 IB=1:GOSUB 1009: REM Default: evaluate expression 690 PRINT BL$;NU:REM Display numeric answer 691 IF OU=PR THEN LPRINT BL$;NU 700 GOTO 300: REM end with ESC 800 DE$="DATA":GOSUB 2570:REM CHECK DISK ID 810 PRINT CL$:FOR N=1 TO 11:PRINT:NEXT 820 PRINT SPC(13);"Reloading Desk Master...":CHAIN "DESK-DM.BAS" 898 REM ****************************************** 899 REM ****************************************** 900 REM *** TRANSLATE UPPERCASE TO LOWERCASE *** 910 REM IMPORT: LW$ (lowercase string) 915 REM EXPORT: UP$ (UPPERCASE STRING) 920 UP$=NU$ 930 FOR N=1 TO LEN(LW$) 940 C$=MID$(LW$,N,1) 950 IF C$>"Z" THEN C$=CHR$(ASC(C$)-32) 960 UP$=UP$+C$ 970 NEXT 980 RETURN 999 REM *************************************** 1009 REM *** CONVERT INFIX EXPRESSION TO POSTFIX *** 1030 REM IMPORT: I$(),I 1035 REM EXPORT: P$(),P 1040 REM 1060 TP=0:P=0:REM Top of stack 1062 FOR C=IB TO I 1064 C$=I$(C) 1066 IF C$=")" THEN GOSUB 2000:GOTO 1090 1068 PC=1:PS=1 1070 IF C$<>"/" AND C$<>"*" AND C$<>"-" AND C$<>"+" THEN GOTO 1084 1072 IF C$="*" OR C$="/" THEN PC=2 1074 IF TP=0 THEN PS=0: GOTO 1080 1076 IF S$(TP)="*" OR S$(TP)="/" THEN PS=2 1078 IF S$(TP)="(" THEN PS=0 1080 IF PC>PS THEN TP=TP+1:S$(TP)=C$:GOTO 1090 1082 IF PCL3 THEN ME$="Undefined variable":GOTO 1470 1440 IF N$(N)=ID$ THEN NU=V(N):GOTO 1470 1450 GOTO 1430 1460 ME$="Undefined variable" 1470 RETURN 1499 REM ****************************************** 1500 REM *** ASSIGN A VALUE TO A VARIABLE *** 1510 REM IMPORT: I$(),I 1515 REM EXPORT: IB,ME$ 1520 C$=LEFT$(I$(3),1):GOSUB 5000 REM GET TYPE 1530 IF I=3 AND TP$="NUMERIC" THEN NU=VAL(I$(3)) 1540 IF I=3 AND TP$="ALPHA" THEN ID$=I$(3):GOSUB 1400 1550 IF I>3 THEN IB=3:GOSUB 1009:REM POSTFIX AND EXECUTE 1555 IF ME$<>NU$ THEN GOTO 1599 1560 ID$=I$(1):GOSUB 1300 REM PUT VALUE IN TABLE 1570 RETURN 1599 REM *************************************** 1600 REM DISPLAY VARIABLES 1610 REM 1620 PRINT:PRINT 1625 IF L3<1 THEN PRINT "No variables set":GOTO 1680 1630 PRINT "::::::::::::: SET VARIABLES ::::::::::::":PRINT 1635 IF OU=PR THEN LPRINT "::::::::::::::: SET VARIABLES ::::::::::::::":LPRINT 1650 FOR N=1 TO L3 1660 PRINT N$(N);"=";V(N) 1665 IF OU=PR THEN LPRINT N$(N);"=";V(N) 1670 NEXT 1680 RETURN 1699 REM ******************************************* 2000 REM *** EMPTY OPERATOR STACK *** 2010 REM 2020 IF TP=0 THEN GOTO 2080 2030 FOR N=TP TO 1 STEP -1 2050 IF S$(TP)<>"(" THEN P=P+1:P$(P)=S$(TP) 2060 TP=TP-1 2070 NEXT 2080 RETURN 2099 REM ***************************************** 2500 REM *** WAIT FOR RESPONSE *** 2510 PRINT:PRINT:PRINT 2520 PRINT SPC(13);"Hit any key to continue..."; 2530 K$=INPUT$(1) 2540 RETURN 2550 REM ***************************************** 2570 REM *** CHECK DISK ID *** 2580 DK$="NOID" 2590 OPEN "I",#F1,"IDENT-DM" 2600 INPUT #F1,DK$ 2605 CLOSE #F1 2610 IF DK$="DATA" AND DE$="DATA" THEN GOTO 2670 2620 IF DK$="PROGRAM" AND DE$="PROGRAM" THEN GOTO 2670 2630 PRINT CL$:FOR N=1 TO 11:PRINT:NEXT 2640 PRINT "Insert the Desk Master ";DE$;" disk." 2645 RESTORE 2650 GOSUB 2500: REM PAUSE 2660 GOTO 2590 2670 RETURN 2679 REM *************************************** 5000 REM *** DETERMINE CHARACTER TYPE *** 5010 REM IMPORT: C$ 5015 REM EXPORT: TP$ 5025 TP$="Bad character" 5030 IF (C$>="A" AND C$<="Z") OR (C$>="a" AND C$<="z")THEN TP$="ALPHA" 5040 IF (C$>="0" AND C$<="9") OR C$="." THEN TP$="NUMERIC" 5050 IF C$=")" OR C$="(" OR C$="+" OR C$="-" OR C$="*"OR C$="/" OR C$="=" THEN TP$="OPERATOR" 5060 RETURN 5099 REM **************************************** 6000 REM *** LIST COMMANDS *** 6010 RESTORE:FOR N=1 TO 23:READ X$:NEXT 6020 FOR N=24 TO 33 6030 READ X$ 6040 PRINT X$ 6050 IF OU=PR THEN LPRINT X$ 6060 NEXT 6065 PRINT 6070 PRINT "Like HELP, type command after colon.":PRINT 6080 RETURN 6099 REM ****************************************** 7000 REM *** SOPHISTICATED ERROR ROUTINE *** 7010 ME$="Error in expression":GOTO 300 7020 REM So much for sophistication 7099 REM ***************************************** 20000 REM *** GET LINE *** 20020 REM IMPORT: LN,FC,LC 20030 REM EXPORT: T$,EC$ 20040 REM 20060 EC$=NU$:T$=NU$ 20080 C=0: REM for each character input 20090 C=C+1: C$=INPUT$(1): REM get character 20095 IF C$=BU$ THEN C$=BS$:PRINT C$; 20100 IF C$=EK$ THEN EC$="ESC":GOTO 20250 20150 IF C$=RE$ THEN PRINT:GOTO 20250 20160 IF (ASC(C$)LC) AND C$<>BS$ THEN C=C-1:GOTO 20090 20170 IF C$=BS$ AND C=1 THEN PRINT;:GOTO 20060 20180 PRINT C$;:IF OU=PR THEN LPRINT C$; 20190 IF C$=BS$ AND C<=2 THEN PRINT :PRINT ": ";:GOTO 20000 20200 IF C$=BS$ AND C>2 THEN C=C-2:T$=LEFT$(T$,C):GOTO 20090 20210 IF C=LN THEN T$=T$+C$:GOTO 20250 20240 T$=T$+C$:GOTO 20090 REM add character and get another 20250 IF OU=PR THEN LPRINT 20251 RETURN 49999 REM **************************************** 50000 DATA "Simple calculations: "," "," " 50010 DATA ": 2+2"," 4"," ",": 5*5"," 25"," " 50020 DATA ": 2+(8/2)"," 6" 50030 DATA "Assignments: "," "," " 50040 DATA ": A=15"," ",": A"," 15"," " 50050 DATA ": TOTAL=A+15"," ",": TOTAL"," 30" 50060 DATA " " 50070 DATA " List of commands" 50080 DATA " " 50090 DATA "PON.................TURNS PRINTER ON" 50100 DATA "POFF................TURNS PRINTER OFF" 50110 DATA "LIST................LIST VALUES OF VARIABLES" 50120 DATA "CLEAR...............ERASES ALL VARIABLES" 50130 DATA "HELP................LIST THESE COMMANDS" 50140 DATA "EXAMPLES1...........SIMPLE CALCULATIONS" 50150 DATA "EXAMPLES2...........VARIABLE ASSIGNMENTS" 50160 DATA " " 55555 END A "EXAMPLES1...........SIMPLE CALCULATIONS" 50150 DATA "EXAMPLES2...........VARIABLE 5 CLOSE:ON ERROR GOTO 3000 10 REM *** DATA DISK INITIATER *** 15 CL$=CHR$(26):F1=1 20 PRINT CL$:FOR N=1 TO 11:PRINT:NEXT 30 PRINT "Insert a blank, CP/M formatted disk to be" 40 PRINT "set up as a Desk Master data disk." 50 PRINT 60 PRINT "WARNING:  The current contents of the" 70 PRINT "inserted disk will be lost." 80 PRINT:PRINT:PRINT 90 GOSUB 2500:RESET: REM Pause 99 REM *************************************** 100 REM 170 REM *** SET UP INDEX FILES *** 175 REM Label disk for data 180 OPEN "O",#F1,"IDENT-DM" 190 PRINT #F1,"DATA" 200 CLOSE #F1 250 PRINT CL$:FOR N=1 TO 11:PRINT:NEXT 260 PRINT SPC(6);"Writing file indexes..." 300 OPEN "O",#F1,"MEMINDEX":GOSUB 700:CLOSE #F1 310 OPEN "O",#F1,"CDXINDEX":GOSUB 700:CLOSE #F1 320 OPEN "O",#F1,"APTINDEX":GOSUB 700:CLOSE #F1 330 PRINT CL$:FOR N=1 TO 11:PRINT:NEXT 399 REM *************************************** 400 REM *** RETURN TO MAIN PROGRAM *** 410 PRINT "Insert the Desk Master program disk again..." 420 GOSUB 2500:REM PAUSE 430 DE$="PROGRAM":GOSUB 2570:REM CHECK DISK ID 550 PRINT CL$:FOR N=1 TO 11:PRINT:NEXT 570 PRINT SPC(12);"Reloading Desk Master" 580 CHAIN "DESK-DM.BAS" 599 END:REM ************************************* 600 REM 700 REM *** WRITE INDEXES *** 710 PRINT #F1,"0L" 720 FOR F=1 TO 39:PRINT #F1,"0N":NEXT 730 RETURN 740 REM ***************************************** 2500 REM *** PAUSE FOR RESPONSE *** 2510 PRINT:PRINT:PRINT 2520 PRINT "Hit any key to continue..."; 2530 K$=INPUT$(1) 2540 RETURN 2550 REM *********************************** 2570 REM *** CHECK DISK ID *** 2580 DK$="NOID" 2590 OPEN "I",#F1,"IDENT-DM" 2600 INPUT #F1,DK$ 2610 CLOSE #F1 2620 IF DK$="DATA" AND DE$="DATA" THEN GOTO 2670 2630 IF DK$="PROGRAM" AND DE$="PROGRAM" THEN GOTO 2670 2640 PRINT CL$:FOR N=1 TO 7:PRINT:NEXT 2645 PRINT "Insert the Desk Master ";DE$;" disk." 2650 GOSUB 2500:RESET:REM PAUSE 2660 GOTO 2590:REM Until proper disk in drive 2670 RETURN 2999 REM ************************************* 3000 REM *** ERROR ROUTINE *** 3010 PRINT CL$:FOR N=1 TO 10:PRINT:NEXT 3020 IF ERR=53 THEN PRINT "File not found: " 3030 IF ERR=57 THEN PRINT "Disk problem:" 3040 IF ERR=61 THEN PRINT "Disk full:" 3050 PRINT:PRINT 3060 PRINT "Make sure you want to use the inserted disk" 3070 PRINT "for Desk Master data, then FORMAT it again" 3080 PRINT "for CP/M and re-initiate it. Otherwise, try" 3090 PRINT "another blank disk." 3100 IF ERR<>53 AND ERR<>57 AND ERR<>61 THEN GOTO 4000 3110 PRINT:PRINT:PRINT 3120 PRINT "Hit any key to return to main menu..." 3130 K$=INPUT$(1):RESUME 400 4000 ON ERROR GOTO 0 110 PRINT:PRINT:PRINT 3120 PRINT "Hit any key to return 5 CLOSE 10 REM ******************************************** 20 REM ********* Desk Master Main Program ********* 30 REM ************* by Leon LJ Starr ************* 40 REM ******************************************** 50 REM Copyright 1982, Personal Computing Magazine 60 REM ******************************************** 70 REM 80 REM 90 REM 100 REM *** CONSTANTS *** 110 CL$=CHR$(26):RE$=CHR$(13):BS$=CHR$(8):BU$=CHR$(19) 115 REM clear screen,return,backspace,and backup characters 120 EK$=CHR$(27):BE$=CHR$(7):REM ESC and BELL keys 125 US$="_":BL$=" ":NU$="":REM Underscore,blank,null 130 SC=1:PR=2:F1=3:F2=4:REM screen,printer, and disk device codes 140 PS=66:TM=5:SW=70:REM page size,top margin,screen width 145 REM 160 OU=SC:REM Output to the screen default 220 ON ERROR GOTO 41600 650 GOTO 2000:REM Bypass GET LINE routine. GET LINE HERE FOR SPEED. 651 REM 660 REM *** GET LINE *** 670 REM IMPORT: LN,FC,LC,WR$,TI$ 675 REM EXPORT: T$,EC$ 680 REM 690 EC$=NU$:T$=WW$:REM Start line out with word wrap (null at first) 691 FD$=BL$: REM Field character (blank or underline) 692 IF WR$<>"WRAP" THEN FOR N=1 TO LN:PRINT US$;:NEXT 693 IF WR$<>"WRAP" THEN FOR N=1 TO LN:PRINT BS$;:NEXT:FD$=US$ 695 PRINT WW$;:REM Wrapped word from previous line, if any 700 C=LEN(WW$):WW$=NU$ 705 C=C+1:C$=INPUT$(1) 706 IF C$=BU$ THEN C$=BS$ 725 IF C$=RE$ AND TI$="TIME" THEN PRINT BL$:PRINT:PRINT:TI$=NU$:GOTO 780 729 IF C$=EK$ THEN EC$="ESC": GOTO 780 730 IF C$=RE$ THEN PRINT :GOTO 780 735 IF ((ASC(C$)LC)) AND C$<>BS$ THEN C=C-1: GOTO 705 740 IF C$=BS$ AND C=1 THEN GOTO 700 743 PRINT C$; 745 IF C$=BS$ AND C=2 THEN T$=NU$:GOTO 700 758 IF C$=BS$ AND C>2 THEN C=C-2:T$=LEFT$(T$,C):GOTO 705 760 IF C=LN AND TI$="TIME" THEN PRINT:PRINT:PRINT:T$=T$+C$:TI$=NU$:GOTO 780 761 IF C=LN AND WR$<>"WRAP" THEN T$=T$+C$:GOTO 780 765 IF C>=LN AND C$=BL$ THEN PRINT :GOTO 780 770 IF C>LN AND C$<>BL$ THEN T$=T$+C$:GOSUB 790:GOTO 780 775 T$=T$+C$:GOTO 705 780 WR$=NU$ 785 RETURN 790 REM *** WORD WRAP *** 795 REM IMPORT: T$,LN 800 REM EXPORT: T$,WW$ 805 REM 810 LN=LN+1 815 C=LN:WW$=NU$ 820 C=C-1:C$=MID$(T$,C,1) 822 PRINT BL$;BS$;BS$; 825 IF C$=BL$ THEN PRINT FD$;BS$:WW$=RIGHT$(T$,LN-C):T$=LEFT$(T$,C):GOTO 845 830 IF C>1 THEN GOTO 820 840 IF LEN(T$)>=LN THEN T$=LEFT$(T$,LN):PRINT 845 RETURN 850 REM ************************************* 900 REM *** TRANSLATE TO UPPERCASE *** 910 REM IMPORT: LW$ (lowercase string) 915 REM EXPORT: UP$ (UPPERCASE STRING) 920 UP$=NU$ 930 FOR N=1 TO LEN(LW$) 940 C$=MID$(LW$,N,1) 950 IF C$>"Z" THEN C$=CHR$(ASC(C$)-32) 960 UP$=UP$+C$ 970 NEXT 980 RETURN 2000 REM *** DECLARATIONS, continued from line 650 *** 2008 REM *** ARRAY DECLARATIONS *** 2009 OPTION BASE 1 2010 BS=50:FL=40 2040 DIM L$(BS), L2$(BS):REM text buffers 2045 DIM FT$(FL):REM file index table 2050 REM --- Calendar Array Declarations --- 2055 DIM C(28):REM calendar numbers 2060 DIM MS(12):REM month sizes 2065 DIM MN$(12):REM month names 2070 DIM DN$(7):REM day names 2075 DIM FV(3),LV(3),FE$(3):REM date input fields 2080 REM *************************************** 2085 REM ********** MAIN PROCESS *************** 2086 REM *************************************** 2087 REM 2111 REM *** MAIN MENU *** 2140 F$=NU$:OF=1:GOSUB 5600: REM MENU GENERATOR 2145 IF CH$="W" THEN GOSUB 2800:GOTO 2140 2150 IF CH$="F" THEN GOSUB 3850:GOTO 2140 2155 IF CH$="A" THEN GOSUB 27900:GOTO 2140 2160 IF CH$="C" OR CH$="I" THEN DE$="DATA":GOSUB 41555 2165 IF CH$="C" THEN PRINT CL$:FOR N=1 TO 11:PRINT:NEXT:PRINT TAB(14);"Getting calculator...":CHAIN "CALC-DM.BAS" 2175 IF CH$="I" THEN CHAIN "DDISK-DM.BAS" 2180 IF CH$="Q" OR CH$=EK$ THEN GOTO 2200 2190 ME$="Choice not on the menu" 2195 GOTO 2140: REM End with ESC 2200 PRINT CL$:END 2750 REM ************************************** 2800 REM *** MEMO MENU *** 2950 PR$="memo":TY$=".MEM" 3150 OF=2: GOSUB 5600: REM MENU GENERATOR 3200 IF CH$="E" THEN NM$="NUMBER":GOSUB 6800:GOTO 3150 3250 IF CH$="C" THEN GOSUB 37450:GOTO 3150 3300 IF CH$="P" THEN GOSUB 11950:GOTO 3150 3350 IF CH$="S" THEN GOSUB 17500:GOTO 3150 3400 IF CH$="R" THEN GOSUB 19400:GOTO 3150 3450 IF CH$="L" THEN GOSUB 13850:GOSUB 16850:GOTO 3150 3500 IF CH$="D" THEN GOSUB 21150: GOTO 3150 3600 IF CH$="Q" OR CH$=EK$ THEN GOTO 3610 3605 ME$="Choice not on the menu" 3607 GOTO 3150: REM End with ESC 3610 IF T=0 THEN GOTO 3750:REM if buffer empty 3620 PRINT CL$ 3623 PRINT "In case you haven't already, would you like" 3624 PRINT "to save your memo in a disk file before the" 3630 PRINT "buffer is erased? "; 3635 LW$=INPUT$(1):GOSUB 900:K$=UP$ 3640 IF K$<>"N" THEN CH$="S": GOTO 3350 3650 T=0:ME$="Buffer erased" 3750 RETURN 3799 REM *************************************** 3800 REM 3850 REM ********* CARD FILE MENU ************** 4000 TY$=".CDX" 4150 OF=3:GOSUB 5600: REM MENU GENERATOR 4190 PR$="file" 4200 IF CH$="C" THEN GOSUB 22200:GOTO 4150 4250 PR$="card" 4300 IF CH$="A" THEN GOSUB 40250:GOTO 4150 4350 IF CH$="F" THEN GOSUB 4800:GOTO 4150 4400 PR$="file" 4450 IF CH$="D" THEN GOSUB 21150:GOTO 4150 4500 IF CH$="L" THEN GOSUB 13850:GOSUB 16850:GOTO 4150 4550 IF CH$="Q" OR CH$=EK$ THEN GOTO 4700 4600 ME$="Choice not on the menu" 4650 GOTO 4150: REM End loop with ESC/Q/q 4700 RETURN 4750 REM *************************************** 4799 REM 4800 REM *** CARD FILE FIND MENU *** 5000 OP$=NU$: REM option 5150 OF=4:GOSUB 5600 REM MENU GENERATOR 5200 IF CH$="D" THEN OP$="DISPLAY" 5250 IF CH$="E" THEN OP$="DELETE" 5300 IF CH$="P" THEN OP$="PRINT" 5350 IF CH$="D" OR CH$="E" OR CH$="P" THEN GOSUB 24650:GOTO 5150 5400 IF CH$="Q" OR CH$=EK$ THEN GOTO 5500 5450 ME$="Choice not on menu":GOTO 5150 5500 RETURN 5549 REM **************************************** 5550 REM 5600 REM *** MENU GENERATOR *** 5650 REM IMPORT: ME$,DATA 5750 REM EXPORT: CH$,EC$ 5800 REM 5900 PRINT CL$:REM Error or status message 5950 IF ME$<>NU$ THEN PRINT "*** ";ME$;" ***" 6000 IF ME$<>NU$ THEN PRINT 6050 ME$=NU$ 6100 RESTORE 6150 PRINT:PRINT 6200 N=0 6250 N=N+1: REM for each menu number 6300 READ OM 6350 FOR O=1 TO OM: REM for each option 6400 READ O$ 6450 IF N=OF THEN PRINT SPC(14);O$:PRINT 6500 NEXT 6550 IF N<>OF THEN GOTO 6250: REM if wrong menu 6600 PRINT:PRINT "Select one of the above: "; 6650 LW$=INPUT$(1):GOSUB 900:CH$=UP$ 6700 RETURN 6750 REM *************************************** 6751 REM 6800 REM *** INPUT TEXT *** 6900 REM IMPORT: PR$,TI$,NM$,TY$,T 6950 REM EXPORT: L$(),T,ME$ 7000 REM 7010 IF T=0 OR TY$<>".MEM" THEN GOTO 7050 7020 PRINT:PRINT:PRINT "Okay to erase memo currently in buffer? "; 7025 LW$=INPUT$(1):GOSUB 900:K$=UP$ 7030 IF K$<>"Y" THEN ME$="Canceled":GOTO 7950 7050 EC$=NU$:WW$=NU$:REM wrapped word 7150 PRINT CL$ 7200 PRINT "Enter your ";PR$;":":PRINT 7250 PRINT "Hit the ESC key when you are finished.":PRINT 7300 LN=SW 7350 IF TI$="TIME" THEN PRINT "Enter a valid such as like 7:30 AM,":PRINT "Time (HH:MM AM/PM): "; 7400 L=0 7450 L=L+1:REM for each input line 7500 IF NM$="NUMBER" THEN GOSUB 10000: REM NUMBER MARGIN 7550 WR$="WRAP":LN=SW 7560 IF TI$="TIME" THEN WR$=NU$:LN=8 7600 FC=32:LC=127:GOSUB 660:REM GET LINE 7650 L$(L)=T$ 7700 IF EC$="ESC" THEN GOTO 7850 7750 IF L9 THEN MA$=STR$(L)+BL$ 10150 PRINT MA$; 10200 RETURN 10225 REM ************************************* 10250 REM 10300 REM *** CHANGE LINE *** 10450 PRINT "Line to change "; 10500 EC$=NU$ 10600 GD$="NN":FV(1)=1:LV(1)=T:GOSUB 26500 10650 IF EC$="ESC" THEN GOTO 11150 10700 L=VAL(FE$(1)) 10750 IF L<1 OR L>T THEN PRINT "No line with that number!":GOTO 10300 10800 PRINT:PRINT:PRINT:PRINT 10950 PRINT:PRINT "Hit (ESC) or (RETURN) when finished:":PRINT 11000 GOSUB 10000:REM NUMBER MARGIN 11050 LN=SW:FC=32:LC=127:GOSUB 660:L$(L)=T$ 11150 RETURN 11151 REM *************************************** 11152 REM 11250 REM *** PUT TEXT BUFFER *** 11300 REM IMPORT: L$(),T,OU 11400 REM EXPORT: ME$ 11500 MA$=NU$: REM CLEAR MARGIN 11550 IF OU=F1 OR OU=F2 THEN PRINT #OU,T 11575 IF ME$<>NU$ THEN GOTO 11850 11600 FOR L=1 TO T 11650 IF NM$="NUMBER" THEN GOSUB 10000 11700 IF OU=F1 OR OU=F2 THEN PRINT #OU,L$(L) 11705 IF ME$<>NU$ THEN GOTO 11850 11710 IF OU=SC THEN PRINT L$(L) 11720 IF OU=PR THEN LPRINT L$(L) 11730 IF (INT(L/20)=L/20) AND OU=SC THEN GOSUB 16850:PRINT:PRINT 11750 NEXT 11800 OU=SC:NM$=NU$ 11850 RETURN 11900 REM ************************************* 11901 REM 11950 REM *** PRINT TEXT BUFFER *** 12000 REM IMPORT: L$(),T,TY$ 12100 PRINT CL$ 12200 IF T=0 THEN ME$="Nothing to print":GOTO 12500 12225 FOR N=1 TO 11:PRINT:NEXT 12250 PRINT SPC(13);"Make sure the printer is on...":PRINT:PRINT:PRINT 12260 IF TY$=".MEM" THEN FOR N=1 TO TM:LPRINT:NEXT 12300 OU=PR:GOSUB 11250:REM PUT TEXT 12400 IF TY$=".MEM" THEN FOR N=1 TO PS-T-TM:LPRINT:NEXT 12500 RETURN 12550 REM **************************************** 12551 REM 12600 REM *** PUT INDEX *** 12650 REM IMPORT: FI$,FT(),FL,ME$ 12700 REM EXPORT: ME$ 12800 DE$="DATA":GOSUB 41555:REM CHECK DISK ID 12850 OPEN "O",#F1,FI$ 12950 FOR F=1 TO FL 13000 PRINT #F1,FT$(F) 13050 NEXT 13100 CLOSE #F1 13150 RETURN 13200 REM *************************************** 13201 REM 13250 REM *** ADD TO INDEX *** 13350 REM IMPORT: FT$(),L3,EX,F$ 13400 REM EXPORT: FT$(),L3,ME$ 13500 REM 13550 IF EX<>0 THEN GOTO 13750 13600 FT$(L3)=F$ 13605 IF L3<>FL THEN FT$(L3+1)="0L" 13650 L3=L3+1 13700 GOSUB 12600: REM PUT INDEX 13750 RETURN 13800 REM *************************************** 13801 REM 13850 REM *** GET INDEX *** 13900 REM IMPORT: TY$ 13950 REM EXPORT: FI$,L3,FT$(),FL,ME$ 14050 REM 14100 EC$=NU$ 14200 IF TY$=".MEM" THEN FI$="MEMINDEX" 14250 IF TY$=".CDX" THEN FI$="CDXINDEX" 14300 IF TY$=".APT" THEN FI$="APTINDEX" 14350 DE$="DATA":GOSUB 41555 14400 IF TY$<>".APT" THEN PRINT CL$;PR$;"s on disk:" 14450 PRINT:PRINT 14500 OPEN "I",#F1,FI$ 14600 L3=FL+1: REM default for last element 14650 FOR F=1 TO FL 14700 LINE INPUT #F1,FT$(F) 14750 IF FT$(F)<>"0N" AND FT$(F)<>"0L" AND TY$<>".APT" THEN PRINT FT$(F) 14800 IF FT$(F)="0L" THEN L3=F 14850 NEXT 14900 IF L3=1 AND TY$<>".APT" THEN PRINT "No ";PR$;"s";" yet.":PRINT:PRINT 14950 CLOSE #F1 15050 RETURN 15100 REM *************************************** 15101 REM 15150 REM *** DOES FILE EXIST *** 15200 REM IMPORT: FT$(),L3 15250 REM EXPORT: EX 15300 REM 15400 EX=0: REM Default 0 for non-existence of file 15450 FOR F=1 TO L3-1 15500 IF F$=FT$(F) THEN EX=F 15550 NEXT 15575 RETURN 15600 REM ************************************* 15700 REM *** GET FILE NAME *** 15750 REM IMPORT: CF$ 15800 REM EXPORT: F$,EC$,ME$ 15900 REM 15950 EC$=NU$:ME$=NU$ 16000 GOSUB 13850:REM GET INDEX 16010 IF ME$<>NU$ THEN GOTO 16750 16050 IF F$<>NU$ THEN PRINT:PRINT:PRINT "Do you want the ";F$;" ";PR$;"? ";: LW$=INPUT$(1):GOSUB 900:K$=UP$:PRINT:PRINT 16100 IF K$=EK$ THEN EC$="ESC":GOTO 16750 16150 IF K$<>"N" AND F$<>NU$ THEN GOTO 16500 16200 PRINT:PRINT:PRINT "Enter a ";PR$;" name: "; 16250 WR$=NU$ 16300 LN=8:FC=32:LC=127:GOSUB 660:REM GET LINE 16350 IF EC$="ESC" OR T$=NU$ THEN EC$="ESC":GOTO 16750 16400 LW$=T$:GOSUB 900:F$=UP$:C$=LEFT$(F$,1) 16450 IF C$<"A" OR C$>"Z" THEN PRINT "(First character must be a letter).":PRINT BE$;"Please try again...";:GOTO 16200 16500 GOSUB 15150: REM FILE EXISTS 16550 PRINT:PRINT:PRINT 16600 IF (CF$="SHOULD BE" OR CF$="NO MATTER") AND EX=0 THEN ME$="No such file" 16650 IF (CF$="SHOULDN'T BE" OR CF$="NO MATTER") AND EX>0 THEN PRINT TAB(18);:PRINT "Overwrite ";F$;"? ";:LW$=INPUT$(1):GOSUB 900:K$=UP$:IF K$<>"Y" THEN ME$="Canceled" 16750 RETURN 16800 REM ***************************************** 16801 REM 16850 REM *** WAIT FOR RESPONSE *** 16950 PRINT:PRINT:PRINT 17000 PRINT "Hit any key to continue..."; 17050 K$=INPUT$(1) 17100 RETURN 17150 REM *************************************** 17151 REM 17200 REM *** WAIT MESSAGE *** 17250 PRINT CL$ 17300 FOR N=1 TO 11:PRINT:NEXT 17350 PRINT SPC(15);"Please wait" 17400 RETURN 17450 REM ************************************* 17451 REM 17500 REM *** SAVE FILE *** 17600 EC$=NU$ 17700 IF T=0 THEN ME$="Nothing to save": GOTO 18400 17750 CF$="SHOULDN'T BE":GOSUB 15700:REM GET FILE NAME 17775 IF L3-1=FL AND EX=0 THEN ME$="No more "+PR$+"s allowed":GOTO 22950 17800 IF EC$="ESC" THEN ME$="Canceled": GOTO 18400 17850 IF ME$<>NU$ THEN GOTO 18400 17900 GOSUB 17200: REM WAIT MESSAGE 17950 PRINT:PRINT SPC(18);"Writing" 17975 DE$="DATA":GOSUB 41555 18000 OPEN "O",#F1,F$+TY$ 18050 IF ME$<>NU$ THEN CLOSE #F1:GOTO 18400 18100 OU=F1:GOSUB 11250:REM PUT TEXT 18150 CLOSE #F1 18200 IF ME$<>NU$ THEN GOTO 18400 18250 ME$="Saved as: "+F$ 18300 GOSUB 13250: REM ADD TO INDEX 18400 RETURN 18450 REM ************************************ 18451 REM 18500 REM *** GET TEXT *** 18550 REM IMPORT: OU 18600 REM EXPORT: L$(),T,ED$ 18700 ED$=NU$ 18850 IF EOF(OU) THEN ED$="EOF":GOTO 19100 18900 INPUT #OU,T 18950 FOR L=1 TO T 19000 LINE INPUT #OU,L$(L) 19050 NEXT 19100 OU=SC 19300 RETURN 19350 REM ************************************* 19351 REM 19400 REM *** LOAD FILE *** 19500 EC$=NU$ 19600 CF$="SHOULD BE":GOSUB 15700:REM GET FILE NAME 19650 IF EC$="ESC" THEN ME$="Canceled":GOTO 20200 19750 GOSUB 17200:REM WAIT MESSAGE 19800 PRINT:PRINT SPC(18);"Reading" 19825 DE$="DATA":GOSUB 41555 19850 OPEN "I",#F1,F$+TY$ 19950 OU=F1:GOSUB 18500: REM GET TEXT 20000 CLOSE #F1 20100 ME$=F$+" retreived" 20200 RETURN 20250 REM ************************************** 20251 REM 20300 REM *** DELETE FROM INDEX *** 20400 REM IMPORT: EX,FT$(),L3 20500 REM EXPORT: ME$ (from PUT INDEX) 20550 EC$=NU$ 20650 IF EX=FL THEN FT$(FL)="0L": GOTO 20950 20700 FOR F=EX TO FL-1 20750 FT$(F)=FT$(F+1) 20800 NEXT 20850 IF FT$(FL-1)="0L" OR FT$(FL-1)="0N" THEN FT$(FL)="0N" 20900 IF FT$(FL-1)<>"0L" AND FT$(FL-1) <> "0N" THEN FT$(FL)="0L" 20950 L3=L3-1 21000 GOSUB 12600: REM PUT INDEX 21050 RETURN 21100 REM *************************************** 21101 REM 21150 REM *** DELETE FILE *** 21250 EC$=NU$ 21300 CF$="NO MATTER" 21350 IF TY$=".APT" THEN GOTO 21650 21400 GOSUB 15700:REM GET FILE NAME 21450 IF EC$="ESC" THEN ME$="Canceled": GOTO 22150 21500 IF ME$<>NU$ THEN GOTO 22150 21550 GOSUB 17200:REM WAIT MESSAGE 21600 PRINT : PRINT SPC(17);"Deleting" 21625 DE$="DATA":GOSUB 41555 21650 KILL F$+TY$ 21700 GOSUB 20300:REM DELETE INDEX 21725 IF ME$<>NU$ THEN GOTO 22150 21750 PRINT CL$:FOR N=1 TO 9:PRINT:NEXT 21800 IF TY$=".APT" THEN GOTO 22150 21850 PRINT PR$;": ";F$;" deleted.":PRINT:PRINT 21950 PRINT "Delete another? ";:LW$=INPUT$(1):GOSUB 900:K$=UP$ 22000 IF K$="Y" THEN GOTO 21350 22050 IF K$=EK$ THEN ME$="Canceled" 22150 RETURN 22155 REM *************************************** 22160 REM 22200 REM *** CREATE FILE *** 22250 REM IMPORT: F$,TY$ 22300 REM EXPORT: ME$ 22450 EC$=NU$ 22550 CF$="SHOULDN'T BE":GOSUB 15700:REM GET FILE NAME 22575 IF L3-1=FL AND EX=0 THEN ME$="No more "+PR$+"s allowed":GOTO 22950 22600 IF EC$="ESC" THEN ME$="Canceled":GOTO 22950 22650 DE$="DATA":GOSUB 41555 22750 OPEN "O",#F1,F$+TY$:CLOSE #F1 22800 IF ME$<>NU$ THEN GOTO 22950 22900 GOSUB 13250:REM ADD TO INDEX 22905 IF ME$<>NU$ THEN GOTO 22950 22910 ME$="Created "+F$ 22920 IF EX<>0 THEN ME$="Cleared "+F$ 22950 RETURN 23000 REM ************************************** 23001 REM 23050 REM *** APPEND BUFFER TO FILE *** 23100 REM IMPORT: F$,L$(),T,TY$ 23150 REM EXPORT: ME$ 23155 ED$=NU$ 23160 FOR L=1 TO T:L2$(L)=L$(L):NEXT:T2=T:REM Save buffer for appending 23200 DE$="DATA":GOSUB 41555 23250 OPEN "O",#F2,"TEMP" 23300 OPEN "I",#F1,F$+TY$ 23350 OU=F1:GOSUB 18500:REM GET TEXT 23400 IF ED$="EOF" THEN GOTO 23500 23450 OU=F2:GOSUB 11250:GOTO 23350:REM PUT TEXT 23475 IF ME$<>NU$ THEN CLOSE :GOTO 23651 23500 FOR L=1 TO T2:L$(L)=L2$(L):NEXT:T=T2 23550 OU=F2:GOSUB 11250:REM append buffer 23600 CLOSE #F1,#F2 23605 IF ME$<>NU$ THEN GOTO 23651 23610 KILL F$+TY$:NAME "TEMP" AS F$+TY$ 23650 ME$="Appended to "+F$+" file" 23651 RETURN 23700 REM ************************************** 23701 REM 23750 REM *** KEY/ORDER MATCH *** 23800 REM IMPORT: KE$,L$(),T,FU$ 23850 REM EXPORT: GI$ 24100 GI$=NU$ 24150 IF KE$="*" THEN GI$="GOT IT":GOTO 24550 24200 IF FU$="ORDER" AND K2$>KE$ THEN GI$="GOT IT":GOTO 24550 24250 IF FU$="ORDER" AND K2$<=KE$ THEN GOTO 24550 24300 L=0 24350 L=L+1 24400 IF L$(L)=KE$ THEN GI$="GOT IT":GOTO 24550 24450 IF L".APT" THEN GOSUB 15700:REM GET FILE NAME 25000 IF TY$=".APT" THEN GOTO 25150 25100 IF EC$="ESC" THEN ME$="Canceled":GOTO 26400 25150 IF ME$<>NU$ THEN GOTO 26400 25175 DE$="DATA":GOSUB 41555 25200 OPEN "I",#F1,F$+TY$ 25250 IF OP$="DELETE" THEN OPEN "O",#F2,"TEMP" 25275 IF ME$<>NU$ THEN CLOSE:GOTO 26400 25300 IF TY$=".APT" THEN GOTO 25700 25350 PRINT CL$:FOR N=1 TO 7:PRINT:NEXT 25400 PRINT "Enter a key line to search for, below: " 25425 PRINT "(To match all cards, just type an '*')":PRINT 25450 LN=SW:FC=32:LC=127:GOSUB 660 25500 IF EC$="ESC" THEN ME$="Canceled":GOTO 26400 25550 KE$=T$ 25700 OU=F1:GOSUB 18500:REM GET TEXT 25750 IF ED$="EOF" THEN GOTO 26150 25800 GOSUB 23750: REM MATCH 25850 IF GI$<>"GOT IT" AND OP$="DELETE" THEN OU=F2:GOSUB 11250:GOTO 25700 25875 IF ME$<>NU$ THEN CLOSE:GOTO 26400 25900 IF GI$<>"GOT IT" THEN GOTO 25700 25950 FO$="FOUND" 26000 IF OP$="DISPLAY" THEN PRINT:GOSUB 11250:PRINT: REM PUT TEXT 26050 IF OP$="PRINT" THEN LPRINT:GOSUB 11950:LPRINT: REM PRINT TEXT 26100 GOTO 25700: REM END WITH EOF(F1) 26150 IF FO$="NOT FOUND" THEN ME$="Not found" 26200 IF FO$="FOUND" AND TY$<>".APT" AND OP$="DISPLAY" THEN GOSUB 16850:REM PAUSE 26250 CLOSE #F1 26275 IF OP$="DELETE" THEN CLOSE #F2 26300 IF OP$="DELETE" THEN KILL F$+TY$:NAME "TEMP" AS F$+TY$ 26350 IF TY$<>".APT" AND OP$="DELETE" THEN ME$="Matched cards deleted" 26400 OU=SC:RETURN 26450 REM ************************************ 26500 REM *** GET DATE FIELDS *** 26550 REM IMPORT: GD$,FV(),LV() 26700 REM EXPORT: FE() 26850 EC$=NU$ 26950 N=LEN(GD$) 27000 PRINT US$;US$;:N=N-2 27050 IF N<>0 THEN PRINT "/";:N=N-1:GOTO 27000 27100 FOR N=1 TO LEN(GD$):PRINT BS$;:NEXT 27150 F=0 27200 F=F+1 27350 WR$=NU$:LN=2:FC=48:LC=57:GOSUB 660 27400 IF EC$="ESC" THEN GOTO 27700 27450 N=VAL(T$):FE$(F)=T$ 27500 IF LEN(T$)<2 THEN FE$(F)="0"+T$ 27550 IF NLV(F) THEN PRINT:PRINT "Bad value, try again...":GOTO 26950 27600 IF F<((LEN(GD$)-INT(LEN(GD$)/3))/2) THEN PRINT "/";:GOTO 27200 27650 IF RIGHT$(GD$,2)="YY" THEN FE$(F)="19"+FE$(F) 27700 RETURN 27750 REM **************************************** 27751 REM *** APPOINTMENT CALENDAR *** 27850 REM *** READ CALENDAR DATA *** 27900 PRINT CL$ 27950 RESTORE 28000 REM Skip past menus 28050 FOR N=1 TO 4 28100 READ OM 28150 FOR O=1 TO OM:READ O$:NEXT 28200 NEXT 28250 REM Now read the calendar data statements 28300 FOR N=1 TO 28:READ C(N):NEXT: REM Calendars 28350 FOR N=1 TO 12:READ MS(N):NEXT:REM Month sizes 28400 FOR N=1 TO 12:READ MN$(N):NEXT:REM Month names 28450 FOR N=1 TO 7:READ DN$(N):NEXT: REM Day names 28550 EC$=NU$:PR$="appointment":TY$=".APT" 28650 REM DELETE OLD APPOINTMENTS 28700 FOR N=1 TO 11:PRINT:NEXT 28710 PRINT "So that past appointments can be erased," 28740 PRINT 28750 PRINT "please enter the current date: "; 28800 GD$="MM/DD/YY" 28850 FV(1)=1:FV(2)=1:FV(3)=61 28900 LV(1)=12:LV(2)=31:LV(3)=99:GOSUB 26500:REM GET DATE 28950 IF EC$="ESC" THEN GOTO 35900 29000 F2$="C"+RIGHT$(FE$(3),2)+FE$(1)+FE$(2) 29050 GOSUB 13850: REM GET INDEX 29075 IF ME$<>NU$ THEN GOTO 35900 29100 X=1: REM For each appointment file 29150 IF X>=L3 THEN GOTO 29300: REM No appts anyway 29170 REM Delete appointment if older than current date 29200 IF F2$>FT$(X) THEN F$=FT$(X):GOSUB 15150:GOSUB 21150:GOTO 29100 29250 X=X+1:GOTO 29150 29300 PRINT CL$:FOR N=1 TO 11:PRINT:NEXT 29350 PRINT "Display or print (D/P)? "; 29400 LW$=INPUT$(1):GOSUB 900:CH$=UP$:IF CH$=EK$ THEN GOTO 35900 29425 CP$="DISPLAY" 29450 IF CH$="P" THEN CP$="PRINT":OU=PR 29650 REM *** MAKE CALENDAR *** 29700 PRINT CL$:FOR N=1 TO 11:PRINT:NEXT 29750 PRINT "Enter month and year to view: "; 29850 GD$="MM/YY":FV(1)=1:LV(1)=12 29900 FV(2)=61:LV(2)=99:GOSUB 26500:REM GET DATE 29950 IF EC$="ESC" THEN GOTO 35900 30000 MM=VAL(FE$(1)):YY=VAL(FE$(2)) 30050 MM$=FE$(1):YY$=FE$(2) 30100 PRINT CL$:FOR N=1 TO 9:PRINT:NEXT 30200 PRINT SPC(13);"Hold on":PRINT:PRINT:PRINT TAB(10);"I'm counting..." 30350 REM *** CALCULATE INDEXES *** 30400 REM Find calendar 30450 YI=YY-1959 30500 IF YI>28 THEN YI=YI-28:GOTO 30500 30550 CA=C(YI) 30600 REM Find the month name 30650 MO$=MN$(MM) 30700 REM Is it a leap year? 30750 IF CA>7 THEN MS(2)=29 30900 FD=CA:REM first day of year 30950 IF CA>7 THEN FD=CA-7 31000 WD=FD:REM week day counter, (modulo 7) 31050 REM count up to selected month 31100 M=0 31150 M=M+1:REM for each month 31200 IF M=MM THEN GOTO 31700 31250 MD=0 31300 MD=MD+1:REM for each month-day 31350 WD=WD+1:REM and each week-day 31400 IF WD>7 THEN WD=1:REM start week over 31500 IF MD9 THEN S=9 32450 IF MD<=9 THEN S=10 32500 IF EX<>0 THEN N=1:CO$=":" 32525 IF WD=1 THEN N=N+3 32550 PRINT SPC(S-N);:IF OU=PR THEN LPRINT SPC(S-N); 32575 IF WD=1 THEN N=N-3 32650 PRINT CO$;RIGHT$(STR$(MD),LEN(STR$(MD))-1);CO$;:IF OU=PR THEN LPRINT CO$;RIGHT$(STR$(MD),LEN(STR$(MD))-1);CO$; 32700 IF N=1 AND EX=0 THEN N=0 32750 WD=WD+1 32800 IF WD>7 THEN WD=1:PRINT:PRINT:IF OU=PR THEN LPRINT:LPRINT 32850 IF MDNU$ THEN GOTO 34860 34840 GOTO 34820: REM end with EOF(F1) 34843 IF CP$="PRINT" THEN OU=PR 34845 PRINT STRING$(79,"="):PRINT:PRINT 34846 IF OU=PR THEN LPRINT STRING$(79,"="):LPRINT:LPRINT 34848 OU=SC 34850 CLOSE #F1 34860 RETURN 34869 REM **************************************** 34900 REM *** DELETE APPOINTMENT *** 34910 PRINT:PRINT:PRINT "Enter appointment time: ";:LN=8:FC=32:LC=127:GOSUB 660:IF EC$="ESC" THEN GOTO 34940 34920 KE$=T$:OP$="DELETE":GOSUB 24650:REM DELETE CARD 34922 IF ME$<>NU$ THEN GOTO 34940 34925 IF FO$="NOT FOUND" THEN PRINT "Appointment ";ME$:ME$=NU$:FOR X=1 TO 200:NEXT 34930 GOSUB 41150:REM DELETE EMPTY DAY 34940 RETURN 34949 REM ************************************ 35050 REM *** MAKE APPOINTMENT *** 35100 TI$="TIME":GOSUB 6800:REM INPUT TEXT 35150 PRINT:PRINT:PRINT "Would you like to change this? "; 35160 LW$=INPUT$(1):GOSUB 900:K$=UP$:IF K$=EK$ THEN GOTO 35900 35200 IF K$="Y" THEN GOSUB 37450:REM CHANGE TEXT 35275 IF LEFT$(L$(1),1)=BL$ THEN L$(1)=RIGHT$(L$(1),LEN(L$(1))-1) 35300 KE$=LEFT$(L$(1),8) 35350 IF LEN(KE$)=7 THEN KE$="0"+KE$ 35400 IF LEFT$(KE$,2)="12" THEN KE$="00"+RIGHT$(KE$,6) 35450 KE$=RIGHT$(KE$,2)+LEFT$(KE$,5) 35490 REM transfer text to insert buffer 35500 FOR L=1 TO T:L2$(L)=L$(L):NEXT:T2=T 35700 GOSUB 36000:REM INSERT CARD 35800 IF EX=0 AND ME$=NU$ THEN GOSUB 13250:REM ADD TO INDEX 35900 RETURN 35950 REM ************************************ 35951 REM 36000 REM *** INSERT CARD INTO FILE *** 36050 REM IMPORT: L$(),T,L2$(),T2,F$,TY$ 36150 REM EXPORT: ME$ 36200 EC$=NU$:NF$=NU$ 36300 FO$="NOT FOUND" 36350 DE$="DATA":GOSUB 41555 36400 OPEN "I",#F1,F$+TY$ 36450 OPEN "O",#F2,"TEMP" 36475 IF ME$<>NU$ THEN CLOSE:GOTO 37350 36500 IF NF$="NOFILE" THEN NF$=NU$:GOTO 37150 36550 OU=F1:GOSUB 18500:REM GET TEXT 36600 IF ED$="EOF" THEN GOTO 37150 36650 K2$=LEFT$(L$(1),8) 36700 IF LEN(K2$)=7 THEN K2$="0"+K2$ 36800 IF LEFT$(K2$,2)="12" THEN K2$="00"+RIGHT$(K2$,6) 36850 K2$=RIGHT$(K2$,2)+LEFT$(K2$,5) 36950 FU$="ORDER":GOSUB 23750:REM KEY MATCH/ORDER 36960 IF GI$<>"GOT IT" OR FO$<>"NOT FOUND" THEN GOTO 37100 36970 FO$="FOUND" 36980 PRINT #F2,T2:IF ME$<>NU$ THEN CLOSE:GOTO 37350 36990 FOR L=1 TO T2:PRINT #F2,L2$(L):IF ME$<>NU$ THEN GOTO 37350 37000 NEXT:OU=F2:GOSUB 11250 37010 IF ME$<>NU$ THEN CLOSE:GOTO 37350 37020 GOTO 36550 37100 OU=F2:GOSUB 11250:IF ME$<>NU$ THEN CLOSE:GOTO 37350 37110 GOTO 36500 37150 IF FO$<>"NOT FOUND" THEN GOTO 37200 37160 PRINT #F2,T2:IF ME$<>NU$ THEN CLOSE:GOTO 37350 37170 FOR L=1 TO T2:PRINT #F2,L2$(L):IF ME$<>NU$ THEN CLOSE:GOTO 37350 37180 NEXT 37200 CLOSE #F1,#F2 37250 KILL F$+TY$:NAME "TEMP" AS F$+TY$ 37350 RETURN 37400 REM ***************************************** 37401 REM 37450 REM *** CHANGE TEXT *** 37600 EC$=NU$ 37650 IF T=0 THEN ME$="Nothing to change":GOTO 38500 37700 PRINT CL$ 37750 IF ME$<>NU$ THEN PRINT "*** ";ME$;" ***" 37800 IF ME$=NU$ THEN PRINT 37850 ME$=NU$ 37900 PRINT:PRINT:PRINT 37950 NM$="NUMBER":GOSUB 11250:REM PUT TEXT 38000 PRINT:PRINT 38010 PRINT "Change, Insert, Delete, Append, or (ESC) ?"; 38020 LW$=INPUT$(1):GOSUB 900:CH$=UP$ 38030 PRINT:PRINT 38050 IF CH$="I" AND T=BS THEN ME$="No more space in the buffer":GOTO 37650 38100 IF CH$="C" THEN GOSUB 10300:GOTO 37650 38150 IF CH$="I" THEN GOSUB 38600:GOTO 37650 38200 IF CH$="D" THEN GOSUB 39550:GOTO 37650 38250 IF CH$="A" THEN GOSUB 40700:GOTO 37650 38300 IF CH$=EK$ THEN CH$=NU$:GOTO 38500 38400 ME$="Choice not on menu" 38450 GOTO 37650:REM end with ESC 38500 RETURN 38550 REM *************************************** 38551 REM 38600 REM *** INSERT A LINE *** 38700 IF T=BS THEN ME$="Buffer full":GOTO 39450 38750 PRINT "Line below insert: "; 38800 GD$="NN":FV(1)=1:LV(1)=T:GOSUB 26500:REM GET LINE NUMBER (DATE FIELD) 38850 IF EC$="ESC" THEN GOTO 39450 38900 I=VAL(FE$(1)) 38950 PRINT 39000 FOR L=T+1 TO I+1 STEP -1:L$(L)=L$(L-1):NEXT 39050 GOSUB 10000:REM NUMBER MARGIN 39100 WR$="WRAP":LN=SW:FC=32:LC=127:GOSUB 660 39200 L$(I)=T$:T=T+1 39250 I=I+1 39300 IF EC$="ESC" THEN GOTO 39450 39350 IF T"ESC" THEN GOTO 40800 41050 RETURN 41100 REM ************************************ 41101 REM 41150 REM *** DELETE EMPTY DAY *** 41200 OPEN "I",#F1,F$+TY$ 41350 IF EOF(F1) THEN CLOSE #F1:GOSUB 21150:REM Delete day file 41500 CLOSE #F1:RETURN 41550 REM ************************************ 41551 REM 41555 REM *** CHECK DISK ID *** 41556 DK$="NOID" 41557 OPEN "I",#F1,"IDENT-DM":INPUT #F1,DK$:CLOSE 41560 IF DK$="DATA" AND DE$="DATA" THEN GOTO 41595 41561 IF DK$="PROGRAM" AND DE$="PROGRAM" THEN GOTO 41595 41565 PRINT CL$:FOR N=1 TO 7:PRINT:NEXT 41570 PRINT "Insert the Desk Master ";DE$;" disk." 41592 GOSUB 16850:RESET: REM PAUSE 41593 GOTO 41557:REM end with correct disk found 41595 RETURN 41597 REM ************************************** 41599 REM 41600 REM ****** ERROR HANDLING ****** 41700 IF ERR=53 THEN NF$="NOFILE":RESUME NEXT:REM File does not exist 41750 IF ERR=61 THEN ME$="Disk Full":RESUME NEXT 41800 IF ERR=57 THEN PRINT "Unrecoverable disk error encountered. Re-start program.":PRINT "Once Desk Master is running again, do not switch":PRINT "when you are instructed to do so." 41850 IF ERR=64 THEN PRINT "Bad character in file name. See manual." 41900 IF ERR=53 THEN PRINT "Check disk, file not found on it." 41999 ON ERROR GOTO 0 42349 REM 42350 REM *************************************** 42351 REM ********* INTERNAL PROGRAM DATA ******* 42352 REM *************************************** 42353 REM 42450 REM *** MENU DATA *** 42475 REM --- MAIN MENU --- 42500 DATA 6,"Write Memo (W)" 42550 DATA "Card File (F)" 42600 DATA "Appointment Calendar (A)" 42650 DATA "Calculator (C)" 42750 DATA "Initiate Data Disk (I)" 42800 DATA "Quit Desk Master Program (ESC)" 42850 REM --- MEMO MENU --- 42900 DATA 8,"Enter Memo (E)" 42950 DATA "Change or View Memo (C)" 43000 DATA "Print Memo (P)" 43050 DATA "Save Memo on Disk (S)" 43100 DATA "Retrieve Memo from Disk (R)" 43200 DATA "Delete Memo from Disk (D)" 43250 DATA "List Memo Names from Disk (L)" 43300 DATA "Return to Main Menu (ESC)" 43350 REM --- CARD FILE MENU --- 43400 DATA 6,"Create File (C)" 43450 DATA "Add Card to File (A)" 43500 DATA "Find Card(s) in File (F)" 43600 DATA "Delete File from Disk (D)" 43650 DATA "List File Names from Disk (L)" 43675 DATA "Return to Main Menu (ESC)" 43700 REM --- CARD FILE FIND MENU --- 43750 DATA 4,"Display Matched Cards (D)" 43800 DATA "Erase Matched Cards (E)" 43850 DATA "Print Matched Cards (P)" 43900 DATA "Return to Card File Menu (ESC)" 43950 REM ------------------------------------ 43951 REM --- CALENDAR DATA --- 44100 REM CALENDARS (INDEXES), from phone book 44150 DATA 13,1,2,3,11,6,7,1,9,4,5,6,14,2,3,4,12,7,1,2,10,5,6,7,8,3,4,5 44200 REM MONTH SIZES 44250 DATA 31,28,31,30,31,30,31,31,30,31,30,31 44300 REM MONTH NAMES 44350 DATA "January","February","March","April","May" 44400 DATA "June","July","August","September","October" 44450 DATA "November","December" 44500 DATA "Sunday","Monday","Tuesday","Wednesday" 44550 DATA "Thursday","Friday","Saturday" 50000 REM *************************************** 50100 REM and they lived happily ever after. hursday","Friday","Saturd10 CLOSE 20 CL$=CHR$(26):NU$="":EK$=CHR$(27) 30 PRINT CL$ 40 PRINT SPC(18);STRING$(45,"*") 50 FOR N=2 TO 18 60 PRINT SPC(18);"*"; 70 IF N=3 THEN PRINT SPC(7);"Compliments of Donald Jenner";SPC(8);:GOTO 170 80 IF N=5 THEN PRINT SPC(5);"Washington Market Logical Systems";SPC(5);: GOTO 170 90 IF N=8 THEN PRINT SPC(12);"Presenting Desk Master";SPC(9);:GOTO 170 100 IF N=10 THEN PRINT SPC(9);"Personal Computing Magazine";SPC(7);:GOTO 170 110 IF N=15 THEN PRINT SPC(15);STRING$(14,"=");SPC(14);:GOTO 170 120 IF N=13 THEN PRINT SPC(21);"By";SPC(20);:GOTO 170 130 IF N=9 THEN PRINT SPC(20);"From";SPC(19);:GOTO 170 140 IF N=16 THEN PRINT SPC(16);"Leon LJ Starr";SPC(14);:GOTO 170 150 IF N=17 THEN PRINT SPC(15);STRING$(14,"=");SPC(14);:GOTO 170 160 PRINT SPC(43); 170 PRINT "*":NEXT 180 PRINT SPC(18);STRING$(45,"*") 190 PRINT:PRINT SPC(23);"Please be patient while I get set up!"; 200 CHAIN "DESK-DM.BAS" 210 END T SPC(18);STRING$(45,"*") 190 PRINT:PRINT SPC(23);"Please be patient while I get set up!"; DATA 6"" #/x^i^^6ZS^Mʐ^F C:dʯ^z{2ô^"v +^C/}^C:d" ô^+*v +" A Few Comments on Desk Master 1. This program is a transcription of one orignally ap- pearing in Popular Computing (as per the sign-on in INIT-DM.BAS). Copyright resides in the author, who has placed it in public domain with all the usual pro- visoes. 2. The complex of programs consists of a calendar, memo- writer, card-file database and calculator; it runs un- der MBASIC and apparently just as well under BASICA. The files are: INIT-DM.BAS -- a sign-on, which also loads the main program. DESK-DM.BAS -- the main program, with cal- endar, memowriter and card-file functions DDISK-DM.BAS -- this program is called to initiate the data disk for indices of the various functions; it creates the indices APTINDEX, CDXINDEX and MEMINDEX, and modi- fies the IDENT-DM file, as indicated below. CALC-DM.BAS -- this is the full-function programmable calculator IDENT-DM -- this file contains one word, either PROGRAM or DATA. If one runs a two- disk Desk Master, the program disk is thus identified and differentiated from the data disk. 3. These programs were transcribed by Dave Mintie (as I re- call -- apologies if my memory serves me badly) and put up on the Connecticut Morrow Decision Users' Group BBS in Groton, CT. 4. As originally supplied, Desk Master was arranged to use two disks in one drive. That is, one disk held MBASIC and the Desk Master programs; the other disk, to be ini- tiated using DDISK-DM.BAS (called from the Desk Master main menu), created an indexed data disk, which Desk Master instructed the user to swap into drive A: when accessing any of the applications. This was silly, since most of us have more than enough space on a disk to store both the programs and MBASIC and a substantial number of appointments, short memos, and a couple of card-files. So, I have made a couple of changes in the code (notably to lines 800 and 2160 in DESK-DM.BAS); the modification is a very inelegant one, from DE$ = "PROGRAM" to DE$ = "DATA". This should allow the user to "initiate" the same disk on which he has the Desk Master programs, then reset the system, reload Desk Master and never have to swap. Desk Master still in- sists on being in drive A: (user 0). 5. A number of elegances suggest themselves: (1) the re- writing of the code in a nicer language, (2) compiling the damn thing, (3) making a version that is not de- pendent on everything being in drive A0:. A truly per- fect version for a larger system would load and sit, SIDEKICK fashion (Borland's nifty new product) at the top of memory -- or maybe just load the menu part of DESK-DM into the top of memory, calling the other parts as needed, and using the disk-drives for virtual memory, in a top-end CP/M80 system. I have neither the skill or time to do this, but would be delighted if someone else came up with the mods.... 6. As it is, it is a nice program. I have put in a little "compliments of" message, and give it as a gift to friends and occasional clients (there was all that space at the top of the box going to waste...). I keep my phone book on the card index, and find it as convenient to load Desk Master and find a number as it is to look the same number up in a conventional card-file or loose-leaf phonebook. The appointment calendar is nice, will print out a month with the day's schedule -- hard-copy for reference. In short, I like this program. I hope you'll like it too. Donald Jenner Washington Market Logical Systems  **** F O R S A L E ******* F O R S A L E ******* F O R S A L E **** JULY 1985 JULY 1985 JULY 1985 JULY 1985 JULY 1985 ************************************************************************* NEW IN JULY TERMINAL: HAZELTINE 1420 $ 75.00 PAUL GLANVILLE (415) 632-9253 ************************************************************************* NEW IN JULY PRINTER: DIABLO 1610 (IPSI 1612) $300.00 ALSO S-100 SYSTEMS & BOARDS--CALL CABLES-ASSORTED FOR POWER & DISK DRIVES--AVAILABLE AT MEETINGS OR CALL CHARLES STEVENSON (415) 524-8329 EVE (415) 499-4256 DAYS ************************************************************************* NEW IN JUNE PMC MICROMATE WITH DUAL DRIVE ADD-ON QUME 108 - PROGRAMMABLE KEYS AN UPGRADE FROM THE 102 TERMINAL PANASONIC PRINTER - DOT MATRIX 80 COLUMN SOFTWARE: T/MAKER III, ELECTRIC WEBSTER, C BASIC & WS W/FOREIGN LANGUAGES PRICE: $1,000 DOUG SISKIN PH:232-4165  ************************************************************************* NEW IN JUNE TERMINALS: 1. TELEVIDEO 920 $275 CUT $50 FROM LAST MONTH!!!!!!!!!! 2. ADM-1A $100 TERRY LUKE W (415) 828-4422 ************************************************************************* NEW IN JUNE PRINTER: MPI MODEL 88 2K BUFFER GRAPHICS OPTION INSTALLED SERIAL AND PARALLEL OPTIONS FRICTION & TRACTOR FEED $200 DAVE THOMPSON 405 CALDERON AVE., #5, MT. VIEW 94041 W (408) 980-0242 EXT. 4166 H (415) 965-9717 ************************************************************************* END OF LIST ÅPRINT COMB9K/~:ʉ *N͐*#"o :͐!p+q!'"!6> **{2*́1>2!""!~o|g#6 #6!2~# ʭ~#:++~Au ERROR -- Invalid Drive Specification; 22!4>P"2!22:.G~#à u Writing ͩu to Disk2#DxG!~#{pmu PRINT Save Complete -- Returning to CP/M; u File Write Error -- Unsuccessful Save; ~0 p; GȸOGu Configuration Command? Lpu New Name of PRINT File (=No Change)?  !N#y>2ͱ ͱ:> º~.# ~.# y2u Invalid File Name Specification -- ReenterWu Number of Characters/Line (=No Change)? 2-:2/22:0/20://2/:1/21:3/23u Number of Text Lines/Page (=No Change)? 2,u Number of Physical Lines/Page (=No Change)? 2+ !N#yF~0H H#_zttttWt zu Invalid Decimal Number -- Reenter: u Numeric Overflow -- Value > 255 -- Reenter: !ͼ>. ͼ~ #¼a{_ u ++ PRINT II Configuration Display ++:@u Support Package is Installed -- Clock is AvailableÀu Support Package is NOT Installed -- Clock is not Availableu Cmd Function --- -------- ^C Abort to CP/M C Number of Characters/Line = :-ͯu E Exact Mode is :0]u F Form Feed is :2]u L Numbering of Lines is :1]u N Number of Text Lines/Page = :,ͯu Number of Physical Lines/Page = :+ͯu P Numbering of Pages is :3]u T Time Display is :/]u X Exit to CP/M and Rewrite PRINT to Disk Y Change Name of PRINT File from ͩu ++ End of Configuration Display ++ ɷhuOnuOff ~#ʖ ʘ ʧ x x> y˜x x20d÷d0  0_W{0: >2z://2/#:0/20#:3/23#:1/21#q {2-q {2,~,q {2+~,q {2->2q zi "#~0:0bk „ T]_zW#u :/ : *~ #ô > >->-> :0 :+2,212324 :G x_\" p; :11 :-2-D:2T]"p; ;   >  L :O ʙ ʙ } >2Þ >2*:1ʺ *#"+ͳ >:  ~ ͝ :¡ M.~# ib%":O :ž } #F#~  # #kp~ ʐ    :B > J # :-عX X #~ } #~ } #~ } >  ><  yˆ #  # #>  ͤ y‘  :-ڱ ʱ yW>n W#~ n ¿ n  # # :0 >  >  :=2:,G:+GL >  >   L 2:` X m X X X X >^͖ >2@͖ [ [ > ͖ :2ʁ > ͖ Ð > ͖ :=2 [ _  ʹ  u PRINT Aborted; _ !~ >@# \p; :26 :G; >  >  , ; >  :I _:l **|l }l >2:3ʑ !~ʂ  #v 2*#"+ͳ !4~ʜ  :,2:0¯ ɯ2'  d  }0  }o|g }o|g: 2y0 >  ~# "2*6G:,=2*p#"CE H L N P5 SY TW+ ; CEbFXLvNPTlX-YW PRINT II Version 3.0 $ Please set Top of Form Type CTRL-C or to Abort, Anything Else to Continue -- $ PRINT x:filename.typ /o Only 'filename.typ' is required. PRINT Options may be combined; Valid PRINT Options are -- /C = Enter PRINT II Configuration Mode /E = Exact Print [Expand Tabs, Form Feed, No Line or Page Numbers, Line Length Check] /H heading text = Heading /L = TOGGLE Numbering of Each Line /N = TOGGLE Numbering of Each Page /Pn1,n2,n3 = Set Page Parameters n1 = Number of lines of text on page n2 = Number of physical lines on page (",n2" is optional) n3 = Number of characters per line (",n3" is optional) /Sn = Skip to Specified Page /T = TOGGLE Time Display in Header /Wn = Set Width of Line (Chars/Line) to n Examples of options are -- /H/text/ /H'text of header' /S24 /N /P56,66,80 $Invalid Command $ File not Found$ Disk Read ERROR$ Page = Skip to Specified Page /T = TOGGLE Time Display in Header /Wn = Set Width o IN) 44P aplof opns are -- /H/text/ /H'text of header' /S24 /N /P56,66,80 $Invalid Command $ File not Fou!¡!6[–ͱ!N5:2:2!4=:[¼ͱ4:!6:.2O8: :* ͇g; 6/25/82---THIS PROGRAM, WHICH WAS ADAPTED FROM ; THE FMAP(CATALOG) PROGRAM, WILL LIST ; YOUR FILE DIRECTORY ON A LABEL SIZED ; OUTPUT. IT WAS WRITTEN USING AN EPSON ; MX-100. I DON'T KNOW WHETHER OR NOT IT ; WILL WORK WITH MX-80 BUT TRY IT. IT USES ; EPSON CONTROL CODES SO WOULD PROBABLY HAVE ; TO BE MODIFIED FOR OTHER PRINTERS. ; ; ANY SUGGESTIONS OR COMMENTS SHOULD BE FORWARDED ; TO: DENNIS MC FERRAN ; 1038 POLK LANE ; SAN JOSE, CA 95117 ; (408-296-6021) ; ; ; TO USE-------- ; 1) PLACE DISC WITH THIS PROGRAM ON IT IN DRIVE B ; 2) TURN ON YOUR PRINTER. ; 3) PLACE DISC THAT YOU WOULD LIKE TO LABEL IN DRIVE A: ; 4) GO TO DRIVE A: ; 5) AT THE A: PROMPT TYPE B:DIRBANER ; 6) PLACE ANOTHER DISC IN DRIVE A AND REPEAT ; AS MANY TIMES AS YOU WOULD LIKE. ; ; ; 8/82 Revised by Jim Woolley, FOG Disk Librarian ; 4 files/line, " | " between files, unidirectional print ; (unidir. print = esc,U,1 may only work with Graftrax) ; ; 9/82 Revised by Jim Woolley ; Print directory on printer, 6 lines/inch, ; with disk name in expanded characters, wallbanger mode ; ; ;*********EQUATE TABLE - BDOS*********************** ; * RDCHR EQU 1 ;READ CHAR FROM CONSOLE * WRCHR EQU 5 ;WRITE CHR TO PRINTER * PRINT EQU 9 ;PRINT CONSOLE BUFF * CONST EQU 11 ;CHECK CONS STAT * FSRCHF EQU 17 ; " " * FSRCHN EQU 18 ; " " * FCB EQU 5CH ;FILE CONTROL BLOCK * BDOS EQU 5 ; * ; * ;**********EPSON MX-100 PRINTER CODES*************** ESCAPE EQU 27 ; * ;SPACING EQU 65 ;LINE SPACING * CONDON EQU 15 ;CONDENSED PRINTING ON * CONDOFF EQU 18 ;CONDENSED PRINTING OFF * UNIDIR EQU 'U' ;UNIDIRECTIONAL PRINT * emphas equ 69 ;emphasized doubon equ 71 ;double strike expand equ 14 ;expanded FORLEN EQU 67 ;SETS FORM LENGTH * FORMFEED EQU 12 ;FORM FEED * CR EQU 13 ;CARRIAGE RETURN * LF EQU 10 ;LINE FEED  * ;*************************************************** ; ORG 100H START LXI H,0 ;SAVE THE OLD STACK DAD SP ;H=STACK SHLD STACK ;SAVE IT LXI SP,STACK ;GET NEW STACK ;SAVE FILE WRITE REQUEST CHAR LDA FCB+17 STA FILESW ;NO FCB SPECIFIED? LXI H,FCB+1 MOV A,M CPI ' ' JNZ GOTFCB ;NO FCB - MAKE FCB ALL '?' MVI B,11 ;FN+FT COUNT QLOOP MVI M,'?' ;STORE '?' IN FCB INX H DCR B JNZ QLOOP ;LOOK UP THE FCB IN THE DIRECTORY GOTFCB MVI C,FSRCHF ;GET 'SEARCH FIRST' FNC LXI D,FCB CALL BDOS ;READ FIRST INR A ;WERE THERE ANY? STA TEMP ;SAVE JNZ PRTTL ;GOT SOME - PRT TITLE, CONT LXI H,NONMSG CALL WRCON JMP EXIT NONMSG DB '++NOT FOUND$' ;SET UP PRINTER COMMANDS PRTTL LXI H,TTL CALL WRCON LDA TEMP ;RELOAD EXTENT JMP SOME TTL ; DB ESCAPE,FORLEN,0,1 ;SET PAGE LENGTH AT 1". ; DB ESCAPE,SPACING,8 ;SET LINE SIZE TO 8/72". ; DB ESCAPE,UNIDIR,1 ;SET UNIDIRECTIONAL PRINT. ; DB CONDON,'$' ;SET CONDENSED PRINT. db escape,forlen,10,'$' ;11 lines ;READ MORE DIRECTORY ENTRIES MOREDIR MVI C,FSRCHN ;SEARCH NEXT LXI D,FCB CALL BDOS ;READ DIR ENTRY INR A ;CHECK FOR END (0FFH) JZ SPRINT ;NO MORE - SORT & PRINT ;POINT TO DIRECTORY ENTRY SOME DCR A ;UNDO PREV 'INR A' ANI 3 ;MAKE MODULUS 4 ADD A ;MULTIPLY... ADD A ;..BY 32 BECAUSE ADD A ;..EACH DIRECTORY ADD A ;..ENTRY IS 32 ADD A ;..BYTES LONG LXI H,81H ;POINT TO BUFFER ;(SKIP TO FN/FT) ADD L ;POINT TO ENTRY MOV L,A ;SAVE (CAN'T CARRY TO H) ;MOVE ENTRY TO TABLE XCHG ;ENTRY TO DE LHLD NEXTT ;NEXT TABLE ENTRY TO HL MVI B,31 ;ENTRY LENGTH TMOVE LDAX D ;GET ENTRY CHAR MOV M,A ;STORE IN TABLE INX D INX H DCR B ;MORE? JNZ TMOVE SHLD NEXTT ;SAVE UPDATED TABLE ADDR LDA COUNT ;GET PREV COUNT INR A STA COUNT JMP MOREDIR ;SORT AND PRINT SPRINT LDA COUNT ;INIT THE ORDER TABLE LXI H,ORDER LXI D,TABLE LXI B,31 ;ENTRY LENGTH BLDORD MOV M,E ;SAVE LO ORD ADDR INX H MOV M,D ;SAVE HI ORD ADDR INX H XCHG ;TABLE ADDR TO HL DAD B ;POINT TO NEXT ENTRY XCHG DCR A ;MORE? JNZ BLDORD ;..YES LDA COUNT ;GET COUNT STA SCOUNT ;SAVE AS # TO SORT DCR A ;ONLY 1 ENTRY? JZ DONE ;..YES, SO SKIP SORT SORT XRA A ;GET A ZERO STA SWITCH ;SHOW NONE SWITCHED LDA SCOUNT ;GET COUNT DCR A ;USE 1 LESS STA TEMP ;SAVE # TO COMPARE STA SCOUNT ;SAVE HIGHEST ENTRY JZ DONE ;EXIT IF NO MORE LXI H,ORDER ;POINT TO ORDER TABLE SORTLP CALL COMPR ;COMPARE 2 ENTRIES CM SWAP ;SWAP IF NOT IN ORDER INX H ;BUMP ORDER INX H ;..TABLE POINTER LDA TEMP ;GET COUNT DCR A STA TEMP JNZ SORTLP ;CONTINUE ;ONE PASS OF SORT DONE LDA SWITCH ;ANY SWAPS DONE? ORA A JNZ SORT ;SORT IS ALL DONE - PRINT ENTRIES DONE LXI H,ORDER SHLD NEXTT call typbnr MVI A,4 ;SET 4 FILES/LINE STA PRCOUNT ;PRINT AN ENTRY ENTRY MVI C,CONST ;CK STATUS OF KB CALL BDOS ;ANY KEY PRESSED? DCR A JZ ABORT ;YES, ABORT LHLD NEXTT ;GET ORDER TABLE POINTER MOV E,M ;GET LO ADDR INX H MOV D,M ;GET HI ADDR INX H SHLD NEXTT ;SAVE UPDATED TABLE POINTER XCHG ;TABLE ENTRY TO HL MVI B,8 ;FILE NAME LENGTH CALL TYPEIT ;TYPE FILENAME MVI A,'.' CALL TYPE MVI B,3 ;GET THE FILETYPE CALL TYPEIT ENDEXT LDA NFILE ;GET # FILES INR A ;BUMP DAA ;MAKE DECIMAL STA NFILE ;SAVE IT BACK LDA PRCOUNT DCR A STA PRCOUNT CPI 0 JZ CLCR LXI H,SPACES CALL WRCON JMP CLCRPLUS CLCR CALL CR1 ;END, TYPE C/R MVI A,4 ;RESET 4 FILES/LINE STA PRCOUNT ;SEE IF MORE ENTRIES CLCRPLUS LDA COUNT DCR A STA COUNT JNZ ENTRY ;YES, MORE JMP EXIT ;type banner banr db escape,emphas,escape,doubon,expand,' $' cond db cr,lf db escape,(emphas+1),escape,(doubon+1) db condon,escape,unidir,1,'$' typbnr lxi h,banr ;start banner call wrcon lhld nextt ;get first table pointer mov e,m inx h mov d,m xchg mvi b,8 ;print filename call typeit mvi a,'.' call type mvi b,3 call typeit lxi h,cond ;set condensed jmp wrcon ;print and return ;TYPE CHAR IN A TYPE PUSH B PUSH D PUSH H MOV E,A MVI C,WRCHR CALL BDOS POP H POP D POP B RET WRCON MVI A,24H CMP M RZ MOV A,M PUSH H CALL TYPE POP H INX H JMP WRCON TYPEIT MOV A,M CALL TYPE INX H DCR B JNZ TYPEIT RET SPACE MVI A,' ' JMP TYPE CR1 MVI E,13 ;PRINT MVI C,5 ;C/R CALL BDOS MVI E,10 ;LF MVI C,5 JMP BDOS TEMP DS 1 ;SAVE DIR ENTRY ;ERROR EXIT ERXIT POP D ;GET MSG MVI C,PRINT JMP CALLB ;PRINT MSG, EXIT ;ABORT - READ CHAR ENTERED ABORT MVI C,RDCHR CALLB CALL BDOS ;DELETE THE CHAR ;FALL INTO EXIT ;EXIT - ALL DONE , RESTORE STACK EXIT LXI H,RESPRINT CALL WRCON LHLD STACK ;GET OLD STACK SPHL ;MOVE TO STACK RET ;..AND RETURN ;RESPRINT DB 12,18,27,65,12,27,46 ;EPSON CODES ; DB 27,UNIDIR,0,'$' ;TO RESTORE PRINTER TO NORMAL resprint db condoff,escape,unidir,0,formfeed db '- - - - - - - - - - - - - - - - - - - - - - -|' db cr,lf,'$' ;COMPARE ROUTINE FOR SORT COMPR PUSH H ;SAVE TABLE ADDR MOV E,M ;LOAD LO INX H MOV D,M ;LOAD HI INX H MOV C,M INX H MOV B,M ;BC, DE NOW POINT TO ENTRIES TO BE COMPARED XCHG CMPLP LDAX B CMP M INX H INX B JZ CMPLP POP H RET ;COND CODE TELLS ALL ;SWAP ENTRIES IN THE ORDER TABLE SWAP MVI A,1 STA SWITCH ;SHOW A SWAP WAS MADE MOV C,M INX H PUSH H ;SAVE TABLE ADDR+1 MOV B,M INX H MOV E,M MOV M,C INX H MOV D,M MOV M,B POP H MOV M,D DCX H ;BACK POINTER TO CORRECT LOC'N MOV M,E RET DS 30 ;STACK AREA STACK DS 2 ;SAVE OLD STACK HERE NFILE DB 0 ;NUMBER OF FILES PRINTED ; NEXTT DW TABLE ;NEXT TABLE ENTRY COUNT DB 0 ;ENTRY COUNT SCOUNT DB 0 ;# TO SORT PRCOUNT DB 0 ;COUNTER FOR ITEMS ON LINE SPACES DB ' | $' SWITCH DB 0 ;SWAP SWITCH FOR SORT FILESW DS 1 ;'F' IF WRITING FILE BUFAD DW 80H ;OUTPUT ADDR MYFCB DB 0,'NAMES SUB',0 DS 19 DB 0 ORDER DS 128 ;ORDER TABLE TABLE EQU $ ;READ ENTRIES IN HERE END 100H  !9"1:m2!]~ " 6?#\<2xF!:MÄ++NOT FOUND$!RM:xjCAU$\<ʒ=!o*w#}":<2^:!s#r# =ž:2=2:=2x2!͚##:x=2x:³!">2 =*^#V#"[>.@[:<'2:=2+!M3j>2:=2Ä_>$~@#M~@#[> @   Á!M* A .U$^#V#N#F #ʣ>2N#F#^q#Vpr+s | $NAMES SUBCOUNTER FOR ITEMS ON LINE SPACES DB ' | $' SWITCH DB 0 ;SWAP SWITCH FOR SORT FILESW DS 1 ;'F' IF WRITING FILE BUFAD DW 80H ;OUTPUT ADDR MYFCB DB 0,'NAMES SUB',0 DS 19 DB 0 ORDER DS 128 ;ORDER TABLE TABLE EQU $ ;READ ENTRIES IN HERE END 100H !9";1;:m2L!]~ " 6?#\<2F!:ö++NOT FOUND$!R:bC $\<ʊ=!o*>w#u">:@<2@V:@!ps#r# =–:@2A=2K:A=22A!p ##:=2¿:K«!p">P>2B =ʱ*>^#V#">͍>.r͍:=<'2=:B=2B&!C.͜>2B:@=2@öEG $ FHU$!;*>^#V͍>.r͍!E_>$~r#~r#> r   ó!*;U - - - - - - - - - - - - - - - - - - - - - - -| $^#V#N#F #>2KN#F#^q#Vpr+s | $NAMES SUBCOUNTER FOR ITEMS ON LINE SPACES DB ' | $' SWITCH DB 0 ;SWAP SWITCH FOR SORT FILESW DS 1 ;'F' IF WRITING FILE BUFAD DW 80H ;OUTPUT ADDR MYFCB DB 0,'NAMES SUB',0 DS 19 DB 0 ORDER DS 128 ;ORDER TABLE TABLE EQU $ ;READ ENTRIES IN HERE END 100H #B !9"*++"*͛!9* H*t/*++"*}2:%*++"*ͭ/*++"*"**++"*/!!9*ͭ!9$}2!9*"!9*"!!9*ͭ*$q *$q q *#"+$:%[!9$J *#"+!9$}*6!9$:%UkP +D!"l" !9*/*++"*#"$"͍ ʤ! }2*͍ "|*#"+$"*|!0}2*#"+$"I" *| *#"I" *#"+$"q ,* Ͷ q 8!" *!9*++/*C!9*++/*! EC!"lË! "lË!"l!9*++/*"n*n*lC!9*++/*"p"r*r#"r+$|*r+"r*p* ͵ * q *p* "r*p*rC*CP >cVdso|uxs*G!"G*$"0ͦ n*9ͥ q ʕ*G Q*#"+$"GS*G"G!9*"!9*"!9*+/*͍ *! m*+*g Ͷ}*͍ * !0*͍ &*! m0*!"*|·!9*!9!T9*͵ g!T9*n!T9*"C!9P"*C!V9*ͣ"!T9*͵ :%|!-* +" *+"6-**!P9!9!9P"!V9*!V9*ͣ"**!P9!9*!9*"*͍ L:%*͎*+"#|x!9*#/+$* +" L*|ʍ! !͎!9** Ͷ ʵ!9** +" Î!9* ͥ !0!7!9*C J v !9!9*͵ !!B !9*##*"! e"͍ @!* ! ! e"͍ c!!n ! ! e"͍ ʆ!! !* *! I*ͭ *!9! ͍ !9Vë*! *)))))*)))))*!r*!rI! 9*! I!* *5*5*5!!9!9*T!"T*T͵ ʬ*T#"T+e*T)))))!$9*!9! ͸!9 t"T! 9*!"!9**͵  *#"!9*#/+! 9*#/+$}"* * * * * *#"+)))))" *!<r͵ S *ͭ ! * *! * I!" !" * ͵ k Þ * #" +Ä !" * ͵ [ þ * #" +ä !" * ͵ > * #" +* #" + ! 9** $ ! 9** $ ͵ ' ! 9** $~Ͷ q ; ! 9** 6. ! *U! *Uó ! *UÓ ! !9**!' !9*I" " " " " *Ͷ ! *U*!2 !9*I!9$!9; !9$*U!9#$*U!9$*U!9#$*U;!9!9$! }!9*!9$̓ }!9*#!9$̓ }3!9!9$/!9!9*&}o/!9* !9!9*0/ !9!9*7/!9!9*}!9$!9*!9* !!A *!9*)*!9*pdump:Usage: pdump filename <--- to wide printercan't open input file: can't access device: start ... finis ... rbLST:wCON:consoleBMQ %d bytes <%xx> %d records <%xx>BM Qj %04x %04x *%-32.32s*%-32.32s  %s  %s %s%s \7}o|g}o|g}o|g|!,|}!‹ ‹ ,ɯ|w !|}!-z· { !,z z {!-|! |g| }! -ɵz {!-||g}o ) {ozg+|/g}/o~og~#fos#rN#F#xP~#~#99`iDM!z>`S\))h =`ɯ}z|MD!x<‘z>ږjS\>))Ҟ# Ҧ =– !"# *+%"%"%" " " "y 6"f+6+!^6 F+N+_!* !%!9~#ʺ uO"ʎ'ʎ +}|+#~ʥ˜6#~#<>!#4u6#6*#!%*.|5!e"r!,e".u Can't open > or < file.$w*Y L! 9 !"Y+*:e<*f 2e ͤi ) £> _*f~+#4N s> )> !N:hi2e_~   > % ʻ%!*.U> !N} 7 > _con:rdr:pun:lst: ``_~O7!=  ‡#ti& ~p!~ʦ#˜ý~#F6%pw62 !9*y= ʽͨ>w<ʽ!s 6#6 ~+21s#r{ʽ{ U!N#^{!!w#w!~<ʽ6!~rʯ!N!*}ʮ*ybʞ>w#—%!=){= b*x h&{ ! ~!N#F{p+pH#.e s+!9~ !~bʚ!5˜> Ý6> * w`i#/᯾%,!|!!9n&:Uɯ2>!9*):|!w#4!w>2>2:hĆ͑x}:OJ! DM:}c !ÃWrite error - Disk full $`i!9~=+ V+^+F+N "> w+ ±w w##w w #~+:~##@~#.*++w#a O! ~_#V!$1r+sbk#| "> w+ ±w w##w w #~+:~##@~#.*++w#:@<2@V:@!ps#r# =–:@2A=2K:A=22A!p ##:=2¿:K«!p">P>2B =ʱ*>^#V#">͍>.r͍:=<'2=:B=2B&!C.͜>2B:@=2@öEG $ FHU$!;*>^#V͍>.r͍!E_>$~r#~r#> r   ó!*;U - - - - - - - - - - - - - - - - - - - - - - -| $^#V#N#F #>2KN#F#^q#Vpr+s | $NAMES SUBCOUNTER FOR ITEMS ON LINE SPACES DB ' | $' SWITCH DB 0 ;SWAP SWITCH FOR SORT FILESW DS 1 ;'F' IF WRITING FILE BUFAD DW 80H ;OUTPUT ADDR MYFCB DB 0,'NAMES SUB',0 DS 19 DB 0 ORDER DS 128 ;ORDER TABLE TABLE EQU $ ;READ ENTRIES IN HERE END 100H  ɀCPM22RSX;*56"1b SORT AND PACK DIRECTORY v3.5 04/14/83  |?27,ͨF͉ͻ DONE !"*~ ~##~_#~**#~+- 6# *@#**#͒ګ***, ~G# *.>23"4:^#"9^#"@~#2;~#2<^#">^#"B^"F^#V#"1~#fo9628*F!"3*@#$$"(!"&*3#*9͒ұ*5#!*&DM':8*"5DM!"3DM*1 3DM:7$-~#O)))))*&"&*(+"(|˜'~#6 ++ SAP not useable with MPM ++(Previously sorted) - DONE !"* ~0 2,#~$#~$#:,w+6$+6$+6$**#*@#͒ڌ ---> Reading, v++ READ ERROR - Exiting to CP/M - NO CHANGE made |g}o:\=8O:7\20Sorting, !"***#",ܙ*,#",*@#͒d**#"**@͒]}o|g>20***, G~p# ¯:0fWriting, >v++ WRITE ERROR - Exiting to CP/M - directory left in UNKNOWN condition ++ yBIOS2.21çç69<?BE1>6CO]; BIOS ver 2.21 ACTIVE ! "Ͱ*"3-!"!`Ͳ *"22!"22 :e22222y22> ;|^#V"! ^#V"+~2###~2 ~2!!CCi`y2>2<2ò2y2 :<2:2:2:2:(8=2:! +:! ":! 4~!8 *#"222<22:G:!( 0)2"!~6(":! :! :!($:e:2*":2:Y2**: >2: : 2e:q> ;2q>;2:o&"*">;}2"> ;*"> ;!"> ;>2>;~N<#ò$I$I $ @I D @A"I$H$D AI$  I IBBCOUNTER FOR ITEMS ON LINE SPACES DB ' | $' SWITCH DB 0 ;SWAP SWITCH FOR SORT FILESW DS 1 ;'F' IF WRITING FILE BUFAD DW 80H ;OUTPUT ADDR MYFCB DB 0,'NAMES SUB',0 DS 19 DB 0 ORDER DS 128 ;ORDER TABLE TABLE EQU $ ;READ ENTRIES IN HERE END 100H ()CPM22RSX*+++3~# !_w!_^&&'Y"/{ Y(E Y*9 { a   { a 1 { a N a'͓'!`>wRʛ&UTSu ͓&!\>w!K>wR'&͡#&Y#;  a'Y86f **"<͘" <'ͩ'ͻ$**}|"]&'R'͓'*]o$*6"C*:"E!(~w!\>w͡#**o$*6"8R'&Y#;  Fej"s"a''!\~ʊ Òo '&'ͩ'ͤ  SʠTQV@Wʀ P(R!K~!\~ U4   U.͓& Þg![>w͓'a'Y86J *T"<͘" <'ͻ$z~Ä{ʄ*T}|ڄ"V"MR'͓'&*V!͊}ʼ!Xw!Owi`ƀ!Xw!Owi`+! ͊}=!Rwy!Sw!w!Rwy=!Sw!wS!X^!Q~!o͊} !Zwy!Yw.!Q~!Zwy=!Yw$**|`!Y~P=E!o !Y~t=gog ͓&.}/o|/g#ږ !P>w!\~#!K~.*T*M{zk!L~=w!O~w!\~!K~!QF!L~ʴw!Hw!!G~p !H~p ʵs#W͗{͗!͗HA B! CB DO Qe R͓&{'gWxq ͗{͓&{x6 ͗{͓&{#W͗{+x_ ͗{͓&W'g͗!͗{a'' '<''Y)X!eͭ! s#ʗ ͗û ͗͘!͗H A B1 CR D_ Qe R× xq% ͗û ͓&û xF ͗û ͓&û #ʗ ͗û +xo ͗û ͓&× !J>wR'&Y+3 <'ͩ'!2>wʻ #ò ! ;  ! w; # ͓&  , x +& ͓& _  b  !~:X ! #w  # a w > w#  > w # xG> w # !M>w#>w!P>w![>w!Sxw!R>w!K>w!\>w!T>w#w#!og"TS!O>w!$!(~wa!P~x%**|Ø Ø !P~**|Ø Ø x **|Ø Ø !R~wS M$**|n!oy!og!(F>!Ow ͓&a''Y8;+ R''O ͓'&u ͓&a''Y84 R''O ͓'& R'&͓&a''Y8-+ R''O ͓'&u ͓&Y5 <'} &'TʶtʶCck&͓'a''Y8=e R''O &͓''Y5   Y6   a !R~ ʋ!wʞ'  ‚=}xw!S~ =DE: =D: =D: =2 = _2GͅG͛G*=##: =2=G= ~5E5Ew# +E #+E w#>E:=!=~ bEw#XEͭFY__     +  # a'Y8; *6"<͘" <'ͩ'ͻ$*6}|""C&'͓'a'Y8; *%+"<͘" <'ͩ'ͻ$*%+}|G#"E&'Ϳ'R'͓'Y%( Y%/*C"<͘"Y%R Y%Z*E"<͘"Y'(l Y(' Y)" !e͊!͝%!e!Y*" !u͊!͝%!u!Y+" !͊!͝%!!Y," !͊!͝%!!Y-" !͊!͝%!!Y."  !͊!͝%!!Y/" !͊!͝%!!Y0" !͊!͝%!!R'!`>w!K~!J&ͺ%!Dͺ%!ͺ%:!~ ___#G!~ ʋ.~ ʋ_ʋ#s%%%!6&ͺ%!Mͺ%"&"<*&͘"%!&ͺ%!Vͺ%*M"<͘"%%%!%ͺ%!ͺ%!ͺ%%%%!6&ͺ%!&ͺ%*C"<͘"%!\~( !b&ͺ%!Mͺ%*]"<͘"%!&ͺ%!&ͺ%*E"<͘"%%%!6&ͺ%!lͺ%%%!?&ͺ%!ͺ%%%!G&ͺ%!ͺ%!e͊!͝%!e!%%!G&ͺ%!ͺ%!u͊!͝%!u!%%!G&ͺ%!ͺ%!͊!͝%!!%%!G&ͺ%!ͺ%!͊!͝%!!%%!G&ͺ%!ͺ%!͊!͝%!!%%!G&ͺ%! ͺ%!͊!͝%!!%%!G&ͺ%!ͺ%!͊!͝%!!%%!G&ͺ%!ͺ%!͊!͝%!!%%%%!`>w͘!#!!͝%#Œ!~!ڨ!Ҩ!!>.!''_~!0:!!_!`~!!''xZ"0A" /" A"K"!))))_!͓&!G>w*A"0A" /""͓&!H>w*CDM*EDM*2*C#{zғ"*4"DMÔ"|$!>~ګ"0"7_!`~"""#á""0!`~""͓&&'R'͓'a''Y88 'R'O R'  ͓'[͓&&'R'͓'a''Y88 'R'O R'  ͓'^!I>wR'&Y+7j a'͓'#A#G$R'$R'&͓&&#a#g#R' 2A!K~4$<2%=%O |Q$j%!J>w!I~#^#V"4 ~#fo%~#f$DM@%"6":*<'ͪ$2>ͪ$2?dͪ$2@ ͪ$2A}02B}o|gҬ$ z0  %"% "%-%0$ $!)))_$͓&&$x%&ʻ$%͓&û$͓&$͓&b $`i:')=E%*%}/o|/g#Y% *%*2 ͓&a'Y8## ͓' !`~ʲ%÷%~$_#ú%  ???????????? $ $ $ $ $ $ $TRACK: $SECTOR: $z*+++"& EFGpqx5y5Hx1Y8 y1x4y4x6y6  y1x4y4x6y6yBIOS2.21çç69<?BE1>6CO]; BIOS ver 2.21 ACTIVE ! "Ͱ*"3-!"!`Ͳ *"22!"22 :e22222y22> ;|^#V"! ^#V"+~2###~2 ~2!!CCi`y2>2<2ò2y2 :<2:2:2:2:(8=2:! +:! ":! 4~!8 *#"222<22:G:!( 0)2"!~6(":! :! :! ($:e:2*":2:Y2**: >2: : 2e:q> ;2q>;2:o&"*">;}2"> ;*"> ;!"> ;>2>;~N<#ò$I$I $ @I D @A"I$H$D AI$  I IBBCOUNTER FOR ITEMS ON LINE SPACES DB ' | $' SWITCH DB 0 ;SWAP SWITCH FOR SORT FILESW DS 1 ;'F' IF WRITING FILE BUFAD DW 80H ;OUTPUT ADDR MYFCB DB 0,'NAMES SUB',0 DS 19 DB 0 ORDER DS 128 ;ORDER TABLE TABLE EQU $ ;READ ENTRIES IN HERE END 100H ɀ<=CPM22RSX8 ;b͸{==Jw{ÖüH!K]jU 2͵ ^#V#*~#fo^#*~#fo^#V#*n^#*n^#V# ~#fo^#& ~#fo!+!#!+!#!+!+}|z{|}|z7||7zZZ)|/g}/o#|͉k|/g}/o#ɯ2hZZk:h|/g}/o#|/g}/o#:h<2hqDM!xxGyO҃)v|͔`i|)Öxڷz/W{/_ѯzW{_=yOxGæ2hZZ͉M|}ȯ|g}o)|/g}/o#z/W{/_!9~#fo! ! ! ! ! ! P!9~#A!9"w**w"j!z*"d!"f!Y"H>2^>2a>2`2c>2s2t>2r>2v!"@!"D!@"B!"F !F#x:~#!|2i~# :" 2i +}|~#:G:ix."2i+w# +6#!6#@A2n2?*j**|+`"d!"f!!>ڌo&͖=}  w~2ʸͼ56!+W ?_!~7z?ͧ:>͞@w#5.ww#w#w#w*>?@͌>w#͌5> w#@ͧ͵g 2q&0OxG͵j/ʆSx\͞.7:77!a{  ʨ ʨ0:?ŷO !y$ 7o&))T])))!y 2p_ :p6)))Y~0̿7G~`2@2@#~2@~?>&=2@#^#V#^#V#"@^#V"@:@ '*{@!:@@'"@*@#w"@*@~9'D'/Ϳ7͈?+"@*@+"@!6D"@6!^D"@*@~*@*@s#r#*@s#r#*@s#r#*@s#r#*@s#r#:@w#"@'*@*@s#r#*@s#r#*@s#r#*@s#r#*@s#r#:@w#"@'|E'}X27*@+~2@+V+^+"@V+^+"@V+^ +"@V+^+"@V+^"@"@*@+~2@+V+^+"@V+^+"@V+^+"@V+^+"@V+^"@"@p';(ͯ''͋(!"@"K@2@<2@2@2@ͥ)()(*¾(2@2@(S*(#)2@2@)l*-2 s 8*w#w*w#w! ! ͻ!D ͻ![ ͻ;| Rev 2.4 3/29/84 DISK CERTIFICATION & UTILITY %s By: Carl Beck Arvada, CO. } 8!9DM!!z !Y!z ͐ !z ͐ !z 8! !  8 !A!  8 !@!  8!! !0! < P2!G 9 0PQ P2!\ N Ke P2!p b kÑ -2 Â2#îW $!9DM! v ! v !! v !G v !k v ! v ! v ! v ! v ! v `iy ! `i| | ! ! ! `i| |. ! ! ! `i| |H ͂ ! ! `i| |b ͅ ! !! `i| || ͈ ! !% `i| |– ͋ ! !) `i| |° ͎ ! `i!!- v !9 SELECT DESIRED TASK FROM THE FOLLOWING MENU CERT - Read Disk & Report Errors | LOGBAD - Log Bad Blocks in Directory DIR - Print DIR | DIB - Print DIR with Block Numbers CPM - Return to CP/M | DSK - Select a Drive DUMP - Display in Hex/ASCII | Only the first 3 letters CERLOGDIRDIBCPMDSKDUM %c%3s is an invalid command. Try again. ` -2×!9DM`iw#w\+|€ ! Z \|ڢ *~#fo+s#rô *~#fo#s#r͐] !9 Flushing BIOS buffer with revised data. 389!9DM`iw#w͐|ҷ!! ! s!|w! n&|w! ^#Vr+s! ns`i^#Vr+s! n& ͐|ڴ! n}ʚ! n}´`i^#Vr+s! ^#Vr+sn ͐6! ͐!99!9DM`i6`in&! `in&!9-2369k9'!9DM`in&|B`in&|V!`is!! `in&+|g}o`is`in&!`in&`in&A!\ !\ !\!1\!Y!s\\!\\?!\|ʤ\!\! s#r! w#w͐\Ҝ͐|Ҝ͐|t!! ^#Vr+sn&!! ^#Vr+s?!!9 Enter desired drive. ( A - P) The Disk in Drive %c has: %-4d Logical Tracks %-4d Reserved System Tracks %-4d 128 Bytes Records per Track %-4d Directory Entries. DISK CAPACITY: %-6d Blocks at %-6d Bytes Each. = %-6d Kilobytes. The Following Sector Translate Table is at: %4xH %4d Check to see if your first sector is 1 or 0 3|9-28!9DM!! n&! *! s#r͐|z! n&A! -0͐~#fo*s#r͐~#fo*s#r͐ ~#fo~#fo*s#r͐ ~#fo##n&+++*s#r͐ ~#fo~#fo#*s#r͐ ~#fo~#fo#*s#r͐ ~#fo ~#fo* s#r͐ ~#fo###n&#*s#r`iw#w* 6#6! w#w͐\`i~#fo\s#r͐\`i~#fo\s#r* ^#Vr+s! ^#Vr+sÃ* ~#fo\ s#r!9 DRIVE %c SELECT ERROR 2-28~b!9DM! w#w!* 60! 6#6͐\ +͐!&͐! )`iw#w͐\͐,! s#r* ! )͐\ ͐\?͐\! s#r! )|͐͐͐͐!.&͐1+|! ^#Vr+s)! ͐s#r\|چ͐|†!* n&! ͐/!* n&#s! w#w\|͐|!* n&! ͐/!* n&#s! w#w`i^#Vr+sÄ! ^#Vr+sQ͐1+|͐|!* n&! ͐/!-9 Track %3d ERROR track %3d - lsec %3d - psec %3d - block %4d wK3â9-299ð:!9DM!7!0 e!E n!6 s!0 h! s#rz½!0 !Ck͐ n`is#r!\͐ q͐͐A\?s\|ڻ! w#w! w#w͐͐AҸ͐͐!C ~#fo͐)~#fo|g}os͐͐#!C ~#fo͐)~#fos͐|ڔø! ^#Vr+s! ^#Vr+s! ^#Vr+s! w#w͐͐A͐͐!C ~#fo͐)~#fos! ^#Vr+s͐A\?͐A!Vk͐ t!=9BLOCKS0.BAD Can't create '%s' %2d blocks with %d bytes blocked out. Ç|98!9DM\͐!́`is`in&! ̈́`in&þ!9-2"(Ù!9DM!X`isz`in&|k }M`in&Ok }MG`i6`in&|D`in&`i4&O!!9 Enter User Number: (0-15 or ax for All Users Invalid User.â-2k9!9DM! 6\#6!) w#w͐)|͐͐)6?!) ^#Vr+sû!) 6 #6͐)|͐͐)6!) ^#Vr+s!+ w#w!- 6#6!u͐͐͜-͟!/ s#r!|U!- 6#6͐/ ?!' s#r͐'n`is{R`in!7 n}R͐' n}R͐'n&!w͜!) 6#6͐)|͐'͐)n&!|͜!) ^#Vr+sò!͜!) 6 #6͐)|)͐'͐)n&!͜!) ^#Vr+s!+ ^#Vr+s!|J!͜R!͜-!7 n&͐+!͜!39 %2d %c.%c | %3d Directory Entries on User %2d.÷t#\ ?!ʹͱ×-2 38í,P0!9DM! 6 #6! ^#Vr+sz\\ _\\ \?͐ ! s#r͐\! s#r\|o͐ `is#r\͐ʙ*w#w͐*s#r͐ \!͐͐!͐!A!q!! 6#6͐|!!! s! n}N>PTEʐFʞSʬï! w#w! ^#Vr+sï! w#w͐ |‚\! s#r*^#Vr+sÍ! ^#Vr+sï! w#wï! w#wï͐ \*^#Vr+s! ~#fo\s#r! 9 TRACK %3d - SECTOR %2d - PHYSICAL SECTOR %2d - BLOCK %3d ext sector

revious sector top dit ill with Data à|98!9DM\͐!͚`is#r͐! ͝\! ͝* ! ͝!! ͐͝!9-29ó:9!!9DM! `iw#w͐|X͐! `i^#Vr+s1! ! w#w͐|m ͐ ?! `iw#w͐|͐))))* ͐n&! `i^#Vr+sÏ!!`iw#w͐|W ͐))))* ͐n&|g}o! s! n&|C ! n&|C ! n&K !.`i^#Vr+s! ! ^#Vr+sh͐ \ ?\ڏ !!`iw#w͐| ͐ ?* ! s#r͐`i^#Vr+sÝ !9addr %02x %02d %02x User Filename Ext Records Assigned Blocks E!-2(#9!9DM͐`is#r͐n! s!|"͐n&!"<í,P0!9DM!+ )`i)!`i)! s#rz€)`i!!+ )Û+! s#r! s#r!* ͐)! s#rzʛ+͐|)͐)! s#r͐ ))Û+͐)+\! s#r\|%*͐͐  )! s#r@*͐͐ #)! s#r͐͐d*͐! s#r! w#w͐&)! s#r͐͐͐\!+ )͐))!+ )!., )! 6#6͐|ʘ+!!/),)! s! n}N*P+EB+Fj+Sʒ+Õ+! w#w! ^#Vr+sÕ+! w#w!͐)++͐2)! ^#Vr+sÕ+! w#w5)!͐)+͐2)Õ+! w#w8)!͐)+͐2)Õ+Û+ø*Ñ)!"9 Enter filename.type: %cCant Open %s TRACK %-3d - SECTOR %-2d - BLOCK %-3d  ext sector

revious sector top dit ill with Data !9DM͐`is#r͐͐)~#fox,!9!9DM͐`is#r͐͐n&ä,!9ÿ,-2"(0698!9DM!E.Ͱ,!.Ͱ,!.Ͱ,!&/Ͱ,!e/Ͱ,ͳ,`is#r͐|<.͐|<.͐Ͷ,ͳ,! sz.! n&|.k } T-IW-'ʂ-.-..͐* ! ns! n&!/Ͱ,.!/Ͱ,!/Ͱ,͐Ͷ,͹,! s{ -͐* ! ns! n&!/Ͱ,`i^#Vr+s͐Ͷ,Û-`i^#Vr+s* 6.!!ͼ,*6#6<.!/Ͱ,`i^#Vr+s͐|9.`iw#w,!9 Use Hex Numbers Only. A Hex Number followed by (I) will be inserted. A will leave original data. A (.) will exit the edit mode and write the modified sector to disk. To enter ASCII characters, type a (') followed he characters to be entered. A will stop ASCII entry. Enter HEX Address to edit. %02xH Hex Number Inserted. Type Characters to be Inserted. Type to end. %c ASCII Character Inserted. Data L eft Unchanged.0-2!9DM͐* n&͐!@00 %02x %02x \0-2"(8!9DM!Z1S0V0`is#r!|ډ0!y1S0l0!1S0V0! s#r!|ҵ0͐͐0!1S0Ñ0!1S0V0! s!|0! 2S00! w#w͐͐͐51͐* ͐! ns! ^#Vr+s0!!Y0*6#6Q1!9 Enter Start Address to Fill: Start Address must be >= 0 and <= 7F. Enter End Address to Fill: End Address must be < 128 and > Start Address. Enter Hex Byte to Fill with: Fill Byte must be >= 0 and <= FF.62ó:Ó3!9DM*12! 32V2ó:!9DM͐n}ʀ2! ^#Vr+sn&S2^2!9DM`iw#w! ~#fo͐n! ~#fo͐n}2! ~#fo`i^#Vr+sn}2!3Ð2! ~#fo͐n! ~#fo͐nѯgW3!93Ì7!9DM! n&3|>3! n&E3! n&&!9DM͐`is#r! ^#Vr+s! ^#Vr+sns{ʃ3]3͐Ê3!9â3û7c8Ò83!Y9DM! ^#Vr+s~#fo! s#r͐! s#r! ^#Vr+sn`is{}7`in}%N7! ! s#r! 6#6! s! s! s͐n}-24! ^#Vr+s! 4͐n}0B4! 4͐n&͙3}_4! ͜3b4!! s#r! ^#Vr+sn`is{.ª4! ͜3! s#r! 4! ^#Vr+sn`is`in&͟3}D4U5X 5O)5Co5Sʠ577͐~#fo|5! ^#Vr+s6-͐͐~#fos#r! ^#Vr+s! 6 /5! 6/5! 6! ~#fo! n&! ^#Vr+s~#fo! ͖3ѯgs#r6! ^#Vr+s! ^#Vr+s~#fos! ^#Vr+s6! n}³5! 6#6! ^#Vr+s~#fo! s#r͐n}6͐|6! ^#Vr+s! ^#Vr+sns! ^#Vr+s! ^#Vr+s5͐6! ! s#r! n}†6! ^#Vr+s!|چ6͐͐! n}c6!0f6! !t6!9~#fo#|ƒ6!Ã746͐n}6͐͐! ^#Vr+sn&!6!9~#fo#|6!Ã7Æ6! n}7! ^#Vr+s!|7͐͐! !7!9~#fo#|7!Ã76K7!Ã7͐͐`in&!<7!9~#fo#|K7!Ã7z7͐͐`in&!k7!9~#fo#|z7!Ã73!Ã7!9!9DM! n&|ͯڷ7! n&|ͩ7û7!9DM͐͐ 8͐^#Vr+s͐7͐08͐7s!&Z8͐ ͐͐ ͉͐;7`is͐ ͐͐ )͐;7`in&#&Z8!9!9DM! n&|ͯڎ8! n&|ͩØ8c8!9DM`iw#w͐~#fon&͕8}8͐ ?͐^#Vr+snѯg`is#ræ8͐8!9 7*+++:PG_*RDM!9o& _ 19  :noE92n& !o h9 . &7:PO*R7*+++:PG_*RDM*TT]!9ë9Ï<;7*Pͥ9:q2\59> 2?!*Pͨ9 )9>2? ,7:P)"XV>ڪ:z> ʪ:z2:P,"j!"l*T|X:*j!^#V*X#^#VP:r+s*l5*R"R*j"*lʀ:2?S:#"l*T+"T*j! N#Fp+qx*:##6>2?P:2?#  : > _ :  !j96  #F#x;~#;7,";> 2h*P/:q2> r;:h):R^;=^;=> r;:qw#w#w:ho&552?7:P)V>2?ë;2? ,5<>2?!~#foD<ö<7:P,>Z<2?!^#V*R:Tʃ<=t<Ã<*PA<*R!s#r !\/:q25!> 2?+ ,<>2?)~2#"j!!~#fo#^#Vp+q*j~#fo=s#r5#yBIOS2.21çç69<?BE1>6CO]; BIOS ver 2.21 ACTIVE ! "Ͱ*"3-!"!`Ͳ *"22!"22 :e22222y22> ;|^#V"! ^#V"+~2###~2 ~2!!CCi`y2>2<2ò2y2 :<2:2:2:2:(8=2:! +:! ":! 4~!8 *#"222<22:G:!( 0)2"!~6(":! :! :!($:e:2*":2:Y2**: >2: : 2e:q> ;2q>;2:o&"*">;}2"> ;*"> ;!"> ;>2>;~N<#ò $I$I $ @I D @A"I$H$D AI$  I IBBCOUNTER FOR ITEMS ON LINE SPACES DB ' | $' SWITCH DB 0 ;SWAP SWITCH FOR SORT FILESW DS 1 ;'F' IF WRITING FILE BUFAD DW 80H ;OUTPUT ADDR MYFCB DB 0,'NAMES SUB',0 DS 19 DB 0 ORDER DS 128 ;ORDER TABLE TABLE EQU $ ;READ ENTRIES IN HERE END 100H  DU-V87.DOC ---------- By Ward Christensen (revised 05/14/84) additional notes by Ron Fowler, Irv Hoff, and Jeffrey Nonken This version of DU is compatible with CP/M 1.4, 2.x and 3.x and does not require alteration for various hardware configurations. It adjusts itself automatically to the correct number of sectors, tracks, directory size, etc. INDEX 1.0 INSTALLATION: 2.0 USE: 2.1 COMMANDS, BY FUNCTION 2.2 ALPHABETIC COMMAND SUMMARY 3.0 NOTES 4.0 INTERPRETATING DIRECTORY DATA 4.1 SINGLE DENSITY 4.2 DOUBLE DENSITY 1.0 INSTALLATION: === "DU" should require no changes to the source file because of the use of the automatic adaption feature. The only alteration that needs to be done is to use DDT to set the byte at 103H for your clock speed. Use 0 for 2MHz, 1 for 4MHz, 2 for 6MHz. (This only affects the "Z" SLEEP command.) 2.0 USE: === To invoke "DU", simply enter "DU" at the CP/M prompt. A>DU An initial command string may optionally be placed as an operand of the original "DU" command, i.e.: A>DU M;X for example, if you want to only map the disk, and then exit: Once "DU" is running, it expects single-letter commands much like "SID" OR "DDT". For ease of use, multiple commands may be placed on one line, separated by ";". In addition, a given command or string of commands may be repeated -- either indefinitely (until ^C is pressed) or a given number of times. To avoid an accidental ^C from dropping out of "DU", only the explicit "X" command will exit "DU". 2.1 COMMANDS, BY FUNCTION === HELP: ? displays the help guide POSITIONING: Gnn by allocation group Snn by sector Tnn by track +nn going ahead nn sectors -nn going back nn sectors I/O: < puts current sector "away" into a buffer > recalls previously saved sector K writes "yanked" sectors to a file (see "saving sequential memory" in notes below) R reads sector W writes sector Y "yanks" current sector into sequential memory DISPLAYING: # shows disk parameters A dump sector in ASCII D dump the sector (hex + ASCII) G shows current group, track, sector H dump sector in hex M maps the disk -- where the files are located Mxx map starting at group xx Vnn views (like CP/M type) nn sectors CHANGING: CAnn,VAL change data in ASCII (with escape to hex) CHnn,VAL change data in hex Unn change user to nn SEARCHING: =Abc scan for Abc (IN ASCII) from current sector on (very slow, allow up to 15 minutes to scan an entire disk. Either finds the answer or says: "out of bounds". FNAME find a file in the directory F find next occurrence (extent) of same name MISC: ( toggles the map display to show/not show erased files /nn repeat previous command nn times (repeats indefinitely if nn omitted) Bnn boot nn sectors per track LX log in disk X P printer toggle Q before a command does it "quietly" X exit to CP/M Znn sleep (nn tenths of a second) to allow viewing data before it scrolls off 2.2 ALPHABETIC COMMAND SUMMARY === # Prints the disk parameters + Advance 1 sector (if below track 2, this advances to next numerical, if 2 or more, advances based on CP/M"s normal sector scrambling algorithm, i.e., allows + to the next logical sector of the file. - backs up 1 logical sector NOTE: + and - may take an amount: For example, +15 advances 15 sectors / repeats entire command -- defaults to "forever" /nn nn may be 2 TO 65535 ( toggles the map display to show/not show erased files. When showing erased files "*" indicates that block duplicates a block in another file. It may not be possible to restore this program without errors. If there are no "*" in this complete file, it can be correctly restored. < saves current sector in a "save" buffer =Abc ASCII search, starting at current sector. hex  may be imbedded or used alone. To find the ASM instruction: "IN 0FEH" use: = (Ignores bit 7 unless using .) Since ";" is a command delimiter, you have to use <3B> to search for a ";". Also, since "<" is a hex escape character, use << to mean a single "<". NOTE: This is a very slow routine. It can take 15 minutes or longer to search an entire double- density double-sided disk so be patient. It either finds the string or says: "OUT OF BOUNDS". > gets saved buffer. < and > may be used to move a sector to another place. ? displays the help guide A dump sector (ASCII only) Bnn boot nn sectors per track -- not all disks have 26. CHADDR,VAL,VAL,VAL... change hex values in sector CAADDR,CHAR STRING... change ASCII calues in sector NOTE: may be hex imbedded in the ASCII string: CA00,OK<0D><0A><1A> ----> W writes changes to disk note that the "C" command echoes the over-  laid data for verification. CHADDR-ADDR,BYTE repeats a change CAADDR-ADDR,BYTE repeats a change D dump sector (hex + ASCII) FNAME print directory for file "NAME", then positions to its directory sector. F find next occurrence of name in directory Gnn position to group nn and read G shows current position H dump sector, hex only Kdu:filename.ext save a file from "yanked" sectors. drive, user are optional. Resets "yank" address. see "saving sequential memory" in notes below. L re-logs in the current disk -- you may pull out a disk, put in a new one, and "L" just to log it in. (see "logging in disk" in notes below) LX logs in disk "X", such as: LB, LC, LA, etc. M dumps a map of the group allocations for files Mn shows which file is allocated to group "N" N resets CP/M via BDOS -- this may make it possible under some implementations of CP/M to change the disk format, i.e., density, sides, etc. P toggles the printer on/off Q quiet -- preceedintg any command, suppresses CRT output R reads into memory the sector currently positioned at. NOTE: "R" (read) is implicit in the G, +, and - commands but NOT in the "S" and "T" commands Snn position to sector nn, and read TNN seek to track nn (no read) Ux logs user "x" for next "F" command V views the current sector -- assumes ASCII data Vnn views nn sectors W writes the current sector to disk NOTE: may NOT be used after an "F" command as CP/M was used to find file in the directory X exit back to CP/M (must press return). ^C was too easy to hit over modem lines -- requires two bytes: (X,CR) to exit. Y "yank" the current sector into sequential memory (starts at 3000H, increments for each yank) Z sleep -- causes the porgram to pause -- such as to look at a dump. Z is 1 second Znn nn tenths of a second Z50 = 5 seconds 3.0 NOTES === * Multiple commands: May be separated by ";" EXAMPLE: The following commands will erase the B: disk directory to all E5"s: LB log in B: drive G0 position to directory CH0-7F,E5 fill with E5 < save the sector >;W;+;/16 restore, write, next, repeat 16 ---- this could be shortened to: LB;G0;CH0-7F,E5;< >;W;+;/16 * DUMP COMMANDS: All dump commands (D, A, H) may be optionally followed by a starting and ending address: D0,7F the same as just "D" D3,5 A20,3F * LOGGING IN DISK: If you have a disk with a "blown directory", try logging in a good disk of the same density, then put in the "blown" disk without logging it in. You are opening yourself to possible problems because of the buffering of physical sectors in the "BIOS". The best technique, (but not guaranteed), would be to seek to the unused inner tracks of the first disk, do the read, then change disks. That way, if it writes anything, you won"t have destroyed anything -- assuming the disk is not completely full. Another technique (assuming the second disk does not contain a CP/M system, would be to seek to track 1, do the read there, then change disks to the blown one. * SAVING SEQUENTIAL MEMORY: Since CP/M v 3.0 does not have a SAVE function, one has been added. Syntax is: Kdu:filename.ext ^^^ ^ ^ ||| | +-- file extension (0-3 characters) ||| +-------- file name (1-8 characters) ||+--------------- user # (or none) |+---------------- drive designation (A-P or none) +----------------- DU command Drive and user may be omitted. If so, omit the colon as well. Drive must be specified if the user is. If the user # is omitted, the current user is used. If the drive is omitted, the current CP/M default drive is used. This function saves the current contents of sequential memory into a disk file. The contents of sequential memory are determined by the "yank" function, and the pointer of that function is used here. If nothing has been yanked, you get an error. Once the file has been saved, the "yank" pointer is re-initialized to its original value (3000H). Control is re- turned to DU. 4.0 INTERPRETATING DIRECTORY DATA === 4.1 SINGLE DENSITY === The following explains the format of a CP/M directory entry as shown by "DU", using either the "F" (find file) command, or just doing "D" (dump) of the directory sectors, which are located in groups 0 and 1 on a single-density disk. SAMPLE RESULT OF "FSID.COM" COMMAND: 40 00534944 20202020 20434F4D 0000003A *.SID COM...:* 50 33343536 3738393A 00000000 00000000 *3456789:........* FIRST LINE - 40 00534944 20202020 20434F4D 0000003A *.SID COM...:* || ||| | || || | | || ||^---hex file name/type--^ || || ^file name^ || || || || in ASCII || || extent-^^ || || || || || || file size in sectors-^^ || || || ^^-00 = file active other values (E.G 03) = user # || E5 = file erased ^^-displacement of line in directory sector SECOND LINE - 50 33343536 3738393A 00000000 00000000 *3456789:........* | | | | | ^- allocation groups ^-----allocation group numbers-----^ (just happened to be printable) 4.2 DOUBLE DENSITY === The following is a sample of "FSID.COM" running on a double- density system: :FSID.COM 00 00534944 20202020 20434F4D 0000003A *.SID COM...:* 10 38003900 3A003B00 00000000 00000000 *8.9.:.;.........* G=0000:00, T=2, S=1, PS=0 The primary difference is that the groups now occupy 2 bytes, i.e., 38 00" "39 00" ... this follows the Intel and CP/M convention of putting 16-bit values high-byte-first. This it means group 0038, 0039 etc. Note that in double-density, each group stood for 2k not 1K, so there were half as many groups for the same file. Be very careful when patching a directory under double-density. For exmaple: CH10,38,39,3A,3B... This might try to access group 3938 with resultant angry noise from the disk stepper as it attempts to find where it should go for the data. $I$I $ @I D @A"I$H$D AI$  I IBBCOUNTER FOR ITEMS ON LINE SPACES DB ' | $' SWITCH DB 0 ;SWAP SWITCH FOR SORT FILESW DS 1 ;'F' IF WRITING FILE BUFAD DW 80H ;OUTPUT ADDR MYFCB DB 0,'NAMES SUB',0 DS 19 DB 0 ORDER DS 128 ;ORDER TABLE TABLE EQU $ ;READ ENTRIES IN HERE END 100H DU.COM v8.9 09/01/84*."g "}0! 6! "!0"*"Q"[""0қ"""""""}:ʇ"RÛ*.!"R!"ͦ DISK UTILITY v8.9 Universal Version under :>M>CaͦP/M :>0:a>.a0aͦ Type ? for help Type X to exit ͕!~WGWM## > !M^2͊>2s2t12u>2!"o~W: ~ W;#fG2+ʶ-=- <ʰ>#t?A5 BʈCD5 Fʋ GW H5 K+ LʞMdNP?QRSW TW U Vʶ W8XJYCZJ/(@2ͦ?W:v/2vf 2ͦ+++ OUT OF MEMORY +++ WͦStatistics for drive :Aa>:aͦ Tracks: *#z> a]ͦ Sys tracks: *z> a]**ͺͦ Sec/track: 7ͦ Sec/trk 00: *z> a]ͦ Sec/non-trk 00: *z> a]ͦ Groups: *z> aNͦ Dir groups: *z> a]ͦ Sec/group: : a]ͦ Dir entries: *#z> a]=f :O͹f2fOz*s#|"s*s!Mzf"s|fW:4O{ 4z4 f:w2wf{T @:i>i] xi~WTfMˆWWOùͤf~ ; G#AOy2> :|4^#V+"! ~#fo**|2ͼ   *"|!"~*#ͦͦDM/BK:=R͹*|*~6! x,͹*|"*~"{ʐ*ͺ?ڐ*ͺڃÓ* DM:ĔN>-a> 2*#}¼|~z{ʯ NØ N=**ͺ*"|*"|2ú*x4 ͜|n~> 0>(a~c͜#ͮ>.aͮ:a:2~c~> h>)aÆͦ ++FREE++ :u2u>2:u¡=é>:a͜2~# ڼ~>a®*#"!"!/:v#~,~!,~_#~,: W#͒(*|> !>*2"  *+"|*:G:ҍ:,*! ͦLAST ADDR=* "+|c}cͦ f2ͦ++ YANK MEMORY FULL ++ f:,! >2{f:{! f2ͦ++ NO "<" SAVE COMMAND ISSUED ++ W~# ɯ2~- !M6 ö ́ G~{4:” *o} 62*~*|ͼ !~#"o:< { !~. ~ ~ ~> a, . 6*~*| ͦ ++ EOF ++ =ö :¤ 2ͦ++ Can't dump, no sector read ++ 2ͦUse G command following F, or R or S following T W~;ʯ ¸  BK ; #`i}c͜͜:A ~c}̜}̜{ #} ~W:HJ ͡~ " ~$ >.a{3 #} ͡=~W{ f={ f~;c g úTz Sʖ G 4O*ͺڃ >2ö Oz4*ͫͺ42ͼ ú**|ͺ**~+:G}2z:Gͦ :g"x*2:2z- o&"x4 *ͺڃ"x2zI 2úbk:)U =P x2:zo*͞m :=2m ** # >2\  \< 2ͦ++ FILE NOT FOUND ++ f=2o&))))) >D2 ~.! :! " ;" G# ~ ;#.:4#> $ ɯ2\ +~#:} !]~G@2\#~ t ~ o yO~0O#Y y<2]  "$ *|0¨ }¨ ͦEmpty! ð 2: =_ \< ͦFile exists! Delete? WGY ͦN çͦY \\<+ͦNo dir space! ç!0"2*\^ͦWrite error ß!4*"*z5{5*&zͦ sectors written. !0"\:_ *f~ ;z46z*~*|ö ~ ;z4*~+|)*||*"|*)+"|*ͫ"~z*~#*ͫͺh*|#*ͺ["|!"~**|ͺb*ͺb[Oz˜*ã*ͺ4"f*||¸*f**|ͺͦG=*xDMN>:a:zcͦ, ͦT=*|zͦ, S=*~zͦ, PS=*z=~G##-8#BK=,4HʑA4~ f;f a~ag>ja"l #y~f*H~ f;f4#~ f;f,ʐ"q{cyʽf*q‘~ f;f4:f2ͦ++ Can't read - not positioned ++ Position by: Track then Sector, or Group f%f>>a:Yxcycxcyl u0a ڃ |z{0a> a>*a~W~¾WWa#~§#z{ƀ_ɯ2ͦ++ BAD DISPLACEMENT (NOT 0-7F) ++ W#~#N~G ;,->#04:AA4G40))))o#~# ~G ;,->#04:40bk)))o|gXͦ :!MWO0  ږw#aÖ+>*aÖwa> a!Mɯ0+y~aÖÖʑ  $6 =!M~ ʖa#">^a>UaÊ> a> a`_O z> a:jô ҉ ʉ  :y  >2ì ڬ:<2:wĸ>*ͺڃ"|BK> *"~*|ͺ`i/+:2:+Wͦ$#DM>:i+i* Q>T":_g:i&i"*DM~> ɯ2ͦ++ Not within tracks 0-*zͦ ++  W`i"> >2͡* #2ͦ++ READ failed, sector may be invalid ++ :^2ͦ++ CANNOT WRITE UNLESS READ ISSUED ++ f |͡ƒ* >ʟ2ͦ++ WRITE failed ++ > > : =º:0""`i"22ͦ Operands in brackets [...] are optional Numeric values: 'n' are decimal, 'x' hex +[n] step in [n] sectors -[n] step out [n] sectors # print disk parameters for current drive =Abc search for ASCII Abc from current sector caution: upper/lower case matters use for hex: to find "IN 0" use: =<0> or "(tab)H,0(CR)(LF)" use: =<9>H,0 < save current sector into memory buffer > restore saved sector ( toggle map display of erased files ? help (displays this guide) A[ff,tt] ASCII dump B[nn] Boot track number of sectors per track [More] CHANGE: CHaddress,byte,byte... (hex) CAaddress,data... (ASCIIx Allowed for imbedded hex CHfrom-through,byte, e.g. CH0-7F,E5 CAfrom-through,byte D[ff,tt] Dump (hex+ASCII) Fn.t Find file Gnn CP/M Allocation Group nn H[ff,tt] hex dump K[du:]filename[.ext] Dump sequential memory to disk L Log in drive LX Log in drive X M[nn] Map [from group nn] [More] N New disk P Printer toggle switch Q Quiet mode (no msgs) R Read current sector Snn Sector nn Tnn Track nn Unn User nn for Find command (CP/M-2 only) V[nn] View [nn] ASCII sectors W Write current sector X Exit program Y Yank current sector into sequential memory Z[nn] Sleep [nn tenths] /[nn] Repeat [nn (decimal) times] [More] Cancel a function with C or Ctl-C Suspend output with S or Ctl-S Separate commands with ";" Example: G0 +;D;Z#20;/ would step in, dump, sleep 2 seconds and repeat until CTL-C is typed All "nn" usage except "/", "T", and "S" are hex (use #nn for decimal) (See DU.DOC for complete examples) fyʜ#x}/o|/g#ɷ|g}o&ҵ,%°}o|g2BKx! T]x:<2 : *"@*.:^#""^#"~#2~#2^#"^#"^"!z~:w*I ""w.:ͮ:ͮ&" COUNTER FOR ITEMS ON LINE SPACES DB ' | $' SWITCH DB 0 ;SWAP SWITCH FOR SORT FILESW DS 1 ;'F' IF WRITING FILE BUFAD DW 80H ;OUTPUT ADDR MYFCB DB 0,'NAMES SUB',0 DS 19 DB 0 ORDER DS 128 ;ORDER TABLE TABLE EQU $ ;READ ENTRIES IN HERE END 100H  7Z80ASM COMoDCZ80DOC DOCSJZ80MAIN ASMw Z80OPCDSASMZZ80SUBS ASMX ;-----------------------------------------------; ; Z80 RESIDENT ASSEMBLER ; ;-----------------------------------------------; ; ; ;(C) 1977 LEHMAN CONSULTING SERVICES ; ; ALL RIGHTS RESERVED ; ; ; ;-----------------------------------------------; ; ; ; SUBROUTINE PACKAGE ; ; ; ;-----------------------------------------------; ; ; ; REV 0 14-JULY-77 MGL ; ; ; ;-----------------------------------------------; ; ; EJECT ;-----------------------------------------------; ; ; ; CPMUTIL COMMUNICATIONS AREA ; ; ; ;-----------------------------------------------; ; ORG 103H ; ; JUMP TABLE EQUATES ; WLINE DS 3 ;WRITE PRINTER LINE WMSG DS 3 ;WRITE CONSOLE MSG DSKSEL DS 3 ;SELECT DISK OPNFIL DS 3 ;OPEN FILE CLSFIL DS 3 ;CLOSE FILE DELFIL DS 3 ;DELETE FILE DREAD DS 3 ;DISK READ DWRITE DS 3 ;DISK WRITE CREFIL DS 3 ;CREATE FILE DMASET DS 3 ;SET DMA ADDRESS MOVE DS 3 ;MOVE BYTES CMPCHR DS 3 ;COMPARE CHARACTERS CMPHD DS 3 ;COMPARE HL:DE MUL16 DS 3 ;HL <= HL * DE GNB DS 3 ;GET NEXT BYTE (1K BLOCKING) WNB DS 3 ;WRITE NEXT BYTE GNB2 DS 3 ;GET NEXT BYTE (FCB2) WNB2 DS 3 ;WRITE NEXT BYTE (FCB2) CNV2HX DS 3 ;CONVERT TO HEX - BUF => HL REG ; ; FCB1 DS 33 FCB2 DS 33 IBP DS 2 IBP2 DS 1 OBP DS 1 OBP2 DS 1 IBUF DS 2 OBUF DS 2 IBUF2 DS 2 OBUF2 DS 2 INBUF DS 1024 OUTBUF DS 128 INBUF2 DS 128 OUTBF2 DS 128 ; ; EJECT ;-----------------------------------------------; ; COMMON DATA AREA (CDA) ; ;-----------------------------------------------; ; ORG 980H ;LEAVE SPACE FOR CPMUTIL ; HDRBUF DS 16 ;MUST FOLLOW ORG REC DS 80 ;MUST FOLLOW HDRBUF PC DS 2 ;CURRENT PROGRAM COUNTER OBJ DS 32 ;OBJECT CODE BUFFER OBJCNT DS 1 ;LEN OF DATA IN OBJ LEN DS 1 ;LEN OF CURRENT INSTRUCTION VAL DS 2 ;RETURN FROM EVAL ROUTINE INST DS 80 ;CURRENT INSTRUCTION (OR DATA FROM DB) EOM DB 0 ;END OF BUFFER CHARACTER (FOR WLINE) PTR1 DS 2 ;POINTS TO NEXT CHAR IN REC PASSNO DS 1 ;CURRENT PASS =0 PASS1 =FF PASS2 IDBUF DS 16 ;CURRENT ID INTBUF DS 2 ;RETURNED VALUE FROM INT ROUTINE CURLNE DS 1 ;CURRENT LINE NUMBER FOR PAGING OUTPUT LEN2 DS 2 ;FOR DEFS LBLADR DS 2 ;LAST LBL ADDR IN SYM (FOR EQU) EQUFLG DS 1 ;IF NON-ZERO EQUVAL IS USED INSTEAD OF PC FOR PRINT EQUVAL DS 2 ;VALUE OF LAST EQU ENDADR DS 2 ;EXPRESSION VALUE ON END STATEMENT EFLG DS 1 ;END OF PROGRAM FLAG (TO ALLOW PRINTING OF END STMT) OPCODE DS 2 ;CURRENT OPCODE FROM SYMBOL TABLE SAVVAL DS 2 ;SAVED CONTENTS OF VAL LFLAG DS 1 ;LISTING FLAG =N NO LISTING, =' ' OR 'Y' LISTING HFLAG DS 1 ;HEX OBJ FLAG =N NO HEX OBJ, =' ' OR 'Y' HEX OBJ OUTPUT ERRFLG DS 1 ;ERROR CHARACTER FOR THIS LINE TEMP DS 2 ;TEMP 2 BYTE AREA MULT DS 2 ;BASE OF NUMBER IN INT CONVERT LOOP SYMPTR DS 2 ;ADDRESS OF NEXT SYMBOL TABLE ENTRY SYMPT DS 2 ;ADDRESS OF BEGINING OF SYMBOL TABLE UFLAG DS 1 ;UNDEFINED FLAG FROM EVAL, =0 ALL OK, =1 >1 UNDEFINED EVFLGS DS 1 ;FLAG FIELD FROM LAST SYMLUK ; ; EJECT ; ; JUMP TABLE FOR ROUTINES IN THIS ASSEMBLY ; JMP EVAL JMP ID JMP INT JMP SETUP ;INIT FILES FOR ASSEMBLER JMP SYMENT JMP SYMLUK JMP GNR ;GET NEXT RECORD JMP GNC ;GET NEXT CHARACTER JMP BACKUP ;BACKUP TO LAST CHARACTER ; ; EJECT ; ; ; EXPRESSION EVALUATOR ; ; VALID OPERATORS ARE: +, - AND * ; ; VALID ELEMENTS ARE: ID'S, NUMBERS, AND '$' FOR PC ; ; EVAL EQU $ MVI A,0 ! STA OP ! STA UFLAG ;DEFAULT OP TO +, UFLAG=0 STA EVFLGS ;RESET FLAGS FROM LAST SEARCH LXI H,0 ! SHLD VAL ;SET VAL TO 0000 EVAL1 EQU $ CALL GNC ;GET NEXT ELEMENT OR OPERATOR CPI '0' ! JC EVAL3 ! CPI '9'+1 ! JC EVAL9 ;BRANCH IF NUMBER EVAL3 EQU $ CPI '$' ! JZ EVAL11 ;BRANCH IF PC REF CPI 'A' ! JC EVAL5 ! CPI 'Z'+1 ! JC EVAL13 ;BRANCH IF ID EVAL5 EQU $ CPI '+' ! JZ EVAL22 CPI '-' ! JZ EVAL24 CPI '*' ! JZ EVAL26 CPI 27H ! JZ EVAL29 ;PROCESS SINGLE BYTE QUOTED STRING RET ;GET OUT OF HERE WE ARE DONE ; ; PROCESS NUMBER ; EVAL9 EQU $ CALL BACKUP ! CALL INT ! JMP EVAL28 ; ; ; PROCESS '$' REF ; EVAL11 EQU $ LHLD PC ! SHLD INTBUF ! JMP EVAL28 ; ; ; PROCESS ID ; ; EVAL13 EQU $ CALL BACKUP ! CALL ID CALL BACKUP ;BACKUP SO AS TO NOT IGNORE OPERATOR OR COMMA LXI H,IDBUF ! CALL SYMLUK ! JNZ EVAL19 ;BRANCH IF UNDEFINED MOV A,M ! STA INTBUF ! INX H ! MOV A,M ! STA INTBUF+1 ! JMP EVAL28 EVAL19 EQU $ ;PROCESS UNDEFINED ID LXI H,0 ! SHLD INTBUF ;SET VALUE TO 0000 LDA UFLAG ! ORI 1 ! STA UFLAG ;SET UNDEFINED FLAG JMP EVAL28 ; ; PROCESS OPERATORS ; EVAL22 EQU $ MVI A,0 ! JMP EVAL27 ; EVAL24 EQU $ MVI A,1 ! JMP EVAL27 ; EVAL26 EQU $ MVI A,2 EVAL27 EQU $ STA OP JMP EVAL1 ; ; ; PROCESS VALUE USING CURRENT OPERATOR ; ; EVAL28 EQU $ ;VAL = VAL OP INTBUF LDA OP CPI 1 ! JZ EVAL28A ;BRANCH IF SUBTRACT CPI 2 ! JZ EVAL28B ;BRANCH IF MULTIPLY LHLD VAL ! XCHG ! LHLD INTBUF ! DAD D ! SHLD VAL ;+ JMP EVAL1 ; EVAL28A EQU $ ;SUBTRACT LHLD VAL ! XCHG ! LHLD INTBUF MOV A,E ! SUB L ! MOV L,A ! MOV A,D ! SBB H ! MOV H,A ! SHLD VAL JMP EVAL1 ; EVAL28B EQU $ ;MULTIPLY LHLD VAL ! XCHG ! LHLD INTBUF ! CALL MUL16 ! SHLD VAL JMP EVAL1 ; ; ; PROCESS SINGLE BYTE IN QUOTES ; EVAL29 EQU $ CALL GNC ;GET CHARACTER STA INTBUF ! XRA A ! STA INTBUF+1 ;FAKE 2 BYTE VALUE CALL GNC ;BYPASS TRAILING QUOTE JMP EVAL28 ;AND GO PROCESS VALUE NORMALLY ; ; OP DS 1 ;CURRENT OPERATOR FOR EVAL ; ; EJECT ; ; ; ID - COLLECT ID AND PLACE IN IDBUF ; ID EQU $ PUSH H ! PUSH D ! PUSH B ;SAVE REGS MVI A,' ' ! STA IDBUF LXI H,IDBUF+1 ! LXI D,IDBUF ! LXI B,15 ! CALL MOVE ;BLANK IDBUF LXI H,IDBUF CALL GNC ID2 EQU $ CPI 'A' ! JC ID1 ! CPI 'Z'+1 ! JNC ID1 ;IF NOT A LETTER THEN BRANCH ID3 MOV M,A ! INX H PUSH H ! LHLD PTR1 ! MOV A,M ! INX H ! SHLD PTR1 ! POP H JMP ID2 ; ID1 CPI '.' ! JZ ID3 ; ALLLOW LABELS WITH '.' IN THEM (E.G. LAB.01) CPI '$' ! JZ ID2 ; ALLOW $ FILLERS (E.G. SQR$ROOT) CPI '0' ! JC ID4 ! CPI '9'+1 ! JC ID3 ;ALLOW DIGITS ID4 POP B ! POP D ! POP H RET ; ; EJECT ; ; ; INT - CONVERT CHARACTERS TO BINARY ; ; ALLOW TRAILING 'H' FOR HEX AND 'B' FOR BINARY ; DEFAULT TYPE IS DECIMAL (BASE 10) ; INT EQU $ LHLD PTR1 ! SHLD TEMP ;SAVE POINTER LXI H,10 ! SHLD MULT ;SET DEFAULT BASE TO 10 MVI B,0 ;SET UP LENGTH COUNTER CALL GNC ;SKIP BLANKS INT1 EQU $ CPI '+' ! JZ INT1A ;BRANCH IF A TERMINATOR CPI '-' ! JZ INT1A CPI '*' ! JZ INT1A CPI 0DH ! JZ INT1A CPI ';' ! JZ INT1A CPI ')' ! JZ INT1A CPI ',' ! JZ INT1A CPI 20H ! JZ INT1A LHLD PTR1 ! MOV A,M ! INX H ! SHLD PTR1 ;GET NEXT CHARACTER INR B ! JMP INT1 ;INCREMENT COUNTER AND CONTINUE LOOP INT1A EQU $ DCX H ! SHLD PTR1 ! DCX H ! MOV A,M INT2 CPI 'H' ! JNZ INT3 ;BRANCH IF NOT HEX DCR B ;DECREMENT COUNTER LXI H,16 ! SHLD MULT ;SET UP BASE 16 JMP INT4 ; INT3 CPI 'B' ! JNZ INT4 ;BRANCH IF NOT BINARY DCR B ;DECREMENT COUNTER LXI H,2 ! SHLD MULT ;SET UP BASE 2 INT4 LHLD PTR1 ! XCHG ! LHLD TEMP ! SHLD PTR1 ! XCHG ! SHLD TEMP ;SAVE PTR LXI D,0 ;SET UP ACCUMULATOR CALL GNC ! CALL BACKUP INT5 EQU $ LHLD PTR1 ! MOV A,M INX H ! SHLD PTR1 CPI 'A' ! JC $+5 ! ADI 9 ;FOR A-F ANI 0FH ! PUSH PSW ;GET BINARY VALUE OF THIS DIGIT PUSH B ;SAVE COUNTER LHLD MULT ! CALL MUL16 POP B ;RESTORE COUNTER POP PSW ! MOV E,A ! MVI D,0 ! DAD D ;ADD IN NEW DIGIT XCHG ! DCR B ! JNZ INT5 ;GO BACK IF MORE TO DO INT6 LHLD TEMP ! SHLD PTR1 XCHG ! SHLD INTBUF ;SAVE VALUE RET ; ; EJECT ; ; SETUP - SET UP FILES FOR Z80ASM ; ; INPUT FROM CONSOLE IS FILENAME.AB ; ; A= Y OR N FOR LISTING ; B= Y OR N FOR HEX FILE ; SETUP EQU $ LXI H,FCB1 ! LXI D,5CH ! LXI B,33 ! CALL MOVE ;GET DEFAULT FCB LXI H,FCB1+9 ! LXI D,ASMEXT ! LXI B,3 ! CALL MOVE ;SET UP EXTENSION LXI H,FCB2 ! LXI D,5CH ! LXI B,33 ! CALL MOVE ;GET DEFAULT FCB LXI H,FCB2+9 ! LXI D,HEXEXT ! LXI B,3 ! CALL MOVE ;SET UP EXTENSION LDA 5CH+9 ! STA LFLAG ;SET UP LISTING FLAG LDA 5CH+10 ! STA HFLAG ;SET UP HEX FLAG LXI D,FCB1 ! CALL OPNFIL ! JZ SETER1 ;BRANCH IF SOURCE FILE NOT FOUND LDA HFLAG ! CPI 'N' ! JZ SETUP1 ;BRANCH IF NO HEX FILE SETUP LXI D,FCB2 ! CALL DELFIL ;DELETE FILE LXI D,FCB2 ! CALL CREFIL ! JZ SETER2 ;BRANCH IF UNABLE TO CREATE LXI D,FCB2 ! CALL OPNFIL ! JZ SETER2 ;BRANCH IF UNABLE TO OPEN SETUP1 EQU $ LXI H,INBUF+1024 ! SHLD IBP ! XRA A ! STA OBP2 ;SET UP POINTERS RET ;AND GET OUT OF HERE ; SETER1 LXI D,SM1 ! CALL WMSG ! JMP 0 ;MSG AND REBOOT ; SETER2 LXI D,SM2 ! CALL WMSG ! JMP 0 ;MSG AND REBOOT ; SM1 DB 13,10,'SOURCE (.ASM) FILE NOT FOUND',13,10,'$' ; SM2 DB 13,10,'UNABLE TO CREATE/OPEN OBJECT (.HEX) FILE',13,10,'$' ; ASMEXT DB 'ASM' HEXEXT DB 'HEX' ; ; EJECT ; ; SYMENT - ENTER A SYMBOL INTO THE SYMBOL TABLE ; ; UPON ENTRY HL POINTS TO NEW ENTRY ; ; ENTRY FORMAT: FLAGS/LENGTH (EACH 4 BITS) ; N A M E ... (UP TO 11 BYTES) ; VALUE LOW (1 BYTE) ; VALUE HIGH (1 BYTE) ; TYPE BYTE (1 BYTE) ; ; ON RETURN HL POINTS TO VALUE LOW BYTE IN NEW ENTRY FOR POSSIBLE ; FURTHER UPDATE (USED BY EQU PSEUDO OPERATOR) ; ; SYMENT EQU $ MOV A,M ! PUSH B ! XCHG ! ANI 0FH ! MOV C,A ! MVI B,0 ;GET LEN LHLD SYMPTR ! CALL MOVE ;MOVE INTO SYMBOL TABLE SHLD SYMPTR ! MVI M,0 ; SET UP NEW POINTER AND NEW END MARKER DCX H ! DCX H ! DCX H ;BACKUP TO POINT TO VALUE LOW FIELD POP B RET ; ; EJECT ; ; ; SYMLUK - LOOK UP SYMBOLS IN TABLE ; ; ON RETURN Z=0 MEANS SYMBOL NOT FOUND. ; Z=1 SYMBOL FOUND, HL POINTS TO VALUE LOW BYTE IN TABLE ENTRY ; ; SYMLUK EQU $ XCHG LHLD SYMPT ;GET POINTER TO BEGINING OF TABLE XCHG SYML1 LDAX D ! CPI 0 ! JZ SYMNF ;BRANCH IF END OF TABLE STA EVFLGS ;SAVE FOR MAIN PROCESSOR ANI 0FH ! SUI 4 ! MOV B,A ! INX D ;SET UP FOR COMPARE CALL CMPCHR ! JZ SYML2 ;BRANCH IF MATCH DCX D ;BACK UP LENGTH BYTE AGAIN SYML3 EQU $ LDAX D ! ANI 0FH ! MOV C,A ! MVI B,0 ! XCHG ! DAD B ! XCHG JMP SYML1 ;ADVANCE POINTER AND CONTINUE TO LOOP ; SYML2 EQU $ ;NOW SEE IF EXACT MATCH DCX D ! LDAX D ! ANI 0FH ! SUI 4 ;GET LENGTH PUSH H ! MOV C,A ! MVI B,0 ! DAD B ! MOV A,M CPI ' ' ! POP H ! JNZ SYML3 ;IF NXT CHR NOT BLANK THEN NOT EXACT MATCH LDAX D ! ANI 0FH ! DCR A ! DCR A ! DCR A ! MOV C,A ! MVI B,0 XCHG ! DAD B ! XRA A ! RET ;POINT TO VALUE LOW AND EXIT ; SYMNF XRA A ! INR A ! RET ;SET Z=0 AND RETURN ; ; EJECT ; ; GNR - GET NEXT RECORD - FILL REC UNTIL 0AH OR 1AH (CTRL/Z) IS FOUND ; GNR LXI H,REC ! SHLD PTR1 ;RESET POINTER MVI M,' ' ! XCHG ! LXI H,REC+1 ! LXI B,79 ! CALL MOVE ;BLNK BUFFER LXI H,REC ;GET ADDRESS OF RECORD BACK AGAIN GNR1 CALL GNB ! CPI 1AH ! RZ ;RETURN IF EOF MARKER (CTRL/Z) IF FOUND CPI 09H ! JZ GNR2 ;BRANCH IF TAB CHARACTER MOV M,A ! INX H ! CPI 0AH ! JNZ GNR1 ;BRANCH IF NOT LF RET GNR2 EQU $ ;PROCESS TAB LXI D,8 ! DAD D ! MOV A,L ! ANI 0F8H ! MOV L,A ;PROCESS TAB STOP JMP GNR1 ; ; EJECT ; ; ; GNC - GET NEXT CHARACTER ; USE PTR1 TO INDEX INTO REC, SKIP BLANKS ; GNC EQU $ PUSH H ! LHLD PTR1 MOV A,M ! CPI ' ' ! INX H ! JZ $-4 ;SKIP BLANKS CPI 09H ! JZ $-9 ;BRANCH IF TAB CHARACTER SHLD PTR1 ! POP H RET ; ; ; BACKUP - BACKUP PTR1 AND RETURN CHARACTER ; ; BACKUP PUSH H ! LHLD PTR1 DCX H ! MOV A,M SHLD PTR1 ! POP H RET ; ; EJECT ;-----------------------------------------------; ; ; ; Z80 RESIDENT ASSEMBLER ; ; ; ;-----------------------------------------------; ; ; ; (C) 1977 LEHMAN CONSULTING SERVICES ; ; ; ; ALL RIGHTS RESERVED ; ; ; ;-----------------------------------------------; ; ; ; OPCODE TABLE MODULE ; ; ; ;-----------------------------------------------; ; ; ; REV 0 15-JULY-77 MGL ; ; REV 1 20-OCT-77 MGL ; ; ; ;-----------------------------------------------; ; ; ORG 1F80H ;****** ADDRESS EQUATE ****** ; ; ; EJECT ; ; ; EACH SYMBOL TABLE ENTRY IS OF VARYING LENGTH ; ; THE FIRST BYTE CONTAINS THE LENGTH IN THE LOWER 4 BITS ; AND FLAGS IN THE UPPER 4 BITS. ; ; THIS LIMITS THE MAX LENGTH OF AN ENTRY TO 15 BYTES ; ; FOLLOWING THE FLAG/LENGTH BYTE IS THE NAME WHICH MAY BE FROM ; 1 TO 11 BYTES IN LENGTH ; ; FOLLOWING THE NAME ARE 2 BYTES OF VALUE (LO,HI) ; AND 1 BYTE OF TYPE (USED IN OPCODES) ; ; ; THE TABLE IS SCANNED SEQUENTIALLY AND IS ENDED BY A 0 BYTE ; ; SYM EQU $ ; ; ; ; FLAG EQUATES ; RNAME EQU 20H ;REGISTER NAME FLAG ULBL EQU 40H ;USER LABEL FLAG RPNAME EQU 80H ;REGISTER PAIR NAME FLAG ; ; ; EJECT ; ; ; SYMBOL TABLE ; ; DW SYMNXT ;SYMBEG DW CONDS ;SYMCND DB 7,'EXX',0D9H,0,1 DB 7,'LDI',0EDH,0A0H,1 DB 8,'LDIR',0EDH,0B0H,1 DB 7,'LDD',0EDH,0A8H,1 DB 8,'LDDR',0EDH,0B8H,1 DB 7,'CPI',0EDH,0A1H,1 DB 8,'CPIR',0EDH,0B1H,1 DB 7,'CPD',0EDH,0A9H,1 DB 8,'CPDR',0EDH,0B9H,1 DB 7,'DAA',27H,0,1 DB 7,'CPL',2FH,0,1 DB 7,'NEG',0EDH,040H,1 DB 7,'CCF',03FH,0,1 DB 7,'SCF',037H,0,1 DB 7,'NOP',0,0,1 DB 8,'HALT',76H,0,1 DB 6,'DI',0F3H,0,1 DB 6,'EI',0FBH,0,1 DB 7,'IM0',0EDH,46H,1 DB 7,'IM1',0EDH,56H,1 DB 7,'IM2',0EDH,5EH,1 DB 8,'RLCA',07H,0,1 DB 7,'RLA',17H,0,1 DB 8,'RRCA',0FH,0,1 DB 7,'RRA',1FH,0,1 DB 8,'RETI',0EDH,4DH,1 DB 8,'RETN',0EDH,45H,1 DB 7,'INI',0EDH,0A2H,1 DB 8,'INIR',0EDH,0B2H,1 DB 7,'IND',0EDH,0AAH,1 DB 8,'INDR',0EDH,0BAH,1 DB 8,'OUTI',0EDH,0A3H,1 DB 8,'OTIR',0EDH,0B3H,1 DB 8,'OUTD',0EDH,0ABH,1 DB 8,'OTDR',0EDH,0BBH,1 DB 6,'LD',0,0,8 DB 7,'RLC',0,0,2 DB 6,'RL',10H,0,2 DB 7,'RRC',8,0,2 DB 6,'RR',18H,0,2 DB 7,'SLA',20H,0,2 DB 7,'SRA',28H,0,2 DB 7,'SRL',38H,0,2 DB 7,'RLD',0EDH,06FH,1 DB 7,'RRD',0EDH,067H,1 DB 8,'PUSH',0C5H,0,9 DB 7,'POP',0C1H,0,9 DB 6,'EX',0EBH,0,10 DB 7,'ADD',0,9,6 DB 7,'ADC',8,4AH,6 DB 7,'SBC',18H,42H,6 DB 7,'SUB',10H,0,6 DB 7,'AND',20H,0,6 DB 6,'OR',30H,0,6 DB 7,'XOR',28H,0,6 DB 6,'CP',38H,0,6 DB 7,'INC',04H,03H,13 DB 7,'DEC',05H,0BH,13 DB 7,'BIT',040H,0,12 DB 7,'SET',0C0H,0,12 DB 7,'RES',80H,0,12 DB 6,'JP',0C3H,0,3 DB 8,'CALL',0CDH,0,3 DB 6,'JR',18H,0,4 DB 8,'DJNZ',10H,0,4 DB 7,'RET',0C9H,0,11 DB 7,'RST',0C7H,0,5 DB 6,'IN',0DBH,0,7 DB 7,'OUT',0D3H,0,7 DB 7,'EQU',1,0,14 DB 8,'DEFS',2,0,14 DB 8,'DEFB',3,0,14 DB 8,'DEFW',4,0,14 DB 7,'END',5,0,14 DB 7,'ORG',6,0,14 DB 9,'EJECT',7,0,14 DB 7,'IBM',8,0,14 ;IBM PSEUDO FOR 3270 (ICC) SCREEN FORMATTING ; ; REGISTERS ; DB 5+RNAME,'A',7,0,0 DB 5+RNAME,'B',0,0,0 DB 5+RNAME,'C',1,0,0 DB 5+RNAME,'D',2,0,0 DB 5+RNAME,'E',3,0,0 DB 5+RNAME,'H',4,0,0 DB 5+RNAME,'L',5,0,0 DB 6+RPNAME,'HL',4,0,0 DB 6+RPNAME,'BC',0,0,0 DB 6+RPNAME,'DE',2,0,0 DB 6+RPNAME,'SP',6,0,0 DB 6+RPNAME,'IX',0FFH,0,0 DB 6+RPNAME,'IY',0FEH,0,0 DB 6,'AF',06H,0,0 ;FOR PUSH/POP CONDS EQU $ DB 5,'Z',1,0,0 DB 6,'NZ',0,0,0 DB 5,'C',3,0,0 DB 6,'NC',2,0,0 DB 6,'PO',4,0,0 DB 6,'PE',5,0,0 DB 5,'P',6,0,0 DB 5,'M',7,0,0 SYMNXT EQU $ ;FIRST AVAILABLE SLOT DB 0 ;-----------------------------------------------; ; Z80 RESIDENT ASSEMBLER ; ;-----------------------------------------------; ; ; ; (C) COPYRIGHT 1977 ; ; LEHMAN CONSULTING SERVICES ; ; ; ; ALL RIGHTS RESERVED ; ; ; ;-----------------------------------------------; ; ; ; MAIN ASSEMBLER MODULE ; ; ; ;-----------------------------------------------; ; ; ; REV 0 14-JULY-1977 MGL ; ; REV 1 20-OCT-77 MGL ; ; ; ;-----------------------------------------------; ; ; ORG 100H ;MAIN MODULE ; JMP Z80ASM ;CP/M ENTRY POINT BRANCH ; ; EJECT ;-----------------------------------------------; ; ; ; CPMUTIL LINKAGE ; ; ; ;-----------------------------------------------; ; ORG 103H ;JUMP TABLE BASE ADDRESS ; ; ; FOR AN EXPLANATION OF THESE ROUTINES SEE CPMUTIL ASSEMBLY ; ; WLINE DS 3 WMSG DS 3 DSKSEL DS 3 OPNFIL DS 3 CLSFIL DS 3 DELFIL DS 3 DREAD DS 3 DWRITE DS 3 CREFIL DS 3 DMASET DS 3 MOVE DS 3 CMPCHR DS 3 CMPHD DS 3 MUL16 DS 3 GNB DS 3 WNB DS 3 GNB2 DS 3 WNB2 DS 3 CNV2HX DS 3 ; ; ; CPMUTIL DATA AREA - FOR MORE DETAIL SEE CPMUTIL LISTING ; ; FCB1 DS 33 FCB2 DS 33 IBP DS 2 IBP2 DS 1 OBP DS 1 OBP2 DS 1 IBUF DS 2 OBUF DS 2 IBUF2 DS 2 OBUF2 DS 2 INBUF DS 1024 OUTBUF DS 128 INBUF2 DS 128 OUTBF2 DS 128 ; ; EJECT ;-----------------------------------------------; ; Z80SUBS LINKAGE AREA ; ;-----------------------------------------------; ; ORG 980H ; ; FOR A MORE DETAILED DESCRIPTION OF THESE FIELDS SEE Z80SUBS LISTING ; HDRBUF DS 16 REC DS 80 PC DS 2 OBJ DS 32 OBJCNT DS 1 LEN DS 1 VAL DS 2 INST DS 80 EOM DS 1 PTR1 DS 2 PASSNO DS 1 IDBUF DS 16 INTBUF DS 2 CURLNE DS 1 LEN2 DS 2 LBLADR DS 2 EQUFLG DS 1 EQUVAL DS 2 ENDADR DS 2 EFLG DS 1 OPCODE DS 2 SAVVAL DS 2 LFLAG DS 1 HFLAG DS 1 ERRFLG DS 1 TEMP DS 2 MULT DS 2 SYMPTR DS 2 SYMPT DS 2 UFLAG DS 1 EVFLGS DS 1 ;FLAGS FROM LAST SYMLUK EVFLAGS EQU EVFLGS ; ; ; Z80SUBS JUMP TABLE ; EVAL DS 3 ID DS 3 INT DS 3 SETUP DS 3 SYMENT DS 3 SYMLUK DS 3 GNR DS 3 GNC DS 3 BACKUP DS 3 ; ; EJECT ; ; LOCAL DATA AREA FOR ASSEMBLER  ; ORG 0E80H SYMAREA DS 15 ;AREA FOR SYMBOL TABLE BUILD SYMADR DS 2 ;ADDRESS OF VALUE LOW FIELD FOR LAST SYMENT OLDADR DW -1 ;LAST ADDR OF WOBJ OBJADR DS 2 PAGENO DS 1 ; RNAME EQU 20H ;FLAG BIT - REGISTER NAME RPNAME EQU 80H ;FLAG BIT - REGISTER PAIR NAME ; ; MAXLNE EQU 55 ;LINES PER PAGE ;:::::::::::::::::::::::::::::::::::::::::::::::; ; ; ; SYMBOL TABLE ADDRESS EQUATES ; ; ; ;:::::::::::::::::::::::::::::::::::::::::::::::; ; SYMBEG EQU 1F80H ;POINTER TO FIRST USABLE ENTRY SYMCND EQU SYMBEG+2 ;POINTER TO COND CODE TABLE SYM EQU SYMCND+2 ;ACTUAL BEGINING ADDRESS FOR SEARCHES ; ; ; ; ; EJECT ;-----------------------------------------------; ; ; ; Z 8 0 A S M - RESIDENT Z80 ASSEMBLER ; ; ; ; WRITTEN IN 8080 ASSEMBLY LANGUAGE ; ; TO BE ASSEMBLED BY THE CP/M ASSEMBLER ; ; ; ; AUTHOR: MICHAEL G. LEHMAN ; ; ; ;-----------------------------------------------; ; ; Z80ASM EQU $ ; ; INIT FIELDS AND SETUP FILES ; LXI SP,STACK+128 JMP STACK+128 VSNMSG DB 13,10,10,'ZILOG/MOSTEK Z-80 ASSEMBLER VERSION 2.0' DB 13,10,'(C) 1977 LCS',13,10,'$' STACK DS 128 LXI D,VSNMSG ! CALL WMSG ;DISPLAY ON CONSOLE LXI H,SYM ;GET ADDRESS OF SYMBOL TABLE SHLD SYMPT ! LHLD SYMBEG ! SHLD SYMPTR ;SET UP POINTERS CALL SETUP ;PROCESS FILE NAME, PARAMETERS, ETC. MVI A,MAXLNE+1 ! STA CURLNE ;SET UP FOR HEAD OF FORM ON FIRST PRINT XRA A ! STA PASSNO ;INDICATE PASS 1 LXI H,0 ! SHLD PC ;SET UP DEFAULT PROGRAM ORIGIN ; ; ; MAIN LOOP - READ A SOURCE RECORD ; PROCESS LABEL AND OPCODE ; PRINT LINE (UNLESS OPTION=N) ; OUTPUT HEX (IF NECESSARY) ; BACK TO MAIN LOOP FOR NEXT RECORD ; ; NEXT EQU $ XRA A ! STA LEN ! STA EFLG ! STA EQUFLG ! LXI H,0 ! SHLD LEN2 ;INIT LENGTH & FLGS MVI A,' ' ! STA ERRFLG ;FOR THIS RECORD CALL GNR ;GET NEXT RECORD CPI 1AH ! JZ S321 ;BRANCH IF EOF LDA REC ;GET COL 1 CPI 09H ! JZ S12 ;BRANCH IF TAB CPI 0DH ! JZ ENDSTMT ;IGNORE NULL LINE CPI ' ' ! JZ S12 ;BRANCH IF NO LABEL CPI ';' ! JZ ENDSTMT ;IF COMMENT THEN IGNORE CALL ID ! CALL GNC ! CPI ':' ! JZ S9 ! CALL BACKUP S9 EQU $ LDA PASSNO ! ORA A ! JNZ S12 ;BRANCH IF PASS 2 ; ; CALCULATE LENGTH OF SYMBOL AND BUILD ENTRY ; MVI B,0 ;LENGTH + FLAGS ! LXI H,IDBUF LXI D,SYMAREA+1 S10 EQU $ MOV A,M ! CPI ' ' ! JZ S10A STAX D ! INX H ! INX D ! INR B ! JMP S10 S10A EQU $ ;SYMBOL COLLECTED MOV A,B ! CPI 0CH ! JC S10B ;BRANCH IF LEN < 12 (I.E. OK) MVI A,'L' ! STA ERRFLG ! JMP ENDSTMT ;ELSE LABEL ERROR S10B EQU $ ADI 4 ! STA SYMAREA ;ADD 4 FOR OVERHEAD XCHG ;SWITCH REGISTERS LDA PC ! MOV M,A ! INX H ;MOVE IN PC AS VALUE LDA PC+1 ! MOV M,A ! INX H ! MVI M,0 ;AND SET TYPE =0 LXI H,IDBUF ! CALL SYMLUK ! JNZ S11 ;BRANCH IF NOT ALREADY THERE MVI A,'M' ! STA ERRFLG ! JMP ENDSTMT ;ELSE MULTI DEFINED ERROR S11 EQU $ LXI H,SYMAREA ! CALL SYMENT ;ENTER SYMBOL INTO TABLE SHLD SYMADR ;SAVE ADDRESS FOR EQU ; ; ; NOW PROCESS OPCODE ; ; S12 EQU $ CALL ID LDA IDBUF ! CPI ' ' ! JZ ENDSTMT ;BRANCH IF NO OPCODE (COMMENT) LXI H,IDBUF ! CALL SYMLUK ! JZ S16 ;BRANCH IF FOUND MVI A,'O' ! STA ERRFLG ! JMP ENDSTMT ;ERROR IF UNDEFINED OPCODE S16 EQU $ MOV A,M ! STA OPCODE ! INX H ! MOV A,M ! STA OPCODE+1 ;SAVE OPCODE INX H ! MOV A,M ;GET TYPE BYTE DCR A ! ADD A ;-1 AND DOUBLE FOR TABLE INDEX MOV E,A ! MVI D,0 ! LXI H,TYPTBL ! DAD D MOV E,M ! INX H ! MOV D,M ! XCHG PCHL ;DISPATCH TO PROPER INSTRUCTION TYPE ; ; EJECT ;-----------------------------------------------; ; ; ; INSTRUCTION CLASS DISPATCH TABLE ; ; ; ;-----------------------------------------------; ; TYPTBL EQU $ DW S18 ;CLASS 1 - OPCODE ONLY DW S24 ;CLASS 2 - ROTATES DW S42 ;CLASS 3 - JUMPS (NON RELATIVE) CALLS DW S62 ;CLASS 4 - RELATIVE JUMPS (JR AND DJNZ) DW S73 ;CLASS 5 - RST DW S77 ;CLASS 6 - ARITHMETIC INSTRUCTIONS DW S97 ;CLASS 7 - I/O DW S116 ;CLASS 8 - LD INSTRUCTIONS DW S220 ;CLASS 9 - PUSH,POP DW S228 ;CLASS 10- EXCHANGE (EX) DW S243 ;CLASS 11- RETURNS DW S250 ;CLASS 12- BIT,SET,RES DW S268 ;CLASS 13- INC,DEC DW S301 ;CLASS 14- PSEUDO OPERATORS ; ; EJECT ; ; CLASS 1 - OPCODE ONLY ; S18 EQU $ MVI A,1 ! STA LEN LDA OPCODE ! STA INST LDA OPCODE+1 ! ORA A ! JZ ENDSTMT ;BRANCH IF ONLY 1 BYTE MVI A,2 ! STA LEN LDA OPCODE+1 ! STA INST+1 JMP ENDSTMT ; ; EJECT ; ; CLASS 2 - ROTATES ; S24 EQU $ CALL GNC ! CPI '(' ! JZ S30 ;BRANCH IF () FORM CALL BACKUP ! CALL ID ! LXI H,IDBUF ! CALL SYMLUK ! JZ S27 MVI A,'U' ! STA ERRFLG ! JMP ENDSTMT ;BRANCH IF UNDEFINED OPERAND S27 EQU $ LDA IDBUF ! CPI 'A' ! JZ S41 ;BRANCH IF A REGISTER MVI A,0CBH ! STA INST LDA OPCODE ! MOV B,A ! MOV A,M ! ORA B ! STA INST+1 MVI A,2 ! STA LEN ! JMP ENDSTMT ; S30 EQU $ CALL GNC ! CALL GNC ! CPI 'L' ! JZ S40 ;BRANCH IF (HL) CPI 'Y' ! JZ S38 ;BRANCH IF (IY) MVI A,0DDH ! STA INST S33 EQU $ MVI A,0CBH ! STA INST+1 LDA OPCODE ! ADI 6 ! STA INST+3 CALL GNC ;BYPASS + CALL EVAL LDA VAL ! STA INST+2 MVI A,4 ! STA LEN JMP ENDSTMT S38 EQU $ MVI A,0FDH ! STA INST ! JMP S33 ;DO IX AND IY SIMILARLY ; S40 EQU $ MVI A,0CBH ! STA INST ! LDA OPCODE ! ADI 6 ! STA INST+1 MVI A,2 ! STA LEN ! JMP ENDSTMT ; S41 EQU $ ;COMPATIBILITY WITH RRA, ETC LDA OPCODE ! ORI 7 ! STA INST MVI A,1 ! STA LEN ! JMP ENDSTMT ; ; ; EJECT ; ; CLASS 3 - JUMPS - CALLS ; S42 EQU $ CALL GNC CPI '(' ! JZ S53 ;BRANCH IF () FORM LHLD PTR1 ! MOV A,M ! CPI ',' ! JZ S49 ;BRANCH IF CONDITIONAL TYPE INX H ! MOV A,M ! CPI ',' ! JZ S49 LDA OPCODE ! STA INST ! MVI A,3 ! STA LEN CALL BACKUP S46 EQU $ CALL EVAL LHLD VAL ! SHLD INST+1 ! JMP ENDSTMT ; S49 EQU $ ;PROCESS CONDITIONAL JUMPS, CALLS LDA OPCODE ! ANI 0C6H ! STA INST ! MVI A,3 ! STA LEN LHLD SYMCND ! SHLD SYMPT ;SO NO CONFLICTS WITH REGISTER NAMES CALL BACKUP ! CALL EVAL ! LDA VAL ! RLC ! RLC ! RLC ! ANI 38H LXI H,SYM ! SHLD SYMPT ;PUT IT BACK THE WAY IT WAS MOV B,A ! LDA INST ! ORA B ! STA INST MVI A,3 ! STA LEN JMP S46 ;NOW GO PROCESS LIKE NON CONDITIONAL ; S53 EQU $ ;PROCESS () FORM CALL GNC ! CALL GNC ;GET REGISTER TYPE CPI 'L' ! JZ S58 ;BRANCH IF (HL) CPI 'Y' ! JZ S60 MVI A,0DDH ! STA INST S56 EQU $ MVI A,0E9H ! STA INST+1 MVI A,2 ! STA LEN ! JMP ENDSTMT ; S58 EQU $ MVI A,0E9H ! STA INST MVI A,1 ! STA LEN ! JMP ENDSTMT ; S60 EQU $ MVI A,0FDH ! STA INST ! JMP S56 ; ; EJECT ; ; CLASS 4 - RELATIVE JUMPS (JR AND DJNZ) ; ; S62 EQU $ CALL GNC LHLD PTR1 ! MOV A,M ! CPI ',' ! JZ S68 INX H ! MOV A,M ! CPI ',' ! JZ S68 ;BRANCH IF CONDITIONAL LDA OPCODE ! STA INST ! MVI A,2 ! STA LEN CALL BACKUP ! CALL EVAL ! LDA VAL ! DCR A ! DCR A ! STA INST+1 JMP ENDSTMT ; S68 EQU $ LHLD SYMCND ! SHLD SYMPT ;SO NOT CONFLICT WITH REG NAMES CALL BACKUP ! CALL EVAL ! LDA VAL ! RLC ! RLC ! RLC ! ANI 38H LXI H,SYM ! SHLD SYMPT ;PUT IT BACK ADI 20H ! STA INST ! MVI A,2 ! STA LEN CALL EVAL ! LDA VAL ! DCR A ! DCR A ! STA INST+1 ! JMP ENDSTMT ; ; EJECT ; ; ; CLASS 5 - RESTARTS ; ; S73 EQU $ CALL EVAL ! LDA VAL ! ANI 38H ! ORI 0C7H ! STA INST MVI A,1 ! STA LEN ! JMP ENDSTMT ; ; EJECT ;  ; ; CLASS 6 - ARITHMETIC OPCODES ; ; ADD,SUB,ADC,SBC,AND,OR,XOR,CP ; ; S77 EQU $ CALL GNC ! CPI '(' ! JZ S85 ;BRANCH IF () FORM LHLD PTR1 ! INX H ! MOV A,M ! CPI ',' ! JZ S96A ;BR IF REG PAIR CALL BACKUP ! CALL EVAL ! LDA EVFLGS ! ANI RNAME ! JNZ S84 LDA OPCODE ! ADI 0C6H ! STA INST ! LDA VAL ! STA INST+1 MVI A,2 ! STA LEN ! JMP ENDSTMT ; ; PROCESS REGISTER NAME ; S84 EQU $ LDA OPCODE ! ADI 80H ! MOV B,A ! LDA VAL ! ADD B ! STA INST MVI A,1 ! STA LEN ! JMP ENDSTMT ; S85 EQU $ CALL GNC ! CALL GNC ! CPI 'L' ! JZ S95 CPI 'Y' ! JZ S93 MVI A,0DDH ! STA INST S88 EQU $ LDA OPCODE ! ADI 86H ! STA INST+1 MVI A,3 ! STA LEN CALL GNC CALL EVAL ! LDA VAL ! STA INST+2 ! JMP ENDSTMT ; S93 EQU $ MVI A,0FDH ! STA INST ! JMP S88 ; S95 EQU $ LDA OPCODE ! ADI 86H ! STA INST ! MVI A,1 ! STA LEN ! JMP ENDSTMT ; ; ; PROCESS REGISTER PAIR ADD,SUB,ADC,SBC ; S96A EQU $ CALL BACKUP ! CALL EVAL LDA VAL ! CPI 0FFH ;IX ! JZ S96H ! CPI 0FEH ;IY ! JZ S96J LDA OPCODE+1 ! CPI 9 ! JZ S96F MVI A,0EDH ! STA INST ! MVI A,2 ! STA LEN CALL EVAL LDA VAL ! RLC ! RLC ! RLC ! ANI 38H ! MOV B,A ! LDA OPCODE+1 ! ADD B STA INST+1 ! JMP ENDSTMT ; S96F EQU $ CALL EVAL LDA VAL ! RLC ! RLC ! RLC ! ANI 38H ! MOV B,A ! LDA OPCODE+1 ! ADD B STA INST ! MVI A,1 ! STA LEN ! JMP ENDSTMT ; S96H EQU $ MVI A,0DDH ! STA INST JMP S96K ; S96J EQU $ MVI A,0FDH ! STA INST S96K EQU $ CALL EVAL LDA VAL ! CPI 0FFH ! JNZ S96L ! CPI 0FEH ! JNZ S96L ! MVI A,4 ! STA VAL S96L EQU $ LDA VAL ! RLC ! RLC ! RLC ! ANI 38H ! MOV B,A ! LDA OPCODE+1 ! ADD B STA INST+1 ! MVI A,2 ! STA LEN ! JMP ENDSTMT ; ; EJECT ; ; CLASS 7 - I/O INSTRUCTIONS ; ; S97 EQU $ LDA OPCODE ! CPI 0D3H ! JZ S107 ;BRANCH IF OUT OPCODE CALL GNC ! CPI 'A' ! JNZ S104 ;BRANCH IF 8080 TYPE I/O CALL GNC ! CALL GNC ! CALL EVAL ;GET PORT ADDRESS MVI A,0DBH ! STA INST ! LDA VAL ! STA INST+1 ! MVI A,2 ! STA LEN JMP ENDSTMT ; S104 EQU $ CALL BACKUP ! CALL EVAL ;GET REGISTER NAME MVI A,0EDH ! STA INST LDA VAL ! RLC ! RLC ! RLC ! ANI 38H ! ADI 40H ! STA INST+1 MVI A,2 ! STA LEN ! JMP ENDSTMT ; S107 EQU $ ;PROCESS OUT INSTRUCTION CALL GNC ! CALL GNC ! CPI 'C' ! JNZ S109 LHLD PTR1 ! MOV A,M ! CPI ')' ! JZ S112 S109 EQU $ CALL BACKUP ! CALL EVAL ;GET PORT NUMBER MVI A,0D3H ! STA INST ! LDA VAL ! STA INST+1 ! MVI A,2 ! STA LEN JMP ENDSTMT ; S112 EQU $ CALL GNC ! CALL GNC CALL EVAL MVI A,0EDH ! STA INST LDA VAL ! RLC ! RLC ! RLC ! ANI 38H ! ADI 41H ! STA INST+1 MVI A,2 ! STA LEN ! JMP ENDSTMT ; ; EJECT ; ; CLASS 8 - LD INSTRUCTIONS ; ; ; THE FOLLOWING ARE STRINGS WHICH ARE SPECIAL OPERAND FORMS ; LD1 DB 'A,I' LD2 DB 'A,R' LD3 DB 'I,A' LD4 DB 'R,A' LD5 DB 'SP,HL' LD6 DB 'SP,IX' LD7 DB 'SP,IY' ; S116 EQU $ CALL GNC ! CALL BACKUP ;POINT TO OPERAND FIELD LHLD PTR1 ;SET UP POINTER TO OPERAND FIELD LXI D,LD1 ! MVI B,3 ! CALL CMPCHR ! JZ S171 LXI D,LD2 ! MVI B,3 ! CALL CMPCHR ! JZ S173 LXI D,LD3 ! MVI B,3 ! CALL CMPCHR ! JZ S175 LXI D,LD4 ! MVI B,3 ! CALL CMPCHR ! JZ S177 LXI D,LD5 ! MVI B,5 ! CALL CMPCHR ! JZ S179 LXI D,LD6 ! MVI B,5 ! CALL CMPCHR ! JZ S181 LXI D,LD7 ! MVI B,5 ! CALL CMPCHR ! JZ S183 ;PROCESS SPECIAL OPRNDS ; CALL GNC CPI '(' ! JZ S185 ;BRANCH IF () FORM CALL BACKUP ! CALL EVAL LDA EVFLGS ! ANI RPNAME ! JNZ S147 ;BRANCH IF RPAIR NAME CALL GNC ! CPI '(' ! JZ S130 ;BRANCH IF () OPERAND LHLD VAL ! SHLD SAVVAL CALL BACKUP ! CALL EVAL ! LDA EVFLAGS ! ANI RNAME ! JNZ S128 ;> RNAME LDA SAVVAL ! RLC ! RLC ! RLC ! ANI 38H ! ADI 6 ! STA INST LDA VAL ! STA INST+1 ! MVI A,2 ! STA LEN ! JMP ENDSTMT ;IMMED OPERAND ; S128 EQU $ ;PROCESS RNAME LDA SAVVAL ! RLC ! RLC ! RLC ! ANI 38H ! MOV B,A ! LDA VAL ! ADD B ADI 40H ;FOR R-R TYPE INST STA INST ! MVI A,1 ! STA LEN ;REG-REG OPERAND JMP ENDSTMT ; S130 EQU $ CALL GNC ! CALL GNC CPI 'L' ! JZ S138 CPI 'X' ! JZ S140 CPI 'Y' ! JZ S145 CALL BACKUP ! CALL BACKUP ! CALL EVAL LDA EVFLAGS ! ANI RPNAME ! JNZ S136 ;BRANCH IF REG PAIR MVI A,3AH ! STA INST ! LHLD VAL ! SHLD INST+1 MVI A,3 ! STA LEN ! JMP ENDSTMT ; S136 EQU $ LDA VAL ! RLC ! RLC ! RLC ! ANI 38H ADI 0AH ! STA INST ! MVI A,1 ! STA LEN ! JMP ENDSTMT ; S138 EQU $ LDA VAL ! RLC ! RLC ! RLC ! ANI 38H ADI 46H ! STA INST ! MVI A,1 ! STA LEN ! JMP ENDSTMT ; S140 MVI A,0DDH ! STA INST S140A LDA VAL ! RLC ! RLC ! RLC ! ANI 38H ! ADI 46H ! STA INST+1 CALL GNC CALL EVAL ! LDA VAL ! STA INST+2 MVI A,3 ! STA LEN JMP ENDSTMT ; S145 EQU $ MVI A,0FDH ! STA INST ! JMP S140A ; S147 EQU $ CALL GNC ! CPI '(' ! JZ S159 LHLD VAL ! SHLD SAVVAL CALL BACKUP CALL EVAL LDA SAVVAL ! CPI 0FFH ! JZ S155 ! CPI 0FEH ! JZ S157 LDA SAVVAL ! RLC ! RLC ! RLC ! ANI 38H ! INR A ! STA INST LHLD VAL ! SHLD INST+1 ! MVI A,3 ! STA LEN ! JMP ENDSTMT ; S155 EQU $ MVI A,0DDH ! STA INST S156 EQU $ MVI A,21H ! STA INST+1 ! MVI A,4 ! STA LEN LHLD VAL ! SHLD INST+2 JMP ENDSTMT ; S157 EQU $ MVI A,0FDH ! STA INST ! JMP S156 ; S159 EQU $ LHLD VAL ! SHLD SAVVAL CALL EVAL LDA SAVVAL ! CPI 4 ! JZ S165 CPI 0FFH ! JZ S167 CPI 0FEH ! JZ S169 MVI A,0EDH ! STA INST LDA SAVVAL ! RLC ! RLC ! RLC ! ANI 38H ! ADI 4BH ! STA INST+1 LHLD VAL ! SHLD INST+2 ! MVI A,4 ! STA LEN JMP ENDSTMT ; S165 EQU $ MVI A,2AH ! STA INST ! LHLD VAL ! SHLD INST+1 ! MVI A,3 ! STA LEN JMP ENDSTMT ; S167 EQU $ MVI A,0DDH ! STA INST S168 MVI A,2AH ! STA INST+1 ! LHLD VAL ! SHLD INST+2 ! MVI A,4 ! STA LEN JMP ENDSTMT ; S169 EQU $ MVI A,0FDH ! STA INST ! JMP S168 ; S171 LXI H,57EDH S171A SHLD INST ! MVI A,2 ! STA LEN ! JMP ENDSTMT ; S173 LXI H,5FEDH ! JMP S171A ; S175 LXI H,47EDH ! JMP S171A ; S177 LXI H,4FEDH ! JMP S171A ; S179 MVI A,0F9H ! STA INST ! MVI A,1 ! STA LEN ! JMP ENDSTMT ; S181 LXI H,0F9DDH ! JMP S171A ; S183 LXI H,0F9FDH ! JMP S171A ; S185 JMP S186 ; LD01 DB 'HL)' LD02 DB 'IX+' LD03 DB 'IY+' ; S186 LHLD PTR1 LXI D,LD01 ! MVI B,3 ! CALL CMPCHR ! JZ S204 LXI D,LD02 ! MVI B,3 ! CALL CMPCHR ! JZ S210A LXI D,LD03 ! MVI B,3 ! CALL CMPCHR ! JZ S210B CALL EVAL ! LHLD VAL ! SHLD SAVVAL LDA EVFLAGS ! ANI RPNAME ! JNZ S202 CALL GNC ;BYPASS COMMA CALL EVAL ! LDA EVFLAGS ! ANI RPNAME ! JNZ S193 MVI A,32H ! STA INST ! LHLD SAVVAL ! SHLD INST+1 MVI A,3 ! STA LEN ! JMP ENDSTMT ; S193 EQU $ LDA VAL CPI 4 ! JZ S196 CPI 0FFH ! JZ S198 CPI 0FEH ! JZ S200 ; MVI A,0EDH ! STA INST LDA VAL ! RLC ! RLC ! RLC ! ANI 38H ! ADI 43H ! STA INST+1 LHLD SAVVAL ! SHLD INST+2 MVI A,4 ! STA LEN ! JMP ENDSTMT ; S196 EQU $ MVI A,22H ! STA INST LHLD SAVVAL ! SHLD INST+1 ! MVI A,3 ! STA LEN ! JMP ENDSTMT ; S198 EQU $ MVI A,0DDH ! STA INST S199 EQU $ MVI A,22H ! STA INST+1 ! LHLD SAVVAL ! SHLD INST+2 MVI A,4 ! STA LEN ! JMP ENDSTMT ; S200 EQU $ MVI A,0FDH ! STA INST ! JMP S199 ; S202 EQU $ LDA VAL ! RLC ! RLC ! RLC ! ANI 38H ! ADI 2 ! STA INST MVI A,1 ! STA LEN ! JMP ENDSTMT ; S204 EQU $ CALL GNC ! CALL GNC ! CALL GNC ! CALL GNC CALL EVAL LDA EVFLAGS ! ANI RNAME ! JNZ S209 MVI A,36H ! STA INST ! LDA VAL ! STA INST+1 ! MVI A,2 ! STA LEN JMP ENDSTMT ; S209 EQU $ LDA VAL ! ADI 70H ! STA INST ! MVI A,1 ! STA LEN ! JMP ENDSTMT ; S210A MVI A,0DDH ! STA INST ! JMP S211 S210B MVI A,0FDH ! STA INST S211 EQU $ CALL GNC ! CALL GNC ! CALL GNC ! CALL EVAL LHLD VAL ! SHLD SAVVAL CALL GNC ;BYPASS COMMA CALL EVAL LDA EVFLAGS ! ANI RNAME ! JNZ S218 MVI A,36H ! STA INST+1 LDA SAVVAL ! STA INST+2 ! LDA VAL ! STA INST+3 MVI A,4 ! STA LEN ! JMP ENDSTMT ; S218 EQU $ LDA VAL ! ADI 70H ! STA INST+1 ! LDA SAVVAL ! STA INST+2 MVI A,3 ! STA LEN ! JMP ENDSTMT ; ; EJECT ;END OF LD PROCESSING ; ; CLASS 9 - PUSH POP ; ; S220 EQU $ CALL EVAL LDA VAL ! CPI 0FFH ! JZ S224 ! CPI 0FEH ! JZ S226 LDA VAL ! RLC ! RLC ! RLC ! ANI 38H ! MOV B,A ! LDA OPCODE ! ADD B STA INST MVI A,1 ! STA LEN ! JMP ENDSTMT ; S224 EQU $ MVI A,0DDH ! STA INST S225 EQU $ LDA OPCODE ! ADI 20H ! STA INST+1 ! MVI A,2 ! STA LEN JMP ENDSTMT ; S226 MVI A,0FDH ! STA INST ! JMP S225 ; ; EJECT ; ; ; CLASS 10 - EXCHANGE (EX) ; ; S228 EQU $ CALL GNC ! CPI '(' ! JZ S235 ;BRANCH IF () FORM CPI 'A' ! JZ S233 ; BRANCH IF EX AF,AF' MVI A,0EBH ! STA INST ! MVI A,1 ! STA LEN ! JMP ENDSTMT ; S233 EQU $ MVI A,8 ! STA INST ! MVI A,1 ! STA LEN ! JMP ENDSTMT ; S235 EQU $ LHLD PTR1 ! LXI D,5 ! DAD D ! SHLD PTR1 CALL GNC CPI 'L' ! JZ S239 CPI 'Y' ! JZ S241 ; MVI A,0DDH ! STA INST S238 EQU $ MVI A,0E3H ! STA INST+1 ! MVI A,2 ! STA LEN ! JMP ENDSTMT ; S239 EQU $ MVI A,0E3H ! STA INST ! MVI A,1 ! STA LEN ! JMP ENDSTMT ; S241 EQU $ MVI A,0FDH ! STA INST ! JMP S238 ; ; EJECT ; ; ; CLASS 11 - RETURNS ; ; S243 EQU $ CALL GNC CPI 0AH ! JZ S248 ;BRANCH IF NO OPERAND CPI 0DH ! JZ S248 ! CPI ';' ! JZ S248 ;BRANCH IF NO OPERAND LHLD SYMCND ! SHLD SYMPT ;FOR ELIMINATING REG NAME CONFLICTS CALL BACKUP ! CALL EVAL LXI H,SYM ! SHLD SYMPT ;PUT IT BACK LDA VAL ! RLC ! RLC ! RLC ! ANI 38H ! ADI 0C0H ! STA INST MVI A,1 ! STA LEN ! JMP ENDSTMT ; S248 EQU $ LDA OPCODE ! STA INST ! MVI A,1 ! STA LEN ! JMP ENDSTMT ; ; EJECT ; ; CLASS 12 - BIT,SET,RES ; ; S250 EQU $ CALL EVAL ! LHLD VAL ! SHLD SAVVAL ;SAVE BIT NUMBER CALL GNC ! CPI '(' ! JZ S257 CALL BACKUP ! CALL EVAL MVI A,0CBH ! STA INST LDA SAVVAL ! RLC ! RLC ! RLC ! ANI 38H ! MOV B,A ! LDA OPCODE ! ADD B MOV B,A ! LDA VAL ! ADD B ! STA INST+1 MVI A,2 ! STA LEN ! JMP ENDSTMT ; S257 EQU $ CALL GNC ! CALL GNC ! CPI 'L' ! JZ S266 CPI 'Y' ! JZ S264 ; MVI A,0DDH ! STA INST S260 CALL GNC CALL EVAL MVI A,0CBH ! STA INST+1 ! LDA VAL ! STA INST+2 LDA SAVVAL ! RLC ! RLC ! RLC ! ANI 38H ! ADI 6 ! MOV B,A LDA OPCODE ! ADD B ! STA INST+3 MVI A,4 ! STA LEN ! JMP ENDSTMT ; S264 EQU $ MVI A,0FDH ! STA INST ! JMP S260 ; S266 EQU $ MVI A,0CBH ! STA INST ! LDA SAVVAL ! RLC ! RLC ! RLC ! ANI 38H ADI 6 ! MOV B,A ! LDA OPCODE ! ADD B ! STA INST+1 MVI A,2 ! STA LEN ! JMP ENDSTMT ; ; EJECT ; ; CLASS 13 - INC,DEC ; ; S268 EQU $ CALL GNC ! CPI '(' ! JZ S290 CALL BACKUP ! CALL EVAL LDA EVFLAGS ! ANI RNAME ! JNZ S280 LDA VAL ! CPI 0FFH ! JZ S275 ! CPI 0FEH ! JZ S278 LDA VAL ! RLC ! RLC ! RLC ! ANI 38H ! MOV B,A ! LDA OPCODE+1 ! ADD B STA INST ! MVI A,1 ! STA LEN ! JMP ENDSTMT ; S275 MVI A,0DDH ! STA INST S276 LDA OPCODE+1 ! ADI 20H ! STA INST+1 ! MVI A,2 ! STA LEN JMP ENDSTMT ; S278 EQU $ MVI A,0FDH ! STA INST ! JMP S276 ; S280 EQU $ LDA VAL ! RLC ! RLC ! RLC ! ANI 38H ! MOV B,A ! LDA OPCODE ! ADD B STA INST ! MVI A,1 ! STA LEN ! JMP ENDSTMT ; S290 EQU $ CALL GNC ! CALL GNC CPI 'L' ! JZ S299 CPI 'Y' ! JZ S297 MVI A,0DDH ! STA INST S293 CALL GNC ! CALL EVAL LDA OPCODE ! ADI 30H ! STA INST+1 ! LDA VAL ! STA INST+2 MVI A,3 ! STA LEN ! JMP ENDSTMT ; S297 EQU $ MVI A,0FDH ! STA INST ! JMP S293 ; S299 EQU $ LDA OPCODE ! ADI 30H ! STA INST ! MVI A,1 ! STA LEN ! JMP ENDSTMT ; ; EJECT ; ; CLASS 14 - PSEUDO OPERATORS ; ; S301 EQU $ LDA OPCODE ! DCR A ! ADD A MOV E,A ! MVI D,0 ! LXI H,PSDTAB ! DAD D MOV E,M ! INX H ! MOV D,M XCHG PCHL ; PSDTAB EQU $ DW S302 ;EQU DW S305 ;DEFS DW S308 ;DEFB DW S317 ;DEFW DW S320 ;END DW S323 ;ORG DW S324 ;EJECT DW S325 ;IBM FOR FORMATTING 3270 (ICC) SCREENS ; ; S302 EQU $ ;EQU CALL EVAL ! LHLD VAL ! XCHG ! LHLD SYMADR MOV M,E ! INX H ! MOV M,D LHLD VAL ! SHLD EQUVAL ! MVI A,1 ! STA EQUFLG JMP ENDSTMT ; S305 EQU $ ;DEFS CALL EVAL ! LHLD VAL ! SHLD LEN2 ! JMP ENDSTMT ; S308 EQU $ ;DEFB CALL GNC ! CPI 27H ! JZ S313 ;BRANCH IF QUOTE CALL BACKUP ! CALL EVAL ! MVI A,1 ! STA LEN LDA VAL ! STA INST JMP ENDSTMT ; S313 EQU $ LXI D,INST LHLD PTR1 S313A LDA LEN ! INR A ! STA LEN MOV A,M ! INX H ! STAX D ! INX D ! MOV A,M CPI 0DH ! JZ ENDSTMT ! CPI 27H ! JNZ S313A JMP ENDSTMT ; S317 EQU $ CALL EVAL ;DEFW LHLD VAL ! SHLD INST MVI A,2 ! STA LEN JMP ENDSTMT ; S320 EQU $ ;END CALL EVAL ! LHLD VAL ! SHLD ENDADR ! SHLD EQUVAL S321 MVI A,1 STA EQUFLG ! STA EFLG JMP ENDSTMT ; S323 EQU $ ;ORG CALL EVAL ! LHLD VAL ! SHLD PC SHLD EQUVAL ! MVI A,1 ! STA EQUFLG JMP ENDSTMT ; ; S324 EQU $ ;EJECT MVI A,MAXLNE-1 ! STA CURLNE ;CAUSE HOF ON RECORD AFTER EJECT JMP ENDSTMT ;TREAT THIS LIKE A COMMENT ; ; S325 EQU $ ;IBM PSEUDO FOR 3270 (ICC 40+) SCREEN FORMATTING LXI H,INST ! SHLD TEMP ;SET UP FOR MULTI-BYTE OUTPUT S325X EQU $ CALL GNC ! CPI 27H ! JZ S326 ;BRANCH IF LEADING QUOTE ; ; DO HEX UNTIL COMMA FOUND ; S325A EQU $ CALL S325B ;CONVERT TO BINARY AND STORE AWAY LDA LEN ! INR A ! STA LEN ;INCREMENT LENGTH CALL GNC ;GET NEXT CHARACTER CPI ',' ! JZ S326 ;IF COMMA THEN SWITCH TO ASCII CPI 0DH ! JNZ S325A ;BRANCH IF NOT DONE JMP ENDSTMT ;BRANCH IF CARRIAGE RETURN FOUND ; ; DO ASCII UNTIL COMMA FOUND ; S326 EQU $ LHLD PTR1 ! MOV A,M ! INX H ! SHLD PTR1 ;(GNC SKIPS BLANKS) CPI 0DH ! JZ ENDSTMT ;BRANCH IF END CPI ',' ! JZ S325X ;BRANCH IF END OF ASCII- SWITCH BACK TO HEX LHLD TEMP ! MOV M,A ! INX H ! SHLD TEMP ;PUT CHARACTER AWAY LDA LEN ! INR A ! STA LEN ;INCREMENT LENGTH COUNTER JMP S326 ;AND CONTINUE ; ; CONVERT HEX TO BIN FOR 'IBM' PSEUDO (INTERNAL SUBROUTINE) ; S325B EQU $ LXI B,0 ;SET UP FOR POSSIBLE SINGLE CHAR HEX DIG, ZERO B AND C CALL CNVDIG ;CONVERT DIGIT WE ALREADY HAVE CALL GNC CPI ',' ! JZ S325D ! CPI 0DH ! JZ S325D ;BRANCH IF ONLY SINGLE DIGIT PUSH PSW ;SAVE CHARACTER MOV A,B ! RLC ! RLC ! RLC ! RLC ! ANI 0F0H ! MOV C,A ;SET UP POP PSW ! CALL CNVDIG ;CONVERT SECOND DIGIT S325C EQU $ ;NOW COMBINE THEM MOV A,B ! ORA C LHLD TEMP ! MOV M,A ! INX H ! SHLD TEMP ;PUT CHARACTER AWAY RET ; S325D CALL BACKUP JMP S325C ; CNVDIG EQU $ ;CONVERT DIGIT TO BINARY (0-9 , A-F) CPI 'A' ! JC CNVD2 ;BRANCH IF NUMBER ADI 9 ;ADJUST 41 (A) TO 4A TO MAKE IT BINARY EQUIVALENT CNVD2 ANI 0FH ! MOV B,A RET ; ; EJECT ; ; ; E N D O F S T A T E M E N T P R O C E S S I N G ; ; ; ENDSTMT------HERE IT IS!!!! ; ; ENDSTMT EQU $ LDA PASSNO ! ORA A ! JZ S417 ;DONT PRINT DURING PASS 1 LDA UFLAG ! ORA A ! JZ $+8 ! MVI A,'U' ! STA ERRFLG ! XRA A ! STA UFLAG LDA ERRFLG ! CPI ' ' ! JNZ S402 ;ALWAYS PRINT ERRORS LDA LFLAG ! CPI 'N' ! JZ S412 ;DON'T PRINT IF USER ASKED US NOT TO S402 EQU $ LDA ERRFLG ! STA HDRBUF MVI A,' ' ! STA HDRBUF+1 LXI H,HDRBUF+2 ! LXI D,HDRBUF+1 ! LXI B,14 ! CALL MOVE LDA EQUFLG ! ORA A ! JNZ S410 ;BRANCH IF TO USE EQUVAL LHLD PC ! XCHG ! LXI H,HDRBUF+1 MOV A,D ! CALL CNV2HX MOV A,E ! CALL CNV2HX INX H LXI D,INST MVI C,4 ! LDA LEN ! MOV B,A ORA A ! JZ S408 ;BRANCH IF LENGTH IF ZERO S406 EQU $ LDAX D ! CALL CNV2HX INX D DCR B ! JZ S408 DCR C ! JNZ S406 S408 EQU $ LXI H,HDRBUF ! CALL PLINE ;WRITE AND PAGE JMP S412 ; S410 EQU $ LHLD EQUVAL ! XCHG ! LXI H,HDRBUF+1 MOV A,D ! CALL CNV2HX MOV A,E ! CALL CNV2HX LXI H,HDRBUF ! CALL PLINE ; S412 EQU $ LDA LEN ! ORA A ! JZ S417 MOV B,A LXI D,INST LHLD PC ! SHLD TEMP S414 EQU $ PUSH B LDAX D ! LHLD TEMP ! CALL WOBJ POP B INX D LHLD TEMP ! INX H ! SHLD TEMP DCR B ! JNZ S414 ; S417 EQU $ LHLD PC ! LDA LEN ! MOV C,A ! MVI B,0 ! DAD B XCHG ! LHLD LEN2 ! DAD D ! SHLD PC LDA EFLG ! ORA A ! JZ NEXT ;GO PROCESS NEXT RECORD LDA PASSNO ! CMA ! STA PASSNO CPI 0 ! JZ ENDIT LXI H,FCB1+12 ! MVI M,0 LXI D,FCB1 ! CALL OPNFIL LXI H,FCB1+32 ! MVI M,0 LXI H,INBUF+1024 ! SHLD IBP XRA A ! STA EFLG ;RESET END OF RECORD FLAG LXI H,0 ! SHLD PC ;RESET PC MVI A,1 ! STA PAGENO ;SET UP PAGE NUMBER MVI A,MAXLNE+1 ! STA CURLNE LXI D,-1 ! SHLD OBJADR JMP NEXT ; ENDIT EQU $ LDA HFLAG ! CPI 'N' ! JZ ENDITX ;BRANCH IF NO HEX FILE LDA OBJCNT ! ORA A ! JZ ENDIT1 ;BRANCH IF NO OBJ TO WRITE CALL WREC ;ELSE WRITE FINAL RECORD ENDIT1 LXI H,EOFREC ! MVI B,13 ENDIT2 MOV A,M ! CALL WNB2 ! INX H ! DCR B ! JNZ ENDIT2 MVI B,255 ;FLUSH BUFFER ENDIT3 MVI A,1AH ! CALL WNB2 ! DCR B ! JNZ ENDIT3 LXI D,FCB2 ! CALL CLSFIL ENDITX EQU $ LHLD PC ! XCHG ! LXI H,PCMSGA MOV A,D ! CALL CNV2HX ! MOV A,E ! CALL CNV2HX LXI D,PCMSG ! CALL WMSG LHLD SYMPTR ! XCHG ! LXI H,SYMSGA MOV A,D ! CALL CNV2HX ! MOV A,E ! CALL CNV2HX LXI D,SYMSG ! CALL WMSG LXI D,ENDMSG ! CALL WMSG JMP 0000H PCMSG DB 13,10,'LAST ADDRESS USED IN THIS ASSEMBLY IS: ' PCMSGA DB 'XXXX','$' ; SYMSG DB 13,10,'NEXT SYMBOL ADDRESS IS: ' SYMSGA DB 'XXXX$' ; ENDMSG DB 13,10,10,'Z-80 ASSEMBLY COMPLETE',13,10,10,'$' ; EOFREC DB ':00000001FF',13,10 ; ; EJECT ; ; WOBJ - WRITE OBJECT BYTE ROUTINE ; ; INPUT BYTE IN A REGISTER ; WOBJ EQU $ MOV B,A ;SAVE INPUT LDA HFLAG ! CPI 'N' ! RZ ;RETURN IF NO HEX FILE MOV A,B ;GET INPUT CHARACTER BACK PUSH D ! PUSH PSW PUSH H ! LHLD OBJADR ! LXI D,-1 CALL CMPHD ! POP H ! JZ WOBJ0 ;BRANCH IF FIRST TIME THROUGH XCHG ! LHLD OLDADR ! INX H ! CALL CMPHD ! JZ WOBJ1 ;BRA IF NEXT SEQ BYT CALL WREC WOBJ0 EQU $ XCHG ! SHLD OBJADR ! XCHG XRA A ! STA OBJCNT WOBJ1 EQU $ XCHG ! SHLD OLDADR LDA OBJCNT ! CPI 10H ! JC WOBJ2 ;BRANCH IF NOT TIME TO WRITE CALL WREC LHLD OBJADR ! LXI D,16 ! DAD D ! SHLD OBJADR ;ADVANCE ADDR XRA A ! STA OBJCNT WOBJ2 EQU $ INR A ! STA OBJCNT ;UPDATE COUNT DCR A ! MOV E,A ! MVI D,0 ! LXI H,OBJ ! DAD D WOBJ3 POP PSW ! MOV M,A POP D RET ; ; WREC - FORMAT AND WRITE HEX RECORD ; ; WREC EQU $ PUSH H ! PUSH D LHLD OLDADR ! LXI D,-1 ! CALL CMPHD ! JZ WREC3 ;BRANCH IF FIRST TIME LDA OBJCNT ! MOV C,A ! MOV B,A ;SET CHKSUM AND COUNT LXI H,REC ! MVI M,':' ! INX H MOV A,B ! CALL CNV2HX LDA OBJADR+1 ! ADD C ! MOV C,A ! LDA OBJADR+1 ! CALL CNV2HX LDA OBJADR ! ADD C ! MOV C,A ! LDA OBJADR ! CALL CNV2HX XRA A ! CALL CNV2HX LXI D,OBJ WREC1 EQU $ LDAX D ! ADD C ! MOV C,A ! LDAX D ! CALL CNV2HX INX D ! DCR B ! JNZ WREC1 MOV A,C ! CMA ! INR A ! CALL CNV2HX MVI M,0DH ! INX H ! MVI M,0AH ;PUT CRLF ON END LXI H,REC ;WRITE OUT RECORD WREC2 EQU $ MOV A,M ! CALL WNB2 MOV A,M ! CPI 0AH ! INX H ! JNZ WREC2 ;GO UNTIL LF WREC3 EQU $ POP D ! POP H RET ; ; EJECT ; ; ; PLINE ROUTINE - WRITE AND PAGE ; ; PLINE EQU $ LDA CURLNE ! CPI MAXLNE ! JC PLINE1 ;BRANCH IF LESS LXI D,FCB1+1 ! LXI H,HOFNAM ! LXI B,8 ! CALL MOVE ;GET FILE NAME LXI H,HOFPG ! LDA PAGENO ! CALL CNV2HX LDA HOFPG ! CPI '0' ! JNZ $+8 ! MVI A,' ' ! STA HOFPG LDA PAGENO ! ADI 1 ! DAA ! STA PAGENO LXI H,HOFMSG ! CALL WLINE ! XRA A PLINE1 EQU $ INR A ! STA CURLNE LXI H,HDRBUF ! CALL WLINE RET ; HOFMSG EQU $ DB 0DH,8AH,0DH,8AH,0CH DB 'Z80ASM-2.0A (C) 1977 LCS' DB 0DH,8AH,0DH,8AH DB 'SOURCE FILE NAME: ' HOFNAM DB 'XXXXXXXX PAGE # ' HOFPG DB 'XX' DB 8AH,0DH,8AH,0DH,0AH ; ; ; EJECT ; ;  Z 8 0 A S M ZILOG/MOSTEK Z80-CPU ASSEMBLY LANGUAGE PROCESSOR (C) COPYRIGHT 1977 LCS ALL RIGHTS RESERVED LATEST REVISION: 21-JULY-1977  Z 8 0 A S M Z80ASM IS AN ASSEMBLER FOR THE ZILOG/MOSTEK Z80-CPU MICROPROCESSOR. IT IS DESIGNED TO RUN UNDER THE CP/M OPERATING SYSTEM FROM DIGITAL RESEARCH. CP/M WILL RUN ON EITHER AN 8080A SYSTEM OR A Z80 SYSTEM. Z80ASM WILL RUN IN THE CP/M MINIMUM (16K) SYSTEM BUT WILL UTILIZE MORE MEMORY FOR SYMBOL TABLE STORAGE IN LARGER (UP TO 64K) CP/M SYSTEMS. Z80ASM READS A SOURCE (ASM) FILE PRODUCED BY THE CP/M 'ED' TEXT EDITOR PROGRAM AND PRODUCES AN OPTIONAL LISTING (ON THE LST: DEVICE) AND AN OPTIONAL OBJECT CODE (HEX) FILE IN INTEL FORMAT HEX. THE 'HEX' FILE CAN BE LOADED FOR EXECUTION USING 'DDT' OR 'LOAD' COMMANDS OF CP/M OR IT CAN BE PUNCHED ON PAPER TAPE USING THE 'PIP' PROGRAM. INPUT STATEMENTS ARE FREE FORMAT (I.E. NOT COLUMN ORIENTED). BETWEEN FIELDS ANY NUMBER OF BLANK OR TAB CHARACTERS MAY BE PRESENT BUT WITHIN A FIELD THERE MAY BE NO BLANK OR TAB CHARACTERS. HOWEVER, STATEMENTS LABELS MUST BE IN THE FIRST POSITION OF THE LINE. STATEMENT LABELS MAY HAVE A COLON FOLLOWING THEM BUT THE COLON IS NOT REQUIRED. COMMENTS ARE PRECEEDED BY A SEMICOLON AND MAY APPEAR BY THEMSELVES OR FOLLOWING ALL OF THE FIELDS ON A SOURCE LINE. ALL THE ZILOG/MOSTEK MNEMONICS ARE SUPPORTED WITH THE FOLLOWING EXCEPTIONS: 1. THE Z80CPU TECHNICAL MANUAL HAS CONFLICTING INFORMATION REGARDING THE SYNTAX OF THE RLC,RL,RRC AND RR INSTRUCTIONS WHEN THE A REGISTER IS USED AS THE OPERAND. ON PAGE 50 THE FORMS 'RLCA','RLA','RRCA','RRA' ARE USED WHILE ON PAGE 68 THE FORM 'RR A' IS SHOWN. Z80ASM WILL SUPPORT ONLY THE 'RRA', ETC. FORM. 2. THE Z80CPU MANUAL DOES NOT DESCRIBE THE PSEUDO OPERATORS AVAILABLE EXCEPT THAT 'EQU' AND 'DEFS' ARE USED ON PAGE 67 IN THE SAMPLE PROGRAM. THE LIST BELOW DESCRIBES THE PSEUDO OPERATORS AVAILABLE IN Z80ASM AND THEIR ARGUMENT FORMATS: