• Please review our updated Terms and Rules here

Computek PCM210 - what is this ISA card?

That is a good guess. I'll spend some more time analyzing the code. That might go with the data bits at the end as well. They look like they might be mask of some type. It might be nothing more than a roller ball to serial.That fits with the shift and xor operations as well.
Dwight
 
It is also interesting that every time it sends a bit to the RCA, it makes a few uS blip on P2.6. It isn't wired out but it essentially like a synchronous clock. I suspect it is for test purposes. Each bit that is to be a +5 at the RCA is determined by the state of F0=1 while a -5 is F0=0. Most short runs of RS232 will see that properly. Now to dig a little more into the code.
Dwight
 
I've not fully figured it all out but I agree, this converts the track ball into data to send at 1200 baud to a serial port. It is an interface board.
If I had this, I's run the RCA to a serial input, set the port to 1200 baud, connect a quadrature signal to the pins and look at the serial data.
Dwight
 
There should be a couple of inputs dedicated to buttons as well, if my guess is right.

But so nothing exotic. Back in the day when a trackball was offered for a bunch of (very) different platforms, this makes sense for the PC--does the RCA jack appear to swing between EIA levels (that would explain the transistor)?
 
Looking at the code, I'd say the quadrature was on the pairs P1.4 - P1.5 and P1-6 - P1.7. The buttons were on P1.0, P1.1 and P1.2.
The RCA swings -5V to +5V. I think I recall that +-3V was enough for most serial inputs.
I guess the advantage was that the track ball was all just switches, with no electronics. The type of machine it was used in would determine the boards to translate it and what data to send. I noticed that the receiving end could even be a synchronous port as there was a clock signal on P2.6 and a different board.
Dwight
 
I do have to admit that what the board sends out is a little confusing. There are a number of shifts, xoring , anding and lookups before the data is put into the output register for sending. I think the easiest way is to plug it into a PC, connect the RCA to a serial in and put some switches on the 9 pin connector.
Without a '48 emulator, that is what I'd do.
Dwight
 
Hi!
I'm the one who started the thread on the "Verein zum Erhalt klassischer Computer" (roughly translates to "Vintage Computer preservation club") forum years ago.
Now one of my dear club colleagues, who's also active here, nudged me to this thread.

I found the card in an IBM 5155 I had acquired. There weren't any cables or adapters connected to it, and when pulling apart the machine I was instantly intrigued by the lack of connections on the ISA bus. I left the card out and tried figuring out, what it's supposed to do. I came to no conclusion, so I started the thread and shortly after forgot about the card...

Following this thread, an adapter from quadrature bus mouse to serial seems plausible, but why on earth would then someone plug this card into an C= PC30-III? Those slimline Commodore machines already have an Amiga-compatible quadrature bus mouse connector...
 
P1.4/5 and P1.6/7 are used to detect a direction of move and have to look like that:
Code:
Positive direction
     ______
____|      |_____
        ______
_______|      |_____
Negative direction
        ______
_______|      |_____
     ______
____|      |_____

Whenever a move is detected or any of P1.0-3 are pushed (for longer than 10ms), a message will be transmitted on the RCA.
The message seems to be built of bytes transmitted bit-by-bit from least significant to most significant.
Individual bytes are padded (separated) by 4 bits of 1.

Message seems to be always the following, regardless of what it triggered:
Code:
Byte 1: 10000XXX - XXX are values of P1.2, P1.1, P1.0
Byte 1: move delta of P1.4/5 since last message transmitted - can be positive or negative byte value 
Byte 3: move delta of P1.6/7 since last message transmitted - can be positive or negative byte value
Byte 4: repeated byte 2
Byte 5: repeated byte 3

I need to find a way to generate the move signals and will verify this hypothesis.
Or maybe someone has Computek trackball?
 
And the whole code with comments for reference:

Code:
	ORG	00007H

; disable external interrupt
	DIS	I		; 0007
; disable timer/counter interrupt
	DIS	TCNTI		; 0008
; select memory bank 0 and register bank 0
	SEL	MB0		; 0009
	SEL	RB0		; 000A
; set R2, R3, R4, R6, R7 to 0x00
	CLR	A		; 000B
	MOV	R2,A		; 000C
	MOV	R3,A		; 000D
	MOV	R4,A		; 000E
	MOV	R6,A		; 000F
	MOV	R7,A		; 0010
; set R1, R5 to 0xFF
	DEC	A		; 0011
	MOV	R1,A		; 0012
	MOV	R5,A		; 0013
; clear flags and complement F1
	CLR	F0		; 0014
	CLR	F1		; 0015
	CPL	F1		; 0016
; clear external ports
	OUTL	P1,A		; 0017
	OUTL	P2,A		; 0018

; initialize timer to 0xFA and start it
; timer runs at 7.457 kHz, this timer run will expire (overflow) in 6 cycles
; that is 0.8 ms
	STRT	T		; 0019
	MOV	A,#0FAH		; 001A
	MOV	T,A		; 001C

; 0xBF = clear P2.6
	ANL	P2,#0BFH	; 001D

; if F0 is set, enable P2.7 (will not happen on the first run)
	JF0	0025H		; 001F
	ORL	P2,#080H	; 0021
	JMP	029H		; 0023
;  otherwise disable P2.7 and enable P2.6
	ANL	P2,#07FH	; 0025
	ORL	P2,#040H	; 0029

;;;;;;;;;;;;;;
;; this section detects if any of P1.0, P1.1, P1.2 changed their state and kept
;; it changed for around 10ms 

; check if R7 is zero (will be at first run) 
	MOV	A,R7		; 002B
	ANL	A,#0FFH		; 002C
	JNZ	003BH		; 002E

; if R7 is zero: if any of P1.0, P1.1, P1.2 is zero on first run or
; changed their value from the previous check
; remember which one in R2 and set R7 to 12
		IN	A,P1		; 0030
		XRL	A,R1		; 0031
		ANL	A,#007H		; 0032
		JZ	0045H		; 0034
		MOV	R2,A		; 0036
		MOV	R7,#00CH	; 0037
		JMP	045H		; 0039

; decrement R7, if went down to zero check if P1.0, P1.1 or P1.2
; still have the changed values, if yes store the new values in R1 and clear F1
	DJNZ	R7,0045H	; 003B
	IN	A,P1		; 003D
	XRL	A,R1		; 003E
	ANL	A,R2		; 003F
	JZ	0045H		; 0040
	XRL	A,R1		; 0042
	MOV	R1,A		; 0043
	CLR	F1		; 0044
; F1=0 if such event happened
;;;;;;;;;;;;;;;;


; check if P1.4 or P1.5 changed their values
	IN	A,P1		; 0045
	XRL	A,R1		; 0046
	ANL	A,#030H		; 0047
	JZ	0062H		; 0049
; if yes, set F1 to 0 immediately
	CLR	F1		; 004B

; restore A to P1 value
	XRL	A,R1		; 004C
; replace A and R1: R1=P1 value, A=previous P1 (PP1)
	XCH	A,R1		; 004D
; PP1 >> 2
	RR	A		; 004E
	RR	A		; 004F

	ANL	A,#00CH		; 0050
	MOV	R0,A		; 0052
	MOV	A,R1		; 0053
; R0.3=PP1.5 R0.2=PP1.4 (rest is 0)

; here A contains P1 value again
	SWAP	A		; 0054
; keep only P1.4 and P1.5 on bits 0,1
	ANL	A,#003H		; 0055
; now we have on one nibble previous and current value of bits:
; A3-0 = PP1.5,PP1.4,P1.5,P1.4
	ORL	A,R0		; 0057
; now it is 0xF(PP1.5,PP1.4,P1.5,P1.4)
	ORL	A,#0F0H		; 0058
	MOVP	A,@A		; 005A

; read a value from memory depending on previous and current values of P1.5,P1.4
; +-------+-------+------+------+-----+-----+
; | PP1.5 | PP1.4 | P1.5 | P1.4 | ADR | VAL |
; +-------+-------+------+------+-----+-----+
; |   0   |   0   |   0  |   0  | 0x0 | 0A  | 1010
; |   0   |   0   |   1  |   1  | 0x3 | 0A  |
; |   0   |   1   |   0  |   1  | 0x5 | 0A  |
; |   0   |   1   |   1  |   0  | 0x6 | 0A  |
; |   1   |   0   |   0  |   1  | 0x9 | 0A  |
; |   1   |   0   |   1  |   0  | 0xA | 0A  |
; |   1   |   1   |   0  |   0  | 0xC | 0A  |
; |   1   |   1   |   1  |   1  | 0xF | 0A  |
; 0A - both bits behave in the same way - both change or both stay the same
; it may be interpreted as P1.5 and P1.4 are in phase sync

; +-------+-------+------+------+-----+-----+
; | PP1.5 | PP1.4 | P1.5 | P1.4 | ADR | VAL |
; +-------+-------+------+------+-----+-----+
; |   0   |   0   |   0  |   1  | 0x1 | 05  | 0101
; |   0   |   1   |   1  |   1  | 0x7 | 05  |
; |   1   |   0   |   0  |   0  | 0x8 | 05  |
; |   1   |   1   |   1  |   0  | 0xE | 05  |
; 05 - P1.5 is lagging behind P1.4

; |   0   |   1   |   0  |   0  | 0x4 | 00  |
; |   0   |   0   |   1  |   0  | 0x2 | 00  | 0000
; |   1   |   1   |   0  |   1  | 0xD | 00  |
; |   1   |   0   |   1  |   1  | 0xB | 00  |
; 00 - P1.4 is lagging behind P1.5

; for 0x05 increment R3
; for 0x00 decrement R3
	JB1	0062H		; 005B
	INC	R3		; 005D
	JB0	0062H		; 005E
	DEC	R3		; 0060
	DEC	R3		; 0061

;;;;;;;;;;;;;;;;;;
;; now similar with P1.6 and P1.7
	IN	A,P1		; 0062
	XRL	A,R1		; 0063
	ANL	A,#0C0H		; 0064
	JZ	007FH		; 0066
	CLR	F1		; 0068

; restore P1 value and store current P1 in R1 and previous P1 value in A
	XRL	A,R1		; 0069
	XCH	A,R1		; 006A
; shift previous P1.6 and P1.7 values to bits 2 and 3
	SWAP	A		; 006B
	ANL	A,#00CH		; 006C

; A.3=PP1.7
; A.2=PP1.6
; A.1=P1.7
; A.0=P1.6
	MOV	R0,A		; 006E
	MOV	A,R1		; 006F
	RL	A		; 0070
	RL	A		; 0071
	ANL	A,#003H		; 0072
	ORL	A,R0		; 0074
; read from the table value one of 0,A,5, rules are same as with 
; P1.4 and P1.5
	ORL	A,#0F0H		; 0075
	MOVP	A,@A		; 0077
; for 0x05 increment R4
; for 0x00 decrement R4
	JB3	007FH		; 0078
	INC	R4		; 007A
	JB2	007FH		; 007B
	DEC	R4		; 007D
	DEC	R4		; 007E

;;;;;;;;;;;;;;
; R3 value represents the phase direction of P1.4 and P1.5
; R4 value represents the phase direction of P1.6 and P1.7

; if R6 bits 0-3 non-zero, decrease R6 and rotate right R5 filling bit 7 with 1
; if R5 bit 0 was 0, set F0 - this will cause to emit signal on P2.7
; this actually sends on P2.7 a bit signal of length R6 (4 lower bits) coded on R5
; if this sending is executed, the rest of the loop is omitted until all bits are sent
	MOV	A,R6		; 007F
	ANL	A,#00FH		; 0080
	JZ	0090H		; 0082
	DEC	R6		; 0084
	CLR	C		; 0085
	CPL	C		; 0086
	MOV	A,R5		; 0087
	RRC	A		; 0088
	MOV	R5,A		; 0089
	CLR	F0		; 008A
	JC	00BBH		; 008B
	CPL	F0		; 008D
	JMP	0BBH		; 008E

; put 0xC (12) to R6 (count of bits to transmit) and set F0 to not send signal on P2.7
	MOV	A,R6		; 0090
	ORL	A,#00CH		; 0091
	MOV	R6,A		; 0093
	CLR	F0		; 0094

; check higher 4 bits of R6, if they are zero and F1 is set (happened event
; indicating move on P1.4/5 or P1.6/7 or push on P1.0/1/2) set R6 to 0x5*
; and move previous stored P1.0/1/2 to A, additionally set A.7. A will get
; transmitted as R5 later 
	ANL	A,#0F0H		; 0095
	JNZ	00A7H		; 0097
	JF1	00BBH		; 0099
	CPL	F1		; 009B
	MOV	A,R6		; 009C
	ORL	A,#050H		; 009D
	MOV	R6,A		; 009F
	MOV	A,R1		; 00A0
	ANL	A,#007H		; 00A1
	ORL	A,#080H		; 00A3
	JMP	0B9H		; 00A5


; this decreases 4 higher bits of R6 (starting from 0x5* to 0x0* - 4 iterations)
	MOV	R5,#0FFH	; 00A7
	MOV	A,R6		; 00A9
	ADD	A,#0F0H		; 00AA
	MOV	R6,A		; 00AC
	ANL	A,#0F0H		; 00AD

	JZ	00BBH		; 00AF
; at odd iterations transmit R4, at even iterations transmit R3
	JB4	00B7H		; 00B1
	CLR	A		; 00B3
	XCH	A,R3		; 00B4
	JMP	0B9H		; 00B5

	CLR	A		; 00B7
	XCH	A,R4		; 00B8
; store bit message in R5
	CPL	F0		; 00B9
	MOV	R5,A		; 00BA

; wait for timer to expire - delay
	JTF	001AH		; 00BB
	JMP	0BBH		; 00BD

	ORG	000F0H
	data	0A05000A 000A0A05 050A0A00 0A00050A

	END
 
P1.4/5 and P1.6/7 are used to detect a direction of move and have to look like that:
Code:
Positive direction
     ______
____|      |_____
        ______
_______|      |_____
Negative direction
        ______
_______|      |_____
     ______
____|      |_____

Whenever a move is detected or any of P1.0-3 are pushed (for longer than 10ms), a message will be transmitted on the RCA.
The message seems to be built of bytes transmitted bit-by-bit from least significant to most significant.
Individual bytes are padded (separated) by 4 bits of 1.

Message seems to be always the following, regardless of what it triggered:
Code:
Byte 1: 10000XXX - XXX are values of P1.2, P1.1, P1.0
Byte 1: move delta of P1.4/5 since last message transmitted - can be positive or negative byte value 
Byte 3: move delta of P1.6/7 since last message transmitted - can be positive or negative byte value
Byte 4: repeated byte 2
Byte 5: repeated byte 3

I need to find a way to generate the move signals and will verify this hypothesis.
Or maybe someone has Computek trackball?

Changes happen on both positive and negative edges. Your drawings are to simplified.
Anytime one of the levels changes, it is a direction change or a step in the same direction.
Dwight
 
Hi!
I'm the one who started the thread on the "Verein zum Erhalt klassischer Computer" (roughly translates to "Vintage Computer preservation club") forum years ago.
Now one of my dear club colleagues, who's also active here, nudged me to this thread.

I found the card in an IBM 5155 I had acquired. There weren't any cables or adapters connected to it, and when pulling apart the machine I was instantly intrigued by the lack of connections on the ISA bus. I left the card out and tried figuring out, what it's supposed to do. I came to no conclusion, so I started the thread and shortly after forgot about the card...

Following this thread, an adapter from quadrature bus mouse to serial seems plausible, but why on earth would then someone plug this card into an C= PC30-III? Those slimline Commodore machines already have an Amiga-compatible quadrature bus mouse connector...

It was designed to go with their trackball not a mouse. It was likely part of a complete package with their software. They'd need a patch for any specific machine and mouse. It would need to run on any machine with our without mouse hardware.
Dwight
 
I think the drawings show all situations that qualify as a move in a direction. A full cycle as shown will generate a value of 4 or -4 - as there are 4 edges.
OK, it is possible that the signals just switch between 1 and 0 any time along the way if both edges change exactly at the same time, but it does not affect a move, would there be any sense for that?
 
It was designed to go with their trackball not a mouse. It was likely part of a complete package with their software. They'd need a patch for any specific machine and mouse. It would need to run on any machine with our without mouse hardware.
Dwight

Well, I think we don't know that for sure and are figuring it out. What would be connected to the RCA on the other end to read the serial data?
 
It's quite likely--Computek made trackballs, mice and joysticks. I imagine that the RCA jack would be connected to a cable with a DB25 on the other end.
 
Back
Top