As many of you will recall, prior to moving from Portland in May, I was teaching MC to several CCATS members, at the MC SIG. I have not heard but, I hope that SIG did not die with my departure.
The last project we worked on is the topic of this article. I had hoped that one the members of the MC SIG would submit and explain this program for the Plotter readers. As 6 months have elapsed and that has not happened, I felt the rest of the CCATS group should have this knowledge, so here it is!
Briefly, we needed a goal to reach for and a tangible program to study. By concensus of the group, we elected to do something visual for immediate feedback and a screen dump routine was decided upon as no one felt any of the commercial programs did an adequate job.
As presented here, this program is bug-free but needed some fine tuning when I left. As I do not know what has happened since May, I am presenting the program as we left it in the last class. I hope one of the MC SIG members (Jack, Ken, Lynn, Tom?) will follow-up and tell you what refinements were added.
The following code was written to explain many instructions and techniques. It is written assuming that you are using an Epson compatible dot-matrix printer and that your printer interface is mapped to the standard port, 7Fh. The comments should make adjustment for your hardware easy to accomplish. The printer set-up codes are stored at labels ESCK and ESCA.
The technique used is to move each character block of pixel data to a buffer for manipulation, as the printer needs to ‘see’ the data differently. The left-most bit of each pixel row is rotated into the Carry flag and then in to A, until all eight pixel rows of data, from each character block, are processed. Then the processed data is sent to the printer. It was not necessary to transfer the data to a buffer however, this made the operation easier to understand and demonstrated another technique.
The printer is sent 256 bytes of the 8 pixel row high by 1 bit wide data which comprises one screen row of 32 character blocks, then a carriage return is sent to end the row and do a linefeed on the printer. This sequence is repeated until all 24 rows of the screen have been sent to the printer.
There is little else that I can tell you about the routine. The source is well commented and should prove self-explanatory, so have fun and enjoy!
;**************************************************************
;* *
;* Large Screen Dump for Timex 2068 *
;* *
;* written by Syd Wyncoop *
;* for the CCATS MC SIG *
;* *
;**************************************************************
;
ORG 0FE00h ;put at top of memory & below UDG's
;
ENTER CALL GRAFIC ;initialize printer in graphic mode
LD HL,4000h ;get start address of DFile
LD B,3 ;initialize counter for # of thirds
ENTER2 LD C,0 ;initialize counter for # of character
;blocks in each third of DFile
PUSH BC ;save the counters on the stack
THIRD LD (STORE),H ;save the DFile character block address
;in our variable
LD DE,BUFFER ;get start address of data buffer
LD B,8 ;initialize counter for # of pixel rows
GETLP LD A,(HL) ;get and move each byte of pixel data
LD (DE),A ;to the data buffer
INC H ;adjust pointers
INC DE
DJNZ GETLP ;count each pixel row as moved
PUSH BC ;save pointers while we process data
CALL PROCES ;and go process it
POP BC ;retrieve the pointers
LD HL,(STORE) ;retrieve character block address
INC HL ;adjust character block pointer
DEC C ;count each char block as processed
JR NZ,THIRD ;until the third is complete
POP BC ;retrieve # of thirds counter
DEC B ;count each third as completed
RET Z ;and exit when screen is done
LD DE,2048-256 ;get # of bytes in each third, less
;amount already counted
ADD HL,DE ;adjust character block pointer to
;point to start of next third
JR ENTER2 ;and loop to dump next third
;
STORE DEFW 0 ;variable to store character block
BUFFER DEFS 8 ;buffer to manipulate pixel data
;
;Process each byte of pixel data from DFile format into dot-matrix
;printer format. DFile is up/down and printer needs in left/right.
PROCES LD C,8 ;initialize counter for # of
;manipulations needed
PRLP1 LD B,8 ;initialize counter for # of bytes
LD HL,BUFFER ;get start of the data buffer
XOR A ;clear any old data and CARRY
PRLP2 RLC (HL) ;rotate bit 7 into CARRY
RLA ;rotate A & put CARRY into bit 0 of A
INC HL ;adjust buffer pointer
DJNZ PRLP2 ;get bit 7 from each byte
CALL PRINT ;send adjusted data to the printer
DEC C ;count each manipulation
JR NZ,PRLP1 ;loop until all are done
RET ;else, return when finished
;
;Put printer in single density bit-image graphics mode and ready to
;accept one line of graphic data of length 256. Also, set linefeed
;spacing to 7/72" to avoid white space in dump.
;
GRAFIC XOR A ;clear line counter, temporarily
LD (LNCNT),A
LD HL,ESCK ;get bit-image graphics mode data
LD B,7 ;initialize counter # of bytes of data
GRLOOP LD A,(HL) ;get each byte of set-up data
CALL PRINT ;and send it to the printer
INC HL ;point to next byte of data
DJNZ GLOOP ;loop until all have been sent
XOR A ;set the line counter to 256
LD (LNCNT),A
RET ;printer ready for one line of data
;
;The following table must be customized with the indicated commands
;for your printer.
;
ESCK DEFB 27,'K',0,1 ;Epson single density bit-image graphics
ESCA DEFB 27,'A',7 ;Epson 7/72" linefeeds
;
;Send byte in A to printer but, only if the printer is ready and
;adjust the line counter for each byte sent. Exit via the set-up
;routine for bit-image graphics mode.
;
PRINT PUSH AF ;save data to be printed on stack
PRTLP1 IN A,(7Fh) ;and check if printer is ready
CP 0EDh
JR NZ,PRTLP1 ;loop until printer is ready for data
POP AF ;then retrieve data from the stack
OUT (7Fh),A ;send data to the printer
LD A,(LNCNT) ;and count each piece of data sent
DEC A ;by adjusting our variable
LD (LNCNT),A
RET NZ ;return unless end of third is reached
LD A,0Dh ;else, send carriage return to end the
OUT (7Fh),A ;line of data and advance paper
JR GRAFIC ;go set-up for more graphics
;
LNCNT DEFB 0 ;variable to store number of pixel rows
;to be sent in each line of DFile
;
END
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.