                            LISTINGS

The programing enclosed is provisional and rudimentary example to demomstrate user port interrupt hand shaking for the Z80 PIO working. This uses a parallel link from the Einstein's user port to a PC ECCP printer port set for byte mode. BBCBASIC is used for the Einstein and BBCBASIC FOR WINDOWS used on the PC.

 POUT_WIN.BBC  FOR BBCBASIC FOR WINDOWS works in combination with U_IN_EN.BBC for the Einstein
 P_IN_WIN.BBC  FOR BBCBASIC FOR WINDOWS works in combination with U_OUT_EN.BBC for the Einstein
 Both combinations when run in there respctive machines will print ASCII characters to the       
 recipent programs screen.

=============================POUT_WIN BBC4W PROG==================================

      *|Windows BBC4W program POUT_WIN.BBC  works with
      *|U_IN_EN.BBC running in the Einstein
      *|PC WINDOWS PROGRAM TO RUN IN BBCBASIC FOR WINDOWS
      *|
      *|This BBC4W Prog will work for win95/98 only
      *|It works in conjunction with the Einstein
      *|with linked printer ports or with the user
      *|port on the Einstein. It will output data bytes
      *|to the program U_IN_EN.BBC running on the Einstein.
      *|
      *|The linking printer cable is simply wired -
      *|         WIRING EINSTEIN PRINTER PORT
      *|PC data lines D0 to D7 to Einstein D0 to D7
      *|PC strobe to Einstein acknowledge
      *|PC acknowledge to Eistein Strobe.
      *|Plus one or more ground lines.
      *|
      *|         WIRING EINSTEIN USER PORT
      *|PC data lines D0 to D7 to Einstein D0 to D7
      *|PC strobe to Einstein STB
      *|PC acknowledge to Eistein RDY.
      *|Plus one or more ground lines.
      *|Using the user port will require programming
      *|for the Einstein. See U_IN_EN.BBC for the Einstein.
      *|
      *|        USING EINSTEIN PRINTER PORT "A"
      *|It could be a fault with my Einstein that the
      *|strobe pin is not pulling low and resetting
      *|acknowledge low on the PC.
      *|Therefore-
      *|Exporting bytes to the Einstein's printer port
      *|has not been tried with this program.
      *|
      *|      WHEN Linked To The Einstein User Port
      *|All handshaking lines work as expected and data
      *|can be received by U_IN_EN.BBC when run on the Einstein.

      *|                 LPT 1 PORT ADDRESSES
      datap%=&378   :           *| printer data port
      status%=&378+1:           *| status port
      controll%=&378+2:         *| controll port
      eccport%=&378+&402:       *| extended controll port

      *| *********************************************
      *| Code to access
      *| input/output ports directly,
      *| BBC4W HELP "Direct port input/output"
      DIM P% 6
      [OPT 0
      .inport in al,dx : movzx eax,al : ret
      .outport out dx,al : ret : ]
      REM D% = address%         :*|input example
      REM data% = USR(inport)
      REM
      REM D% = address%         :*|output example
      REM A% = data%
      REM CALL outport
      *| **********************************************
      *| CONFIGER ENHANCED PARALLEL PORT BYTE MODE
      PROC_setup_eccp
      *| SET PRINTER PORT FOR OUTPUT
      PROC_setup_controll
      *| *********************************************
      *|                         ********************
      *|               ****************************************
      *|        *****************************************************************
      *|********** MAIN PROGRAM FOR EXPORTING Bytes TO THE PRINTER PORT ******************
      *|
      *|
      PRINT "      MAIN PROGRAM FOR EXPORTING BYTES TO THE PRINTER PORT "
      PRINT "PRESS ANY KEY TO CONTINUE MAIN PROGRAM "
      H=GET


      REPEAT
        FOR i=32 TO 126
          D$=INKEY$(0)
          PROC_strb_low
          REPEAT:PROC_poll_ack:UNTIL ack%=64
          E=i
          D% = datap%
          A% = E
          CALL outport
          PROC_strb_high
        NEXT i
      UNTIL D$="A"
      STOP
      *| *******************************************************************************


      DEF PROC_setup_eccp
      D% = eccport%
      data% = USR(inport)
      data%=data% AND %00111111         :*| ; to set bits 6 & 7 to 0
      data%=data% OR %00100000          :*|  ; to set bit 5 to 1
      :
      :                      *|; needed to set ECP port to byte mode. 001XXXXX
      D% = eccport%
      A% = data%
      CALL outport
      D$=FN_BIN(data%)
      PRINT "ENHANCED PARALLEL PORT BIT PATTEN    " D$
      PRINT"Needed to set ECP port to byte mode. %001XXXXX"
      PRINT
      ENDPROC

      DEF PROC_setup_controll
      D% = controll%
      data% = USR(inport)
      data%=data% OR %00000001        :*| ; set bits 0 to 1 inverted 1 sets STROBE line to low.
      data%=data% AND %11011111       :*| ; bit 5 set to 0 for output
      D% = controll%
      A% = data%
      CALL outport
      D$=FN_BIN(data%)
      PRINT "CONTROLL PORT BIT PATTEN                     ";D$
      PRINT " Needed bit 5 set to 0 for data outport      %XX0XXXXX"
      PRINT " To set bit 0 to 1. Sets STROBE line to low. %XXXXXXX1"
      PRINT " STROBE line hardware inverted"
      PRINT
      ENDPROC

      DEF PROC_strb_high
      D% = controll%
      data% = USR(inport)
      data%=data% AND %11011110        :*| ; set bit 0 to 0. Inverted-0 sets STROBE line to high.
      :                                 *| ; bit 5 set to 0 maintain byte import.
      D% = controll%
      A% = data%
      CALL outport
      REM D$=FN_BIN(data%)
      REM PRINTD$
      ENDPROC

      DEF PROC_strb_low
      D% = controll%
      data% = USR(inport)
      data%=data% OR %00000001        :*| ; set bit 0 to 1. Inverted-1 sets STROBE line to low.
      :                                *| ; bit 5 set to 1 maintain byte import.
      D% = controll%
      A% = data%
      CALL outport
      REM D$=FN_BIN(data%)
      REM PRINT D$
      ENDPROC

      DEF PROC_poll_ack
      D% = status%
      ack% = USR(inport)
      ack%=ack% AND %01000000
      REM D$=FN_BIN(data%)
      REM PRINT D$
      ENDPROC

      *| *************** FUNCTION PRINTS OUT BINARY STRING OF VAR *************
      *| E,G VAR NUMERIC VALUE 7 WOULD RETURN STRING VAR %00000111
      DEF FN_BIN(A%):LOCAL A$
      REPEAT A$=STR$(A% AND 1)+A$:A%=A% >>> 1:UNTIL LEN A$=8:A$="%"+A$
      =A$
      *| **********************************************************************

=============================REM U_IN_EN.BBC for theEinstein =================================

   10 REM U_IN_EN.BBC EINSTEIN BBCBASIC PROGRAM
   20 REM TEST PROGRAM TO IMPORT DATA BYTES
   30 REM FROM THE USER PORT USING INTERRUPT HANDSHAKING
   40 REM IMPORT CAN BE RECEIVED FROM A PC ECCP PRINTER PORT
   50 REM RUNNING POUT_WIN.BBC IN BBCBASIC FOR WINDOWS
   60 REM ECCP SET TO BYTE MODE AND FOR IMPORT.
   70 REM
   80 REM *| WIRING EINSTEIN USER PORT/PC PRINTER PORT
   90 REM *|PC data lines D0 to D7 to Einstein D0 to D7
  100 REM *|PC strobe to Einstein STB
  110 REM *|PC acknowledge to Eistein RDY.
  120 REM *| PLUS ONE OR MORE GROUND
  130 REM *
  140 ON ERROR GOTO 1140
  150 HIMEM=HIMEM-80
  160 PRINT~HIMEM:H=GET
  170 usrcon=&33
  180 usrdata=&32
  190 REM CODE BEGINS AT ADDRESS &E971  REM these values added
  200 REM END CODE ADDRESS &E9B5        REM for use with other
  210 REM flag=start_code+&0            REM assemblers if the
  220 REM configpio =start_code+&12     REM code is changed
  230 REM getbyte =start_code+&29       REM they will be printed
  240 REM imput_byte=start_code+&43     REM out after assembling.
  250 REM CODE SIZE 68
  260 DIM code 80
  270 code=HIMEM+1
  280 PRINT "Assembling..."
  290 :
  300 FOR pass=0 TO 1
  310   P%=code
  320   [OPT pass*3
  330   .start_code
  340   .flag DEFB 0
  350   .intrrpt
  360   PUSH HL
  370   PUSH DE
  380   PUSH BC
  390   PUSH AF
  400   LD HL,flag
  410   RES 1,(HL)
  420   POP AF
  430   POP BC
  440   POP DE
  450   POP HL
  460   EI
  470   RETI
  480   RET
  490   .configpio
  500   LD  A,&12    ;sets low byte of interrupt address
  510   OUT (usrcon),A  ;writes to parallel printer port reg &10 %00010000
  520   LD  A,&4F    ;sets PIO to mode 1
  530   OUT (usrcon),A  ;writes to parallel printer port reg &0F %00001111
  540   LD  A,&87    ;enables interrupts
  550   OUT (usrcon),A  ;writes to parallel printer port reg &87 %10000111
  560   PUSH HL
  570   LD HL,intrrpt
  580   LD (&FB12),HL
  590   POP HL
  600   IM 2
  610   RET
  620   .getbyte
  630   PUSH HL
  640   PUSH DE
  650   PUSH BC
  660   PUSH AF
  670   LD HL,flag
  680   .POLL
  690   LD HL,flag
  700   BIT 1,(HL)
  710   JR NZ,POLL
  720   IN A,(usrdata)
  730   LD (imput_byte),A
  740   SET 1,(HL)
  750   POP AF
  760   POP BC
  770   POP DE
  780   POP HL
  790   RET
  800   .imput_byte DEFB 0
  810   .end
  820   ]
  830 NEXT pass
  840 CALL configpio
  850 PRINT "CODE BEGINS AT ADDRESS &";~start_code
  860 PRINT "END CODE ADDRESS &";~end
  870 PRINT "flag=start_code+&";~flag-start_code
  880 PRINT "configpio =start_code+&";~configpio-start_code
  890 PRINT "getbyte =start_code+&";~getbyte-start_code
  900 PRINT "imput_byte=start_code+&";~imput_byte-start_code
  910 PRINT "CODE SIZE "; end-start_code
  920 PRINT "PRESS ANY KEY TO START"
  930 REM USER PROGRAMING CAN BE ADDED HERE
  940 REM RECEIVED IMPORT BYTES FROM USER PORT
  950 REM ARE FOUND BY CALLING getbyte THEN
  960 REM PEEKING THE ADDRESS imput_byte
  970 REM "n=?imput_byte" IN BBCBASIC
  980 REM
  990 REM IN THE EXAMPLE PROGRAM BELOW
 1000 REM BYTE VALUES 32 to 126 TO BE PRINTED
 1010 REM TO SCREEN AS ASCII CHARACTERS IN THE PC
 1020 REM WITH BBC4W RUNNING P_IN_WIN.BBC
 1030 REM
 1040 PRINT "PRESS ANY KEY TO RUN EXAMPLE PROGRAM"
 1050 H=GET
 1060 REPEAT
 1070   D$=INKEY$(0)
 1080   n=?imput_byte
 1090   CALL getbyte
 1100   IF n=13 PRINT
 1110   IF n=>32 AND n=<126 PRINT CHR$(n);
 1120 UNTIL D$="A" OR n=27
 1130 STOP
 1140 REPORT:PRINT "AT LINE ";ERL:STOP


=============================U_OUT_EN for the Einstein==========================================
              
   10 REM U_OUT_EN.BBC EINSTEIN BBCBASIC PROGRAM
   20 REM TEST PROGRAM TO OUTPUT DATA BYTES
   30 REM TO THE USER PORT USING INTERRUPT HANDSHAKING
   40 REM OUTPUT CAN BE RECEIVED BY A PC ECCP PRINTER PORT
   50 REM USING BYTE MODE SET FOR IMPORT.
   60 REM RECIEVED ASCII DATA BYTES CAN BE READ TO SCREEN BY
   70 REM P_IN_WIN.BBC PROGRAM RUN BY BBCBASIC FOR WINDOWS.
   80 REM
   90 REM *| WIRING EINSTEIN USER PORT/PC PRINTER PORT
  100 REM *|PC data lines D0 to D7 to Einstein D0 to D7
  110 REM *|PC strobe to Einstein STB
  120 REM *|PC acknowledge to Eistein RDY.
  130 REM *| PLUS ONE OR MORE GROUND
  140 REM *
  150 ON ERROR GOTO 1020
  160 HIMEM=HIMEM-80
  170 PRINT~HIMEM:H=GET
  180 DIM code 80
  190 code=HIMEM+1
  200 REM configpio =start_code+&11 :REM THESE VALUES ARE TO GIVE
  210 REM outbyte =start_code+&3F   :REM REFERENCE FOR OTHER ASSEMBLERS
  220 REM PAOUT =start_code+&28     :REM IF ASSEMBLE CODE IS ALTERED
  230 REM CODE SIZE 64              :REM NEW VALUES WILL BE PRINTED OUT
  240 PRINT "Assembling..."         :REM BY BASIC LINES 810 to 850
  250 :
  260 FOR pass=0 TO 1
  270   P%=code
  280   [OPT pass*3
  290   .start_code
  300   .flag DEFB 0       ;LATCH BYTE FOR INTERRUPT
  310     .intrrpt           ;        INTERUPT ROUTINE
  320     PUSH HL            ;
  330     PUSH DE            ;SAVE REGISTERS
  340     PUSH BC            ;
  350     PUSH AF            ;
  360     LD HL,flag         ;GET ADDRESS OF flag BYTE INTO HL
  370     RES 0,(HL)         ;SET BIT 0 OF flag TO 0
  380     POP AF             ;          Note RST ops SHOULD NOT BE
  390     POP BC             ;                USED IN AN INTERRUPT ROUTINE
  400     POP DE             ;RESTORE REGISTERS
  410     POP HL             ;
  420     EI                 ;ENABLE INTERRUPTS
  430     RETI               ;RETURN FROM INTERRUPT
  440     .configpio
  450     LD  A,&12    ;sets low byte of interrupt address
  460     OUT (&33),A  ;writes to USER port reg &12 %00010000
  470     LD  A,&0F    ;sets PIO to mode 0
  480     OUT (&33),A  ;writes to USER port reg &0F %00001111
  490     LD  A,&87    ;enables interrupts
  500     OUT (&33),A  ;writes to USER port reg &87 %10000111
  510     PUSH HL
  520     LD HL,intrrpt  ;LOAD HL INTERRUPT START ADDRESS
  530     LD (&FB12),HL  ;LOAD USER PORT SCRATCH PAD INTERRUPT ADDRESS
  540     POP HL
  550     IM 2           ; ENABLE INTERRUPT 2 MODE
  560     RET
  570     .PAOUT
  580     PUSH HL
  590     PUSH DE            ;SAVE REGISTERS
  600     PUSH BC
  610     PUSH AF
  620     LD HL,flag    ; FLAG FOR USER PORT INTERRUPT.
  630       .POLL
  640       BIT 0,(HL)
  650       JR NZ,POLL
  660       LD A,(outbyte)
  670       OUT (&32),A        ; outport Parallel port data reg.
  680       SET 0,(HL)
  690       POP AF
  700       POP BC
  710       POP DE             ;RESTORE REGISTERS
  720       POP HL
  730       RET
  740       .outbyte DEFB 0       ;USER LOADS BYTE FOR OUTPUT
  750         .end  RET
  760         ]
  770       NEXT pass
  780       CALL configpio
  790       PRINT "CODE BEGINS AT ADDRESS &";~start_code
  800       PRINT "END CODE ADDRESS &";~end
  810       PRINT "configpio =start_code+&";~configpio-start_code
  820       PRINT "outbyte =start_code+&";~outbyte-start_code
  830       PRINT "PAOUT =start_code+&";~PAOUT-start_code
  840       PRINT "CODE SIZE "; end-start_code
  850       PRINT "PRESS ANY KEY TO START"
  860       H=GET
  870       REM THE EXAMPLE CODE CODE BELOW CAN BE CHANGED
  880       REM THE INSTALLED MACHINE CODE CAN BE USED TO
  890       REM SEND ANY BYTE OUT TO THE USER PORT
  900       REM BY LOADING outbyte ADDRESS WITH THE
  910       REM BYTE TO BE SENT AND CALLING PAOUT
  920       REPEAT
  930         D$=INKEY$(0)
  940         FOR I=32 TO 126
  950           ?outbyte=I
  960           CALL PAOUT
  970           PRINT" ";I;
  980         NEXT I
  990       UNTIL D$="A"
 1000       PRINT"END END END END "
 1010       STOP
 1020       REM
 1030       REPORT:PRINT "AT LINE ";ERL:STOP
 1040

============================P_IN_WIN.BBC========================================================
      
      *|This BBC4W Prog will work for win95/98 only
      *|It works in conjunction with the Einstein
      *|with linked printer ports or with the user
      *|port on the Einstein runing U_OUT_EN.BBC.
      *|
      *|
      *|The linking printer cable is simply wired -
      *|         WIRING EINSTEIN PRINTER PORT
      *|PC data lines D0 to D7 to Einstein D0 to D7
      *|PC strobe to Einstein acknowledge
      *|PC acknowledge to Eistein Strobe. Plus GND.
      *|
      *|         WIRING EINSTEIN USER PORT
      *|PC data lines D0 to D7 to Einstein D0 to D7
      *|PC strobe to Einstein STB
      *|PC acknowledge to Eistein RDY.
      *|Using the user port will require programming
      *|for the Einstein.
      *|
      *|        USING EINSTEIN PRINTER PORT "A"
      *|Any text Output to the printer on the Einstein
      *|such as pressing CTRL+R keys should be printed
      *|on the PC in the BBC4W window with this program.
      *|
      *|It could be a fault with my Einstein that the
      *|strobe pin is not pulling low and resetting
      *|acknowledge low on the PC. It causes this
      *|program to repeatedly print the character on
      *|the printer port data lines.
      *|
      *|A timing delay  D$=INKEY$(6) does stop streams
      *|of data characters from repeating duplicate bytes
      *|but there is no halt for the last character output.
      *|
      *|The value in D$=INKEY$(6) might need ajusting
      *|according to how printer output is made from the
      *|Einstein
      *|
      *|Handshaking with the Einstein's acknowledge does
      *|work with a strobe from the PC.
      *|
      *|      WHEN Linked To The Einstein User Port
      *|All handshaking lines work as expected.
      *|
      *|                 LPT 1 PORT ADDRESSES
      datap%=&378   :           *| printer data port
      status%=&378+1:           *| status port
      controll%=&378+2:         *| controll port
      eccport%=&378+&402:       *| extended controll port
      *| *********************************************
      *| Code to access to access
      *| input/output ports directly,
      *| BBC4W HELP "Direct port input/output"
      DIM P% 6
      [OPT 0
      .inport in al,dx : movzx eax,al : ret
      .outport out dx,al : ret : ]
      *| *********************************************
      
      *| ************* SET UP PRINTER PORT FOR BYTE MODE ****************
      PRINT"     ************** ENHANCED CAPABILTY PORT *************"
      D% = eccport%
      data% = USR(inport)
      data%=data% AND %00111111         :*| ; to set bits 6 & 7 to 0
      data%=data% OR %00100000          :*| ; to set bits 6 & 7 to 0
      :                                  *|  ; to set bit 5 to 1
      :                      *|; needed to set ECP port to byte mode. 001XXXXX
      D% = eccport%
      A% = data%
      CALL outport
      D$=FN_BIN(data%)
      PRINT "ENHANCED PARALLEL PORT BIT PATTEN    " D$
      PRINT"Needed to set ECP port to byte mode. %001XXXXX"
      *|*************** SET UP CONTROLL PORT FOR BYTE IMPORT ****************
      PRINT"    *********** CONTROLL PORT *************"
      D% = controll%
      data% = USR(inport)
      data%=data% OR %00100001        :*| ; set bits 0 & 1 inverted 1 sets STROBE line to low.
      :                                *| ; bit 5 set to 1
      D% = controll%
      A% = data%
      CALL outport
      D$=FN_BIN(data%)
      PRINT "CONTROLL PORT BIT PATTEN                     ";D$
      PRINT " Needed bit 5 set to 1 for data import       %XX1XXXXX"
      PRINT " To set bit 0 to 1. Sets STROBE line to low. %XXXXXXX1"
      PRINT " STROBE line hardware inverted"
      PRINT
      *|                         ********************
      *|               ****************************************
      *|        *****************************************************************
      *|******* Main Program For Importing Bytes And Printing Characters to Screen *********
      *|
      *|
      PRINT "Main Program For Importing Bytes And Printing Characters to Screen "
      PRINT "PRESS ANY KEY TO CONTINUE MAIN PROGRAM "
      H=GET
      REPEAT
        PROC_strb_low
        *| ********** CODE TO POLL ACKNOWLEDGE AND RECEIVE DATA *****************
        *| *************************
        *| ****** NEXT CODE POLLS ACKNOWLEGE PIN FOR A HIGH
        *| ****** THIS SHOULD BE SET BY STROBE PIN 1 ON THE EINSTEIN PRINTER PORT
        *| ****** IMPORTS FROM THE DATA PORT
        *| ****** AND PRINTS ASCII CHARACTERS TO SCREEN
        *| ****** THE STROBE ON MY EINSTEIN'S PRINTER PORT PIN 1 IS NOT PULLING LOW
        *| ****** WITH THE USER PORT
        *| ****** RDY PIN 5 ON THE EINSTEIN'S USER PORT WORKS FINE.
        key$=INKEY$(0)
        REPEAT
          PROC_poll_ack
          IF ack%<>0 THEN
            D% = datap%
            data% = USR(inport)
            IF data%=13 PRINT CHR$(data%)
            IF data% =>32 AND data%=<126 PRINT CHR$(data%);
            PROC_strb_high
          ELSE
            REM PRINT "~"; :REM Debugging line
          ENDIF
        UNTIL ack%<>0
        *| ************************ END OF TO RECEIVE DATA  ********************
        *|
        
      UNTIL key$="A" OR key$="a"
      *|  ***********************************************************************
      *|            ***************************************************
      *|                    ***********************************
      
      DEF PROC_strb_high
      REM PRINT"HIGH "
      D% = controll%
      data% = USR(inport)
      data%=data% AND %11111110  :*| ; set bit 0 to 0. Inverted-0 sets STROBE line to high.
      :                           *| ; bit 5 set to 1 maintain byte import.
      D% = controll%
      A% = data%
      CALL outport
      REM D$=FN_BIN(data%) :REM Debugging line
      REM PRINTD$          :REM Debugging line
      ENDPROC
      
      DEF PROC_strb_low
      D% = controll%
      data% = USR(inport)
      data%=data% OR %00100001   :*| ; set bit 0 to 1. Inverted-1 sets STROBE line to low.
      :                           *| ; bit 5 set to 1 maintain byte import.
      D% = controll%
      A% = data%
      CALL outport
      REM D$=FN_BIN(data%) :REM Debugging line
      REM PRINT D$         :REM Debugging line
      ENDPROC
      
      DEF PROC_poll_ack
      D% = status%
      ack% = USR(inport)
      ack%=ack% AND %01000000
      REM D$=FN_BIN(data%):REM Debugging line
      REM PRINT D$        :REM Debugging line
      ENDPROC
      
      *| *************** FUNCTION PRINTS OUT BINARY STRING OF VAR *************
      *| E,G VAR NUMERIC VALUE 7 WOULD RETURN STRING VAR %00000111
      DEF FN_BIN(A%):LOCAL A$
      REPEAT A$=STR$(A% AND 1)+A$:A%=A% >>> 1:UNTIL LEN A$=8:A$="%"+A$
      =A$
      *| **********************************************************************
      
