From:	CSBVAX::MRGATE!@KL.SRI.Com,@wiscvm.wisc.edu:UHAC010@VAXB.RHBNC.AC.UK@SMTP 27-SEP-1987 08:53
To:	EVERHART
Subj:	Accessing the Q-bus on uVax II

Received: from wiscvm.wisc.edu by KL.SRI.COM with TCP; Sun 27 Sep 87 05:16:48-PDT
Received: from UKACRL.BITNET by wiscvm.wisc.edu ; Sun, 27 Sep 87 07:16:16 CDT
Received: from RL.IB by UKACRL.BITNET (Mailer X1.24) with BSMTP id 4523; Sun,
 27 Sep 87 13:15:49 BST
Via:      UK.AC.RL.EARN; Sun, 27 Sep 87 13:15:49 BST
Received: from RL.IB by UK.AC.RL.IB (Mailer X1.24) with BSMTP id 4522; Sun, 27
          Sep 87 13:15:49 BS
Via:      UK.AC.RHBNC.VAXB; 27 SEP 87 13:15:41 BST
Date:     27-SEP-1987 13:15:48
From:     UHAC010@VAXB.RHBNC.AC.UK
To:       info-vax@KL.SRI.COM
Subject:  Accessing the Q-bus on uVax II

Dave Martin wrote: (14-Sep-1987):

> I have the Data Translation High Resolution frame grabber board DT2651
> and coprocessing board DT2658, and a MicroVax II/GPX running MicroVMS 4.5
> and VWS window services 3.1.  If anyone has drivers for these boards or
> could offer suggestions about how to address the memory and control
> registers on the Q-Bus, please let me know.

Well, I can't help you with those specific boards, but I enclose a program
to produce an address map of the Q-bus, some hints on Q-bus access and a
request for information from other hardware hackers (C'mon you're not all
quiche eaters on INFO-VAX are you?)

I use homebrewed VMEbus hardware to do image processing under the control
of (previously) PDP-11s and (now) uVaxen using Pascal. The attached piece
of code shows you how to do this. The program maps the Q-bus to a Pascal
array using PFN mapping. An error handler is established to detect Qbus
time outs and the array is then scanned for active addresses. The terminal
displays a list of active addresses (in octal! spot the PDP-11 bias) and
their contents.

WARNING:
 You need PFN map privilege to run this program. Since you will be reading
every location in the Q-bus I/O page you may corrupt disk controllers,
Ethernet ports etc. If you do this on a uVAX with multiple users you may
cause serious problems.

 I have run this code on uVax IIs where I am the only user with no ill
effects, but I haven't tried it on my GPX, or on a machine with an active
Ethernet controller. It's very useful for finding out exactly which
addresses are in use.

 Before all you Pascal people jump on me for the messiness in the mainline
routine - the VMS error-handling routines do NOT allow you to transfer
control back into a structured statement (although I must admit I haven't
actually tried).

 Q-bus hints and gotchas:
 The Q-bus I/O page lives at physical addresses $20000000 and up. Note that
the first byte of the I/O page (ie virtual 160000 for all you RT11 FB
users) corresponds to physical $20000000, it is preceded by the rest of
Q-bus I/O space. That lives at uVAX physical $30000000.

 There are _significant_ limitations on how you may access I/O space even
when it is mapped. According to the VMS device drivers book (which is
primarily documenting Unibus Vaxen) you may only use indirect addressing
(ie the virtual address which you want to hit must be in a register),
only some of the instructions (the simple ones) work, and only word addressing
is supported.

 Some, but not all, of the restrictions seem to apply to the uVAX II. Use
of an array in Pascal is sufficient to ensure that indirect addressing is
used, although a very smart compiler could conceivably 'optimise' your code
into an invalid addressing mode. I've had no trouble using byte, word or
longword addressing on the microVAX, but beware fancy instructions. I tried
some assembler that should have packed a word array down into bytes on the
Qbus and got nothing but machine checks. Similarly, I have not been able to
get absolute addressing to work.

 This is a pain, because in the PDP-11 incarnation of my software I could
use an 'ORIGIN' construct to declare Pscal variables on top of machine
locations, and then access them just like any other simple variable.
Currently on VMS I have to use an array and access these locations
indirectly, which incures run-time overhead and is syntactically messy in
the source code.

QUESTIONS:
 I note that VMS Pascal does have an ORIGIN attribute (a hangover from
VAXEln?). How do I use this and what do I have to do to the linker to make
it establish absolute PSECTs?

 What is the reason for the hardware restictions on Q-bus access, and does
it affect access to Q-bus main memory (ie the $30000000 region).

 Has anybody accessed Q-bus main memory? How does the Q-bus map work on the
microVAX?

 If you can, reply to me directly and I will summarise to the net. Any
hints, code etc will be gladly received. This is the first time I have sent
anything to the states - I hope my return addresses are correct and offer
sincere apologies in advance if they're not

                         Adrian Johnstone, University of London.

--- cut here --------------------------------------------------------------

[INHERIT ('SYS$LIBRARY:STARLET')] PROGRAM q_bus(INPUT,OUTPUT);

$ QBUS.PAS
  This program creates and maps a private section by PFN onto the Q-22 bus
  I/O page. Data in the section is accessed through an array 

LABEL
 1111, 9998, 9999;

CONST
 io_space_base=%x20000000;

TYPE
 byte_integer= [BYTE] 0..255;
 Int_Pointer=byte_integer;
 sig_args = ARRAY[0..100] OF integer;    $signal parameters
 mech_args = ARRAY[0..4] OF [unsafe] integer;   $mechanism parameters

VAR
 my_adr, sys_adr: ARRAY[1..2] OF int_pointer;
 iopage: [GLOBAL,VOLATILE,ALIGNED(9)] ARRAY [0..8191] OF byte_integer;
 offset, io_page_pfn, addr:integer;
 name: PACKED ARRAY [1..4] OF char;
 temp,sys_stat: integer;

PROCEDURE lib$stop(%IMMED cond_value: integer); external;

[ASYNCHRONOUS] FUNCTION handler_0(VAR SA: sig_args; VAR ma: mech_args):
                                                         [UNSAFE] integer;

BEGIN
 GOTO 9998;
 handler_0:=ss$_resignal
END;

BEGIN
 establish(handler_0);

 $obtain starting and ending addresses of the section
 my_adr[1]:=address(iopage[0]);
 my_adr[2]:=address(iopage[8191]);

 io_page_pfn:=(io_space_base) DIV 512;
 sys_stat:=$crmpsc(inadr:=my_Adr,
                   retadr:=Sys_Adr,
                   flags:=sec$m_pfnmap+sec$m_wrt,
                   pagcnt:=16,
                   vbn:=io_page_pfn);
 IF NOT ODD (Sys_Stat) THEN LIB$STOP (Sys_Stat);
 offset:=-1;
1111:
 offset:=offset+1;
 IF offset=8192 THEN GOTO 9999;
 temp:=iopage[offset];
 writeln('read address: ',oct(offset),' data is ',oct(temp));
 GOTO 1111;
9998:
 GOTO 1111;
9999:
END.

---------------------------------------------------------------------------

------------------------------------------------------------------------------

Adrian Johnstone,

Mail:    Royal Holloway & Bedford New College, Egham, Surrey, TW20 0EX, England
Phone:    0784 39025
Fax:    0784 37520
Telex:    935504 RHC
Email:
 Janet:    uhac010@uk.ac.rhbnc.vaxa
 Arpa:    uhac010%vaxa.rhbnc.ac.uk@cs.ucl.ac.uk
 Bitnet/NetNorth/Earn:    uhac010@vaxa.rhbnc.ac.uk

------------------------------------------------------------------------------
