PARALLEL INPUT & OUTPUT
ALLOCATING I/O BITS
The parallel port capability of TDS2020F depends on whether the analog and other facilities are used or not. There can be up to 41 bits of input or output, PIN CONNECTIONS, page 38, has details. This is a summary:
In allocating I/O study the pin connections and circuit diagram to make sure that pins are not used that have second functions needed later.
DRIVE CAPABILITY & INPUT LEVELS
See section 20 in the Hardware Manual for more electrical specifications.
Port 7 has Schmitt trigger inputs VT- 1.0 to 2.5V and VT+ 2.0 to 3.5V. There is a guaranteed minimum of 0.4V hysteresis. Maximum input capacitance on parallel ports is 15pF.
DIRECTION OF PORTS A & B
At power-up all are inputs, you must set up any outputs needed. In the data direction registers a 1 means output and a 0 is input. For Port A and Port B use the write-only register at address hex 81F0. This has 3 bits:
A copy of the content of address 81F0 should always be written to the user variable CFIGM . You can then change direction on just Port A or Port B without affecting the direction of the other. Read CFIGM , then AND or OR to give the new value, and put it to both address 81F0 and CFIGM . This is necessary because of the write-only nature of 81F0. You can always get its value from CFIGM , it is a mirror of the content of 81F0. Note that address 81F0 is a single byte, but CFIGM is a 16-bit word (as are all user variables). For example:
To set A and B as outputs:
3 DUP CFIGM ! $81F0 PC!
To change Port B to input:
CFIGM @ 5 AND DUP CFIGM ! $81F0 PC!
Posts A and B have an unspecified direction at power-up, but will be inputs within 200ms. External circuitry will need to take this into account.
ADDRESSING INPUT & OUTPUT
The ports are all memory-mapped and have these addresses in hex:
It is usually convenient to stay in the DECIMAL base and to define hex characters with the $ prefix. E.g. to output decimal 24 to Port 7:
24 $FF8E C!
Whenever you use a 16-bit input or output with @ or ! the top byte on the stack (which is the left two digits of the hex number) will be taken from, or put to, the lesser of the two adjacent addresses. The other byte corresponds to the greater of the two addresses.
Take care when using @ or ! because they will only work if the address is even. For example it is permissible to set both data direction register and data output on Port 9 with the instructions $FF34 $FFFE ! . This puts FF to address FFFE (direction register) and 34 to address FFFF (data register). Execution on an odd address will cause an ADDRESS ERROR trap. @ODD and !ODD can be used at any address, however.
The word pairs PC! C! and PC@ C@ have identical functions but the choice of which one to use depends on the memory being addressed. In summary:
If just one bit in an I/O or memory needs changing use the special bit set and clear words ONE and ZERO . Do not use them with write only addresses such as data direction registers, or with addresses shown above as needing special PC! & PC@ instructions, in particular ports A and B.
Parallel input and output can be almost indefinitely expanded, see the suggestions in PARALLEL INPUT & OUTPUT EXPANSION, page 299. This also has more software examples for using I/O.
USING ASSEMBLER FOR I/O
Fastest access to input and output is through assembly code. Simple primitive assembler I/O words can often result in the complete program running close to machine code speeds. Use MOVO, to output words or bytes. For input use MOVI, or any of the test, add, compare instructions etc. E.g.
CODE !PORT7 ( n - ) \ Output data n to Port 7
@R7+ R3 MOVI, \ pull n from stack to R3
B $FF8E )) R3 MOVO, \ move bottom byte of n out
\ to address hex FF8E
Now !PORT7 will write the top of the stack to Port 7. Use of the immediate with memory instructions can manipulate I/O bits directly and so are even faster. E.g.
CODE PULSE ( - ) \ Output narrow pulse on bit 7
\ of Port 7
B $FF8E )) 7 ## BSETI, \ set bit to logic 1
B $FF8E )) 7 ## BCLRI, \ clear it to logic 0
For Ports A & B and other clock synchronised peripherals the assembler equivalents to PC! PC@ are as shown in these examples:
CODE !A ( n - ) \ Output byte n to Port A
@R7+ R3 MOVI, \ pull n from stack B
$81E0 )) R3 MOVTPE, \ MOVe byte To Peripheral
\ with E clock
CODE @A ( - n ) \ Input byte n from Port A
B $81E0 )) R3 MOVFPE, \ MOVe byte From
\ Peripheral with E clock
@-R7 R3 MOVO, \ push n to stack