• Please review our updated Terms and Rules here

CPUville Z-80 printer port addition

MykeLawson

Experienced Member
Joined
Mar 21, 2014
Messages
382
First a little back story... I bought the CPUville Z-80 CPU card and it works great and I'm running CP/M 2.2. It has a 40 pin expansion port that I have interfaced with an STD Bus card cage. As my first real project with this, besides the bus interface, is to add a Centronics printer port. Several of you helped me rewrite the CP/M DUMP program to use as a base for a program to send data to my printer port. I know I have some hardware design work to finalize, but I wanted to post what my plan is for how I will integrate the device driver code into the re-written DUMP program; which I aptly renamed PRINT.COM. Anyway, here is the device driver program flow I plan to use as a starting point:

1. Bits 2 & 3 of Port 15h wil be set low to both /INITIALIZE the printer and select it /SELECT.

2. Test Bits 2 & 3 of Port 15h to confirm the PAPER OUT & ONLINE inputs are still low.

3. Printer output data is first clocked into the 74LS374 (Port 14h) to be placed on the Parallel Port pins 2 to 9.

4. Bit 0 of Output Port 15h is set which causes a 555 bistable timer low pulse of 1ms to be sent to the /STROBE input of the printer.

5. The software will monitor the returning Busy signal Bit 1 on Port 15h from the printer. Once that bit returns to a low state, the process will restart at step 2 for the next character.

1670466007420.png
 
Well, I have toyed with a few ideas on the actual circuitry to start out with, and I think this will work best. And it seems to work with what I have read about how the code should flow. And I have even taken a stab at a starting point for what code I need to add to the modified DUMP program I started out with; now aptly called PRINT.COM..... So, the latest batch of parts and pieces will be under the tree ready for me to start building and testing real soon.

1670863706589.png
 

Attachments

  • PRINT.txt
    8.5 KB · Views: 2
One question regarding U10-A and U08-F. I don't see the source of "port 14" so can't tell whether that is active-high or active-low, but I think it must be active-low for the gate to work. Maybe double-check that logic? Usually, rising-edge triggered latches are fed the active-low signal (derived from /WRITE) because it is that trailing edge, the rising edge, where the data is valid. I'm thinking that you don't need/want U08-F in there.

Also, check whether you need pull-ups on the inputs to U11. Typically, those are driven by open-collector devices and you need some pull-ups to get proper rise-times on the signals.
 
Doug, here is the entire board. The 'P3' connector is the 40 pin bus connection from the CPUville Z-80 CPU board. The 'diamond' shaped connectors are to the STD Bus.
 

Attachments

  • BusDriver.pdf
    29.7 KB · Views: 2
OK, things make more sense now. Both the 74LS175 and the 74LS374 are positive-edge-triggered, so you do not need/want the inverter U08-F. Also note, all the "Port x4-x7" signals are active low. By convention, they would be labeled "/Port x4-x7" or something similar.
 
Yep Doug, I'm sure there are a bunch of tweaks I will be making to the board and to the code. That is already the 3rd board design so I couls make sure everything fits on the 4.5" x 6.5" STD Bus card footprint and so I can use parts and pieces I already have. Same with the nomenclature cleanup as well. All part of it being a hobby; I get to do it when I get the time..... And it is far more enjoyable.
 
Well, I have rebuilt my 'I/O Panel' and now have the DB25 to connect up to a printer. And I bought a Panasonic KX-P1080i printer off eBay. Now I just have to finish wiring up the driver/latches to the header on the Printer Card. I'll cobble something up with MBASIC to do some rudimentary testing to read the printer status port, check the timing on the control port, and send a character or two to the printer to make sure the wiring is good. I have tested the printer connected to an old laptop and it works fine.

There is another thread here about parsing a filename with a program I posted awhile back. It was for printing text files. My ultimate goal there was to be able to actually print a text file. That program works in sending the text to the screen just fine, so I will modify it to actually print the file on the printer....
 

Attachments

  • Printerv1.pdf
    88 KB · Views: 2
Well, after discovering a port addressing issue, it seems to work. I wrote up a simple BASIC program to send characters to the printer and it actually printed. Once I write up something in BASIC a little more complex and test that, I can put this thing to bed and move on to the next project...... I attached the latest version of the schematic. Yippie
 

Attachments

  • Printerv1.pdf
    105.5 KB · Views: 4
Well, success at last. I created three paragraphs of text in a test file. and ran it through the LPRINT program that works just like the PRINT program from earlier, but with line printer code in it. And I was able to actually print. The schematic of the board is what I posted last week. Here is the code and a scan of what the printed page looks like. I will clean it up in the future so words are not chopped up at the end of a line, but it does function. I'm happy.....
 

Attachments

  • LPRINT.pdf
    71.5 KB · Views: 2
  • TestPage.pdf
    217.2 KB · Views: 2
That is awesome :)

Have you considered finding a little unused space in the BIOS and writing it in for the LIST jump? Then all it needs to do is wait until the interface is not busy, send the character out and exit. Then it would work with existing software and BASIC too :)
 
LIST Jump? Sorry for my ignorance; I'm not sure if that is built into CP/M or a transient program. Or are you referring to the LST: device? But yes, at some point, I would like to integrate this more tightly into CP/M. I'm still, quite slowly getting my feet wet again with Z-80 machine code and CP/M.....
 
Yes, the LIST device in CP/M. There are some routines in the BIOS in CP/M that deal with it - Which version of CP/M are you using?

Typically you'd hook your code something like this ;

LD HL,(0001) LD DE,$000C ADD HL,DE LD DE,MYKESPRINTROUTINE LD (HL),E INC HL LD (HL),D

Then when the print routine is called, you'll get a byte in C to send to your printer interface at the address "MYKESPRINTROUTINE" wherever that is. If you find a place to hide your code, you can stick it there.

Finding a place to hide your code can be challenging, and I'm not really sure how to go about that process. Maybe Doug or one of the other experienced CP/M programmers can make a suggestion as to how to find some spare memory that isn't going to break anything and sits outside the TPA?

David.
 
I'll add a little more - the BIOS is a series of jumps that head to known routines. If you redirect one of those jumps you can replace it with your own code.

I think there's some other calls that tell the system if a printer is present, but I don't know what versions of CP/M they exist under. Also there's some redirection options for the console in case you want to see your A: prompts come out on the line printer like a teletype :)
 
I'm running CP/M 2.2. And this is about all of the actual code needed to print:
BUSY: IN A,(PTRSTAT) ;GET STATUS FROM PORT 16H
BIT 7,A ;CHECK THE BUSY BIT (7)
JR NZ, BUSY ;IF BUSY BIT IS SET, KEEP CHECKING
LD A,PTRSTRB ;SET SELECT & STROBE HIGH
OUT (PTRCTRL),A ;OUTPUT TO CONTROL PORT
LD A,E ;GET CHARACTER BACK FROM H REG
OUT (PTRDATA),A ;OUTPUT A REG TO DATA PORT
LD A,PTRSEL ;SET SELECT HIGH & STROBE LOW
OUT (PTRCTRL),A ;OUTPUT TO CONTROL PORT
LD A,PTRSTRB ;SET SELECT & STROBE HIGH
OUT (PTRCTRL),A ;OUTPUT TO CONTROL PORT
 
Back
Top