Article 1285 of alt.sys.perq: Path: mystica!uunet!pipex!warwick!bsmail!siva.bris.ac.uk!ard From: ard@siva.bris.ac.uk (PDP11 Hacker .....) Newsgroups: alt.sys.perq Subject: Microcode Part 2 Message-ID: <21NOV199416591459@siva.bris.ac.uk> Date: 21 Nov 94 15:59:00 GMT Sender: usenet@info.bris.ac.uk (Usenet news owner) Organization: University of Bristol Physics Department Lines: 96 News-Software: VAX/VMS VNEWS 1.41 Nntp-Posting-Host: siva.bris.ac.uk Here, as promised, is the second part of the introduction to microcode. This bit covers reading an input port. ---- Reading from an Input Port -------------------------- The last section showed the standard method for outputing data to a port, an operation that is performed in one instruction cycle. The converse operation, reading data from a port, is less simple - it takes 2 instructions and thus 2 cycles. The first instruction addresses the input port and copies the data into an internal IOD (I/O Data) register in the CPU. The second instruction transfers the data into the ALU for processing. In order to try out the example programs, it is necessary to have a PERQ fitted with an OIO card having the PERQlink circuitry. The examples use the 16 data lines of the PERQlink input as a 16-bit User input port, and display the decimal value read from this port on the CRT. Here is the microcode for reading the port : !userin.micro !read value from user input port (=perqlink in) define(r330,330); place(7000,7777); loc(7000), iob(42),next; ! Copy User input to IO latch r330:=iod,next; ! Read IO latch into register tos:=r330,push,next; ! Push onto stack nextinst(0); end; The 'iob(42)' phrase addresses the perqlink input port and copies the data into the IOD register. The 'r330:=iod' phrase in the next instruction then transfers it into a CPU register. The other instructions should be familiar by now. Since this program requires no arguements from the pascal driver, it may be called using the 'jumpcontrolstore' procedure, as illustrated by the following pascal program. program userin(input,output); imports controlstore from controlstore; var microcode:microfile; x:integer; begin; reset(microcode,'userin.bin'); loadcontrolstore(microcode); close(microcode); repeat; jumpcontrolstore(#7000); storexpr(x); write('x=',x:0,' '); until false; end. This program repeatedly calls the microcode and displays the returned value. There are no new concepts here, and so no explanation will be given. Transfer the 2 files to the PERQ using kermit (or type them in using the editor), and build them in the usual way. When the program is executed it will print x= -1 repeatedly. Since the input lines are pulled up by resistors in the PERQ, an unconnected input is read as a 1, and thus the octal value 177777 (decimal -1) is read. If an input data bit is grounded, the displayed value will change to reflect the new value read from the port. The input lines can be found on the top connector on the OIO board with pin 39 as bit 0, pin 37 as bit 1, etc. All the even-numbered pins (component side) are ground. Since an unconnected pin is read as a logic 1, it is sensible to treat the port as having active-low data lines and to invert the data before displaying it. This can be done by changing the microcode to the following : !userin.micro !read value from user input port (=perqlink in) define(r330,330); place(7000,7777); loc(7000), iob(42),next; ! Copy User input to IO latch r330:=iod,next; ! Read IO latch into register tos:=not r330,push,next; ! Push onto stack nextinst(0); end; The only change is that the complement of r330 is pushed onto the stack. As in the case of active-low data output, this change needs no more instructions and takes no more machine cycles. When the userin.pas program is executed with this microcode, it prints 0 repeatedly, and grounding a particular data line causes 2^(that line) to be displayed. -tony Bristol University takes no responsibility for the views expressed in this posting. They are the personal views of the user concerned.