,-BAMDUA 035bDBL4 ASM:DBL4 COM}DBL4 DOCGSDBLEPSONASMADBLGEN ASMV$DBLOKI ASMgMLOAD23 COM~NULU CMTNULU DOCbNULU11F1ASMrBNULU12 COMwx=NULU12 NOTNULUTERMASMrZASM COM p@ZASM DOC}j -BAMDUA.035 Thi librar volum contain th versio o NUL tha wil correc th bug encountere whil unsqueezing/extractin file whe usin NULU11 utilit t "colum-print tw page o fil o singl shee o pape an Z8 macr assemble ar als included. -BAMDUA .035 2k -You'r readin i now DBL4 .COM 4k -Progra t prin file tw page a tim o singl shee o pape usin th compresse mod foun o mos do-matri printers. DBL4 .DOC 10k <-- Documentatio fo abov - REA M ! DBL4 .ASM 26 -Sourc cod fo th abov program. DBLEPSON.ASM 4 -DBL overla fil - Epso RX80/MX80. DBLGEN .ASM 4 -DBL overla fil - Generalize printer. DBLOKI .ASM 4 -DBL overla fil - Okidat Microline. NULU12 .COM 16k -Versio o NULU1 containin th bu fixe i th NULU11F1.AS file. NULU12 .NOT 2 <-- Documentatio o abov fixe - REA M ! NULU .CMT 4k -Revie o th NUL program. NULU .DOC 58k Documentatio fil fo th NUL serie o program REA M !! NULU11F1.ASM 2k -Patc fil incorporatin th fixe o th bug encountere wit unsqueezing/extractin file wit NULU11. NULUTERM.ASM 4k -Patc fil fo installin NUL wit you termina characteristics. MLOAD23 .COM 4k -Progra t instal progra patche withou usin DD o simila error-pron utility. ZASM .COM 14 -Z8 macr assemble simila t MA an RMAC. ZASM .DOC 26 <-- Documentatio fo abov - REA M !! ; ; ; DBL.ASM ; VERSION OF AUGUST, 1985 ; BY: ALAN W WARREN ;-------------------------------; BDOS: EQU 05H FCB: EQU 5CH LBUFER: EQU 80H STAK: EQU 0FEH ORG 0100H JMP START ;103H ; ;SPACE FOR RELOCATING CODE FOR ;EASY ACCESS BY PROGRAM ;-------------------------------; DFMODE: DB 'Epson RX-80',0 DS 11BH-$ ;11BH - 24 (18H) BYTES FOR CODE HGT: DB 0 ;8 BYTES FOR FORMAT WDT: DB 0 LMG: DB 0 RMG: DB 0 CGP: DB 0 MT: DB 0 MB: DB 0 DB 0 ;123H ; ; ;PRINTER CONTROL STRINGS FOR ;EPSON PRINTER (RX-80) ;-------------------------------; ENDPG: DB 6,13,10,10,10,10,10 DS 130H-$ ;13 BYTES NORMAL: DB 2,1BH,40H ;MASTER RESET DS 140H-$ ;16 BYTES ; ; ;MODE CONTROL BLOCKS ; ; MODE ID STRINGS 32 BYTES ; PRINT MODE CONTROL 24 BYTES ; PAGE FORMAT CONSTANTS 8 BYTES ; TOTALS: 64 BYTES ;-------------------------------; MODE1: DB '16.7 CPI, 6 LPI',0 DS 160H-$ ;32 BYTES ; ;24 BYTES FOR PRINT MODE CONTROL ;-------------------------------; DB 2,0FH,8FH DS 178H-$ ;24 BYTES ; ;8 BYTES FOR PAGE LAYOUT ;-------------------------------; DB 66 ;PAGE HEIGHT IN LINES DB 142 ;PAGE WIDTH IN CHARACTERS DB 5 ;LEFT MARGIN IN CHARACTERS (DEF=12) DB 8 ;RIGHT MARGIN IN CHARACTERS DB 5 ;CENTER GAP IN CHARACTERS (DEF=8) DB 0 ;TOP MARGIN IN LINES DB 6 ;BOTTOM MARGIN IN LINES DB 0 ;180H 8 BYTES ; ;MORE OF SAME FOR 2ND MODE ;-------------------------------; MODE2: DB '10 CPI',0 DS 1A0H-$ ;32 BYTES ; DB 2,12H,92H DS 1B8H-$ ;24 BYTES ; DB 66 DB 80 DB 7 DB 5 DB 5 DB 0 DB 6 DB 0 ;1C0H 8 BYTES ; ;MORE OF SAME FOR 3RD MODE ;-------------------------------; MODE3: DB '16.7 CPI, 8 LPI',0 DS 1E0H-$ ;32 BYTES ; DB 4,1BH,'0' DB 0FH,8FH DS 1F8H-$ ;24 BYTES ; DB 88 ;PAGE HEIGHT IN LINES DB 142 ;PAGE WIDTH IN CHARACTERS DB 12 ;LEFT MARGIN IN CHARACTERS DB 8 ;RIGHT MARGIN IN CHARACTERS DB 8 ;CENTER GAP IN CHARACTERS DB 0 ;TOP MARGIN IN LINES DB 6 ;BOTTOM MARGIN IN LINES DB 0 ;200H 8 BYTES ; ;MORE OF SAME FOR 4TH MODE ;-------------------------------; MODE4: DB 'Teeny Weeny',0 DS 220H-$ ;32 BYTES ; DB 8,0FH,8FH DB 1BH,'A',6 DB 1BH,'S1' DS 238H-$ ;24 BYTES ; DB 132 ;PAGE HEIGHT IN LINES DB 142 ;PAGE WIDTH IN CHARACTERS DB 12 ;LEFT MARGIN IN CHARACTERS DB 8 ;RIGHT MARGIN IN CHARACTERS DB 8 ;CENTER GAP IN CHARACTERS DB 0 ;TOP MARGIN IN LINES DB 12 ;BOTTOM MARGIN IN LINES DB 0 ;240H 8 BYTES ; ;SPACE FOR 3 MORE MODES ;------------------------------; MODE5: DB 0 DS 63 ;280H 64 BYTES ; MODE6: DB 0 DS 63 ;2C0H 64 BYTES ; MODE7: DB 0 DS 63 ;300H 64 BYTES ; ;--- ; ; ;PROGRAM ACTION STARTS HERE ; ; ;-------------------------------; ; START LX SP,STAK CALL TYPDIS DB 'DBL Version 4.00, setup for a ',0 LXI H,DFMODE CALL TYPSTR CALL TPTHIS DB ' printer',13,10,10,0 LXI H,0 PUSH H STWTLP: XTHL! XTHL DCR L JNZ STWTLP DCR H JNZ STWTLP POP D LDA FCB+17 CPI 'P' JNZ STCLR MVI A,27 STA CURCHR LXI H,FCB+18 CALL GETPAG JC STCLR SHLD STPAGE ; ;BUFFER & COUNTER INITIALIZATIONS ;-------------------------------; STCLR: CALL CLRSCR STINT: LXI SP,STAK LXI H,DBUFER SHLD CURENT SHLD ODDPAG SHLD EVENPG LXI H,DIGIT MVI M,'1' INX H MVI C,5 MVI M,' ' CALL FILLM LXI H,LSPAGE MVI C,0 CALL ZAPMEM LDA FCB+1 CPI ' '+1 JC GTNAME LDA PASS ORA A MVI A,2 STA PASS JNZ OPENER GTNAME: CALL GTFNAM ; ;CHECK FOR EXISTING FILE & OPEN ;-------------------------------; OPENER: XRA A STA FCB+32 LXI D,FCB MVI C,15 ;FILE OPEN CALL BDOS LXI H,NOFI ;FILE ERROR? INR A JZ FINIS ; ;GET PRINT MODE ;-------------------------------; LDA PASS CPI 2 MVI A,0 STA PASS LXI H,MODE1 JZ MODECX CALL CLRSCR RETRY: LXI H,MODE1 LXI B,6 SAYMOD: MOV A,M ORA A JZ NXTMOD MOV A,B ADI '1' STA MDNUM CALL TYPDIS MDNUM: DB '0> Print using ',0 PUSH H CALL TYPSTR POP H NXTMOD: LXI D,64 DAD D INR B DCR C JNZ SAYMOD CALL TYPDIS DB 10,9,'YOUR CHOICE: ',0 ; ;KEY IN THE MODE NUMBER ;-------------------------------; KEYMD: CALL KEYIN CPI 27 JNZ KMDCK XRA A JMP KMDSET ; ;CHECK FOR NUMERIC INPUT ;-------------------------------; KMDCK: CPI '1' JC KEYMD CPI '6' JNC KEYMD DCR A ANI 00001111B KMDSET: MOV L,A MVI H,0 DAD H! DAD H ;*4 DAD H! DAD H ;*16 DAD H! DAD H ;*64 LXI D,MODE1 DAD D ;PLUS OFFSET MODECX: MOV A,M ORA A JZ MODERR ; ;MOVE CHOSEN MODE TO DEFAULT LOC ;-------------------------------; PUSH H MVI A,' ' CALL TYPE CALL TYPSTR CALL TCRLF POP H LXI D,32 DAD D LXI D,DFMODE MVI C,32 MODMOV: MOV A,M STAX D INX H! INX D DCR C JNZ MODMOV ; ;GET START PAGE NUMBER ;-------------------------------; LHLD STPAGE MOV A,H ORA L JNZ STPRT GTPGST: CALL TYPDIS DB 10,10,'Start print ' DB 'on page: ',0 CALL GETPG JZ ZSTPG SHLD STPAGE ZSTPG: LDA CURCHR CPI 27 JZ TFNAME ; ;GET LAST PAGE NUMBER ;-------------------------------; GTLAST: CALL TYPDIS DB 'Last page to print: ',0 CALL GETPG JZ ZLSPG INX H! INX H SHLD LSPAGE XCHG LHLD STPAGE INX H MOV A,D CMP H JC PAGERR JNZ ASKDTA MOV A,E CMP L JC PAGERR ZLSPG: LDA CURCHR CPI 27 JZ TFNAME ; ;ASK FOR PAGE DATA ;-------------------------------; ASKDTA: CALL TCRLF LXI H,PAGSTR LXI D,HGT MVI C,7 ; ;SAY WHAT THE DATA DOES ;-------------------------------; PGLOOP: PUSH B! PUSH D! PUSH H CALL TCRLF CALL TYPSTR PUSH H ; ;SAY WHAT DEFAULT IS ;-------------------------------; CALL TPTHIS DB ' (Default = ',0 LDAX D PUSH D CALL TYPNBR CALL TPTHIS DB '): ',0 ; ;GET REPLY FROM KEYBOARD ;-------------------------------; CALL KEYNUM POP D JC NUMERR ;NUMBER OUT OF RANGE ON CY JZ REPCK ;NO INPUT IF Z STAX D REPCK: LDA CURCHR CPI 27 JZ TFNAME PGDFLT: POP H ;GET NEXT STRING POINTER XTHL ;XCHG WITH LAST POINTER POP H! POP D! POP B ;HL POINTS TO NEXT STRING INX D ;DE POINTS TO NEXT DATA DCR C JNZ PGLOOP ; ;TELL FILENAME ;-------------------------------; TFNAME: CALL CLRSCR CALL TYPDIS DB 10,'Printing: ',0 LXI H,FCB CALL TYPFCB CALL TYPDIS DB 'Start Page: ',0 LHLD STPAGE INX H CALL TYPGNO CALL TPTHIS DB 9,'Finish Page: ',0 LHLD LSPAGE CALL TYPGNO CALL TYPDIS DB 10,'Page Format:',13,10,0 LXI D,HGT MVI C,7 LXI H,PAGSTR SHOFMT: CALL TYPSTR PUSH B! PUSH D! PUSH H LDAX D CALL TYPNBR CALL TCRLF POP H! POP D! POP B INX D DCR C JNZ SHOFMT CALL TYPDIS DB 10,'Press Return when ' DB 'printer is ready',13,10,10,0 PWAIT: CALL KEYIN CPI 27 JZ STPRT CPI 13 JNZ PWAIT STPRT: CALL TTCRLF CALL TYPPMG DB 'Stop/Resume',0 CALL TYPDIS DB 9,'Press Ctl-Q ' DB 'to Exit to System' DB 13,10,10,0 ; ;CHECK START ;-------------------------------; LHLD STPAGE MOV A,H ORA L CZ PRTINT LXI SP,STAK ;EMPTY STACK CALL TTCRLF ; ;CALCULATING TEXT SPACE ;WIDE = (WDT - LMG - RMG - CGP))/2 ;-------------------------------; XRA A LXI H,WDT MOV A,M INX H SUB M ;-LMG INX H SUB M ;-RMG INX H SUB M ;-CGP RRC ANI 01111111B JZ FMTERR STA WIDE ; ;DISTANCE FROM LEFT EDGE TO ;RIGHT COLUMN ;MGAP = WIDE + CGP ;-------------------------------; MOV B,A ADD M JM FMTERR STA MGAP ; ;DISTANCE BETWEEN 'PAGE [ ]' ;CGAP = MGAP - 10 ;-------------------------------; STC! CMC SBI 10 JM FMTERR STA CGAP ; ;DISTANCE TO FIRST 'PAGE [ ]' ;PNOFF = ((WIDE / 2 ) - 6) + LMRG ;-------------------------------; MOV A,B RRC ANI 01111111B ;/2 SBI 6 DCX H! DCX H ADD M ;+LMRG JM FMTERR STA PNOFF ; ;NUMBER OF PRINTABLE LINES ;LINMAX = HGT - MT - MB -2 ;-------------------------------; LXI H,MT LDA HGT SUB M ;-MT INX H SUB M ;-MB DCR A! DCR A STA LINMAX ; ;START THE READ ;-------------------------------; LXI D,DBUFER CALL FILLER ; ;FIND START OF EVEN NUMBERED PAGE ;-------------------------------; FINDPG: LDA LINMAX STA LCOUNT MOV B,A LHLD CURENT SHLD ODDPAG ; ;SEARCH FOR LINEFEED & EOF ;-------------------------------; FINDEV: CALL GNB CPI ' ' JNC FINDEV CPI 26 JZ NULINE CPI 12 JZ GOTEVN CPI 10 JNZ FINDEV DCR B JNZ FINDEV ; GOTEVN: LHLD CURENT MOV A,M CPI 12 JNZ NULINE INX H SHLD CURENT ; ;PRINT MARGIN AT TOP ;-------------------------------; NULINE: LDA MT ORA A JZ MTOFF MOV L,A MTON: CALL QCRLF DCR L JNZ MTON ; ;FLIP ODD & EVEN PAGE POINTERS ;-------------------------------; MTOFF: LHLD CURENT SHLD EVENPG LHLD ODDPAG SHLD CURENT MOV A,M CPI 26 JZ ENDIT ; ;PRINT A LINE ON SHEET OF PAPER ;-------------------------------; LDA LMG MOV C,A CALL SPACES CALL PRTLIN ;ODD PAGE LINE JC ENDIT ; ;FLIP POINTERS AGAIN ;-------------------------------; LHLD CURENT SHLD ODDPAG LHLD EVENPG SHLD CURENT MOV A,M CPI 26 JZ LNFEED CPI 12 JZ LNFEED ; ;CENTER GAP ;-------------------------------; LDA MGAP MOV C,A LDA BCOUNT SUB C CMA MOV C,A CALL SPACES CALL PRTLIN ;EVEN PAGE LNFEED: CALL CRLF JNZ NULINE ; ;END OF PAGE FLAG OCCURRED ;MOVE DOWN PAGE TO END ;-------------------------------; ENDIT: CALL CRLF LDA LCOUNT INR A JNZ ENDIT ; ;PRINT ODD PAGE NUMBER ;-------------------------------; LDA PCHAR STA PCFLG LDA PNOFF MOV C,A CALL PRTNUM ; ;PRINT EVEN PAGE NUMBER ;-------------------------------; LDA CGAP MOV C,A CALL PRTNUM CALL QCRLF ; ;CHECK TO SEE IF PRINTER WAS OFF ;BEFORE DOING END OF PAGE ;-------------------------------; LDA PCFLG ;WILL BE 0C9H IF OFF, ZERO IF ON ORA A LXI H,ENDPG CZ STRING ; ;CHECK FOR PASSING FORM FEED ;-------------------------------; LHLD ODDPAG MOV A,M CPI 12 JNZ ODDOFF INX H SHLD ODDPAG ODDOFF: LHLD CURENT MOV A,M CPI 12 JNZ EOF INX H SHLD CURENT ; ;CHECK FOR END OF PRINTING ;-------------------------------; EOF: LHLD LSPAGE MOV A,H ORA L JZ DONE ; ;CHECK FOR END OF FILE ;-------------------------------; LHLD EVENPG MOV A,M CPI 26 JNZ FINDPG ; ;FINISH MESSAGE ;-------------------------------; DONE: LXI H,GOOD FINIS: CALL TYPSTR CALL DEINIT JMP STINT ; ; ; ;---- ; ; ;START OF SUBROUTINES ; ; ;-------------------------------; ; ; ; ; ;MODE ERROR ;-------------------------------; MODERR: CALL ERROR DB 'Mode out of range',0 CALL TTCRLF JMP RETRY ; ;FORMAT ERROR ;-------------------------------; FMTERR: CALL ERROR DB 'Page format',0 JMP ASKDTA ; ;PAGE ERROR ;-------------------------------; PAGERR: CALL ERROR DB 'Page number',0 LXI H,0 SHLD STPAGE SHLD LSPAGE JMP GTPGST ; ; ;NUMBER ERROR ;-------------------------------; NUMERR: POP H POP H! POP D! POP B LDA CURCHR CPI 27 JZ TFNAME CALL ERROR DB 'Number out of range ' DB '(0 <= N <= 255)',0 JMP PGLOOP ; ; ;--- ; ; ;BUFFER OPERATIONS ; ;-------------------------------; ; ; ; ;MOVE CHARACTER IN A REG TO ;LINE BUFFER & BUMP COUNTERS ;-------------------------------; TOLIN: INX H MOV M,A LDA BCOUNT INR A STA BCOUNT DCR C RET ; ;MOVE FILE LINE TO LINE BUFFER ;-------------------------------; PRTLIN: LXI H,LBUFER XRA A MOV M,A STLINE: LDA WIDE MOV C,A XRA A STA BCOUNT ; ;FILL LINE BUFFER FROM DISK DATA ;-------------------------------; GETBYT: CALL GNB CPI ' ' JC GOTCTL CALL TOLIN JNZ GETBYT ; ;RAN OUT OF SPACE ON LINE ;-------------------------------; FNDEOL: CALL GNB ORA A CPI 26 JZ EOL CPI 13 JZ GOTCR CPI 12 JZ EOL CPI 10 JNZ FNDEOL ; ;GOT END OF LINE FLAG.. ;CHECK FOR EMPTY LINE BUFFER ;-------------------------------; EOL: PUSH PSW LXI H,LBUFER MOV A,M STA BCOUNT MOV D,A XRA A MOV M,A CMP D JZ NOPRT ; ;PRINT LINE BUFFER ;-------------------------------; PRTBUF: INX H MOV A,M CPI ' ' CNC PCHAR DCR D JNZ PRTBUF NOPRT: POP PSW RET ; ;GOT A CONTROL CHARACTER ;-------------------------------; GOTCTL: CPI 26 JZ EOL CPI 9 JZ TABBER CPI 12 JZ EOL CPI 10 JZ EOL CPI 13 JZ GOTCR JMP GETBYT ; ;TAB ENCOUNTERED ;FILL LINE BUFFER WITH SPACES ;TO NEXT MULTIPLE OF 8 ;-------------------------------; TABBER: PUSH D LDA BCOUNT ANI 00000111B MOV D,A MVI A,8 SUB D MOV D,A ; ;NUMBER OF SPACES IN D TO LINE ;-------------------------------; TABLUP: MVI A,' ' CALL TOLIN JZ TABEND DCR D JNZ TABLUP XRA A INR A TABEND: POP D JZ FNDEOL JMP GETBYT ; ;GOT A CARRIAGE RETURN ;CHECK LENGTH & RESET ;LINE BUFFER POINTER ;-------------------------------; GOTCR: CALL SETLIN JMP STLINE ; ;SET LINE LENGTH BYTE ;-------------------------------; SETLIN: LDA BCOUNT LXI H,LBUFER CMP M RC MOV M,A RET ; ;--- ; ; ;DISK BUFFER CONTROL ROUTINES ; ;-------------------------------; ; ; ; ;GET NEXT BYTE FROM FILE ;-------------------------------; GNB: PUSH B! PUSH D! PUSH H CALL KEYCHK ORA A JZ CURCHK CPI 27 JZ PRXIT ; ;CHECK FOR 'P' INPUT ;-------------------------------; PCHECK: ANI 00011111B CPI 16 JNZ CURCHK CALL TYPPMG DB 'Resume',0 CALL TCRLF ; ;CHECK FOR P TO RESUME ;-------------------------------; PCHK: CALL KEYIN CPI 27 JZ PRXIT ANI 00011111B CPI 16 JNZ PCHK CALL TYPPMG DB 'Stop',0 CALL TTCRLF ; ;CHECK CURRENT DISK POINTER ;AGAINST TOP OF MEMORY ;THEN GET BYTE FROM FILE ;-------------------------------; CURCHK: LHLD CURENT CCHK1: CALL TOPCMP CZ FILMEM LHLD CURENT MOV A,M CPI 26 JZ GNBRET INX H CPI 12 JZ GNBRET SHLD CURENT GNBRET: POP H! POP D! POP B RET ; ;ZERO C BYTES OF MEMORY ;-------------------------------; ZAPMEM: MVI M,0 ; ;FILL C BYTES OF MEMORY ;-------------------------------; FILLM: DCR C RZ MOV D,H MOV E,L INX D ; ;MOVE C BYTES OF MEMORY ;-------------------------------; MEMOV: MOV A,M STAX D INX H! INX D DCR C JNZ MEMOV RET ; ;READ BIGGEST POSSIBLE CHUNK OF ;THE DATA FILE INTO MEMORY ;-------------------------------; FILMEM: LHLD ODDPAG MVI L,0 LXI D,DBUFER ; ;MOVE DATA TO LO MEMORY ;-------------------------------; MOVER: MVI C,80H CALL MEMOV CALL TOPCMP JNZ MOVER ; ;READ DISK DATA TO MEMORY AT DE ;-------------------------------; FILLER: PUSH D MVI C,26 CALL BDOS LXI D,FCB MVI C,20 CALL BDOS POP H MVI C,80H ORA A JZ FILTER ; ;UNABLE TO READ DATA MUST BE END ;FILL THIS BLOCK WITH EOF MARKERS ;-------------------------------; SETEND: MVI M,26 INX H DCR C JNZ SETEND CALL TOPCMP JNZ SETEND JMP SETPTR ; ;STRIP PARITY BIT FROM EVERY ;BYTE IN BLOCK JUST READ ;-------------------------------; FILTER: MOV A,M ANI 01111111B MOV M,A INX H DCR C JNZ FILTER CALL TOPCMP XCHG JNZ FILLER ; ;ADJUST PAGE POINTERS TO ;NEW MEMORY LOCATIONS ;-------------------------------; SETPTR: LHLD ODDPAG LXI D,DBUFER MOV A,H SUB D MOV C,A MOV H,D SHLD ODDPAG LDA EVENPG+1 SUB C STA EVENPG+1 LDA CURENT+1 SUB C STA CURENT+1 RET ; ;CHECK FOR HL POINTING ;TO TOP OF MEMORY ;-------------------------------; TOPCMP: LDA BDOS+2 DCR A CMP H RET ; ;--- ; ; ;PRINTER OUTPUT ROUTINES ; ;-------------------------------; ; ; ;PRINT NUMBER OF SPACES IN C REG ;-------------------------------; SPACES: PUSH B MVI A,' ' CALL PCHAR POP B DCR C JNZ SPACES RET ; ;DO CARRIAGE RETURN & LINEFEED ;THEN BUMP LINE COUNT ;-------------------------------; CRLF: CALL QCRLF LDA LCOUNT DCR A STA LCOUNT RET ; ;CARRIAGE RETURN & LINEFEED ONLY ;-------------------------------; QCRLF: MVI A,13 CALL PCHAR MVI A,10 ; ;PRINT CHARACTER IN THE A REG ;-------------------------------; PCHAR: RET ;THIS INSTRUCTION GETS ;CHANGED BY PROGRAM PUSH B! PUSH D! PUSH H MOV E,A MVI C,5 CALL BDOS POP H! POP D! POP B RET ; ;PRINT C SPACES THEN PAGE NUMBER ;-------------------------------; PRTNUM: LDA PCFLG ORA A JNZ PRBUMP CALL SPACES LXI H,PGNUMB CALL STRING PRBUMP: CALL BMPNUM LHLD LSPAGE DCX H SHLD LSPAGE LHLD STPAGE DCX H SHLD STPAGE DCX H MOV A,H ORA L RNZ ; ;INITIALIZE PRINTER ;-------------------------------; PRTINT: XRA A STA PCHAR LXI H,DFMODE ; ;PRINT STRING AT HL ;-------------------------------; STRING: MOV A,M INX H CPI 0 RZ MOV C,A STRGLP: MOV A,M CALL PCHAR INX H DCR C JNZ STRGLP RET ; ;INCREMENT ASCII PAGE NUMBER ;-------------------------------; BMPNUM: LXI H,DIGIT NXTNUM: INR M MOV A,M CPI '9'+1 RNZ ; ;CURRENT DIGIT IS LARGER THAN 9 ;REPLACE WITH ZERO & DO NEXT DIGIT ;-------------------------------; MVI M,'0' DCX H MOV A,M CPI 'A' RNC CPI ' ' JNZ NXTNUM MVI M,'1' RET ; ;--- ; ; ;CONSOLE INPUT/OUTPUT ROUTINES ; ;-------------------------------; ; ; ;DIVDE HL BY DE & PRINT RESULT ;-------------------------------; TSLASH: MVI C,255 TSLOOP: INR C XRA A MOV A,L SUB E MOV L,A MOV A,H SBB D MOV H,A JNC TSLOOP DAD D MOV A,C ORA A JNZ TDGT ORA B MVI A,' ' JZ TYPE XRA A TDGT: ADI '0' MOV B,A ; ;TYPE CHARACTER IN A ON CONSOLE ;-------------------------------; TYPE: PUSH B! PUSH D! PUSH H MOV E,A MVI C,6 CALL BDOS CALL KEYCHK CPI 19 CZ FREEZE POP H! POP D! POP B RET ; ;FREEZE SCREEN UNTIL CTL-S ENTERED ;-------------------------------; FREEZE: CALL KEYCHK CPI 19 JNZ FREEZE RET ; ;PRINT STRING AT HL ;-------------------------------; TYPSTR: MOV A,M INX H CPI 0 RZ CPI 9 JZ TYPTAB CALL TYPE JMP TYPSTR ; ;PHONEY TAB ;-------------------------------; TYPTAB: PUSH B MVI C,8 TPTAB: MVI A,' ' CALL TYPE DCR C JNZ TPTAB POP B JMP TYPSTR ; ;PRINT STRING FOLLOWING CALL ;-------------------------------; TYPDIS: CALL TCRLF TPTHIS: XTHL CALL TYPSTR XTHL RET ; ;CARRIAGE RETURN & LINE FEED ;-------------------------------; TTCRLF: CALL TCRLF TCRLF: CALL TPTHIS DB 13,10,0 RET ; ;CLEAR SCREEN ;-------------------------------; CLRSCR: MVI C,12 CLS: CALL TTCRLF DCR C JNZ CLS RET ; ;TYPE PRINTER MESSAGE ;-------------------------------; TYPPMG: CALL TYPDIS DB 9,'Press "P" to ',0 XTHL CALL TYPSTR XTHL CALL TPTHIS DB ' Print',13,10 db 9,'Press [Escape] ' DB 'to Exit to Menu',0 RET ; ;DECIMAL PRINT NUMBER IN A REG ;-------------------------------; TYPNBR: MOV L,A MVI H,0 ; ;DECIMAL PRINT NUMBER IN HL ;-------------------------------; TYPNUM: PUSH B! PUSH D MVI B,0 LXI D,10000 CALL TSLASH LXI D,1000 CALL TSLASH LXI D,100 CALL TSLASH LXI D,10 CALL TSLASH POP D! POP B MOV A,L ADI '0' JMP TYPE ; ;TYPE PAGE NUMBER ;-------------------------------; TYPGNO: MOV A,H ORA L JNZ TYPNUM CALL TPTHIS DB ' (Default) ',0 RET ; ;CHECK FOR KEYBOARD INPUT ;-------------------------------; KEYCHK: MVI E,255 MVI C,6 CALL BDOS CPI 24 JZ PRXIT CPI 17 JZ CTLQ ORA A RET ; ;INPUT A CHARACTER - EXIT IF CTL C ;-------------------------------; KEYIN: PUSH B! PUSH D! PUSH H KEYN1: CALL KEYCHK JZ KEYN1 STA CURCHR ; ;ECHO CHARACTER IF NO CONTROL ;-------------------------------; PUSH PSW MOV E,A MVI C,6 CPI ' ' CNC BDOS POP PSW POP H! POP D! POP B RET ; ;CONTROL Q - QUIT ;-------------------------------; CTLQ: LXI SP,STAK CALL CLS CALL DEINIT JMP 0 ; ;CONTROL X ;STOP PRINT & RETURN MAIN ;-------------------------------; PRXIT: CALL DEINIT JMP STCLR ; ;DEINITIALIZATIONS ;-------------------------------; DEINIT: LXI H,0 SHLD STPAGE ; ;RESET PRINTER IF INITIALIZED ;-------------------------------; LDA PCHAR ORA A RNZ LXI H,ENDPG CALL STRING LXI H,NORMAL CALL STRING MVI A,0C9H ;RET STA PCHAR RET ; ;FILL BUFFER FROM KEYBOARD ;-------------------------------; KEYBFR: LXI H,LBUFER PUSH H MVI C,40H CALL ZAPMEM MVI C,3FH POP H ; ;GET A BYTE & CHECK FOR CONTROL ;-------------------------------; KBFR: CALL KEYIN CPI ' ' JNC K2BFR CPI 13 RZ CPI 27 RZ CPI 8 JNZ KBFR MOV A,C CPI 3FH JZ KBFR INR C DCX H MVI M,0 CALL TPTHIS DB 8,' ',8,0 JMP KBFR ; ;MOVE BYTE IN A TO BUFFER ;-------------------------------; K2BFR: MOV M,A INX H MVI M,0 DCR C JNZ KBFR RET ; ;INPUT ERROR OCCURRED ;-------------------------------; ERROR: CALL TTCRLF XTHL CALL TYPSTR XTHL CALL TPTHIS DB 7,' - ERROR! ... ' DB 'Please Retry',13,10,0 RET ; ;CONVERT NUMBER STRING TO BINARY ; RETURNS: ; NUMBER IN HL & ; CARRY FLAG IF HL>255 ; NZ FLAG IF 0U  =2 ͍U ~B 10 CPIp#z 17!9:l2:]!Ͱ Ͱ BP16.7 CPI, 8 LPI`2!vn!05 Ͱ͎͓X Teeny Weeny80= =hAS1 $u @!Ü  6.7 CPI, 6 LPIÙ >U  =2 ͍U ~ 0 CPIp#z 17!9:l2:]!Ͱ Ͱ BP6.7 CPI, 8 LPI`2!vn!05 Ͱ͎͓X 1 DBL Version 4.00, setup for a !  printer !->%>:mPb>2` !nͬ b"\ + 1!"V "X "Z ! 61#6 !^ :]!ڝ:T >2T   2|\! <;:T >2T !@2+ !@~x12 0> Print using @  YOUR CHOICE: %1 6 =o&))))))@~D> $   ~# M*\ | Start print on page: ʹ ʁ"\ :`  Last page to print: ʹ ʾ##"^ *\ #zq{q:` $ ! $  (Default = x  ): v ڌ:`  +  Printing: !\͗  Start Page: *\ #͟  Finish Page: *^ ͟  Page Format: ! x $  x Press Return when printer is ready  ·! 5 Stop/Resume Press Ctl-Q to Exit to System *\ |̏ 1! !~###_2c G_2e 7? _2g x++_2f ! :#==2d :d 2a G*V "X h _ʇ z __*V ~ ‡#"V : ʖoU -*V "Z *X "V ~:O> *V "X *Z "V ~ :e O:b /O> J ‡J :a <:\ 2U :f Oj :g Oj U :U !#̖ *X ~ #"X *V ~ '#"V *^ |8*Z ~R! eL Mode out of range! L Page formatL Page number!"\ "^ ]:` L Number out of range (0 <= N <= 255)#w:b <2b !w:c O2b h h X  !~2b Ww#~ \  8   X:b W>W> QC<^:b !wʹ ʥ ¥5 Resume$  ‹5 Stop! *V 8 *V ~# "V 6 T]~# *X .8 \ 6# 8  ~w# 8 *X |Ob"X :[ 2[ :W 2W :=> \ > U :a =2a > \ > _:U z > ! ͖ ͦ *^ +"^ *\ +"\ +|2\ !~#O~\ # œ ! 4~:60+~A © 61 }o|gҿ y > 0G_ʹ  ʹ  ~#  > $ $   ! -  Press "P" to  Print Press [Escape] to Exit to Menuo&'ͽ ͽ dͽ  ͽ }0 |{  (Default)   ʹ 2` _ 1- b!"\ :\ !#͖ !0͖ >2\ !@? C  y? +6   w#6  !   - ERROR! ... Please Retry  !͒ |7>~0:bk)))_#Ò /| ÷ v } ++}o~#a{_ File to print (D:FILENAME.TYP): !\h  6#6   :` 2 !h  ͗ Á !~+:D ~w## !ځ .i  I !ځ .\ !  !ځ  s #~!L Filename ~ʦ @ >:  #~ y>. ¨ Page 1 finished No File Page Height Page Width Left Margin Right Margin Center Gap Top Margin Bottom Margin .heDOCUMENTATION FILE FOR: DBL.COM Version 4.00 FUNCTION: DBL.CO wa writte t us th compresse mod o mos printer i us today t prin file tw page a tim o singl shee o paper sor o lik this: xxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxx Pg 1 Pg 2 HISTORY: Th firs version (whic wer no release t th public use CP/M' rando dis rea functio extensively Thes version wer har o dis drives th ligh o th drive woul com o an sta o unti th printin quit Th firs versio release t th publi use al o th computer availabl RA spac a giganti dis buffer Thi versio coul rea mos file a on time the begi printin them greatl reducin th driv activity Th secon versio release t th publi (DBL2 containe ne feature i allowe th printin t star i th middl o th file unfortunately i containe severa mino inconvienences an a leas on bug I didn' lik t star printin o pag tha occurre afte th secon dis access Th thir versio cure th problem o seeme t an too car o som o th inconvienence bu neve go release t th public DBL cure th problem fro DBL an contain numbe o ne options includin a assortmen o prin mod option an se prin forma options. MENU OPTIONS: I filenam i specifie whe th progra i calle u a i wa i DBL2 suc as: A>DBL4 D:FILENAME.TYP P5 Al o th defaul option ar take an printin proceed jus a i DBL2. I n filenam i specified th progra wil promp fo filename Thi filenam i entere i th followin format: D:FILENAME.TYP Wher 'D i th driv t b use ( thr P) 'FILENAME i th primar fil nam o eigh o les characters 'TYP i th secondar nam (TYPE i thre o fewe characters Th progra assume tha th secon characte wil b coli (':') i driv i bein specified otherwis th defaul driv wil b used I th 'FILENAME i mor tha eigh (8 character i lengt o i th do separatin i fro th 'TYP i omitted al character beyon thi poin wil b discarde unti eithe do o th en o th specificatio i reached Althoug i take carrag retur o a escap t terminat th entry inter- pretatio o th entr wil terminat i spac i entered Finally th previou filenam i copie t buffe befor th ne entr i interpreted i yo wis t us th sam fil specification yo merel nee t pres th [Escape] key. Afte th filenam i entered eac vali printe mod i show alon wit promp fo you choice A thi poin th compute wil b waitin fo yo t pres numeri ke i th rang o thr 7 i yo ente a invali option you'l ge t d i over A soo a yo pres vali key it'l prin th correspondin mod (i yo goofe there' wa out). Nex it'l as firs fo th star page the th finis page Yo ca ke i an decima numbe yo want bu i onl see number fro thr 65535 bu you'l hav t pres th retur ke t tel i whe yo ar enterin number B th way don' ke i anythin tha isn' decima digi ( t 9) i terminate th numbe whe i see anythin tha isn' decima digit I yo ente finis pag tha come befor th star page i wil no accep it additionally al start ar rounde dow t th neares od number al finishe u t th neares eve number. Th pag forma come next Th progra print eac item the th defaul an wait fo you input I want number a above bu onl accept number i th rang o thr 255 Th prompt are: Page Height (Default = ###): Page Width (Default = ###): Left Margin (Default = ###): Right Margin (Default = ###): Center Gap (Default = ###): Top Margin (Default = ###): Bottom Margin (Default = ###): Afte al o th forma option ar entered i doe som mathmatics I somethin goe wron i th mathmatics yo ge t d th forma over. Onc i ha al o th above i wil sho wha i got an wai fo yo t approv i b pressin th retur key I yo pres th retur key it'l rea th dis an star printing Yo ca interup th printin b pressin th 'P key the resum b pressin th 'P agai 'p an Ctl- d th sam thin ) Whe th printin i don i wil retur t th filenam prompt. Yo ca exi th progra a an tim b enterin Ctl-Q enterin Ctl- wil retur yo t th filenam prompt Pressin th Escap ke whil printin i goin o wil als retur yo t th filenam prompt Additionally th Escap ke wil tak th default fo al o th item i serie o prompts singl defaul ca b take b merel pressin th Retur ke fo an promp excep fo th prin mode. INSTALLING DIFFERENT PRINTER: Differen stroke fo differen folks Ther ar mor differen printer o th marke tha kno about eac o the take differen sequenc o contro codes Fortunatel Epso an Okidat see t b takin u th majo portio o th market s I'v writte overlay fo bot o them Th onl on tha a absolutel sur work i th Epso RX-80 becaus that' wha I'v got Th tw overla file ar name DBLEPSON.OV DBLOKI.OVR respectively ge th on tha matche you printe an renam i wit .AS type Us AS t assembl i a mak .HE file No us DD t combin DBL4.CO an th overla a follows: A>DDT DBL4.COM Call up DDT & tell it to read DDT VERS 2.2 DBL4.COM NEXT PC (Note that DDT signs on with 0D80 0100 information about itself and DBL4.COM) -DD40,D5F Tell DDT to display last two lines of program 0D40 20 20 00 09 42 6F 74 74 6F 6D 20 4D 61 72 67 69 ..Bottom Margi 0D50 6E 20 00 00 01 00 00 00 00 00 00 00 00 00 00 00 n .............. -IDBLOKI.HEX Input overlay filename.hex -R Read overlay NEXT PC DDTs reply 0D80 0100 -G0 Exit DDT A>SAVE 13 DBL+.COM Sav th overlaye fil wit ne name - don't use old name. A>DDT Call up DDT again DDT VERS 2.2 This time theres not much sign on because no other file was read -F100,1000,FF Fill bottom of TPA with 0FFH -IDBL+.COM Insert name of modified version -R Read modified version -DD40,D5F Tell DDT to display last two lines of program (should match previous) 0D40 20 20 00 09 42 6F 74 74 6F 6D 20 4D 61 72 67 69 ..Bottom Margi 0D50 6E 20 00 00 01 00 00 00 00 00 00 00 00 00 00 00 n .............. If the line match the previous dump then the new version is all there F5C,5C,0 Clear out the default file control block F5D,67,20 F68,FF,0 G100 Start program running...and test options If it works properly you can rename it otherwise you get to try the proceedure over again. BUGS: Ther ha t b few ther alway is additionall som o th ne feature ma no b implimente ver wel an nee som refinement s don' thin thi i th ultimat version. OTHER POSSIBLE FEATURES: numbe o peopl hav aske fo do comman interpreter suppos tha it' possibl t do bu th problem tha com u whe printin t page a onc see monumenta righ now Doin som o th thing tha program lik WordSta d i fairl eas t d whe there' onl on page Whe there' tw page thing lik emphasize prin that' o severa line o on pag bu no o th othe a all i mor tha littl bi tricky Doin heading an footing pos simila problems. Th outpu fro DB look sor o lik th wa tha printin compan woul se u thei printin fo book Publisher us metho o puttin th page togethe know a printer gallery th las an firs page ar o th sam sid o shee (i tha order an th secon an nex t las ar o th othe (i tha order) Thi mean tha th star o al o th page hav t b locate befor th printin begins The al o bot page ha t b i memor a th tim th printin begins I coul b done bu no ver easily...it' bette t prin th page on b on an tap the togethe i th prope order. Ho abou sendin th outpu t th consol o t dis file Bot ar possible bu I'v ha abou al o th rampan featureitiu tha ca tak fo now Mayb thi winter. --- Alan Wayne Warren --- Sept 6, 1985; ; ; DBLEPSON.ASM ; DBL4.COM OVERLAY FOR ; EPSON RX80/MX80 PRINTER ; ; VERSION OF SEPT. 6, 1985 ; BY: ALAN W WARREN ;-------------------------------; ORG 0100H DS 3 ;JUMP VECTOR SPACE ; ;SPACE FOR RELOCATING CODE FOR ;EASY ACCESS BY PROGRAM ;-------------------------------; DFMODE: DB 'Epson RX-80',0 DS 11BH-$ ;11BH - 24 (18H) BYTES FOR CODE DB 0,0,0,0,0,0,0,0 ;8 BYTES FOR FORMAT ; ; ;PRINTER CONTROL STRINGS FOR ;EPSON PRINTER (RX-80) ;-------------------------------; ENDPG: DB 1,0CH DS 130H-$ ;13 BYTES NORMAL: DB 2,1BH,40H ;MASTER RESET DS 140H-$ ;16 BYTES ; ; ;MODE CONTROL BLOCKS ; ; MODE ID STRINGS 32 BYTES ; PRINT MODE CONTROL 24 BYTES ; PAGE FORMAT CONSTANTS 8 BYTES ; TOTALS: 64 BYTES ;-------------------------------; MODE1: DB '16.7 CPI, ' DB '6 LPI',0 DS 160H-$ ;32 BYTES ; ;24 BYTES FOR PRINT MODE CONTROL ;-------------------------------; DB 2,0FH,8FH DS 178H-$ ;24 BYTES ; ;8 BYTES FOR PAGE LAYOUT ;-------------------------------; DB 66 ;PAGE HEIGHT IN LINES DB 142 ;PAGE WIDTH IN CHARACTERS DB 12 ;LEFT MARGIN IN CHARACTERS DB 8 ;RIGHT MARGIN IN CHARACTERS DB 8 ;CENTER GAP IN CHARACTERS DB 0 ;TOP MARGIN IN LINES DB 6 ;BOTTOM MARGIN IN LINES DB 0 ;8 BYTES ; ;MORE OF SAME FOR 2ND MODE ;-------------------------------; MODE2: DB '10 CPI',0 DS 1A0H-$ ;32 BYTES ; DB 2,12H,92H DS 1B8H-$ ;24 BYTES ; DB 66 DB 80 DB 7 DB 5 DB 5 DB 0 DB 6 DB 0 ;8 BYTES ; ;MORE OF SAME FOR 3RD MODE ;-------------------------------; MODE3: DB '16.7 CPI, 8 LPI',0 DS 1E0H-$ ;32 BYTES ; DB 4,1BH,'0' DB 0FH,8FH DS 1F8H-$ ;24 BYTES ; DB 88 ;PAGE HEIGHT IN LINES DB 142 ;PAGE WIDTH IN CHARACTERS DB 12 ;LEFT MARGIN IN CHARACTERS DB 8 ;RIGHT MARGIN IN CHARACTERS DB 8 ;CENTER GAP IN CHARACTERS DB 0 ;TOP MARGIN IN LINES DB 6 ;BOTTOM MARGIN IN LINES DB 0 ;8 BYTES ; ;MORE OF SAME FOR 4TH MODE ;-------------------------------; MODE4: DB 'Teeny Weeny',0 DS 220H-$ ;32 BYTES ; DB 8,0FH,8FH DB 1BH,'A',6 DB 1BH,'S1' DS 238H-$ ;24 BYTES ; DB 132 ;PAGE HEIGHT IN LINES DB 142 ;PAGE WIDTH IN CHARACTERS DB 12 ;LEFT MARGIN IN CHARACTERS DB 8 ;RIGHT MARGIN IN CHARACTERS DB 8 ;CENTER GAP IN CHARACTERS DB 0 ;TOP MARGIN IN LINES DB 12 ;BOTTOM MARGIN IN LINES DB 0 ;8 BYTES ; ;SPACE FOR 3 MORE MODES ;------------------------------; MODE5: DB 0 DS 63 ;64 BYTES ; MODE6: DB 0 DS 63 ;64 BYTES ; MODE7: DB 0 DS 63 ;64 BYTES END ;300H = NEXT ADDRESS ; ; ; DBLGEN.ASM ; DBL4.COM OVERLAY ; GENERALIZED PRINTER ; ; VERSION OF SEPT. 6, 1985 ; BY: ALAN W WARREN ;-------------------------------; ORG 0100H DS 3 ;JUMP VECTOR SPACE ; ;PRINTER ID STRING ; TERMINATE WITH ZERO ;-------------------------------; DS 123H-$ ;32 BYTES FOR STRING ; ; ;PRINTER CONTROL STRINGS: ; FIRST BYTE TELLS HOW MANY ; BYTES ARE TO BE SENT TO PRINTER ; START ADDRESS = 123H ;-------------------------------; ENDPG: DB 1,12 ;STRING TO PRODUCE FORM FEED DS 130H-$ ;13 BYTES AVAILABLE NORMAL: DB 0 ;RESET PRINTER TO NORMAL DS 140H-$ ;16 BYTES AVAILABLE ; ; ;MODE CONTROL BLOCKS ; ; MODE ID STRINGS 32 BYTES TERMINATES WITH ZERO, ; LEAD ZERO DISABLES MODE ; PRINT MODE CONTROL 24 BYTES TERMINATES WITH ZERO ; PAGE FORMAT CONSTANTS 8 BYTES ; -------- ; TOTALS: 64 BYTES ;-------------------------------; MODE1: DB '10 CPI ' DB '& 6 LPI',0 ;LAST CHARACTER IN STRING IS ZERO DS 160H-$ ;32 BYTES AVAILABLE ; ;24 BYTES FOR PRINT MODE CONTROL ;-------------------------------; DB 0 ;LEAD BYTE TELLS STRING LENGTH DS 178H-$ ;24 BYTES AVAILABLE ; ;8 BYTES FOR PAGE LAYOUT ;-------------------------------; DB 66 ;PAGE HEIGHT IN LINES DB 85 ;PAGE WIDTH IN CHARACTERS DB 8 ;LEFT MARGIN IN CHARACTERS DB 4 ;RIGHT MARGIN IN CHARACTERS DB 4 ;CENTER GAP IN CHARACTERS DB 0 ;TOP MARGIN IN LINES DB 6 ;BOTTOM MARGIN IN LINES DB 0 ;FILLS UP 8 BYTES ; ;MORE OF SAME FOR 2ND MODE ; (ADDRESS SHOULD BE 180) ;-------------------------------; MODE2: DB 0 ;FIRST CHARACTER MUST BE ZERO ;IF MODE IS NOT IN USE DS 63 ;64 BYTES TOTAL ; ; ;SAME FOR 3RD, 4TH, 5TH, 6TH & 7TH ;-------------------------------; MODE3: DB 0 ;ADDRESS = 1C0H DS 63 ;64 BYTES TOTAL ; MODE4: DB 0 ;ADDRESS = 200H DS 63 ;64 BYTES TOTAL ; MODE5: DB 0 ;ADDRESS = 240H DS 63 ;64 BYTES TOTAL ; MODE6: DB 0 ;ADDRESS = 280H DS 63 ;64 BYTES TOTAL ; MODE7: DB 0 ;ADDRESS = 2C0H DS 63 ;64 BYTES TOTAL END ;300H = NEXT ADDRESS ; ; ; DBLEPSON.ASM ; DBL4.COM OVERLAY FOR ; OKIDATA MICROLINE PRINTER ; ; VERSION OF SEPT. 6, 1985 ; BY: ALAN W WARREN ;-------------------------------; ORG 0100H DS 3 ;JUMP VECTOR SPACE ; ;SPACE FOR RELOCATING CODE FOR ;EASY ACCESS BY PROGRAM ;-------------------------------; DFMODE: DB 'Okidata Microline',0 DS 11BH-$ ;11BH - 24 (18H) BYTES FOR CODE DB 0,0,0,0,0,0,0,0 ;8 BYTES FOR FORMAT ; ; ;PRINTER CONTROL STRINGS FOR ;EPSON PRINTER (RX-80) ;-------------------------------; ENDPG: DB 1,12 DS 130H-$ ;13 BYTES NORMAL: DB 2,24 ;MASTER RESET DS 140H-$ ;16 BYTES ; ; ;MODE CONTROL BLOCKS ; ; MODE ID STRINGS 32 BYTES ; PRINT MODE CONTROL 24 BYTES ; PAGE FORMAT CONSTANTS 8 BYTES ; TOTALS: 64 BYTES ;-------------------------------; MODE1: DB '17.1 CPI, at ' DB '6 LPI',0 DS 160H-$ ;32 BYTES ; ;24 BYTES FOR PRINT MODE CONTROL ;-------------------------------; DB 1,29 DS 178H-$ ;24 BYTES ; ;8 BYTES FOR PAGE LAYOUT ;-------------------------------; DB 66 ;PAGE HEIGHT IN LINES DB 145 ;PAGE WIDTH IN CHARACTERS DB 12 ;LEFT MARGIN IN CHARACTERS DB 8 ;RIGHT MARGIN IN CHARACTERS DB 8 ;CENTER GAP IN CHARACTERS DB 0 ;TOP MARGIN IN LINES DB 6 ;BOTTOM MARGIN IN LINES DB 0 ;8 BYTES ; ;MORE OF SAME FOR 2ND MODE ;-------------------------------; MODE2: DB '10 CPI',0 DS 1A0H-$ ;32 BYTES ; DB 0 DS 1B8H-$ ;24 BYTES ; DB 66 DB 85 DB 7 DB 5 DB 5 DB 0 DB 6 DB 0 ;8 BYTES ; ;MORE OF SAME FOR 3RD MODE ;-------------------------------; MODE3: DB '17.1 CPI, at ' DB '8 LPI',0 DS 1E0H-$ ;32 BYTES ; DB 3,29,27,56 DS 1F8H-$ ;24 BYTES ; DB 88 ;PAGE HEIGHT IN LINES DB 145 ;PAGE WIDTH IN CHARACTERS DB 12 ;LEFT MARGIN IN CHARACTERS DB 8 ;RIGHT MARGIN IN CHARACTERS DB 8 ;CENTER GAP IN CHARACTERS DB 0 ;TOP MARGIN IN LINES DB 6 ;BOTTOM MARGIN IN LINES DB 0 ;8 BYTES ; ;MORE OF SAME FOR 4TH MODE ;-------------------------------; MODE4: DB 'Teeny Weeny',0 DS 220H-$ ;32 BYTES ; DB 7,29,27,76 DB 27,37,57,12 DS 238H-$ ;24 BYTES ; DB 132 ;PAGE HEIGHT IN LINES DB 145 ;PAGE WIDTH IN CHARACTERS DB 12 ;LEFT MARGIN IN CHARACTERS DB 8 ;RIGHT MARGIN IN CHARACTERS DB 8 ;CENTER GAP IN CHARACTERS DB 0 ;TOP MARGIN IN LINES DB 12 ;BOTTOM MARGIN IN LINES DB 0 ;8 BYTES ; ;5TH MODE ;------------------------------; MODE5: DB '12 CPI at ' DB '8 LPI',0 DS 260H-$ DB 3,28,27,56 DS 278-$ DB 88 ;PAGE HEIGHT IN LINES DB 145 ;PAGE WIDTH IN CHARACTERS DB 12 ;LEFT MARGIN IN CHARACTERS DB 8 ;RIGHT MARGIN IN CHARACTERS DB 8 ;CENTER GAP IN CHARACTERS DB 0 ;TOP MARGIN IN LINES DB 6 ;BOTTOM MARGIN IN LINES DB 0 ;8 BYTES ; ;SPACE FOR 2 MORE MODES ;------------------------------; MODE6: DB 0 DS 63 ;64 BYTES ; MODE7: DB 0 DS 63 ;64 BYTES END ;300H = NEXT ADDRESS COM!9" 1I ͇MLOAD ver. 2.3 Copyright (C) 1983, 1984, 1985 by NightOwl Software, Inc. ͏ s͋zdͿͽ : ! * !  &<* !~#ʏG<6#" *}O| G6# x¿* +Fʏ#~ FUi~#Ui" ))))_* \ =A: i: i<2 –#![  < ,K6L#" x–2 ] 7ͽ <!e~ ½6H#6E#6X`^ ! ~4! ~d* 1:˜2 W _° g o: ̖ +: : " *  " :9 * " *   w# ØG! ~wx1N1N: R_!~! 4\ͽ 2 <4!͖ * * !:9ͽ \ͽ ѷ£*  " v+" * * " ͽ \ !  <~ !<ͽ ͽ <* * {OzGxr\!ͽ ͽ * #" yրOxGz͇Loaded * ͇ bytes (͇H)͇ to file %: ʚ͇ Over a * ͇ byte binary file͇ Start address: * ͇H Ending address: * ͇H Bias: * ͇H ͇Saved image size: * )͇ bytes (͇H, - ͇ records) * }G|͇ ++ Warning: program origin NOT at 100H ++ \ͽ <(͍~#%ʜ/Í:\©͋ <@/:[} o&>:/!]>./Í~ #/#  |{0/> /> /|}'Ɛ'@'_ͽ ~#=#~ FUX0:fAG?͇ Command line syntax error Ï͉ Ambiguous file name: % not allowed.͉ File % not found.͉ Disk full.͉ Directory full.͉ Premature end-of-file in %͉ Checksum error in %͉ Can't close %͉ Memory full while loading %͉ Format error in file %͉ Writing %, nothing loaded͉ MLOAD syntax: MLOAD [=] [,...] [] (brackets denote optional items) is the optional output filename are input file(s) is a hex load offset within the output file may be an optional non-HEX file to be patched by subsequently named HEX files (specifying The filetype enables this function). Note that ZCPR3-style drive/user notation may be used in all file specifications (e.g., "B3:MYFILE.COM, "A14:MDM7.HEX"). ͍v>2 " " * }o|g"   !]<: ! } w#͋ 2  % x _ } 6# 6 # 6# ͨ # ͨ #( :~U AC @#~#:+xG~0G#~:K #{ ~.#yu  k { ͨ #*ʗ ?‹ U  { à >? ™ ͨ #à ~/., :=ȷ/  " 2 = go : *  y "    go\ ] y!"#$a{ e!z #v i HEX ͽ ͽ I I PUBLIC DOMAIN / USER-SUPPORTED SOFTWARE REVIEWS: The programs reviewed here are available on the local Lost Dutchman's Gold Mine RCPMs (LD#1 and LD#2). Some are 'user-supported', so if you acquire any of these and find them to be particularly useful, send the author(s) a small donation to show your appreciation. (The donation will usually place you on the author's mailing list for updates and bug fixes... something the commercial software publishers often fail to do for programs costing hundreds of dollars.) NULU11.COM (in NULU11A.LBR) This program has been reviewed previously, but this first update incorporates some significant changes. NULU is a 'library manager', a program that allows the creation, modification, and general manipulation of libraries and library members. It replaces such programs as LUX, LDIR, LSWEEP, and LU301. For com- plete details on the program, see my previous tutorial. NULU11 corrects almost every possible criticism of the original NULU10. The only real problem with NULU10 was that it did not check CRCs. As a consequence of this, a library created with NULU and uploaded to an RCPM would result in a CRC error note when accessed by the RCPM's LDIR program. Though this caused no permanent problem, it was unnerving to the user who didn't know the source of the problem. And it was always possible that the library file was created by some other library manager and that an error DID exist. At any rate, the problem has now been corrected and NULU generates a CRC. The other objections this user had with the program originated out of a sort of greed: It was so good, why couldn't it do EVERYTHING? Well, now it can (almost). NULU was originally designed to combine the advantages of LU300 and LSWEEP (the latter a WASH/SWEEP/NSWP derivative for libraries). It lacked only a mass tagging facility and the ability to delete disk files (like all library managers, it could delete library members from the library). These facilities have now been added. For instance, if you download a library from an RCPM and want to place all of its files on a blank disk, all you need to do is bring up NULU11, open the library, log in the blank disk, and then tag all the files in the library. NULU then asks what operation you wish to perform; you respond with [E]xtract and give the drive/user number for the blank disk. If the files are squeezed, you use the [Q] command (for unsqueeze) and the drive/user info. Before performing the mass tagging operation, you are able to access the sup- posedly blank disk to see if it has any files on it. If it does, and if they are unneeded, you can [Z]ap any or all of them. This is easy since NULU allows the user to use wildcards, eliminating the need to list each file to be zapped. To make things even better, NULU11 now allows such video attributes as reverse video or inverse video. The NULU11A.LBR comes with an installation program for making these changes to fit any computer. It also comes with MLOAD23.COM, the latest version of MLOAD from Ron Fowler. Similar to MDMLNK, MLOAD should be considered a complete replacement for DRI's 'LOAD.COM', as it is much more flexible. (The NULU11A library does not come with documentation for MLOAD23, except as necessary for patching NULU; you will have to access MEX1xx.LBR for that documentation. Unfortunately, it may be contained within MEX1xx.DOC. If so, let me know, and I'll either extract it from that file or write some docs on my own.)  contained within MEX1xx.DOC. NULU.DOC Documentation for NULU.COM as of 02/01/85 Version 1.1 NULU.COM and NULU.DOC are both Copyright 1984 and 1985, by Martin Murray, P.O. Box 35972, Dallas, TX 75235. Both may be used freely for non-commercial purposes, but neither may be sold, included in a package for sale, or used as an incentive to buy, by any person, organization or corporation without prior arrangement with the copyright holder, Martin Murray. Furthermore, Martin Murray will bear no responsibility for losses resulting from the use or inability to use this program. NULU.COM may not be distributed without NULU.DOC, nor may the copyright messages be removed from either file nor caused to not be displayed. ACKNOWLEDGEMENTS This program would not have been possible were it not for the elegant work of Gary P. Novosielski and those others working with the LU library structure. Additionally, I would like to thank the people who have supported the development of NULU in a variety of ways, from suggestions to financial contributions. All comments (good, bad and disasterous) are welcome. Special thanks to Keith W. Antcliff of Mead, Washington for his development of NULUTERM.ASM, a patcher overlay, and to Ron Fowler of Nightowl Software for his gracious permission to include MLOAD23.COM in the NULU release library. Honors for Courage go to Dennis Recla and Sigi Kluger for having the guts to "risk everything" by testing NULU and offering suggestions and pointing out bugs. INTRODUCTION NULU is a complete replacement for LU and LSWEEP. Weighing in at 15k, it includes all features of both programs and then some. It features: Two operation modes with a full menu for each LU style CRC support and verification Viewing and printing of member files, unsqueezing when necessary Extraction of member files with an option to unsqueeze where appropriate Bigger libraries, up to 800 members or more depending on available memory Automatic member sorting, all members kept sorted at all times Faster reorganization Enhanced error handling Access to deleted members Optional read only patch CP/M Plus support General compatibility with LU and NSWEEP syntax Numerous user patches DIFFERENCES BETWEEN NULU AND LU NULU now supports LU style CRC verification. However, because of my desire achieve an orderly transition between the old and new versions, NULU 1.1 will not verify CRC values for members whose initial values were 0000h. In other words, if you use NULU 1.1 to open a library last changed by NULU 1.0, a CRC error will not be the first thing that you see. After changing the library with NULU 1.1, if the directory CRC does not match the next time the library is opened, an error message will be generated. The assumption behind all this is that the likelyhood of a file having a CRC of 0000h is extremely small. In version 1.2 of NULU, all library members will "enjoy" CRC validation even if their initial CRC was 0000h. NULU To the best of my knowledge, NULU will run on any system running CP/M 2.x or higher, however it has only been tested by me on the Osborne 1 and the Osborne Executive computers. It is written entirely in 8080 assembly language. A complete discussion of the nature and advantages of library files is beyond the scope of my endurance, however a short recap is in order. A library file is a single CP/M file which maintains 1 or more smaller files as its members. Each file is written into the library and recorded in the library directory. After that, it may be accessed for viewing, printing, or execution, or may be extracted from the library to assume the status of a stand-alone file once again. The reasons for doing this are many. For one, under CP/M each file occupies a minimum amount of disk space. This amount can range from 1k to 16k, depending on the system. Even though a file may only be 1 byte in length, it will still occupy the minimum required amount; the rest of the space is wasted. Putting these files in a library minimizes the possible waste to 127 bytes. Each file also occupies a directory entry. On most floppy disk systems, the maximum number of file entries per disk is 64. By including a file in a library the directory space it used to occupy is freed for another file. Additionally, using library files can simplify the process of categorization by subsuming several files of similar types or subjects into one file. However, there are also dangers associated with using libraries. The main one is that if a library file is lost or damaged, all of the member files are lost as well. The solution to this problem can be summed up in one word: BACKUP. NULU probably isn't perfect, and we all know that disk systems aren't, so backup your important libraries, please. I don't want to hear any sad stories. Almost as important as backing up libraries is the use of discretion when deciding what to put into them. Let's face it, if a file is in a library it is not as easy to get to. If you need to get to a file every 15 minutes, it probably shouldn't be in a library except as a backup measure. AN ASIDE CONCERNING FILESPECS When specifying a filespec, wildcards may be used freely, however, unlike most programs, NULU doesn't insist that a "." separate the filename from the filetype. For example, the filespec "**" means the same thing as "*.*" to NULU. On the other hand, the filespec "FRED.TXT" should be typed in just like that. "FREDTXT" would make NULU think that no filetype had been specified. The rule is simple: use a dot any time you like, but it is only strictly necessary when it is needed for clarity. When specifying a drive and/or user area the syntax is very liberal. "A15:**" means the same as "15/A:*.*", as does "1A5:**". The colon is absolutely necessary. If a different user area is desired for the default drive, the drive specifier may be omitted, as in "15:**", just as the user area may be omitted as in "A:**". If a drive/user specification is made, but no filespec is indicated, a filespec of ????????.??? is generated. Therefore to indicate the default drive, current user area, and a filespec of ????????.???, just type a colon by itself (e.g., ":") ! NULU OPERATION NULU may be invoked with or without a command tail. A command tail can consist of any combination of valid NULU operators up to 128 characters (the limit imposed by the CCP. Once NULU is running, command lines can be as long as 254 characters.) As in LU, all NULU commands are preceded by a dash. This is a copy of the menu for the command mode of operation: -A Add members -B Brief toggle -C Close the library -D Delete members -E Extract members -F Filesweep mode -G Get filespec -K Krunch the library -L List members -M Menu -N Rename members -O Open a library -P Print members -Q Unsqueeze members -R Replace members -T Replace/Add members -U Drive/User change -V View members -X Exit NULU -Y Disk directory -Z Zap disk files -< Redirect input -> Redirect output Commands may be strung together, each terminated by a space. They are processed left to right. All characters are converted to upper case. The default drive/user area are displayed along with the name of the current command mode each time the console is prompted for input. The commands will be explained in order of their appearance above. All items in [square brackets] indicate optional parameters. The word "filename" refers to an unambiguous file specification, while the term "filespec" refers to a potentially ambiguous file specification. Filespec parameters enclosed in (parenthesis) indicate references to deleted member files. Three dots ("...") after a parameter indicate infinite repetition. During the execution of most commands which receive an ambiguous filespec as a parameter, entering a ^C at the console will interrupt the current process. COMMANDS -A ADD MEMBERS Syntax: -a filespec[ filespec...] Use this command to add files from disk to the current library. NULU will make a series of passes through the directory, adding files as it goes, until the list of matching files is exhausted. If matching filename already exists as an active member in the library, its name will be displayed and the file will not be added. In all file addition and replacement operations, if a deleted entry of identical size can be located, that disk space and directory entry will be used rather than allocating new space for the file. This means that it will be necessary to reclaim wasted disk space less often. An LU style CRC will be generated for each file added. -B BRIEF TOGGLE Syntax: -b This toggles the prompting mode. The release version of NULU is setup to print the full name of the current mode for a prompt, as in "-ADD MEMBERS A0:>". If BRIEF is turned on the user will simply see "-A A0:>". NULU may be permanently patched to default to BRIEF ON or OFF. See NULU MODIFICATION. -C CLOSE THE LIBRARY Syntax: -c This command closes the current library, writing its directory to disk if any changes have been made to the directory. The library directory is NEVER written except when the library is closed, so be sure to do it. If you forget to do so and remove the disk, NULU will prompt you for the disk again and will attempt to recover. Some other operations that cause the current library to be closed are: -k, -o, -x -D DELETE MEMBERS Syntax: -d filespec[ filespec (filespec)...] Member files matching the given filespec will be given deleted status in the library directory, except when the filespec is enclosed in parenthesis. In that case matching deleted members will be given active status. That is, they will be undeleted. If the filename of a matching deleted member file already exists as an active member, the filename will be displayed and the file will not be undeleted. If the member file being deleted has a size of zero sectors, its entry will be entirely REMOVED from the library directory, thereby creating a new, free entry. -E EXTRACT MEMBERS Syntax: -e filespec[=newfilespec filespec...] Use this command to extract active member files. If extraction to the current drive/user area is desired, no further syntax is necessary. To indicate another drive, however, a destination filespec may be included following an equals sign. Example: -e **=a5: would extract all active members to drive A, user area 5. Files may be renamed as well as redirected by indicating a filespec along with, or in place of, a drive user specification. Examples: 1. -e *asm=*bak 2. -e *asm=5:*txt 3. -e fred.txt=sam.txt jane.inf=c8:girls.dbf The examples would produce the following results: 1. Extract all files with a type of .ASM to the default drive/user renaming them with the filetype of .BAK. 2. Extract all files of type .ASM to user area 5 of the default drive, renaming each with the .TXT filetype. 3. Extract the member file FRED.TXT to the default drive/user under the name of SAM.TXT, and extract the member file JANE.INF to user area 8 of drive C: with the filename GIRLS.DBF. The only redirection rule to remember is that if a destination filespec is entered it cannot be any less ambiguous than the source filespec. That is, "*asm=*bak" is valid while "**=*bak" is not valid. During extraction, a CRC is generated for each file. After the destination file has been closed, the CRC so generated is compared to the CRC for that library member that was stored in the library directory, if that value was non-zero. If the results are not identical, an error message will be displayed before the next member file or filespec will be processed. The erroneous destination file will not be deleted from disk by NULU as a result of this error. -F FILESWEEP MODE Syntax: -f This command places NULU in its second operational mode: the filesweep mode. This allows the user to move through the directory of active member files as if they were individual files being examined by a program like NSWEEP. The filesweep mode's command list is as follows: A Next member B Previous member C Close the library D Delete member E Extract member F Find member L Log new drive/user M Mass operations O Open new library P Print member Q Unsqueeze member R Rename member T Tag member U Untag member V View member W Wildcard rename X Exit NULU Y Disk directory Z NULU command mode ? Menu Because of the extreme similarity between these commands and the commands of NULU's command mode, only a short description of each command will be given. A -- Advance to next member (spacebar, cr, or lf will produce the same result) B -- Back up to previous member C -- Close the current library D -- Delete current member file E -- Extract current member file (prompt allows redirection) F -- Find first member matching input filespec L -- Change drive/user defaults (returns file pointer to the top of the file list and untags all member files) M -- Mass operations on all tagged files (allows Deletion, Extraction, Printing, Unsqueezing, or Viewing) O -- Open new library (closes the current library) P -- Dumps the current member file to LST: (unsqueezes if needed) Q -- Extract current member file, unsqueezing if necessary (prompt allows redirection) R -- Rename current member file T -- Tag current member U -- Untag current member V -- View current member file (unsqueezes if needed) W -- Wildcard rename (prompts for oldname & newname) X -- Exit NULU (closes all files) Y -- Get disk directory for default drive/user (returns file pointer to the top of the file list and untags all member files) Z -- Return to NULU command mode (current library remains open) ? -- Print the filesweep mode menu If, when the filesweep mode is entered, or after a library has been closed, there is not a library currently open, the filesweep mode will prompt with: No library open. and will accept only the following commands: L,O,X,Y,Z,? Likewise, if a library is open but only has a directory with no other active members, the message No member files. will be printed and only the commands listed above will be accepted. During filesweep operation, each file will be listed in the order in which it is found in the directory, along with the size in K that the file would occupy if it were extracted to the default drive. If the filesweep mode is terminated by a return to the NULU command mode, any commands that followed the -F command on the previous NULU command line will be executed. -G GET FILESPEC Syntax: -g filespec NULU will search for the filespec indicated. If it is found, processing continues. If not, the user is prompted to insert the disk containing that filespec. The drive is then reset and search again. The program will prompt forever until it receives the proper filespec or until a ^C is entered, forcing NULU to continue without the filespec being found. This command can be useful when attempting to control NULU through a submit utility like DRI's SUBMIT.COM. For example, one might type: nulu -o a:asm -g b5:-work.005 -e **=b10: -g a0:-5.005 -x After loading, NULU would open a library called ASM.LBR on drive A: in the current user area. Next it would search user area 5 of drive B: for filespec -WORK.005 until it was found. Then all active member files would be extracted to user area 10 of drive B:. Finally, NULU would search user area 0 of drive A: for a filespec called -5.005 until found. Then NULU would terminate. Notice here that the ASM.LBR didn't have to be closed before the search for the final filespec because no change had been made to the library directory. If a change had been made, after the new filespec had been loaded, NULU would have demanded the disk with ASM.LBR back so it could update the directory. Therefore the GET operation would be effectively negated. -K KRUNCH LIBRARY Syntax: -k[ -: WAIT FOR RETURN Syntax: -: -failure mode This command will force NULU to wait for the RETURN (0dh) character to be input to the console device. If a RETURN is received, the balance of the command line will be ignored. If a ^C is entered, the remaining commands on the line will be executed. -; COMMENT Syntax: -; comment about this kludge of a JCL This command will cause NULU to ignore all text appearing after the command on the same physical command line. These items together form what I know to be a very incomplete and awkward JCL, or NCL if you will. However, I have found them to be of use in building simple interfaces between people and NULU. More and better stuff to come. -> REDIRECT OUTPUT Syntax: -> filename Syntax: -> With the first form of this command, NULU output will be sent to the filename indicated. The default filetype of ".NOF" will be used if no filetype is specified. If the file already exists, it will be deleted. All special characters that the user may have patched into NULU (see below, NULU MODIFICATION) will be sent to the file as well, with the exception of the EOF character, 26 (1ah). The only output not echoed to the file will be output caused by viewing or printing a member file. Even if the console has been turned off by an NCF file, all console output will continue to be sent to this file. The filename passed must be unambiguous. Under the second form of this command, the current output file, if any will be closed. When NULU is caused to terminate, the current output file is closed along with the current library, if any. ERROR HANDLING NULU should never crash to CP/M anymore. When NULU signs on, it redirects the warm boot BIOS vector, thereby preventing NULU termination due to BDOS errors. Under CP/M Plus, it goes even further, shutting down the console error messages, handling them internally. Therefore, if NULU attempts to perform some operation on a drive where no disk is mounted, one could reasonably expect (on a 2.2 system) for the BIOS to issue some error message. The user then hits RETURN or ^C and NULU should recover. It may think that the disk was full, when there really wasn't one there at all, but it should still take the proper course of action needed to recover. ERROR MESSAGES Most NULU error messages are of the form: ERROR XX: Explanation where "XX" is some number from 0 to 255 and "Explanation" is a clue as to the nature of the error. Each error message is listed below, along with an explanation. Suggestions about ways to handle the error are given when appropriate. ERROR 63: ambiguity error Problem: This means that you entered an ambiguous filespec where an unambiguous filename was required, or that the destination filespec in an extraction or unsqueeze command was less ambiguous than the source filespec. See -E EXTRACT MEMBERS for complete details. ERROR 68: disk full Problem: The library disk became full during file addition or KRUNCHing or the destination disk of an extraction command became full. Solution: If the error occurred during KRUNCHing, NULU should have recovered by itself, reopening the old library. If it did not recover, then you removed the original disk before the KRUNCH was complete or a serious read error occured. If the error occurs during file addition to the library, operation should not be impaired, but no files that required additional disk space can be added to the library until some disk space is cleared. Note that deleted entries can still be overwritten by incoming files as long as the file sizes match. The incoming file that caused the error will be recorded in the library directory as a deleted entry. If the error occurs as a result of attempting to replace a member, the original library member should be unharmed and left as an active member. If the error occurs during file extraction or unsqueezing the destination file is deleted because it is an incomplete file. Extraction can continue as before. ERROR 73: invalid drive Problem: An invalid drive for your system was chosen (see below, NULU MODIFICATION) or a letter higher than "P" was indicated. Solution: Choose another drive or re-patch NULU. ERROR 74: checksum error Problem: During the unsqueezing of a file, the internal checksum generated did not match the explicit checksum stated in the file's squeeze decoding table. Solution: Get a new copy of the member file. Yours has been trashed somehow. ERROR 75: CRC error Problem: When each member file is added to a library, a CRC is created for it and stored in the library directory. If, upon extraction or unsqueezing, the CRC generated at THAT time does not match the original CRC in the directory, that means that the sectors wherein that library entry resides have become corrupted. There is an outside chance that the CRC entry in the library directory has become damaged instead, however that condition would probably also generate ERROR 107. ERROR 77: not enough memory Problem: An attempt was made to open a library with a directory too large to be accounted for with available memory. Solution: Open the library on a computer with a larger TPA and reorganize it so it can be handled by the smaller system. ERROR 78: user cancel Problem: No problem. NULU is simply letting the user know why an operation has been cancelled. Most operations which work on ambiguous filespecs may be interrupted by entering a ^C during their operation. (You may have to hold the key down a while.) The KRUNCH operation may be so interrupted as well. ERROR 79: library is READ ONLY Problem: An attempt was made to use a READ ONLY copy of NULU for some other task than merely viewing member files. ERROR 83: can't make file Problem: An attempt was made to create a file on a disk with no free directory entries. ERROR 85: file not found Problem: The filespec indicated for some operation could not be located. ERROR 86: CP/M 2.x or higher required Problem: An attempt was made to run NULU on a system with an CP/M version number of less than 2.0. ERROR 88: seek to unwritten sector Problem: A sector required to gain access to a file is indicated by CP/M to be unwritten. Solution: The library directory or perhaps the library itself has become trashed at some point. Deleting the entry and KRUNCHing will probably render it harmless, but the safest course to take is to obtain a fresh copy of the library. ERROR 100: no library directory Problem: The file specified could not be opened as a library file. Solution: The directory could be bad, but most likely the file simply isn't a library. Check it out with some disk editor like SPZ or EDFILE. ERROR 107: library directory CRC error Problem: The CRC that was calculated and stored for the directory the last time the library was modified does not match the directory CRC calculated as the library is opened this time. Solution: With most libraries, this error will be valid. In that case, the only remedie is to obtain a new copy of the library. However, there are some libraries that were created with LU, and then modified but never KRUNCHED by NULU 1.0. In that case, it is likely that the old, original CRC stored in the library directory would still be there, even though it is way out of date. My suggestion is, when you first get NULU 1.1, go through all of your .LBR files, if you were using NULU 1.0 previously, and KRUNCH them. This way you will know later on that the CRCs stored in each library should all be accurate. ERROR 115: bad syntax Problem: Improper syntax was used to attempt some operation. ERROR 116: squeeze decode table Problem: A file has a squeeze decoding table, but at some point the table is trashed or perhaps is missing. Solution: None really; get a new copy of the file. If your Data Buffer Size has fallen below 9 sectors, then the reason might be that the entire decode table could not be read into memory. ERROR XX: undefined Problem: Unknown. Solution: Write down all information presented on the terminal. The number following the word ERROR is especially important. Get the information to me. Mail it or call and I will try to help. NULU MODIFICATION Patches are listed in the order in which they appear in NULU.COM. Each patch is explained and the default values are listed immediately next to the patch address. All addresses are absolute hexadecimal. Patch Default Explanation 00149h 00h Non-zero makes NULU use the Z80 instructions LDIR and LDDR for data movement. 0014ah 50h Number of characters each full video line can contain. Not necessarily the same as the number you can see. 0014bh 50h Number of characters visible on a line at any one time. 0014eh 07h This byte indicates the number of files that NULU can have open at any one time. The base number is 4 and should never fall below that. The value of 3 has been added to it to allow 3 level nesting of NCF files. If the NCF value is increased or decreased, identical changes should be made to this byte. (See Patch at 0018bh.) 0014fh 000fh This obscure word controls the number of relocatable tasks that can be controlled by the NULU memory management routines. Because each file is a relocatable task, the same modifications for the previous byte apply here. The base value of this word is 000ch and should never fall below that point. (See Patch at 0018bh.) 00151h 10h Number of contiguously numbered disk drives in your system. If you have drives A and B, set this value to 2. It will prevent you from accessing an invalid drive. 00152h 20h Number of contiguous user areas that NULU will be allowed to access. Under normal CP/M 2.2, Turbo-Dos or a ZCPR system, I understand that this number can be as high as 20h, which is the default. For CP/M Plus or most systems that use time/date stamping this number should not exceed 10h. 00187h 00h Set to a non-zero value to make NULU READ/ONLY. No operators will be executed that could change the library or disk directories in any way. 00188h 00h LU.COM was set up to exit automatically if a command tail was used when LU was invoked. With the release version of NULU, it takes the -X command to exit. Set this byte to a 01h to get it to act like LU in this respect. That is, it will automatically exit after executing the passed command tail, if one was present. 00189h 01h Set to a 00h to start NULU with BRIEF mode ON (long messages not printed). 0018ah 01h Set to zero to prevent users from being able to ESC,RET from the PROMPT AND CHAIN TO PREVIOUS MODE prompts in NCF files. (Be sure to also change the values at 0014eh and 0014fh.) 0018bh 03h This byte indicates the nesting level allowed for NCF files. I have no idea what the upper limit is, but watch that Data Buffer Size! 0018ch '-O',0 Starting here are 39 bytes in which any valid NULU operators may be stored. This line will be automatically executed when NULU is loaded, even before any other parameters passed on the command line. This might be used to create a version of NULU that, after loading, sets the drive/user defaults to B0:, prints the menu, scans the drive for library files, then switches to the open library mode. That command line would look like this: -U B: -M -Y *LBR -O Notice that all characters in this line MUST be UPPER CASE. The entire line MUST be terminated by a null byte. Only 39 bytes are available for text...not a byte more. The 40th byte is for the null terminator. 01944h 0005h This is the address of the BDOS vector. All operating system calls go through this address. If you have some weird, non-standard CP/M implementation you can patch this to try to make NULU work with it. 01a83h 3ch This is the number of lines that NULU will print on each page during member file printing. Change this value in accordance with the line printer patch below. Starting at 01a60h are 5 data areas used to define strings needed to control the console attributes. Each string is preceded by an identification byte and a byte indicating its active length. Then 5 bytes are available for the actual definition. Therefore a total of 7 bytes is consumed for each video control. The attributes are, in order: DIM or REVERSE VIDEO ON (DIM is preferred) DIM or REVERSE VIDEO OFF UNDERLINING ON UNDERLINING OFF CLEAR SCREEN Each control becomes active as soon as it is patched in. Likewise, there is one string defined for the LST: device that will be issued immediately before printing a file. It begins at 01a86h and has the same format as the strings above. FINAL NOTES Please report any bugs or problems to Martin Murray, P.O. Box 35972, Dallas, Tx 75235 or call (214) 351-6117, EVENINGS AND WEEKENDS ONLY. Please specify the version of NULU with which you are working. I anticipate being able to respond with greater speed to any bug reports with this version. The problem with updating version 1.0 was that I didn't have the source code anymore! I was off working on another version. As always, donations will be gratefully accepted. It took a lot of work to produce NULU and if you enjoy it and it benefits you, don't hesitate to show your appreciation with a check! Note: I no longer work for SYSTEM SOLUTIONS, so please, no checks made out to them. I am now working for INOVA, a new company founded specifically to support 8-bit computers running CP/M. Look for new and exciting retail products from that source. (The preceeding has been an official plug.) NEWSOFT}; NULU11F1.ASM NULU V1.1 Patch Fix # 1 5-Feb-85 ; This patch fixes some of the bugs found in NULU11.COM, with regard ; to unsqueezing/extracting files. This patch file is applied to ; to NULU11.COM, and produces NULU12.COM. This file has an unknown ; origin. (See NULU12.NOT) ORG 10BH DB '2' ORG 114H DB '3' ORG 0A4AH DB 0,0,0,0,0,0,0,0,0,0,0,0 ORG 06A7H NOP JMP 17D4H CALL 32D4H JMP 26E1H ORG 1E46H CALL 2B47H CALL 31B7H RZ CALL 3239H CALL 31DDH PUSH PSW LDAX D CALL 324DH POP PSW JMP 06ABH END F NULU 1.2 (02/03/85) Copyright (C) 1984, 1985 by Martin MurrayUPPF D!9"2*L&###:MO *<"!9*ODM) "<+ã-OWORK-LBR.$$$ NCF NOF LBR Add membersBrief toggleClose the libraryDelete membersExtract membersFilesweep modeGet filespecKrunch libraryList membersMenuRename membersOpen a libraryPrint membersUnsqueeze membersReplace membersReplace/Add membersDrive/User changeView membersExit NULUDisk directoryZap disk filesRedirect inputRedirect outputREADYNext memberPrevious memberClose libraryDelete memberExtract memberFind memberLog new drive/userMass operationsOpen new libraryPrint memberUnsqueeze memberRename memberTag memberUntag memberView memberWildcard renameExit NULUDisk directoryNULU command modeMenu?DIJKMNOSUVXdktsambiguity errordisk fullinvalid drivechecksum errorCRC errornot enough memoryuser cancelNULU is READ ONLYcan't make filefile not foundCP/M 2.x or higher requiredseek to unwritten sectorno library directorylibrary directory CRC errorsqueeze decode tablebad syntaxundefined <".=}1-<:I!"{_Tm<k V>VI2*#"<"!r+s22ͺ0!N#=_< 6!"5>2yʛ:2S͂" Û2&2l*5>u!I͞2$%;$>2$%!313 <>D4:<2*313 closed. 2:<Į*~-#~Gx<*6élS! -!3Console input to be received from >OͿ'ʎ:2,2*ZéI6l:*ēIV! !3Console output to be sent to ͮ*2̈́9*3>KͿ'Iʔ2:<2<ͩ!7l!S1>UI!",!3Press ^C to stop...ͮ*:\!- = ,:*\*+̀.u!3Deleting: ͵->PD16*,#",6l*5% :Hʜ\I%I͂8I!3Undeleting...͏% !3 ͧ%%*%*%*%..%"%"% 13 cannot be undeleted--name existsþ &þ8~(#>);6 +6>2H:X jX x<6:S2S> ͦ;2 2 Iz } !܆3~;>܆3# y½ >=2 *3>2 Õ 13 | Õ ͽ21M2:R;=*3/*3M2ú0e#?!:2H<2ɗ2[ l̈́9**5>͚9I*5"J*"P!"̀/!"4 >O2# :*8:*;$yʷ`i#" " ͂8@ͽ<͏% s#r#6 #ͧ%:=P7s#r#ÿ ͂8@8!"*4  *3! yʷ͸: "4 <"D 2v <"U *3!F13.>4!4&-.."5!m 4>  7>k2s 13 : C3O5ABCDEFLMOPQRTUVWXYZ? x y;!1:*4 # *4 +} * ð Á 13elete?2- *D Õ ͧ%!3Deleting: %:>OI> &13xtract to: \- 6 - 13ind what? \- O >*w#w#w%- ͏%BK͸:K *  13Log drive/user: \ʁ "5͹Á >*!3Delete, Extract, Print, Unsqueeze, or View (DEPQV) Enter one: C32+ O5EQDPV- y;# !3Destination drive/user? \\b,I- ->:;#6H >D7 # 4&.."5$ # :+ Dʕ - 13Library name: \ʁ "5SÁ - 13Unsqueeze to: \- - 13ename to: \- <Õ 5* >*"22 13 Tagged = F>k;æ 5 :> - !3Old filespec: \- <<O_<"5!3New filespec: ë a Á I8!"5!"̀- >!/45C3O5LOXYZ?y?{ { ͥNULU Filesweep Menu>͆32 2C>28 !\%> 2 No members. g÷No library open. g'313+9 !" 2$!#" ͸:<>2 #N#F<*4 ##~" #<**5"]*<"5*͇5!"5*>"#;}6#"?O:# ʂ2y2# 5BCFKLMXY>y5'":;HJʂ:ͩÂ" ͩÂI3 lͩSͮ*921Insert disk containing !3 and press RETURN̈́9͚9!="5"!~6‚>!3-::# ʟ5ABCDEFGKLMNOPQRTUVXYZ<>?O!͚7͓75(5â;> ;b>:\313:>>X*5::*|&n5]7 Â!͇5"*528>*7:"͕"!+" } ͷ3!" !" 6:,2&>D4O*5> Hw# C͔>4&2͚9ͳclosed. 2!ó7!3CONOUT file 13l!3 Krunching...* ̈́9;$`i""͂8ͽ<͏%4&#x<͂88G+!-!<͓7Vͮ*D1>͆3!-13will be krunched to >W\3>͆3*3ʎ!"ͧ%"\"!!V1!"."%!<":}"*%}:13 CRC ERROR-Continue?2}!}+"!3 Copying: !#" &#!x<"$_<-ͧ% s#r###"`&M+>5+͡(5+y*!"!!"IMŸ*,DM!"\>Oq)}*,"(.4ʟI&2* ̈́913Krunch aborted...reopening old library>K2# *5!"5S"5ͩ8*I}*,DM*\>Oq)}\D1G+!>:;#>.5 213 krunched.ͩ8!"I*3IL% >N!͆32>-2C>28m!%>?2'3313 >͆313Sͮ*M2͘2ͺ0é2>/*>G+*<-V1Cannot find !3Replace it and press RETURNʤ1®*:# 5KOX©!3NO LIBRARY OPENéSͮ*! $ʲ213 open. (Buffer size: *,* ,:>͖:F13 sectors)ͩUI:>UI!<> 5(513 not found. To make it, enter the number of entries to allow.!"!3 Press RETURN now to abort making the library. Allow how many entries: I~~<~#(5É!> /4ʑ}4}>NI͸:ڪ͸:ҼDM!=;6#D<"l33> b3*5% :H 33I!3Library '322'3O>?>4B*3>;y;> ;(5#:222+:<2<*3(52;*D4ʚ*5͇55~:Úͩ*6" :*ē*3>M2>2:.=1m<*P ͓7*2</<!"*P D<2}.q͓7*2bk.s#r.l*5% *<͸:>sI:HB$I>Oó>Ró:>OIé!3Brief now O:2š>N;73FF:<2<:# 5'":BHIJLMOUY<>>>?2# G+*<-> 5(5͂" >7 5'":;ABCDEFGHJKLMNOPQRTUVXYZ<>?:*͠&n>*u3.z6 i O5n<Sgb? a 6  \ S u { :CV <  "\b,:ͥ:"))j&*!;>PͿ'>2<͇:͸:'*}+ !.͋&" *+6s#r*+",&*$M¹<ͽ<>KD1*&>M ͺ02"!3Library: ̈́*!3Name Index Size KiloBytes CRC2$%>!%"<͏%,ͧ% xͶ>͆3!3DIRECTORY >͆3Û*3%>3ͭ>3ͭ>3:=P7ͭ>3:<>2<*%<4>0 7(52<Û"<*U%jͶ*f%ͶͶ>͆3!3Active sectors !3Unused !3Total <2$%>͆3ͳ(5<4> 72w:+2^'՗%<͂8< =b,%\BKJ.%ͮ*!3Extracting...!H'"{/:^'*:%͏%$. <8!3 ͧ%*%-\13 to `&<͡(`I&!H'"͏***"L'*+ "I'><´."I'tIô*+:"(!<̓<**:>tI!*/"͠&÷&:^'**,*%}:>KI\b,BK! =J.I&\92͵-!<->K;Ϳ'I* ̈́9:<&%*,>͖:!DMq)(G+ͷ1921M2ë%!3Deleting...͏%<ͧ%!3 %y–> &͞p> &p*%+">2< *+"!6A !3Active entries: *N%F13, Deleted: *_%F13, Free: *\&F13, Total: *%F13.ɗ2<>OͿ'!"Z&"^&"\&(~ #~ P###<<"&))j&"%"!9" ͚9;*<>Ϳ'>m:͸:!"+{DM>O!(*+",%{:>kI*+ ~B& x:+ >M&>d̈́9&%:+2^':͏%͡(g I!H'"{/" !͏***"L'*+ ."I'Ž tIû *+:"(13---> !<(5**:>tI!*/" !o!:!>͆3!3^C=abort,^X=next file,L=next line,=next page>͆3>2*!*3!!! !I; >=2*!o!A!:2*!> b3C35 LA!!V!:`!e!j!<`!>,!>,! :<2" =b,! ="<+!*$-!",}2":>#!"$2$%#>#*,#", =!*$ ,6#̓<=$!!*$>.;#$!Õ!!"$#*3%1"<"$$1">Oc"Rc"%13 already exists--not added.Õ!:"Rc" =͵-13 not in library--not replacedÕ! =Ͷ.Җ"͵-13: Cannot add an 8 megabyte file!Õ!"#$> &<$͏%"ͧ%"#*#:¤"L#*#>D"13No room for:  =͵-< #*\&}>f #13No directory space for: "*$"#*%:L#*#$> &•!2"IÕ!*,+}>U>2$%!\"<+$e#13Replacing: t#13Adding: "# &! =͓7̓<͵- q#p###"## =1*,DM!"#>5+͡(5+#¹<"<*#>Oq)"#*#"##õ#!> &q#p<$͏%ͧ%͸:#"$#!+|#ͧ%!'$.7LBR!<%% =b,\J.%͂8!3Renaming...͏%$!3 ͧ%*%! =J.*%*%`i..%"%"%$-13 can't be renamed--new name existsq$<2<-13 to ! _<-q$%8͞<2m%\b,ͽ^%!#"N%!"U%l%!#"_%!"f%&%s#r#&%"%DM"%y>U!|+"%!^#V#"%!:<*,DM"a&4&"%<~ <<<"%"d&"g&%-*+ " &6#6*,DM;"4&>2<~!Z&&&<##&^#Vr+swB&+>͇:*+!Z&Q&<##G&4W!A9 p9~<͠&7#|&xʝ&~͠&ʞ&# Ì&<͏***w:<&**+|&''<*+#"+<<&>&͏*<'< ':***;''2+͝+*+8<<*+DM͙.G+*+s20>D¹*͡(*+ "I'͏***"L'>*H'¹<>*+DMͧ' '*ʤ'!Ì'#"+*+͸:>Rڽ'*+ ~ɿ2^("D(`i>ͥ:>͇:"'(:+**+:NG~'#'>F:N<*;*94PY: (>͖:>͇:$(>$($(>MDM:1(BK*<*+s#r`i" ,͝+!:^(=$xe-*+* ,*+͂8*G+!$>;:+*>2+:<2<* ,DM*+ɷʷ("("(`i"(!",{*,!>O("(*(:"(U+M¹<+")"8)!"1)OM+PY* ,:L)>͖:|>Mg)DM*+s2G+!#")̓21Q)_+g2!#"1)!+"8)|c) x^))>Rg)>X*)+")d)>Md)͖:|>L)DM*+s2G+!#")̓2 1)g2!#")!+")|) x)â)>R)>D*)+"))>L)<*<*+:DM*)*)#!"+*!"F*͏***>͖:|>Mu:NO+*< ͂8+*+O:N+>B+!+ "+!++ "+<"+4 "+!"?,!s2b,<͘22\,3,<ʷ2O!+"?,}1,y!O #b,><÷2:<2Y-> 2<2<20-22S-! >  ;_<>:;,6#}4ʸ,|¸,:Rg}Ҹ,2S-~,6#ʹ,@O:Q$-y,1 ~#*,.,-,?y->,,x, ,+-?-2< -20-x+->I,-=>C-> ?bk#;y2;!#>w>2<7#ͰPD11Kʒ-2-1>Mʱ-1!<-(5ɗ-> !<->:;#5(5͘2:<> 2<2o&1@w#4D< 6:#x<6.#x<62<÷2# >._<~> 2z.#~?h.?g.2z.~=T.#PYx<>?< #~?ʒ.<….<`i|g}oҫ.# ."<1͘2#<# .+V+^<ý2<v͸: /2t/22/<"/!"a/<͓7 <͸:$/"//ɗ/>t/!]/>>/=22/>m/Y/m/P/>==22/:O>„/ʾ/O>=2t/yO!ғ/##^#Vzs/y2q/zʭ/{/*a/:>ʾ/>J<1@2/@@0<13Drive : Total *=]T*=#zW{_0+/:=0)= 0F13k, Used :F13k, Free F13k<<:.=1{0*<*͖:<ͺ0<*=#ڗ0W+|ʦ0ʌ0zÒ0`i:=ʵ0)=°0D÷2͘2!s2<<÷2<<<͘2<<>S÷2͘2<<>U÷2͘2\$_< _<mx<\<<>U÷2=w:%<<_:Qc2<<<<*< s2"<<<͘2!!s#r#6ý2222!#~2~w"2ý22>2!w <<_ <<1<13 (y/n) C3N3Y3;>͆3>2R;*313*313 (5(5:ð7<<*<#" ;3:<2 ; 4*L4++"L4D4##"L4O:L!=#6+qY4w <^#6{<<4(5՗24D<42"54: ;> ;T55:<5G:R;55> ;> ;55~#;)5+ͽ5"5=~ʮ5ʬ5#Ͳ5ʕ5ͽ5y~5 #Ͳ5½5<7O;U~̰Mڡ8*9*O:¦8>TDM#"9*!9 w#s#r9ͽ<" 9: 9"88!|!#~#09~;9͸:##9++~<2V9~>2h9bk"^9<>=2V9!##"^9><<;*9}: :<*9:ڕ9"9<>M!"9շ9_29DM99ʱ9W:929ñ9!9>՗2:>x:xGyO99!:4)=9:>y"Q:}|B:3333xD:՗yOxG{_zW:z[:}o|g!"Q::*Q:<`i͇:DM`i͖:DM͇:}/o|/g#ɷ}o|g=È:|g}o=×:|g}oҳ:#=æ:PY:}o|g>7<>N~w# x:<_ <<<y;͑< ;;_:<< Q; Q; U;Q; <:R;= GU;>G:J^;x2R;< _~;͓;:;=ʁ;o;͕; ʍ; >2; ><2;:<<W:K ʽ;ڼ;ҭ;ý; y \ ?ʻ w# !ͼ ? !ͼ !)ͼ !ͼ :5͡ :6:6͡ :71!\ !2*.+"{46![5+ ~y!"y4!4w_#~ ʸ A:4~~# ¼ > \ ?ʻ w# !ͼ ? !ͼ !)ͼ !ͼ :5͡ :6:6͡ :71/Rͣ:Z !H 4~?! 2rGD͑$%*."p&:.2r&%:C[!:A ' :B ' Gï Z80MR VER 1.2 FILE 12345678 ?ʻ w# !ͼ ? !ͼ !) 0000 ERROR(S) ASSEMBLY COMPLETE !"*y4~!}! ~# Nwy#" j ͆go2Z22C "D "F "A 2&"&"&"&!+~m~#d^F#N#">2>2*y4*!~̢! Ã:<2*:> > > >2> :PG $0ɃUNDEFINED@@DOUBLE DEFINEDERRORREDEFINEDPUBLICEXTRN#ASEGCSEGDSEG SYMBOLS!Z w#”!I 4͌*!͏n!.:C !.*_: : #':C ; &m:C !2"_!.EJECT AHEADIN:INCLUDLIST WMACLIS^2I I:H rPe2Be2<ɗ2I 2"_!|.&>OFF ON >>:!!w# !# 2: 2!:93A<2.!"> w#w#w!" ;&!4933w#93 LIBH# 4^#V*_~ ##.!ʡ ʃw# o>GxPWʡ v6 #6 #622"_:=!6 #6E#6N#6D#Ã2R :# Æ   ;&!4933w#93 LIBH# 4^#V*_ : E: X E k:_J :I :H *}>+ʉ2Y :J ʩ:B '2B :A '2A G:B:8/*C *}o:</P!J >6 #=2I 6 #6 #6!P " : X :0  !' " m&!K z' {' *  8 0w2I #: E: X E k:_J :I :H *}>+ʉ2Y :J ʩ:B '2B :A '2A G:B j D͆ ! > ~ 4 6_' " m&!K z' {'* >\   O >X !4 ! ~#" !" !  !2! 6A#6Z#6M2 : @ڞ ʞ Ҟ 2  ͭ  ø INPUT FILE OPEN ERROR ! > ~ 4 6_' " m&!K z' {'* >\   O >X !4 ! ~#" !" !  !2! 6A#6Z#6M2 : @ڞ ʞ Ҟ 2  ͭ  ø INPUT FILE OPEN ERROR ! > ~ 4 6_' " m&!K z' {'* >\   O >X !4 ! ~#" !" !  !2! 6A#6Z#6M2 : @ڞ ʞ Ҟ 2  ͭ  ø INPUT FILE OPEN ERROR ! > ~ 4 6_' " m&!K z' {'* >\   O >X !4 ! ~#" !" !  !2! 6A#6Z#6M2 : @ڞ ʞ Ҟ 2  ͭ  ø INPUT FILE OPEN ERROR ! > ~ 4 6_' " m&!K z' {'* >\   O >X !4 ! ~#" !" !  !2! 6A#6Z#6M2 : @ڞ ʞ Ҟ 2  ͭ  ø INPUT FILE OPEN ERROR ! > ~ 4 6_>*w#"!/ø OBJECT WRITE ERROR >2D: ZZ>22! !2!>r!22: @ڒʒҒ2!"ø OBJECT FILE CREATE ERROR HEXOBJ>~ 4 6_>*w#"!/ø OBJECT WRITE ERROR >2D: ZZ>22! !2!>r!22: @ڒ*>ʿ:ʲ>û!—!:~#"!"29ͭ ! 2ø 12345678ABC INCLUDE FILE OPEN ERROR !/ø OBJECT WRITE ERROR >2D: ZZ>22! !2!>r!22: @ڒ*>ʿ:ʲ>û!—!:~#"!"29ͭ ! 2ø 12345678ABC INCLUDE FILE OPEN ERROR !/ø OBJECT WRITE ERROR >2D: ZZ>22! !2!>r!22: @ڒ*>ʿ:ʲ>û!—!:~#"!"29ͭ ! 2ø 12345678ABC INCLUDE FILE OPEN ERROR !/ø OBJECT WRITE ERROR >2D: ZZ>22! !2!>r!22: @ڒ*>ʿ:ʲ>û!—!:~#"!"29ͭ ! 2ø 12345678ABC INCLUDE FILE OPEN ERROR !/ø OBJECT WRITE ERROR >2D: ZZ>22! !2!>r!22: @ڒ*>ʿ:ʲ>û!—!:~#"!"29ͭ ! 2ø 12345678ABC INCLUDE FILE OPEN ERROR !/ø OBJECT WRIT>*W7w#"7!rø PRINT WRITE ERROR >2: Eڜ>2:2! !2!6P#6R#6N26: @2!"ø PRINT FILE CREATE ERROR >:W!/ø OBJECT WRIT>*W7w#"7!rø PRINT WRITE ERROR >2: Eڜ>2:2! !2!6P#6R#6N26COND \ELSE END ENDC ENDIF IF \ASEG rCSEG wDATA DB DDB DEFB DEFL JDEFM DEFS 5DEFW $DS 5DSEG |DW $EJEC AENDM EQU QEXTRN LIST LOCAL MACRO NAME NLIST ORG XPUBLICSPAC TITLE X*}&: &!&!# 933w#q &#,62R͌m͏!Xzs*4 UxBp#@\p##̐w# @"4̓!Z4&*46#"4*_: &!~ʽ~~#Ô&ʺ33$YM &!&!# 933w#q &#,62R&*|&#&933&!*4+6#933Qw#A6# '  ' 6#"4,"^#V*_|:C ***4>q#p#=œ"4"#'!*4"6#:' :' 6#"4̓*#"*P~#Z{  ʟ# ͵*Q#,+33>?͵͵~#F͵9~&#>#͵*>+F+N=_"4""*+"G*~#ʎ€~# ڊ͵Î> > "ͣ G> ͵q# '93,!;w# &'w#'w##~'w+~'w*{4~ k*{4*y4!w#xLyL*y4 "y4*{4 "{4!2*4s#r̓:4<*y454!9%ø MACRO OR EXPRESSION NESTED TOO DEEP-STACK OVERRUN #!"""*}4"4*{4~ 6#6#R.:J y&|%!!I 4m+}%ɗ2I 2! ڈw#HÈ!'2 &ڈ'ʁw&#f'u6 #6 # ˆ6!2#'#'>2j2:33 &3*w4 ~w& &93,í#'>2j2:33 &3*w4 ~w93,93AO!0 q93,Mͳ'M0'M͠':&g &O͐&#'>~>~>2&ʈ2j#'2: "_!.&INPAGEPAGE û:&&!#=q: &#''M͆$,2.2.' &2.͆$'!Y$6 $6#'M#,'#'My&&͐&!&;&R.*D #"D :C "F R.y&}>2C *D }&*F }|:C 2C *D |&+"D *F +xy"F 2C #'R.͠'y2.*}&*D }&!Z4#'!,#~2 #^#V*_'!Y$~':AQQo&)^#V!bʅ;E<͔# T&~`j G#b+/{:~; З/ʙ*_bE"_ͩ}͔#;™^.ͮ;0 ڼ))))oͪ-:.&$@$,:. 8&&G: 2 ͪ-:.&: ͔##!>;ͪ-,: :. 8&& 2 ͜-:.&:AS *.:.Ok &:.&:.o:.g++|&y&|<~ =&}>2.&".|2.: ͔#͆$$%&͜->͔#:.':.'*.|'}''>F-#>Vʔ#>^Ô#z-:.!@2 :. !:.a&>͔#: Ô#̓#&&>͔#Æ$z-:.!A2 :. 9!:. >͔#$͜-:.̓#a!:.["$: *2 5#G: Ô#͜-:.':.'*.}Ǵ': Ô#z-:.&:.&*.}&>o: 2 !͜-:.̓#!O: 2 >͔#: Ô#: >2 5#Ô#z-:. l":. ʾ":.̓#2"@2 :.̓#ұ":.["$: p&5#:.̓#$2 :.["$͔#: pv&͔#$mo?m>>:.@!#Œ":.̓#Җ":.["Ң"!#:."#ɇ͔#͆$͔#>6͔#$͆$G: v&Ô#:.@&!%#:."#G &x"&<&O ~Ĕ##~&Ô#:K[*{**!1!!2CS"s"":.["&͔#: ͔#͆$͜-:. d#: F͔#͆$:.̓#5#G: Ô#z-:.'P#$kŠ#>& (?*I-̥#2#!#Ê$@Ҵ#''''''!.#!.:Y$O~O#^#V#"}$p$> ${ZW> $>0$'y!Z$o|gF>0$'AON%{̈́&>0Q$lyN%z̈́&f$ yB2X y z$ZP!.Ê$!.#*y4:j"w4ͩ$%$%!~s&2!o&6#w#w#6*w4 "w4~ N> $>$y$$#^#V:1%>.%$%:*&%:*&ƌ2r&"p&}%%"p&>ƀ2r&>2o&*w4s&2:H :>y»%}:o&ʡ%ҡ%_:&G:r&¡%*p&&z¡%{¡%s&*o&&w!o&4%&"p&>2o&y2r&2s&%"s&yO:&2r&&"p&>2o&:r& %>2o&*}$u&2%:o&*p&U\"p&!o&~G>::j6&~O#&2o&~W&#O6&2o&W&> > Z& h&0:&G:r&¡%*p&&&#͐&A&ʲ&"&:&ڨ&:&"&&"&"&:&&:&"&:H &*&ME*&*&*&:J '++~A2J 2I ## : 3'͍'͠'ͪ'3:H l'*w4y_'ѱw#s#r&~@w>H&y&yѩ&z&{&!P z' {' y&: &͍'͠'ͪ'3*w4~'O_'y|ѱw#s#r())4))))))@*e*e*++$+L+++g,,,,,,,,ADC:HL,BC/ED4A;ADC:HL,DE/ED5A;ADC:HL,HL/ED6A;ADC:HL,SP/ED7A;ADD:HL,BC/9;ADD:HL,DE/19;ADD:HL,HL/29;ADD:HL,SP/39;ADD:IX,BC/DD09;ADD:IX,DE/DD19;ADD:IX,IX/DD29;ADD:IX,SP/DD39;ADD:IY,BC/FD09;ADD:IY,DE/FD19;ADD:IY,IY/FD29;ADD:IY,SP/FD39;CCF/3F;CPD/EDA9;CPDR/EDB9;CPI/EDA1;CPIR/EDB1;CPL/2F;DAA/27;DEC:BC/B;DEC:DE/1B;DEC:HL/2B;DEC:IX/DD2B;DEC:IY/FD2B;DEC:SP/3B;DI/F3;EI/FB;EX:(SP),HL/E3;EX:(SP),IX/DDE3;EX:(SP),IY/FDE3;EX:AF,AF'/8;EX:DE,HL/EB;EXX/D9;HALT/76;INC:BC/3;INC:DE/13;INC:HL/23;INC:IX/DD23;INC:IY/FD23;INC:SP/33;IND/EDAA;INDR/EDBA;INI/EDA2;INIR/EDB2;JP:(HL)/E9;JP:(IX)/DDE9;JP:(IY)/FDE9;LD:(BC),A/2;LD:(DE),A/12;LD:A,(BC)/A;LD:A,(DE)/1A;LD:A,I/ED57;LD:A,R/ED5F;LD:I,A/ED47;LD:R,A/ED4F;LD:SP,HL/F9;LD:SP,IX/DDF9;LD:SP,IY/FDF9;LDD/EDA8;LDDR/EDB8;LDI/EDA0;LDIR/EDB0;NEG/ED44;NOP/0;OTDR/EDBB;OTIR/EDB3;OUTD/EDAB;OUTI/EDA3;POP:AF/F1;POP:BC/C1;POP:DE/D1;POP:HL/E1;POP:IX/DDE1;POP:IY/FDE1;PUSH:AF/F5;PUSH:BC/C5;PUSH:DE/D5;PUSH:HL/E5;PUSH:IX/DDE5;PUSH:IY/FDE5;RET:C/D8;RET:M/F8;RET:NC/D0;RET:NZ/C0;RET:P/F0;RET:PE/E8;RET:PO/E0;RET:Z/C8;RET/C9;RETI/ED4D;RETN/ED45;RLA/17;RLCA/7;RLD/ED6F;RRA/1F;RRCA/F;RRD/ED67;SBC:HL,BC/ED42;SBC:HL,DE/ED52;SBC:HL,HL/ED62;SBC:HL,SP/ED72;SCF/37;+:;BIT @!CALLDJNZ7 IM IN JP JR  OUT !RES !SET !RLC !RRC !RL !RR !SLA !SRA (!SRL 8!LD @!ADC u#ADD u#AND M#CP M#OR M#SBC u#SUB M#XOR M#RST l!INC A!DEC A!ͪ-!.. ~6#†-,ʜ-&ͪ-;!&-:.k·->&2.m-n-:.&&y}'|&".<'!ME".".(.>@2..)&2:33A..3y ..:. 2.R.|>.}F.:.2.:.G*.:.O̓x(2G.xŸq.GU.".2.y2.33".:.O:.ʒ..".:.O*.:.GU.-:.k&2.*.*.!0..O!C/~.#F#~#foɷ####.2:73 ?/.?/!l/33~>/O#/ѱ6/###/F#~#fo\0*1/1+0-0&1^"1=\0>u0<0NOT 0RES 0MOD 1SHR F0SHL .0AND 1OR "1XOR 01EQ \0GT u0LT 0UGT 0ULT 0HIGH/LOW /y&>1x&:.2.‡.2.lgÇ.y&>1x&:.2.‡.2.gÇ.y&x&Ç.ͅ1x0xʇ. )<0ͅ1xʇ. |g}oM0ͅ10}o0!Ç.!Ç.ͅ10+|o0i0ͅ10|o0i0ͅ10i0|i0o0ͅ10o0i0ͅ1|'.!z0͞10Ç.&Ç.>1 Ç.O10Ç.yoxgy&ͅ1x&}/o|/gÇ.ͅ1xgyoÇ.ͅ1xgyoÇ.ͅ1xgyoÇ.:.|1y|1o1:.|1o1:.o1:.2.:.2.&:.O2.:.2.Oo1ͅ1͞1Ç.!x@3yʳ1 é1@3ͅ11Ç.ͅ11*.Ç.}1&!".|x@3ᯰ@3 1@3 ".@3".*.@3".*.93!'K2(g23:҇20I3Ç2 '_2%$&eoK2'U2:2=222R.:2<22)& 2–2:33$&3yʲ2y &>&>O!33.2~# y2!2:!2!93+6 2933:30 3w #9333_Z?139013%$!ɿK2(g` >O>GͶ393Hʈ3͡393Oʈ3Qʈ3͎393Bʈ3393Dʈ33&33!930)oÑ3!930)))oä3!930 3 ))))où3!930  o& 33!3!33" 4*y4"w433~O4+4#4*w4N#~#fo*w4 4;4ø NOT ENOUGH MEMORY *y4"w4"y4:4<54w#f46#p#p44[544B C D E H L A AF BC DE HL SP IX IY I R NZ Z NC PO PE P M $ 558 5*#(:=9**ڴ5`i6#658 5* +" *+"* 6*+(:*#(:g585 6!**$|6 6*~#fo 4846!6rc͍͐=9*" *"*#~#fo !(:!"*6!v6!9Read error or no EOF!9DM͜:͐͐`is#rzº6!ñ8͜:͒#! s#r͐6͐~#fo! s#r|0"2͐ ! s#r*#~#fo"͜:*|7͜:* !(:*~#fo"**78! s! n}–7! ^#Vr+s6 ͐! ~#foڐ7!͐ ͐%͐ ! s#r! 6 ! ^#Vr+s! ns͐! ~#fo7͜:!͐ ͐%͐ ! s#r*#(:'77! ^#Vr+s6͐͐ ͐͐ |g}o|<8!?8!! s#r͜:͐͐͐ ͐%s8ͅ:x8*6͐6͐6͜:͍͐*2ͭ1*23͜:!ñ8! 9!9DM͐n&*n&͜:!8*&*&+wSwappin Documentation for ZASM Introduction ZASM is a Z80 macro assembler with syntax closely following RMAC and MAC. It assembles standard Z80 mnemonics into an Intel Hex format. The resulting file (which has a .HEX extension) can be translated to a .COM file with LOAD.COM (on your CP/M disk that you received with your Kaypro) if it ORG's at 100 (hex). If it ORG's elsewhere the .HEX file may be read into memory and manipulated with DDT.COM. Why Z80 The assembler you received with your Kaypro (ASM.COM) is an 8080 assembler. The Kaypro actually runs a Z80 c.p.u. The reason this is possible is that the Z80 actually runs all of the 8080 instructions but in addition there are more instructions unknown to the 8080. The extra instructions were designed for increased speed, easier programming, and more compact code. For this reason it is to your best advantage to program in Z80 code for the Kaypro. Z80 Mnemonics Z80 mnemonics are a great improvement to 8080. Thought was given to logical, universal mnemonics that are much easier to remember and use. I learned assembly language on the 8080 and resisted the change to Z80 at first. But after using Z80 mnemonics for a short time I became very unwilling to do anything with 8080 code. Now I run almost every 8080 program that comes in through a 8080 to Z80 translating program (XLATE2.COM). Even if you are writing programs for the 8080 it is still far easier to write in Z80 mnemonics. There is a special listing command that flags Z80- only instructions for this very reason (described later). Macros Macros are a way of writing subroutines in assembly language and then calling the subroutine by entering the 'macro name' into the source. The macro may be called as many times as necessary anywhere in the program. When the assembler is operated, the lines of source code that make up the macro will be inserted into the file by the assembler. Note that using a macro does not reduce the size of the object code that is produced since all the lines of code that make up the macro definition are assembled into the object file at assembly time. This is called expanding the macro. By using the *MACLIST ON option, the lines of code produced by the expansion of a macro are listed in the .PRN file. Then the code can be examined and at times optimized in certain locations. Assembler Syntax Components and General Form of Assembly Language Programs The structure of an assembly language program is more important to an assembler than the actual instructions you write. A program that would run beautifully can fail to assemble if the syntax is not correct. A program with no errors at assembly time is not guaranteed to run correctly ( or as expected ). The assemblers report of 0 errors means that it understood all of the instructions you entered, not that your program is logically correct. Fields Assemblers are almost always field oriented some to a greater degree than others. A field is a flexible position in the line of code with respect to the right margin. This assembler recognizes 4 fields in an assembly language source line. label operation operand comment The assembler knows when it has reached the end of a field when it sees a 'field delimiter'. This can be a space or a tab for this assembler though some require tabs so it is a good habit to always use tab characters as delimiters. Label Field A symbol is a word used to represent a number. Symbols that refer to addresses are called labels. The assignment of a number to a label can either be defined as the lines below TEN EQU 10 START EQU 100H or calculated by the assembler as an address for branching instructions. START: JP FINISH NOP NOP FINISH: JP START Also notice that the label is optional and is only for the programmers conveniance. Labels must appear in the label field. Some assemblers allow you to indent labels but this one won't. START EQU 100H START: JP FINISH Will give you a problem. The EQU must be in the operation field and the label in the label field. Most assemblers require that the undefined labels be terminated in a colon but this assembler does not require a colon for symbols in column 1. START JP FINISH will not generate an error but colons are another good habit and also make your code more readable. This assembler only examines the first six characters of any label or symbol so that if the following labels were used in the same program FINISH1 EQU 1000H FINISH2 EQU 2000H A 'D' error (duplicate symbols) would be generated. Operation and Operand Fields The operation field follows the label field and may either contain a Z80 op code mnemonic, an assembler directive (or pseudo op), or a macro call. Assembler directives and macros are described later in this file. This field will usally contain the mnemonic for a Z80 instruction. Some Z80 instructions only use this field while others contain an operand which will be located in the operand field. GOBACK: OR A RET Z LD A,0FFH RET The way Z80 mnemonics were designed, the number of nmenonics in the operation portion of instructions is kept to a minimum since the operands really distinguish the differences between similar instructions. The first line above is a good example of this. The operation is an 'OR' operation on the number in the accumulator (implied) with another register. It makes sense that the operand should be the register containing the other number in the 'OR' operation. In Z80 assembly language this is the case. The first line OR's the accumulator with the accumualator (used to see if the accumulator contains a 0). Notice that the second line uses the operand field to contain the condition for a conditional jump (in this case the zero flag). The third line uses the operand field to contain both the target register for a load and the number to load. The last line is an unconditional return which uses the same operator (RET) as the conditional return but does not use the operand field because there are no conditons to place there. This structure makes Z80 programs much more readable than 8080 programs as well as making the instructions easier to remember. The following is the same code written with 8080 mnemonics. Notice the different philosophy on the use of the fields. GOBACK: ORA RETZ MVI A,0FFH RET Also the LD command in the Z80 is used for all data moves while 8080 users must remember a different mnemonic for different types of moves. 8080 Z80 MOV H,A LD H,A MVI H,00 LD H,00 LXI H,0000 LD HL,0000 The Comment Field Comments are not limited to the comment field and can actually be the entire line. All assemblers recognize the semicolon as the beginning of a comment and most ignore the rest of the line. For compatability between assemblers it is a good to begin comments with a semicolon. But for this assembler the following methods of inserting comments are good syntax. 1. Beginning a line with an '*' in column one causes the assembler to ignore therest of the line except if one of the assembler commands (described below) immediately follows the asterisk (no embedded spaces). 2. A semicolon will cause the assembler to consider everything following it to be considered a comment. 3. The first blank encountered following the beginning of the operand field will cause the assembler to consider the rest of the line to be considered a comment. ****************************************** ;An adventure in Comments * A short tale START: JP FINISH ; finish this story NOP ASM can't handle this FINISH: RET Thats all folks Would assemble with no errors. Comments do not appear in the object code. Numbers and Bases The assembler will accept numbers in HEX (base 16) BINARY (base 2) or DECIMAL. Hex numbers must end with an H and binary numbers must end in a B. Decimal numbers should have no suffix letter. When a HEX digit begins with a letter, the letter should be preceded with a 0. LD A,0F3H OR 01001000B LD HL,4000H+28 Commanding the Assembler The primary responsibility of the assembler is to translate Z80 mnemonics into object code. The assembler also recognizes certain commands and directives that the programmer can use to manipulate the assembler's output. These are often referred to as 'pseudo-ops'. This assembler requires these pseudo-ops to be in upper case. A description of these commands follows: ORG ; Sets the origin of the code or section of code. Actually ; it sets the reference number that the assembler uses to ; generate addresses for labels and instructions. ; could be a number or a previously defined symbol. ; e.g. ORG 0 ; ORG START END ; Determines the end of an assembly language program. ; if present describes the first executable instruction of ; the program. DW wordlist DEFW wordlist ; Both of these have identical meanings. In assembly language ; programs, 8 bit values are called bytes and 16 bit ; values are called words. Addresses are assembled with the ; most significant byte (MSB) following the least significant ; byte (LSB) because this is how the microprocessor handles ; these values. The DW pseudo-op allows us to describe these ; values in the way we are used to (MSB first) and still ; assemble correctly for the processor. ; DW 8000H ; will assemble the same as ; DB 00H ; DB 80H ; ; If more than one word is to follow a DW following values ; should be seperated by commas ; e.g. DW 8000H,0F000H,0000H ; The wordlist can also be symbols ; e.g. START: JP FINISH ; DW START,FINISH ; FINISH: JP START DDB wordlist ; This pseudo-op is a way of assembling 16 bit values with ; the MSB first (opposite of DW). ; DDB 8000H ; will assemble the same as ; DB 80H ; DB 00H DB bytelist DEFB bytelist DEFM bytelist DATA bytelist ; These four pseudo-ops have identical meanings. The bytelist ; can be one byte or multiple bytes seperated with commas. ; The bytes can be any mix of symbols, ascii characters in ; quotes, or numbers on the same line. This is familiar ; code in Kaypro programs: ; ;ESC EQU 1BH ;CLRSCR EQU 1AH ;CRLF DDB 0D0AH ; ; ORG 100H ; ; LD DE,MES ; LD C,9 ; CALL 5 ; RET ; ;MES: DB CLRSCR ; DB ESC,'=',12+20H,12+20H ; DB '*Your Message Here *',CRLF ; DB '*Or Here*','$' ; ; END ; ; If you've been waiting for an example to enter assemble ; and run, try this one out. Just enter it (with out the semicolon o course) us fil typ .AZM an ; assemble it using the same conventions as with ASM.COM. ; (For example: ; A>ZASM YOURFILE.BBZ, i.e., ; Input YOURFILE.AZM from Drive B:, output .HEX file to ; Drive B:, and suppress the .PRN file.) ; ; The program clears the screen, positions the cursor at ; row 12 column 12 and prints the message using the BDOS ; function 9 (print string). ; ; The symbol CLRSCR is defined by an EQU to the hex code to ; clear the screen on the Kaypro (^Z). ; ; The cursor positioning sequence on the Kaypro consists of ; the two lead-in characters (escape and an equals sign) and ; then the row+20H and the column+20H. ; ; Since the next bytes are just a carriage return, line feed ; pair the second part of the message will appear at the ; left side of the screen. We could include extra DB's to ; position the cursor anywhere on the screen if we like. ; ; BDOS function 9 (summoned by loading a 9 in the C register ; and calling 0005H) prints the characters it finds at the ; address in the DE registers until it sees a '$'. DS n DEFS n ; Reserve data space ( n bytes ). This is used to position ; allocate or label data storage space in a program. n is ; a number describing the number of bytes reserved. ; DS 16 ; Reserves 16 bytes. The next instruction will be located ; 16 bytes from the location counter when the DS was ; encountered. label EQU ; ; The EQU sets the label equal to the expression. The ; label should not be terminated with a colon when used ; with an EQU pseudo-op. The label can be any symbol ; (byte or word) and the a number in any of the ; following forms: ; SWEET EQU 16 ;decimal ; SWEET EQU 10H ;hex ; SWEET EQU 00010000B ;binary ; ; With this assembler the EQU must be located in the ; operation field. ; A label defined with an EQU cannot be redefined later ; in the program. label DEFL ; ; This assigns the value of the to the label like ; the EQU pseudo-op but a label defined with a DEFL can ; be redefined later in the program. *INCLUDE *INCLUDE ; This pseudo-op causes the assembler to stop assembling ; lines in the file it is presently in and read in the ; file . It then begins assembling lines in this ; included file until it reaches the end of the file when ; it returns to the original file and resumes assembling ; lines in it once more. The can be any CPM ; filename.ext though if the extent is left off it looks ; for the given filename with an extent of .LIB. The asterisk ; must appear in column 1 with the word INCLUDE immediately ; following with no embedded spaces. ; ;*INCLUDE DRIVER.AZM ; will begin assembly on ; the file DRIVER.AZM ;*INCLUDE Z80MACRO ; will begin assembly on ; the file Z80MACRO.LIB ; Conditional Assembly Pseudo-Ops............................................ IF ELSE ENDIF Conditional assembly is a way of writing a single program so that it can be assembled different ways or with different options by only changing a couple of lines of codes. When the assembler encounters an IF pseudo-op it evaluates the symbol . IF is non-zero it assembles the following lines until it reaches an ELSE or an ENDIF. If is 0 the lines are ignored until the assembler encounters an ELSE or an ENDIF. If the ELSE is encounter the assembler begins assembling lines again. The ENDIF pseudo-op causes the assembler to resume assembling all lines. You can not have an IF without an ENDIF. Any of these pseudo-ops must appear in the operation field. TRUE EQU 0FFH FALSE EQU 0 KPRO2 EQU TRUE KPRO10 EQU FALSE IF KPRO2 BITPRT EQU 1CH ELSE BITPRT EQU 14H ENDIF Operators.................................................................. Operators allow the programmer to make the assembler do arithmetic and logical operations. They are usually used to manipulate operands or generate symbols. Some of them are used to create tests for conditional assembly. There should be no embedded spaces when using these operators as the first blank encountered terminates the operand field. The operands may be symbols or numbers in any of the bases. The operators supported by this assembler are: Arithmetic Operators + ; arithmetic addition. - ; arithmetic subtraction * ; arithmetic multiplication / ; arithmetic division (truncating the result) Logical Operators (Bit Manipulation) & ( or .AND. ) ; logical AND operation ^ ( or .OR. ) ; logical OR operation .XOR. ; logical exclusive OR operation \ ( or .NOT. ) ; logical inversion .SHR. ; shift left operand to right by right operand .SHL. ; shift left operand to left by right operand .HIGH. ; byte value is assigned the high byte of a ; 16 bit value .LOW. ; byte value is assigned the low byte of a 16 ; bit value Conditional Assembly Operators ( return TRUE or FALSE to IF ) = ( or .EQU. ) ; logical equivalence > ( or .GT. ) ; greater than .UGT. ; unsigned greater than < ( or .LT. ) ; less than .ULT. ; unsigned less than Listing Options Pseudo-Ops................................................. There are a number of listing options. All of these options only effect the print file (.PRN). The options include some for debugging as well as some for the actual format of the file on the page. The .PRN file is the basic tool assembly language programmers have for examining the output of the assembler. The pseudo-ops beginning with an asterisk must begin in column 1. *EJECT ( or EJEC ) ; The next line of the listing should be placed at the top ; of the next page. *HEADING ; Place the text ( following this command ) on the top of ; each page. Usually used to date the listing file. TITLE 'text' ; Place the text in the quotation marks (either double or ; single on the top of each page in the listing file. SPAC n ; Leave n blank lines in the listing. Used to leave white ; space in the file with out using a page break. *LIST ON *LIST OFF ; Turn the listing on or off. This is usually used to omit ; long comments or certain sections from the .PRN file. *MACLIST ON *MACLIST OFF ; Turn the expansion of macros on or off. Seeing how the ; macros are being expanded is handy for optimizing code ; but can waste paper when that is no longer the area of ; interest. LIST options NLIST options ; These pseudo-ops allow you to turn any of the supported ; listing file options on (LIST) or off (NLIST) without ; changing the other options. Both of these pseudo-ops ; must be followed with one or more of the following option ; letters. If these pseudo-ops is used some options are ; on by default ( marked with (on) in the following list. ; ; A ; List all bytes in DB, DW, DDB, etc. Otherwise ; ; only the bytes that can fit in one line are ; ; included in the listing ( others are implied ). ; B ; Place symbol table into object file. ; G ; Place system generated symbols into object files ; I (on); List lines of conditional code following a false ; ; conditional. If off only the code actually ; ; assembled is listed. ; M (on); Expand macros in listing files ; O (on); Produce an object module. That is show the bytes ; ; being generated by the assembler otherwise just ; ; the source and (optionally) macro expansions. ; R ; use absolute displacement for JR and DJNZ ; S (on); List source code in listing file ; T (on); List symbol table in listing file ; X ; Generate and list cross references in listing file ; Z ; Generate an error for Z80 only opcodes. Allows you ; ; to write in Z80 mnemonics for an 8080 processor. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Error Reporting ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: When the assembler is unable to understand what you are instructing it to do it generates an error message. These are almost always due to typo's or bad form. It displays the error code below and the line the error was found on to the console and also displays the error codes in the listing file. D ; Duplicate symbol definition. You will see this error ; message if you do any of the following: ; Use the same symbol twice. ; FORMATX ; FORMATC ; will generate an error (only 6 significant ; characters). ; Upper and lower case symbols with the same letters ; FORMAT: ; format: ; are identical to the assembler. ; Assigning a different value to a symbol that was ; previously defined with a EQU pseudo-op. ; If you are going to reassign use DEFL. E ; Relocation error. I believe this occurs if the assembler ; cannot reassign an address as expected. F ; Format Error. You will see this if you break any of the ; rules regarding field use and macro format. K ; Keyword error. This means you tried to use one of the ; assemblers reserved words or pseudo-ops as a symbol. ; ORG: JP END ; NOP ; END: JP ORG ; is in very bad taste. L ; Label error. The attempt to assign a value to a lable was ; unsuccessful. Also remember that labels do not end in a ; colon when preceding EQU. ; START: EQU 100H ; is bad news ; START EQU 100H ; is perfect M ; Missing label. The symbol you are using was never defined. N ; Macro nesting error. Macros can be nested (that is a macro ; can call another macro) but if the nesting gets to deep ; the assembler will quit and give you one of these. Also, ; you can only call macros that were previously defined. O ; Op code error. If you see this, look in the operation and ; operand fields. Consult the mnemonic table. People ; switching over from 8080 will see a few of these. P ; Phase error. A 2 pass assembler builds a symbol table on ; the first pass and generates the object code on the second. ; If a number that it calculates for a symbol on the first ; pass does not agree with a number it generates in the ; pass this error is shown check the symbols in the line ; the error appeared. Q ; Questionable operand. Actually theres no question about it ; it is a bad operand. Typo's give you these as well as ; blowing op code format. Usally easy to find your mistake. S ; Syntax error. You broke one of the syntax rules described ; above. T ; Symbol table full. Not much you can do with this except ; pare down the code. U ; Undefined symbol. You used a symbol but forgot to define ; it in with an EQU. V ; Value error. Usually means you are trying to do a 16 ; bit operation with an 8 bit number or the other way ; around. Macros The macro is a powerful method of writing assembly language programs. It makes it possible to write assembly language programs in a way that resembles higher level languages. In fact by creating a library of macros you are in essence creating your own language, and your own compiler. Often times in assembly language (particularly writing for CP/M) each program contains source lines that are used again and again in other programs. By using macros the routines only need to be written once and then may be called in any program. The best thing about a macro library is that only the macros that are called produce object code. So there is no penalty in having a macro library that is large and complete even if you are only going to call one macro. Macros have a form that is unique and must be followed closely for correct results. The general form of a macro is name MACRO #parameter1,#parameter2,.... instruction instruction instruction . . . ENDM The name is the symbol that will be used to invoke the macro. MACRO is a keyword that will indicate to the assembler that a macro is being defined. The parameters always must begin with a '#' sign in macros and they are seperated by commas. The instruction can be Z80 instructions, or any of the assembler commands listed above incuding conditionals. The instruction can also be another macro call (called nested macros) but only if the nested macro has been already defined. The ENDM keyword tells the assembler that it has reached the end of the code that must be assembled when this macro is called. Do not use a colon behind the macro name. The previous message program example can be rewritten to look like this with macros. ORG 100H *INCLUDE Z80MACRO BDOS PRNSTR,MES RET MES: DB ESC,'=',12+20H,12+20H DB '*Your message here*' DDB CRLF DB '*Or here*' END With the following macro library called Z80MACRO.LIB ;Call Bdos function #FUNCT using paramater contained in #DE ESC EQU 1BH ; ascii escape CRLF EQU 0D0AH ; ascii carriage return line feed PRNSTR EQU 9 BDOS MACRO #FUNCT,#DE LD C,#FUNCT ; FUNCTION NUMBER GOES TO C LD DE,#DE ; GET PARAMETER CALL 5 ; CALL BDOS ENDM We could also rewrite the cursor positioning sequence into a macro. Note how just this small example can save us time in future programs. Also, the macro library is a great place to keep frequently used symbols like ESC and CRLF. But what about using address symbols in macros? How can we avoid the 'D' error if we call the macro more than once. The other keyword unique to macros is LOCAL. This makes the assembler generate its own unique label every time the macro is expanded in a program. Following the word LOCAL ( which must be on the second line of the macro ) are the symbols we want the compiler to generate unique labels for. These symbols must also be proceded with a '#' sign. AJUMP MACRO LOCAL #ADR_Z,#BACK OR A JR Z,#ADR_Z LD A,40H JR #BACK #ADR_Z: LD A,04H #BACK: LD DE,0 ENDM The macro itself is not really useful but it is correct and shows the use of local labels.