;GRAFIX for M100/102 (Source code) ;base=GRFASM.DO(c)12/31/89 R H Pigford ;GRFAS2.DO Update 2/3/93 added ESCs ;For use with SKETCH.BA by R H Pigford. CURSON: EQU 4249H ;like ESC "P" CUROFF: EQU 424EH ;like ESC "Q" TOPRT: EQU 6D3FH ;A regis to LPT PLOT: EQU 744CH ;turn pixel on UNPLOT: EQU 744DH ;turn pixel off POSIT: EQU 427CH ;H=col,L=row pos LCD: EQU 4B44H ;A to LCD KYREAD: EQU 7242H ;like INKEY$ INLIN: EQU 4644H ;LINEINPUT KEYBUF: EQU F685H ;Kybd Buff start,0 CAPS: EQU 0FE8H ;2/89 P100 pg22 BEEP: EQU 4229H ;better than 7662H PUTTXT: EQU 11A2H ;to LCD point HL,0 ERAEOL: EQU 425DH ;Oppendahl pg225 CNVERT: EQU 08EBH ;ROMMAP pg 19 ORG 60000 START: JMP MENU GF: DW START ;Hold 5 addrs PF: DW PRFLAG ;for PEEKing BS: DW BUFFER ;by SKETCH.BA. BE: DW END FZ: DW FILLCD MENU: MVI A,1 ;Flag =1 when enter STA PRFLAG ; here. LXI H,0108H ;Start col 1, row 8 CALL GETROW MENU1: CALL CLR8 LXI H,MSG1 ;Point to msg CALL PUTTXT ;Send it to LCD MENU2: CALL GETKY CALL CAPS CPI 'P' ;print options JZ PSXY CPI 'S' ;save JZ FILBUF CPI 27 ;quit JZ MENU3 JMP MENU2 MENU3: CALL RSL1P MVI E,56 CALL PUTROW RET MSG1: DB 27,'pGRAFIX',27,'q',' ',171, DB 'RHP

rint ' DB 'ave ..',0 ;=== Puts LCD image into BUFFER: ;Save when RET to SKETCH.BA. ;PRFLAG =0 if so. FILBUF: CALL RSL1P MVI E,56 ;line to put row(0-63) CALL PUTROW MVI A,0 STA PRFLAG ;set pntr=0 for RAM LXI H,0101H ;start at 1,1 JMP SCNROW ;=== CALLed only from BASIC ;to fill LCD w/vals from .CO file ;found and pointed to by SKETCH.BA FILLCD: SHLD L1PNTR ;saves file RAM ;addr passed from SKETCH.BA MVI A,5 ; not 0 STA PRFLAG LXI D,0900H FILLC1: DCR D ;Do 8 rows of 240 bytes RZ ;Direct RET to basic PUSH D CALL PUTROW LXI D,240 LHLD L1PNTR DAD D ;incr Mem pointer + 240 SHLD L1PNTR POP D MOV A,E ;incr E, pass to PUTROW ADI 8 ; (0,7,15,...,56) MOV E,A JMP FILLC1 ;=== GETKY: ORA A ;clear carry status CALL KYREAD JZ GETKY ;if nothing there CALL CAPS ;conv to caps RET ;if something in A ;=== CLR8: LXI H,0108H ;col 1, row 8 CALL POSIT CALL ERAEOL RET ;=== find Ht/Wdth combination for Prt PSXY: CALL CLR8 LXI H,HGTMSG CALL PUTTXT ;height multiplier PSXYH: CALL GETKY ; 1,2, or 4 CPI 27 JZ MENU1 CPI '1' JM PSXYH CPI '3' JZ PSXYH CPI '5' JP PSXYH SUI 30H ;ascii -> decimal val STA PRFLAG PSXYH1: CALL CLR8 LXI H,WIDMSG ;width multiplier CALL PUTTXT ;1, 2, 3, or 4 PSXYW: CALL GETKY CPI 27 JZ PSXY CPI '1' JM PSXYW CPI '5' JP PSXYW SUI 30H STA PRWIDE ;save this value ;@@ new lft mrgn attempt GETMGN: CALL CLR8 LXI H,MGNMSG CALL PUTTXT CALL INLIN LXI H,KEYBUF ;point buff,0/Ltr ; ANA A ;clear carry to 0 CALL CNVERT ;rets w/ val in DE ; MOV A,D ;D is supposed = 0 ; CPI 0 ; JP GETMGN ; NOT WORKING! MOV A,E ;get the lsb value=num JM GETMGN CPI 80 JP GETMGN STA LFTMGN ;a keeper CALL SETMGN ;@@ end test CALL SETMD ;to get GMODE vals CALL RSL1P MVI E,56 ;y row val to start CALL PUTROW ;restore graphics LXI H,0101H ;col=row=1 CALL LNSPC ;Set lnsp LPT value JC FINISH ;Bailout if BRK ;=== Print/Save loop starts here SCNROW: CALL GETROW PUSH H LDA PRFLAG ;get RAM/LPT pointr. ANA A ;strobe Z flag. JZ ENDROW ;if 0 fill buffer, CPI 01H ; else Prt. Ht = ? JZ PR1HI CPI 02H JZ PR2HI CPI 04H JZ PR4HI ENDROW: POP H NXTROW: INR L ;row = row + 1 MVI A,09H CMP L ;Is row = 9 ? JZ FINISH ;Ret if L>8 (done). MVI H,01H ;Start on left. JMP SCNROW ;Do next row. ;=== Print/Save loop ends HGTMSG: DB 'Prt HEIGHT multiple? ' DB '<1,2,4>...',0 WIDMSG: DB 'Prt WIDTH multiple? ' DB '<1,2,3,4>...',0 MGNMSG: DB 'Left Margin <0-80> ?',0 ;== SETMGN assumes 0-80 in A SETMGN: MOV C,A ;save lft mgn value MVI A,27 CALL TOPRT MVI A,108 CALL TOPRT LDA LFTMGN CALL TOPRT RET LFTMGN: DS 1 ;== SETMD assumes a good val PRWIDE, ; looks up table, sets GMODE mode ; values N1, N2 SETMD: LDA PRWIDE MOV B,A LXI D,BASE LXI H,TABLE SETMD1: MOV A,M CMP B JZ FOUND DAD D JMP SETMD1 BASE: EQU 0003D ;the TABLE increment FOUND: INX H ;move past PRWIDE val MOV A,M STA N1 INX H MOV A,M STA N2 RET PRFLAG: DB 1 ;default PRWIDE: DB 1 ;default N1: DS 1 N2: DS 1 TABLE: DB 1,240,0,2,224,1 DB 3,208,2,4,192,3 ;=== ; PR1HI to just dump the 240 values ; in BUFFER to PRNTIT then reset PR1HI: CALL GMODE MVI E,240 LXI H,BUFFER PR1HI1: MOV A,M CALL PRNTIT JC BRKOUT INX H DCR E JNZ PR1HI1 CALL PCRLF JMP ENDROW ;exit or PR1HI ;=== ; PR2HI tests the bytes in BUFFER and ; builds new bytes, two bits for each PR2HI: MVI B,2 ;prt pass counter MVI D,10000000B ;test word PR2HI1: CALL GMODE MVI E,240 ;start count LXI H,BUFFER PR2HI2: MVI C,0 ;clear for new byte MOV A,M ;get BUFFER val ANA D CNZ T2BITS MOV A,D ;get test word RRC MOV D,A MOV A,M ;get orig val ANA D CNZ U2BITS MOV A,D RRC MOV D,A MOV A,M ;get orig val again ANA D CNZ L2BITS MOV A,D RRC MOV D,A MOV A,M ANA D CNZ B2BITS MOV A,D RLC ;test word back to begin RLC ;to test next BUFFER val RLC MOV D,A MOV A,C ;get the new word CALL PRNTIT JC BRKOUT INX H ;go to next BUFFER val DCR E ;BUFFER count -1 JNZ PR2HI2 CALL PCRLF MVI D,00001000B ;for 2nd pass DCR B ;prt pass count -1 JNZ PR2HI1 ;do 240 more times JMP ENDROW ;all done so return T2BITS: MOV A,C ;get newword ORI 11000000B MOV C,A RET U2BITS: MOV A,C ORI 00110000B MOV C,A RET L2BITS: MOV A,C ORI 00001100B MOV C,A RET B2BITS: MOV A,C ORI 00000011B MOV C,A RET ;====== PR4HI is to test the 240 values ; in mem at BUFFER and print 4 rows x2 PR4HI: MVI B,04 ;set decr counter MVI D,10000000B ;test val in D NXTPAS: CALL GMODE ;refresh grph mode MVI E,240 ;start count at 240 LXI H,BUFFER ;get begin BUFFER ; addr into HL NXTVAL: MVI C,0 ;clear 2 build new word MOV A,M ;get val from mem ANA D ;test if 'on' CNZ T4BITS ;since on, build new MOV A,D ;get test word RRC ;rotate 1 right MOV D,A ;save rotated test word MOV A,M ;get orig val again ANA D ;test if 'on' CNZ B4BITS ;since on build 4 MOV A,D ;get test word RLC ;restore test bit word MOV D,A ;save test word MOV A,C ;get newword CALL PRNTIT ;send to PRT twice JC BRKOUT ;bail out if S-Brk INX H ;HL=HL+1 DCR E ;count=count - 1 JNZ NXTVAL ;do another row CALL PCRLF MOV A,D ;get test value RRC ;shift to right 1 bit RRC ;rotate again MOV D,A ;save rsult DCR B ;pas# = pas#-1 JNZ NXTPAS ;do 240 more JMP ENDROW ;end of PR4HI T4BITS: MOV A,C ;get NEWWRD ORI 11110000B ;fill in top 4 MOV C,A ;put T4BITS back in C RET B4BITS: MOV A,C ;get NEWWRD ORI 00001111B ;fill in btm 4 MOV C,A RET ;==== store a 40 chr row of data bytes GETROW: CALL RSL1P CALL CURSON NXTCOL: CALL POSIT ;Go to col 1,row 1. PUSH PSW ;Save value. CALL TIMER ;Illumination time. POP PSW ;Get val back. PUSH H ;save for later CALL READ6 ;Go do 6 curs vals. POP H ;get r & c back INR H ;Col pos +1 MVI A,41 ;Ready for test. CMP H ;Count > 40 ? JNZ NXTCOL ;If not, do another CALL CUROFF RET ;PUTROW puts the graphics back by pixs ; assumes E = start row (0-55) for 8 ; rows of pixels. Uses C as a counter. ; D = x = 1->240. PUTROW: MVI B,10000000B MVI C,0 ;count up to 8 pix rows NXTY: MVI D,0 ;the x pixel col count LHLD L1PNTR INR C MOV A,C CPI 9 RZ BYTE: PUSH H MOV A,M ANA B ; test: is it on? PUSH D PUSH B JNZ PSET ;if so PSET it JZ PRESET ;of not PRESET it BACK: POP B POP D POP H INX H INR D ;x=x+1 MOV A,D ;x val CPI 240 JNZ BYTE MOV A,B RRC ; rotate it MOV B,A ; put it back INR E ;next y pixel row JMP NXTY PSET: CALL PLOT JMP BACK PRESET: CALL UNPLOT JMP BACK ;==== read 6 cursor vals and store READ6: LXI H,65515 ;1st mem pointr - 1 POINTR: INR L ;Goto next mem val. MOV A,M ;Get val @ cursor. CMA ;For reverse video. CALL FLIPER ;Invert bits PUSH H CALL STOREA ;put vals in mem POP H MOV A,L ;Curs lo bit val CPI F1H ;Last curs row? If JNZ POINTR ; not last,do next. RET ;Last, so next col. ;====== store values in reserved mem STOREA: LHLD L1PNTR ;get addr pointer MOV M,A ;put ORIG WORD there INX H ;incr the val in HL SHLD L1PNTR ;save incremented RET ; addr pointer ;====== inverts vals, bit by bit ; FLIPER to invert 8 bit vertical row ; B = original, C = new value built ; E = loop counter FLIPER: MOV B,A ;Save value in B MVI E,08H ;Set decr counter MVI C,00H ;Set new word to 0 CALL FLIP1 ;Go do the invert MOV A,C ;Return the invert RET FLIP1: MOV A,B ;Put val back in. CALL CHKBIT ;Are bits on/off ? MOV A,B ;Put old word in RRC ;Rotate to next bit MOV B,A ;Save value. MOV A,C ;Get newword. RLC ;Rotate to next bit MOV C,A ;Save back to C reg DCR E ;Take 1 from count MOV A,E ;Test count, if not JNZ FLIP1 ; 0, go back thru. RET ;If so then return. CHKBIT: ANI 00000001B ;Test bit on/off. CNZ BLDWRD ;If on, build new. RET BLDWRD: MOV A,C ;Get new word. ORI 10000000B ;Add bit to word. MOV C,A ;Keep the new word. RET ;===== sends 24/144 spacing for GRAFIX LNSPC: MVI A,27 ; ESC CALL TOPRT ;Send ESC to LPT. MVI A,51 ;51="3" envoke lnsp CALL TOPRT ;Send 51 to LPT. MVI A,24 ; spacing for EPSON CALL TOPRT ; 9-pin graphics. RET ;=== refresh Graphics mode in LPT GMODE: MVI A,27 CALL TOPRT MVI A,76 ;76="L"= dbl den CALL TOPRT ;graphics mode. LDA N1 ;from TABLE CALL TOPRT ;dump as graphics. LDA N2 ;from TABLE CALL TOPRT RET ;=== reset prt out of graphics mode RSTPRT: MVI A,27 ; ESC CALL TOPRT ;Send to LPT MVI A,50 ; 50 = reset lnfd CALL TOPRT ; to 1/6 inch. RET ;=== send Carriage ret and Line feed PCRLF: MVI A,13 CALL TOPRT ; MVI A,10 ; CALL TOPRT RET ;===== send A value to printer PRNTIT: ANA A ;Set Carry Flag = 0 PUSH B PUSH H LXI H,PRWIDE MOV B,M ;get the width multpl. POP H PRNTI1: CALL TOPRT ;Send A val to LPT. DCR B JZ PRNTI2 JMP PRNTI1 PRNTI2: POP B RET ;=== allow time to illuminate LCD TIMER: MVI A,255 ;255 X # NOPs = TIME?: NOP ;Do nothing NOP NOP NOP NOP DCR A RZ JMP TIME? BRKOUT: POP H ;If BRK from GMODE CALL BEEP ;BEEP signals ERR. CALL BEEP JMP MENU ;then this = END FINISH: LDA PRFLAG ANA A ;strobe Z flag JZ BEEP2 ;0 only if Save CALL RSTPRT ;Val for LPT reset. BEEP1: CALL BEEP CALL CUROFF ;Return LCD to prev JMP MENU BEEP2: CALL BEEP CALL BEEP RET ;to Basic (image in BUFFER) ;=== reset mem pointer value RSL1P: PUSH H ;save row/col LDA PRFLAG ANA A ;strobe Z flag JZ RSL11 ;bypass if PRFLAG=0 LXI H,BUFFER ;get actual addr SHLD L1PNTR ;store that as pntr RSL11: POP H ;get row/col back RET L1PNTR: DS 2 ;reserve 2 bytes BUFFER: DS 1920 ;reserve 240 bytes END: END