QIKDMP.SRC G.W.Flanders [73300,2772] February 4, 1988 This file contains the annotated source code for the machine language found in the BASIC loader in QIKDMP.DOC. The routines herein provide (1) a read/write of the LCD from/to a 1920-byte buffer created by the program and (2) a fast, reliable dump of the graphic screen to a bit-addressable line printer. As discussed in the referenced text file, printer codes used here are for Gemini printers. Modifications will be required for most others. The user should not reassemble the source at an address less than 2500 or so bytes under your particular MAXRAM (some disk operating systems change that value). If you have a straight-up M-100 without disk drive, your MAXRAM is probably $F5F0/62960 and you might reassemble as high as $F230/60000 without trouble. In that case, set HIMEM to 60000 (or whatever start point you choose) before loading the data. Now, the source: BYTES EQU $7432 ;reads bytes under cursor and loads them into ;six memory locations starting at (HL) CINT EQU $3501 ;converts to integer DEVICE EQU $F675 ;signals output to 0=LCD, 1=LPT DIV% EQU $377E ;perform division INTX EQU $765C ;disable interrupts MOD EQU $37DF ;perform DE MOD HL PRLP EQU $5A58 ;print bytes starting at (HL) until a zero is found ORG $D2F0 ;code starts at 54000 SVIMG XRA A ;A=0 (CALL54000 to STORE the image) JMP GO RTIMG MVI A,$01 ;A=1 (CALL54004 REPAINT the screen with the image) GO STA TOGL+1 ;TOGL+1 is the flag for store/repaint LXI H,IMAGE ;the 1920-byte graphics buffer XRA A ;A=0 NXR STA $FFF4 ;set cursor row XRA A ;A=0 NXC STA $FFF5 ;set cursor column PUSH H ;save buffer position CALL INTX ;disable interrupts TOGL MVI D,$00 ;loads the D register with 0 (or 1, depending ;on the entry point) preparatory to the CALL CALL BYTES ;read six bytes under cursor into (HL) POP H ;retrieve last position in buffer LXI B,$06 DAD B ;increment position 6 bytes LDA $FFF5 ;cursor column INR A ;increment by one CPI $28 ;are we at the end of a row? JNZ NXC ;if not, do another column in this row LDA $FFF4 ;check the current row CPI $07 ;are we at the end? RZ ;if so, exit INR A ;if not, increment by 1 JMP NXR ;and start the next row SCRDMP MVI A,$01 ;begin the dump STA DEVICE ;by putting 1 (LPT) in the device flag LXI H,SET ;printer setup codes in the string 'SET' CALL PRLP ;print the string of commands LXI H,IMAGE ;point to the graphics buffer MVI A,$08 ;counter of 8 for rows PRINT STA SW ;set the counter in the buffer 'SW' CALL PROW ;and print a row LDA SW ;get the row count DCR A ;decrement it by 1 JNZ PRINT ;if we're not done, do another row LXI H,NORM ;we're done. Get the string 'NORM' CALL PRLP ;and send the printer those commands XRA A ;A=0 (LCD) STA DEVICE ;the device flag indicates LCD output RET ;exit from screen dump PROW SHLD RBUF ;store row position in the buffer 'RBUF' CALL HIRES ;send high resolution command to printer MVI B,$F0 ;240 bytes of column data per row LHLD RBUF ;get row position in HL XCHG ;and move it to DE MOD16 LDAX D ;get the value pointed to by DE in A PUSH D ;and save the position on the stack PUSH B ;save the counter on the stack MOV E,A ;LSB in E MVI D,$00 ;MSB=0 LXI H,$10 ;HL=16 CALL MOD ;get DE MOD HL CALL CNVRT ;and pick the right printing code POP B ;get counter back DCR B ;and decrement it by 1 JZ CRM ;if zero, go do a linefeed and carriage return POP D ;else get the buffer position back INX D ;and increment it by 1 JMP MOD16 ;print the right code for this byte CRM POP D ;get the buffer position back MVI A,$0D ;put CHR$(13) in A RST 4 ;and send it to the printer DIV16 CALL HIRES ;now we're ready for the second pass. Send hi-res code LHLD RBUF ;where were we in the buffer? XCHG ;load position into DE MVI B,$F0 ;240 bytes of column data in the B counter DIVL LDAX D ;get a byte from the buffer PUSH D ;store the position PUSH B ;and the counter MOV E,A ;E=LSB of value MVI D,$00 ;D=MSB (0) LXI H,$10 ;HL=16 CALL DIV% ;HL=DE/HL CALL CINT ;get integer portion of result CALL CNVRT ;and convert it into the right printing code POP B ;retrieve the counter DCR B ;decrement it by 1 JZ CR ;if we've finished the second pass, goto 'CR' POP D ;else retrieve buffer position INX D ;increment it by 1 JMP DIVL ;and do another byte in this pass CR POP D ;row's done. Get buffer position MVI A,$0D ;put CHR$(13) in A RST 4 ;and print it INX D ;increment buffer position by 1 XCHG ;put it in DE RET ;and set up for the next new row CNVRT MOV A,L ;put the value in A CALL MATCH ;and go fetch the right printing code RST 4 ;now print it RST 4 ;three RST 4 ;times RET ;and go back for another HIRES LXI H,HR ;point to the high resolution code string 'HR' CALL PRLP ;send it to the printer RET ;and return MATCH CPI 0 ;is the byte=0? RZ ;if so, go back and print it as is LXI D,BYTS ;if not, point DE to the list of printing codes NLP DCR A ;and test JZ GET ;if A=0, we've found the right code INX D ;otherwise check the next one JMP NLP ;and keep checking until we find it GET LDAX D ;get the selected code in A RET ;and go print it BYTS DB $C0 ;if A=1, code=192 DB $30 ;if A=2, code=48 DB $F0 ;if A=3, code=240 DB $0C ;if A=4, code=12 DB $CC ;if A=5, code=204 DB $3C ;if A=6, code=60 DB $FC ;if A=7, code=252 DB $03 ;if A=8, code=3 DB $C3 ;if A=9, code=195 DB $33 ;if A=10, code=51 DB $F3 ;if A=11, code=243 DB $0F ;if A=12, code=15 DB $CF ;if A=13, code=207 DB $3F ;if A=14, code=63 DB $FF ;if A=15, code=255 SET DB $1B ;ESC DB $4D ;"M" - left margin is DB $0A ;CHR$(10) - space 10 DB $1B ;ESC DB $41 ;"A" - linefeed value=x/72 DB $08 ;CHR$(8) - x=8 DB $00 ;0 byte string delimiter HR DB $1B ;ESC DB $4C ;"L" - high resolution mode DB $D0 ;CHR$(208) DB $02 ;CHR$(2) - expect 720 columns of data:256*2+208 DB $00 ;0 byte string delimiter NORM DB $1B ;ESC DB $40 ;"@" (reset printer to default settings) DB $0D ;CHR$(13) line feed and carriage return DB $00 ;0 byte string delimiter SW DS $01 ;1-byte buffer POS DS $02 ;2-byte buffer RBUF DS $02 ;2-byte buffer IMAGE DS $0780 ;1920-byte graphics buffer END