• Please review our updated Terms and Rules here

Epson Fx86e

Mike_Z

Veteran Member
Joined
Dec 1, 2013
Messages
1,713
Location
Near Milwaukee Wisconsin
I've been working on adding a parallel port LPT1: on my CP/M 2.2 machine. Up until now I have my Epson printer with an Epson #8143 serial interface card in it, so that I could print serially. The past few days I have been trying some crude programs to output characters to the Epson on the parallel port, but was having trouble. I can reset the printer apply data and send the Strobe pulse, the printer will then show that it is busy, but never sends an ACK pulse, then just hangs. I suspected the printer was not working correctly and connected the printer to my IBM XT LPT1 port and tried to print, but it reported the printer was not there. So I removed the serial interface card and then the parallel port worked fine. Seems that when the serial board is in place, it disables the parallel port. Has anyone else had any experience with this? I'm wondering why both ports can not work one at a time. I called EPSON service and they were not any help. Thanks, Mike
 
I don't know this printer, but traditionally those vintage printers did not operate both interfaces at the same time. there were usually dipswitches to configure one or the other.
 
Well... One would think, but it is not the dip switches. I checked them all. The printer proper has two sets of dips, all they set is the printer character types, language and paper type. The serial card has one set of dips and a few jumpers. The dips set the RS232 stuff, like bits, parity, stop bits baud rate. The jumper select the RS232 or current loop, DTR mark/space and pull up resistors. I don't intend to use both, but am trying to use this printer as my test printer for the LPT: CP/M software. So far I have to have the serial card out to make the printer work on parallel, maybe that is the design? Mike
 
Don, thanks for the link. I have seen these and have pretty much gone through them quite well. The serial interface card has a header that plugs into the main printer board. I suspect that this some how disables the parallel port. I have tried setting up the parallel port and made sure it worked on my IBM XT. Then I plugged in the serial card, doing nothing else and the parallel port stopped working. I have not found any service documents on this printer so up until on I can only guess. Thanks for the help. Mike
 
I hope you can figure out if there's a pin that shuts off the interface. Maybe look for one that grounds out a pin when the board plugs in.

Not directly related, but my own C Itoh printer has both serial & parallel ports and for years the serial port drove me nuts by printing a single period on the first page. Worked great with parallel port. This was with Windows 95 (win 3.0?) to XP, I think. Then one day I stumbled upon a serial driver for Windows that someone put out the solved the problem. Seems MS never fixed the issue and didn't care and so he fixed it for them. Ah, the good old days of dot matrix printers.
 
Well..... I suffered some computer failure. But I believe I have it repaired.

I'm attempting to output some characters from my CP/M machine through a parallel port to my Epson FX86e printer. The users manual talks about the interface signals.

Timing.JPG

So I wrote some code to try and do this, here are the waveforms my code makes

SMALL20210226_112646.jpg

THe top trace is the BUSY. When it is HIGH the printer is NOT BUSY. The middle trace is the strobe. This pulse comes from the computer after the data has been placed on the bus. You can see that after the strobe the printer becomes BUSY and eventually issues an ACK pulse, the bottom trace. My code should print the alphabet from z to a. But the printer seems to accept the all 26 characters, there are 26 sets of traces, but never prints anything. Here is my code.
Code:
                ;THIS IS A TEST PROGRAM TO SEE IF I CAN PRINT TO MY
                ;EPSON PRINTER VIA THE PARALLEL PORT
                ;EPSON.ASM 2/20/2021
                ;THE PROGRAM FIRST SET UP THE PPI THIS CAUSES THE OUTPUT TO HIZ
                ;THIS CAUSES THE EPSON TO BE NOT READY AND OFFLINE
                ;pORT c2 IS THEM PULSED TO RESET THE EPSON THIS PUTS IT READY
                ;AND ONLINE THE SELECT C0 IS SET LOW
                ;NEXT LOOP WAITS FOR NOT BUSY (LOW) AND ACK HIGH
                ;WHEN THE PRINTER IS READY FOR DATA ASCII LETTERS Z-A SHOULD BE 
                ;PRINTED THE Z IS PREPARED AND OUTPUTED NEXT STROBE C1 IS PULSED
                ;LOW/HIGH THE DATA LETTER IS CHANGED TO Y AND JUMPED TO LOOP
                
 006C =         PORTA	EQU	06CH	;PORTA DATA OUT
 006D =         PORTB	EQU	06DH	;PORTB STATUS IN
 006E =         PORTC	EQU	06EH	;PORTC CTRL OUT
 006F =         PORTCR	EQU	06FH	;MODE=0
                
                ;INPUT TO CPU
                ;BO = BUSY LOW = NOT BUSY
                ;B1 = ASKNLG HIGH = READY FOR TRANSFER
                
                ;OUTPUT TO CPU
                ;C0 = PLACE ON LINE, ALLOW PRINTING
                ;C1 = STROBE LOW = TRANSFER DATA 7 SET BUSY
                ;C2 = RESET LOW = RESET
                
 0100           	ORG	0100H
                
 0100 310020    LXI	SP,02000H	;SET STACK
                
                ;SET PPI FPR PORTA AS OUTPUT (DATA)
                ;PORTB AS INPUT (STATUS)
                ;PORTC AS OUTPUT (CONTROL)
                
                START:
 0103 3E82      MVI	A,082H		;1000 0010
 0105 D36F      OUT	PORTCR		;PROGRAM PPI
                
                ;PULSE PORT C2 TO RESET PRINTER TO READY & ONLINE
 0107 3E03      MVI	A,03H		;RESET
 0109 D36E      OUT	PORTC
 010B 3E07      MVI	A,07H		;PULSE C2
 010D D36E      OUT	PORTC
                
                ;TEST DATA WILL BE 26 CHARACTERS Z TO A
                ;START WITH Z AND SUBTRACT ONE UNTIL REG B IS ZERO
 010F 0E41      MVI	C,'A'		;TEST CHARACTER
 0111 0619      MVI	B,019H		;ADD 019H TO MAKE Z
                			;DEC REG B TO MAKE ONE LESS LETTER
                
                ;WAIT HERE FOR PRINTER TO BE NOT BUSY AND ACK HIGH
                LOOP:
 0113 DB6D      IN	PORTB		;B0 = BUSY = HIGH, NOT BUSY = LOW
 0115 E603      ANI	03H		;B1 = ACK = HIGH FOR TRANSFER
 0117 FE02      CPI	02H
 0119 C21301    JNZ	LOOP
                
                ;SET PRINTER SELECTIN LOW
 011C 3E07      MVI	A,07H		;SET C0 SELECT LOW
 011E D36E      OUT	PORTC
                
                ;OUTPUT CHARACTER TO PRINT
 0120 79        MOV	A,C		;MOVE DATA
 0121 80        ADD	B
 0122 D36C      OUT	PORTA
                
                ;PULSE PRINTER STROBE HIGH/LOW/HIGH
 0124 3E05      MVI	A,05H		;STROBE LOW
 0126 D36E      OUT	PORTC
 0128 00        NOP
 0129 00        NOP
 012A 3E07      MVI	A,07H		
 012C D36E      OUT	PORTC		;STROBE HIGH
                
                ;PREPARE NEXT CHARACTER
 012E 05        DCR	B
 012F C21301    JNZ	LOOP
                
                ;QUIT
 0132 C30000    JMP	00H
                
 0135           END

I'm thinking that maybe the timing of these pulses is not correct or maybe the printing of the printer needs to be enabled? This is the first time that I have tried to do anything with a parallel printer. Any ideas? Thanks Mike
 
My guess would be that the printer has the line of data in a buffer, and you need to send a character to cause it to actually print that buffer. CR, LF, FF or some such character should do the trick.
 
I'm not sure whether CR will be enough - depends on the printer's buffering algorithm. LF should definitely work.
 
The manual states CR, but you will still need to output a LF yourself (unless you have the appropriate DIP switch set). Check the words in Appendix A against the CR code.

I also don’t think your software drives the printer according to the timing diagram. You need to achieve the minimum data valid times and ensure that you meet all of the timing requirements by waiting at the appropriate points for signal transitions.

There is also a ‘data dump’ diagnostic mode you can set to print out all of the characters (in HEX and ASCII) that the printer thinks you have sent to it. This mode is set by holding certain buttons down when you power it up. This us described in Appendix C.

Dave
 
Last edited:
Yes, the CR causes the printer to print the outputted characters. Although, the printer will not actually do a carriage return. The print head stays at the end of the character string. The next character will cause the printer to start a new line AND you are correct a line feed is required, but generally I believe that a CRLF is used by most code. I'm not sure if the timing is that important, but will look at it. The manual also talks about ignoring the ACKNLG signal and just to look at the BUSY. I think if the output code waits long enough, 15 uSec or so, the printer will be ready again (unless an error occurs). Error checking maybe a later improvement.

What I want to achieve is to add a LPT: device to my CP/M 2.2 machine. So, the main goal was to determine first if I could write a crude program to determine how I can know the printer was ready to print and then to actually print. If the printer wants to collect characters until a CRLF is found, that's OK.

I have some IOBYTE code in my CBIOS. The purpose of this exercise was to learn how I can change the IOBYTE code in CBIOS, so that I can have a LPT: device. My next step is to work on adjusting this code. Thanks for the help, Mike
 
Great, sounds like it working now - the missing piece being the CR/LF. Your code looked alright to me, you are waiting for "not busy". I also was wondering why you were also waiting for ACK.
 
I waited for ACK because the interface wave form that the manual showed (with very little explanation) seemed to need it. Maybe checking the ACK is required if a faster machine is sending data to be printed. If the data shows up too fast, characters will be over written and missed. There is no chance of this happening on the 8080, but I may keep it anyway. Mike
 
I would wait for BUSY=0 and /ACK=1 (as you are doing at the moment).

Next, send the desired data byte out and wait for 0.5 us (data setup time).

Next, set /STROBE=0

Wait fir BUSY to go high.

Set /STROBE=1.

Wait for 0.5 us.

Ready for the next character.

The key things are the data setup and hold times around the operation of the /STROBE signal and ensuring you wait for BUSY to go active after setting /STROBE low.

Sometimes, you may find that things generally work - but find they are unreliable over time. This can be as a result of breaking the setup and hold times that are there to prevent data bounce and ringing from affecting the results.

Dave
 
I'm always open to improvements. Lord knows, I've been down the confusion path many times. Generally that takes a little to come back from, Thanks, Mike
 
It should not be necessary to do anything highly complex. The protocol is actually very simple. Take for example the Kaypro parallel port, which doesn't even connect to ACK. Keep in mind, all of these vintage systems worked just fine on printers like the one you have. All the Kaypro does is check BUSY (not READY) and then it outputs the byte to the data latches and then pulses STROBE (bit-bang). Unless you have a super fast CPU, it should not be possible to violate any timing. Worst case, you might need to widen the STROBE pulse. Remember, a 2MHz 8080 has a 500nS cycle time, and a single OUT instruction takes 11 cycles. So, your STROBE pulse (by bit-bang) could not possibly be any narrower than 5.5uS in that case. STROBE always (or at least for these vintage devices) clocks a FlipFlop or other h/w latch, so that the printer CPU has a chance to see it. You really only have to meet the requirements of that flip-flop, which is nano seconds.

You are setting the data in latches before pulsing STROBE, and so you can just work out some basic timing based on your CPU clock speed and see if you need any extra delays - probably just a NOP or two - or possibly an instruction that burns more cycles in extreme cases. The protocol is actually pretty fool-proof as long as you are checking BUSY.
 
Today, I successfully printed to my Epson FX86e printer using the LPT: device of CPM. This turned out to be a good exercise in repairing code in my IOBYTE routines that I never tested. There were a few errors that complicated the process. Now I have to clean up the code and add some comments that may help me better understand what I did in the past few days, when I look at it again later.

Since this worked better than I had thought, next week I want to add another device UL1: User List device. I have a Friden FlexoWriter. Last year I wrote a ASCII to FRIDEN character translator. The Friden is pre ASCII. The program I wrote would open a text file and print it out on the writing machine. It is kind of mesmerizing watching those old striking levers hammer out text.

I have to think about where to put the translation code, I don't want to place it all in CBIOS, it would not fit. Somehow I'll have to open a file into memory or something like that. I'm also working on reading the Friden's keyboard, but that is a little harder. Getting a strobe pulse or an indication that the key data is ready to read has been my problem. Well..... it's all in fun and keeps this old man busy. Thanks for the help, let you know how it goes, Mike
 
Well..... I still do not know why the printer parallel port will not work when the serial interface card is in place. Maybe I can find out later. The only other problem with the parallel port was that there is a buffer that holds a line of characters. I do not know how big the buffer is. But you need a CRLF at the end of the string of characters to have the printer display the string. I had to write a PPI$STATUS and PPI$DATA routine for the IOBYTE to work correctly. The status is backwards from the serial. Not Busy is low rather than high and the Data routine needs the strobe pulse.

Do you have any ideas on how to accomplish a character code translation? I have code that does the translation, but not exactly sure on how to get the CBIOS to use it.

It's amazing, last week we had 2 1/2 feet of snow on the ground. My back yard outside table, chairs and BBQ were completely buried. Today, there is hardly 6" left. And probably by next week it will all be gone. Problem is it can snow here into May. So I can not get too excited. Thanks Mike.
 
Back
Top