; ; ; GALLERY ; ; CALCULATES PRINTERS GALLERY ; FOR MAKING BOOKS AND NEWSLETTERS ; ; BY: ALAN W WARREN ; 866 WILLIAMSBURY - APT 168 ; PONTIAC, MICH 48054 ; ;-------------------------------; BDOS: EQU 0005H CR: EQU 0DH LF: EQU 0AH BS: EQU 08H ES: EQU 24H ORG 100H LXI H,0 DAD SP SHLD OLDSP LXI SP,STACK ; ; CHEAP CLEAR SCREEN TRICK ;-------------------------------; MVI A,50 CLR$SCREEN: PUSH PSW MVI E,CR MVI C,6 CALL BDOS MVI E,LF MVI C,6 CALL BDOS POP PSW DCR A JNZ CLR$SCREEN ; CALL PRINT$THIS DB 'How many forword pages? ',ES CALL GET$NMBR PUSH H ; ; WE WANT TO SUBTRACT NUMBER OF ; FORWORD PAGES FROM TOTAL PAGES ; LATER, SO WE DO 2'S COMPLIMENT ;-------------------------------; MOV A,H CMA MOV H,A MOV A,L CMA MOV L,A SHLD INTRO ;MINOR PROBLEM - INCREMENT NOT NEEDED ; CALL PRINT$THIS DB 'How many pages of text? ',ES CALL GET$NMBR POP D DAD D ; ; HL IS MINIMUM NUMBER OF PAGES ; NEEDED IN BOOK, GALLERY REQUIRES ; A MULTIPLE OF 4, AND WE NEED TO ; ROUND UP TO AVOID LOOSING PAGES ;-------------------------------; INX H! INX H! INX H ;ADD THREE PAGES CALL SLASH ;DIVIDE BY 2... CALL SLASH ;... NOW BY 4 SHLD SHEETS ;HL IS NUMBER OF SHEETS DAD H! DAD H ;SHEETS TIMES 4 IS NUMBER OF PAGES ; ; ; NOW TO PRINT WHAT GOES ON SHEETS ; BASIC FORMAT IS: (LP = LAST PAGE) ; ; FRONT SIDE BACK SIDE ; LP , PG1 :: PG 2 , LP-1 ; LP-2, PG 3 :: PG 4 , LP-3 ; LP-4, PG 5 :: PG 6 , LP-5 ; ETC. ;-------------------------------; INX H SHLD LAST ;DECREMENTING BEFORE PRINTING SHEET$LOOP: CALL PRINT$LAST CALL PRINT$THIS DB ', ',ES CALL PRINT$FIRST CALL PRINT$THIS DB ' :: ',ES CALL PRINT$FIRST CALL PRINT$THIS DB ', ',ES CALL PRINT$LAST CALL PRINT$THIS DB CR,LF,ES LHLD SHEETS DCX H SHLD SHEETS MOV A,H ORA L JNZ SHEET$LOOP ; FINISH: CALL PRINT$THIS DB CR,LF,CR,LF,ES LHLD OLDSP SPHL RET ; ; ; SUBROUTINES ; ; ; ; INPUT A NUMBER FROM KEYBOARD ; RETURN WITH NUMBER ROUNDED TO ; MULTIPLE OF 2 IN HL ;-------------------------------; GET$NMBR: LXI H,NUMBER LXI B,10 ;B=0, C=10 ; ; INPUT REQUEST ;-------------------------------; GET$DGT: PUSH B! PUSH H MVI C,1 CALL BDOS POP H! POP B ; ; CHECK FOR EDIT ;-------------------------------; CPI 13 JZ GOT$DGTS CPI BS JNZ GT$DGT$NM ; ; BACKSPACE KEYED IN ; NOT ALLOWED IF AT START OF ; BUFFER (B=0) ;-------------------------------; MOV A,B ORA A JZ NO$BS INR C DCR B DCX H JMP GET$DGT ; ; BACKSPACE NOT ALLOWED, PUT ; CURSOR BACK WHERE IT BELONGS ;-------------------------------; NO$BS: MVI A,' ' CALL PCHAR JMP GET$DGT ; ; OPERATOR KEYED IN NON-NUMBER ; BACKUP & HIDE WHAT HE DID ; (AND DO NOT PUT IT IN BUFFER) ;-------------------------------; DGT$ERR: CALL PRINT$THIS DB BS,' ',BS,ES JMP GET$DGT ; ; MAKE SURE DIGIT KEYED IN ; IS A NUMBER ;-------------------------------; GT$DGT$NM: CPI '0' JC DGT$ERR CPI '9'+1 JNC DGT$ERR ; ; DIGIT IS OK - PUT IN BUFFER ; AND GET NEXT ;-------------------------------; MOV M,A INX H INR B DCR C JNZ GET$DGT ;DO NOT OVER-RUN BUFFER ; ; ; DONE WITH INPUT ; NUMBER IS IN ASCII @NUMBER ; NOW WE READ IT BACK ; & CRUNCH TO BINARY ;-------------------------------; GOT$DGTS: CALL PRINT$THIS DB CR,LF,CR,LF,ES LXI H,NUMBER ;POINT TO ASCII BUFFER LXI D,0 ;START WITH ZERO GET$BINARY: MOV A,M ANI 00001111B PUSH H MOV H,D MOV L,E DAD H! DAD H DAD D! DAD H ;OLD NUMBER TIMES 10 MOV E,A MVI D,0 DAD D ;PLUS NEW DIGIT XCHG POP H INX H DCR B ;B CONTAINED NUMBER OF DIGITS JNZ GET$BINARY ; ; ; NOW FOR THE ROUND OFF ;-------------------------------; XCHG ;NUMBER TO HL INX H ;TO ROUND ODD NUMBERS UP CALL SLASH ;DIVIDE BY 2 & TAKE INTEGER DAD H ;MULTIPLY BY 2 RET ; ; ; PRINT FIRST PAGE NUMBER ; ACTUALLY ANY PAGE NUMBER IN ; FIRST HALF OF BOOK ;-------------------------------; PRINT$FIRST: LHLD FIRST INX H SHLD FIRST JMP PRINT$NUMBER ; ; PRINT LAST PAGE NUMBERS ; ACTUALLY ANY PAGE IN LAST HALF ;-------------------------------; PRINT$LAST: LHLD LAST DCX H SHLD LAST ; ; ; PRINT NUMBER IN HL ; IF NUMBER IS LESS THAN THE NUMBER ; OF PAGES IN FORWARD, THEN PRINT ; IN LOWER CASE ROMAN NUMERALS ; ; IF NUMBER IS LARGER THAN NUMBER OF ; PAGES IN FORWARD, THEN PRINT ; DIFFERENCE IN ARABIC NUMBERALS (1,2,3,..) ;-------------------------------; PRINT$NUMBER: XCHG LHLD INTRO DAD D JNC ROMAN INX H DEC$PRT: XRA A ;FOR LEAD ZERO... STA BLANK ;...SUPPRESSION MVI B,10 ;NUMBER OF SPACES LXI D,-10000 CALL DIV$PRINT LXI D,-1000 CALL DIV$PRINT LXI D,-100 CALL DIV$PRINT LXI D,-10 CALL DIV$PRINT MOV A,L CALL PRT$NUM JMP PRT$SPACES ; ; ; DIVIDE NUMBER IN HL BY NUMBER ; IN DE & PRINT RESULTS ;-------------------------------; DIV$PRINT: MVI C,255 DP$LOOP: SHLD NUMBER INR C DAD D JC DP$LOOP LHLD NUMBER MOV A,C ORA A JNZ PRT$NUM LDA BLANK ORA A MOV A,C RZ ; ; ; CONVERT BINARY NUMBER IN A ; TO ASCII & PRINT RESULTS ;-------------------------------; PRT$NUM: ADI '0' STA BLANK ;KILL LEAD ZERO SUPPRESSION ; ; COUNT CHARACTERS IN B ; AS THEY ARE PRINTED ;-------------------------------; CCHAR: DCR B ; ; ; PRINT BYTE IN A ON CONSOLE ;-------------------------------; PCHAR: PUSH B! PUSH D! PUSH H MOV E,A MVI C,2 CALL BDOS ; ; CHECK FOR KILL REQUEST ; FROM CONSOLE (CTL-C) ;-------------------------------; MVI E,255 MVI C,6 CALL BDOS CPI 3 JZ 0 POP H! POP D! POP B RET ; ; ; PRINT IN ROMAN NUMBERALS ; (READ THRU THIS & YOU'LL FIGURE ; OUT WHY WE DON'T USE ROMAN ; NUMERALS VERY MUCH) ;-------------------------------; ROMAN: MOV A,D ;UPPER BYTE TO A ORA A ;WE CAN ONLY WORK JNZ DEC$PRT ;WITH SMALL NUMBERS MVI B,10 ;MAX NUMBER OF DIGITS ; CK100: MOV A,E CPI 100 JC CK99 SBI 100 MOV E,A MVI A,'c' CALL CCHAR JMP CK100 ; CK99: MOV A,E CPI 99 JNZ CK90 MVI E,0 DCR B! DCR B CALL PRINT$THIS DB 'ic',ES ; CK90: MOV A,E CPI 90 JC CK50 SBI 90 MOV E,A DCR B! DCR B CALL PRINT$THIS DB 'xc',ES ; CK50: MOV A,E CPI 50 JC CK49 SBI 50 MOV E,A MVI A,'l' CALL CCHAR ; CK49: MOV A,E CPI 49 JNZ CK40 MVI E,0 DCR B! DCR B CALL PRINT$THIS DB 'il',ES ; CK40: MOV A,E CPI 40 JC CK10 SBI 40 MOV E,A DCR B! DCR B CALL PRINT$THIS DB 'xl',ES ; CK10: MOV A,E CPI 10 JC CK9 SBI 10 MOV E,A MVI A,'x' CALL CCHAR JMP CK10 ; CK9: MOV A,E CPI 9 JNZ CK5 MVI E,0 DCR B! DCR B CALL PRINT$THIS DB 'ix',ES ; CK5: MOV A,E CPI 5 JC CK4 SBI 5 MOV E,A MVI A,'v' CALL CCHAR ; CK4: MOV A,E CPI 4 JNZ CK1 MVI E,0 DCR B! DCR B CALL PRINT$THIS DB 'iv',ES ; CK1: MOV A,E CPI 0 JZ PRT$SPACES DCR E MVI A,'i' CALL CCHAR JMP CK1 ; PRT$SPACES: MVI A,' ' CALL PCHAR DCR B JNZ PRT$SPACES RET ; ; ; PRINT STRING FOLLOWING CALLER ;-------------------------------; PRINT$THIS: XTHL CALL STRING XTHL RET ; STRING: MOV A,M INX H CPI ES RZ CALL PCHAR JMP STRING ; ; ; INTEGER DIVISION BY 2 ;-------------------------------; SLASH: XRA A ;CLEAR CARRY MOV A,H ;UPPER BYTE TO A RAR ;DIVIDE BY 2, CARRY SET BY LOW BIT MOV H,A ;BACK TO UPPER MOV A,L ;LOW BYTE TO A RAR ;DIVIDE BY 2, OLD CARRY IS UPPER BIT MOV L,A ;BACK TO LOW BYTE RET ; ; ; DATA SPACE ; ; BLANK: DB 0 ; OLDSP: DW 0 INTRO: DW 0 LAST: DW 0 FIRST: DW 0 SHEETS: DW 0 NUMBER: DB 0 ; STACK: EQU $+128 END