          EINSTEIN USER PORT/PC PRINTER PORT LINK             
                       INTRODUCTION

The Einstein user port/PC printer port link required interrupt hand shaking. 

An example for setting the Z80 PIO interrupt hand shaking port "A" mode 0 can be found in MOS.  
With the contribution of Ric Holne's dis assemblies files/rom/einstein.zip an example of MOS routines to set up the printer default shows the way.

Set up Z80 PIO port "A" for mode 0 output,enables interrupts and low byte of interrupt vector. 
Starts in ROM at 00A6 
LD      A,&10   ;low byte of interrupt vector %00010000 
OUT     (&31),A ;write printer controll reg &10 
LD      A,&12   ;FOR USER PORT
OUT     (&33),A ;USER PORT
LD      A,&0F   ;sets port "A" printer to mode 1 output %00001111
OUT     (&31),A ;write printer port control reg &0F 
LD      A,&87   ;enables interrupts %10000111
OUT     (&31),A ;write printer port control reg &87

What is not shown above for adaption to the user port that interrupt mode 2 needs to be enabled.

IM 2

From UPPERMEM.zsm the interrupt routine can be seen.
;pia_a printer interrupt vector
LFC84:  PUSH	HL
	LD	HL, IFLAG
	RES	0, (HL)
	POP	HL
	JR	LFC4E
THEN
LFC4E:  EI
	RETI
The above code sets bit 0 of IFLAG to 1
scratch pad location FB92

The next code polls bit 0 if not zero
it out puts A to the Printer (port A Z80 PIO)
It also then sets bit 0 back to zero.
From Mos12.zsm
L0F5B:	LD	A,C
;MCAL &9F OUTPUT CHARACTER TO PRINTER
ZPOUT:	PUSH	HL
	LD	HL,IFLAG
L0F60:	BIT	0,(HL)
	JR	NZ,L0F60
	OUT	(PIA),A
	SET	0,(HL)
	POP	HL
	RET

Bit 0 of IFLAG acts as a Latch. An interrupt puts it to 0 but the programer has to reset it. I was at a loss to how polling with a pulse was done. Now I know.

The above code installs into the Einstein as default at boot up and is used for MCALL &9F. I wasted some time rewriting code to test out putting text to the PC with the BBC4W program attached. All unnecessary. Any established means of out putting text to the printer port such as by pressing CTRL and R keys will be printed by BBC4W running the attached program. There is though a problem.

Polling of acknowledge-ASTB on the Z80 PIO from a strobe on the PC is working but an output of a low on the strobe pin 1 of the Einstein printer port does not seem to be happening with my Einstein.

From the Z80 PIO Manual
"With Mode 0 active, a data write from the CPU causes the Ready handshake line of that port to go High to notify the peripheral that data is available. This signal remains High until a strobe is received from the peripheral. The raising edge of the strobe generates an interrupt (if it has been enabled) and causes the Ready line to go inactive. This very simple handshake is similar to that used in many peripheral devices."

Here we can't just rely on the Z80 PIO tech sheet. There are differences in the way port "A" printer port and the way the USER port "B" is wired.

Differences between Printer port M001 and User port M002
As labelled in the INTRODUCTION TO THE EINSTEIN MANUAL
USER PORT B
RDY pin 5 connects to Z80 PIO BRDY output
STB pin 11 connects to Z80 PIO BSTB input
PRINTER PORT
ACK pin 19 connects to ASTB on the Z80 PIO input
Strobe pin 1 connects via monostaple (I053bEE) then to ARDY on Z80 PIO output.

From the Einstein Hardware Manual.
Port A is dedicated as a printer output by MOS at power-on, and this port has a monostable (IO53b) [this is a circuit using a 74LS123 chip] which provides  a (1us) pulse triggered by the ready line of the PTO port A and is fed to the strobe output (M001, pin 1). This pulse is needed to comply with the centronics printer-interface timing.

I understand this to mean that the high on pin 1 strobe would be mainly off and only going on for short bursts when data has been put on the data lines. I have tested this with the BBC4W program (listing attached) and by using strobe from pin 1 to power an LED. Strobe from my Einstein stays permanently high.

Without another Einstein to test with the Einstein's user port was used and I've based the programing for it on the MOS routines for the printer port.

The programing is provisional and still rudimentary. The routines for the interrupt,its scratch pad, the code to poll the scratch pad bit and code to configure the user port are located together in one lump. Ideally they should be placed up high in memory with the MOS routines. I've read somewhere that there is limited space up there intended for user programing. Code for import and output could also share the same interrupt routine and scratch pad.

WARNING: I've no great understanding of interrupt handling or system programing except as stated above I have deduced from reading MOS dis assemblies. According to Z80 PIO tech. sheet its ports can be used for daisy chaining a number of peripherals. I don't know how this works but if this has been unintentionally enabled it might have unseen affects.

During development of the program research on the web there was a warning not to use a RST instruction in the interrupt routine.

The PC Bbcbasic For Windows programs are a little untidy and might confuse but work the transfer as stated. I've tried to keep the programing here as basic to basic as I can. I've other programing using assembling routines that work. These programs work with WIN95/98 they will not work with 2000 or XP. There is a way to use direct port access with XP using third party software and I'm working on that at the moment.

Understanding how interrupt handling operates for the Z80 PIO ports in mode 0 and 1 has been the main objective. With that known there might be new hardware that can be attached such as memory modules. A link to the PC might mean that new hardware could be virtually simulated before a hardware build.





