Electronics > Projects, Designs, and Technical Stuff

Cloning a Tandy TRS-80 Model 1

<< < (23/26) > >>

kizmit99:

--- Quote from: GK on July 01, 2019, 11:24:45 am ---The current scheme is to quickly load the shift register after being triggered by the rising edge of !KEYBOARD, before the next polling interval, so to avoid any shift register activity while the keyboard is being scanned.

--- End quote ---

Ah - tricky...  I assume you've done the calcs to verify the PIC (I think that's what you were using for the PS/2 interface) can detect the rising edge and perform the 52 shifts before the Z80 can get back around to checking the keyboard again?  That just seems like it would require a lot of cycles, and I've found that the Z80 (even at 1MHz) can execute quite a few instructions in the time it takes a small microcontroller to respond to an interrupt and start bit-banging.


--- Quote from: GK on July 01, 2019, 11:24:45 am ---I can't remember the finer details off the top of my head right now, but I'm pretty sure my keyboard interface code can handle the situation you describe. In my PET clone both shift and the key mapped to @ have to be asserted simultaneously to give one of the graphics characters.

--- End quote ---

Once you get this all hooked up again, I'd really appreciate if you would take a quick look.  Thanks in advance!

GK:

--- Quote from: kizmit99 on July 01, 2019, 02:50:27 pm ---That just seems like it would require a lot of cycles, and I've found that the Z80 (even at 1MHz) can execute quite a few instructions in the time it takes a small microcontroller to respond to an interrupt and start bit-banging.
--- End quote ---


Yes, that is true, but there is heaps of time between keyboard polls, so it isn't an issue. Anyway, there is another alternative that will (should) fit into the CPLD. I can delete the entire shift register and replace it with a parallel-input register/latch. I have enough I/O pins left over to delete the serial interface and replace it with an 8-bit, addressable interface for programming. Not as elegant as a simple serial uC interface, but it does away with having to monitor & sync to !KEYBOARD. I'm busy with the breadboard right now, but I think I'll give this a whirl after.

GK:
Just, finally, plugged in the last wire not more than 20 minutes ago. Double checked, crossed fingers, plugged in power lead................... So satisfying to see the screen go blank momentarily and the READY prompt appear.

Running bare bones ATM with no I/O, apart from the video display. Next up is get my prototype keyboard interface soldered up on perfboard. I have a bunch of old 5V EPM7064 CPLDs here in the 44 pin PLCC package, which are easy to prototype-build with. It's bedtime again now though.



GK:
The video board schematic.

GK:

--- Quote from: GK on July 03, 2019, 12:57:45 pm ---
--- Quote from: kizmit99 on July 01, 2019, 02:50:27 pm ---That just seems like it would require a lot of cycles, and I've found that the Z80 (even at 1MHz) can execute quite a few instructions in the time it takes a small microcontroller to respond to an interrupt and start bit-banging.
--- End quote ---


Yes, that is true, but there is heaps of time between keyboard polls, so it isn't an issue. Anyway, there is another alternative that will (should) fit into the CPLD. I can delete the entire shift register and replace it with a parallel-input register/latch. I have enough I/O pins left over to delete the serial interface and replace it with an 8-bit, addressable interface for programming. Not as elegant as a simple serial uC interface, but it does away with having to monitor & sync to !KEYBOARD. I'm busy with the breadboard right now, but I think I'll give this a whirl after.

--- End quote ---


Okay, I managed to get the parallel register version to fit into 64 macro cells, but, again, only just and the uC programming interface is a little more primitive as I couldn't fit in any address decoding. The 52-bit "key status" register is programmed in 8-bit chunks (from inputs D[7..0]) with individual strobe/latch input pins (STROBE[6..0]) for each chunk. That gives a 15-line uC interface for programming. A 3-to-7 line decoder for strobe addressing just takes up too much additional logic.

In AHDL this time:


--- Code: ---TITLE "Keyboard matrix decoder";
% Tandy TRS-80 Model 1 %

SUBDESIGN MATRIX
(
D[7..0] : INPUT; -- Key status register data inputs
STROBE[6..0]         : INPUT; -- Key status register latch control inputs

ADDRESS[7..0]         : INPUT; -- Address bus inputs
DATA[7..0] : OUTPUT;                -- Data bus outputs
KEYBOARD : INPUT; -- Output enable for data bus outputs (active low; Hi-Z when high)
)

VARIABLE

KEY[51..0] : LATCH;         -- 52-bit key-status register
Q[7..0] : NODE;         -- Working node for data bus outputs
TRIBUS[7..0]         : TRI_STATE_NODE;         -- Tri-state node for data bus outputs

BEGIN

% Connect tri-state data bus outputs to !KEYBOARD %

TRIBUS[0] = TRI(Q[0], !KEYBOARD);
TRIBUS[1] = TRI(Q[1], !KEYBOARD);
TRIBUS[2] = TRI(Q[2], !KEYBOARD);
TRIBUS[3] = TRI(Q[3], !KEYBOARD);
TRIBUS[4] = TRI(Q[4], !KEYBOARD);
TRIBUS[5] = TRI(Q[5], !KEYBOARD);
TRIBUS[6] = TRI(Q[6], !KEYBOARD);
TRIBUS[7] = TRI(Q[7], !KEYBOARD);

DATA[7..0] = TRIBUS[7..0];

% Key matrix %

Q[0] = ADDRESS[0] & KEY[0] # ADDRESS[1] & KEY[8]  # ADDRESS[2] & KEY[16] # ADDRESS[3] & KEY[24] # ADDRESS[4] & KEY[27] # ADDRESS[5] & KEY[35] # ADDRESS[6] & KEY[43] # ADDRESS[7] & KEY[51];
Q[1] = ADDRESS[0] & KEY[1] # ADDRESS[1] & KEY[9]  # ADDRESS[2] & KEY[17] # ADDRESS[3] & KEY[25] # ADDRESS[4] & KEY[28] # ADDRESS[5] & KEY[36] # ADDRESS[6] & KEY[44];
Q[2] = ADDRESS[0] & KEY[2] # ADDRESS[1] & KEY[10] # ADDRESS[2] & KEY[18] # ADDRESS[3] & KEY[26] # ADDRESS[4] & KEY[29] # ADDRESS[5] & KEY[37] # ADDRESS[6] & KEY[45];
Q[3] = ADDRESS[0] & KEY[3] # ADDRESS[1] & KEY[11] # ADDRESS[2] & KEY[19] #                        ADDRESS[4] & KEY[30] # ADDRESS[5] & KEY[38] # ADDRESS[6] & KEY[46];
Q[4] = ADDRESS[0] & KEY[4] # ADDRESS[1] & KEY[12] # ADDRESS[2] & KEY[20] #                        ADDRESS[4] & KEY[31] # ADDRESS[5] & KEY[39] # ADDRESS[6] & KEY[47];
Q[5] = ADDRESS[0] & KEY[5] # ADDRESS[1] & KEY[13] # ADDRESS[2] & KEY[21] #      ADDRESS[4] & KEY[32] # ADDRESS[5] & KEY[40] # ADDRESS[6] & KEY[48];
Q[6] = ADDRESS[0] & KEY[6] # ADDRESS[1] & KEY[14] # ADDRESS[2] & KEY[22] #                        ADDRESS[4] & KEY[33] # ADDRESS[5] & KEY[41] # ADDRESS[6] & KEY[49];
Q[7] = ADDRESS[0] & KEY[7] # ADDRESS[1] & KEY[15] # ADDRESS[2] & KEY[23] #                        ADDRESS[4] & KEY[34] # ADDRESS[5] & KEY[42] # ADDRESS[6] & KEY[50];

% 52-bit key status latch strobe and data input connections %

KEY[7..0].D = D[7..0];
KEY[7..0].ENA = STROBE[0];

KEY[15..8].D = D[7..0];
KEY[15..8].ENA = STROBE[1];

KEY[23..16].D = D[7..0];
KEY[23..16].ENA = STROBE[2];

KEY[31..24].D = D[7..0];
KEY[31..24].ENA = STROBE[3];

KEY[39..32].D = D[7..0];
KEY[39..32].ENA = STROBE[4];

KEY[47..40].D = D[7..0];
KEY[47..40].ENA = STROBE[5];

KEY[51..48].D = D[3..0];
KEY[51..48].ENA = STROBE[6];

END;

--- End code ---

Navigation

[0] Message Index

[#] Next page

[*] Previous page

There was an error while thanking
Thanking...
Go to full version
Powered by SMFPacks Advanced Attachments Uploader Mod