News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu

Interfacing CPC with a microcontroller

Started by joska, 11:27, 11 July 14

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

nicf82

Ah, I see, thanks for the explanation! It makes more sense now why everything seems to be towards the end of the address space. I suppose it was because it was cheaper back in 1984 to only partially decode the internal devices, fewer logic chips needed?

pelrun

#26
Yup, that's it. The more bits you decode, the more logic you need, which increases chip count, board size and assembly costs. In fact the "inverted one-hot" method that's being used means the decoding is practically free, as you can just run a single address line direct to the chip-select pin of the appropriate IC.

Also the Z80 was intended to only have an 8-bit IO address space; it's technically an undocumented quirk of the implementation that puts B into the high byte of the address bus during an IO cycle. So abusing the high byte to allow simple addressing of the internal devices didn't only allow the CPC to reduce costs, it still left a bigger IO space for peripherals compared to other z80 based systems that only used it as documented!

nicf82

Interesting! I presume that is also why we only use OUT (C) instead of OUT (BC)

pelrun

Bingo! I almost mentioned that but didn't quite get around to it :D

Gryzor

#29
Thread cleaned. Happy new year everyone, didn't you hear? 😀


[EDIT]VintageAdvantage is under moderation for being abusive. The reason in the HoS.

eto

Quote from: nicf82 on 20:54, 25 December 20
OK, got it working finally!


Would you consider writing up what exactly you did? I would be super interested in how that works and how the circuit looks like.




nicf82

Sure I can do, I'm just learning this stuff myself thought so I'm sure there will be some mistakes in there! I'm just trying to fix a problem which stops the CPC powering up when the Arduino is externally powered which I think is caused by a ground loop. Ill post what I did after that.

pelrun

Make sure your circuit isn't inadvertently holding /WAIT if it's powered up before the CPC is... :D

nicf82

Yeah I did think that, but don't think it could be really it needs the correct address etc to be decoded to pull that pin low. Also when I disconnect the Arduino GND it works, and continues to work if I plug it back in, after powering on the CPC. When the CPC monitor is on without the computer, and the Arduino ground is plugged in I head and see interference on the screen, so that's why I'm thinking ground loop?

nicf82

First draft of a guide to setting this up: - I'm 100% confident there will be some mistakes in there but if anyone tries it and spots any or if anything isn't clear please let me know!

pelrun

Don't assume that logic behaves sensibly while the system is initially powering up - everything is still an analog device at the lowest level and until the voltage settles things will be chaotic. That includes the logic on your breadboard, which looks like you're still powering from the CPC in the diagram.
If you watch the /RESET pin you can detect when the CPC is held in reset during initial power on, Keeping out of the way during this period is a good strategy even if it's not the root cause of this particular bug.

A ground loop is certainly possible though - what happens if you power the arduino from a battery pack instead?

nicf82

Quote from: pelrun on 02:46, 03 January 21Don't assume that logic behaves sensibly while the system is initially powering up - everything is still an analog device at the lowest level and until the voltage settles things will be chaotic. That includes the logic on your breadboard, which looks like you're still powering from the CPC in the diagram.
If you watch the /RESET pin you can detect when the CPC is held in reset during initial power on, Keeping out of the way during this period is a good strategy even if it's not the root cause of this particular bug.


I think I would need to introduce a tri-state buffer for this - so I can keep it in high impedance for a short time on startup until I'm ready to hold it low or high - to be honest I don't quite understand how this works at all right now when I'm outputting HIGH from on the /WAIT - what if some other device wanted to pull it LOW. Will do a bit of experimenting.


I haven't tried with a battery, but I'll give it a go!


Cheers!


Nic

Bryce

Quote from: nicf82 on 21:26, 02 January 21
Yeah I did think that, but don't think it could be really it needs the correct address etc to be decoded to pull that pin low. Also when I disconnect the Arduino GND it works, and continues to work if I plug it back in, after powering on the CPC. When the CPC monitor is on without the computer, and the Arduino ground is plugged in I head and see interference on the screen, so that's why I'm thinking ground loop?

How are you powering the Arduino? Through USB or the barrel socket? I would definitely add an external pull-up to the /WAIT signal to ensure it's physically being pulled high while the AVR ports are being initialised.

Bryce.

nicf82

I'm using USB, OK will give this a try also!

pelrun

Quote from: nicf82 on 11:20, 03 January 21
I think I would need to introduce a tri-state buffer for this - so I can keep it in high impedance for a short time on startup until I'm ready to hold it low or high - to be honest I don't quite understand how this works at all right now when I'm outputting HIGH from on the /WAIT - what if some other device wanted to pull it LOW. Will do a bit of experimenting.
You've got a couple of options; either a series resistor or a series diode. The series resistor is what the gate array uses to drive /WAIT with; if nothing else is driving the line it looks normal, but when something else is trying to drive it the opposite way it limits the current that can flow to a safe level. The diode essentially makes your output look like an open-drain, where you can only drive low levels, not high.
A pullup probably isn't necessary, as the z80 should be doing that already.

Bryce

You could use an open collector setup to create a tri-state output.

Bryce.

nicf82

Thanks pelrun, yes the diode makes sense, so unless I'm pulling LOW, it'll not allow any current to flow. Ill do a bit of digging into an open collector setup Bryce sounds interesting, all good learning for me.

Cheers!

Nic

GUNHED

Quote from: Gryzor on 17:29, 01 January 21
Thread cleaned. Happy new year everyone, didn't you hear? 😀


[EDIT]VintageAdvantage is under moderation for being abusive. The reason in the HoS.
He is right about the 16 Bit I/O of the Z80. the OUT (C),r instructions are a reality.
Of course lots of companies used 8 bit I/O, but also lots of companies used the 8088 instead the 8086 for exactly the same reason.
In CPCs world we need to use 16 bit I/O! Else ist won't work.
Why delete his post? Why not Pelruns post?
http://futureos.de --> Get the revolutionary FutureOS (Update: 2024.10.27)
http://futureos.cpc-live.com/files/LambdaSpeak_RSX_by_TFM.zip --> Get the RSX-ROM for LambdaSpeak :-) (Updated: 2021.12.26)

pelrun

Please don't start this again - or do it in the HoS thread  :laugh:

GUNHED

#44
Quote from: pelrun on 07:03, 31 December 20
Yup, partial decoding is the norm rather than the exception as far as CPC internal devices go. While most addresses in the 16-bit IO space are conflicted due to the partial decoding, there is always at least one address for each device that unambiguously addresses it. So it's the responsibility of the code to avoid the ambigious ones. Basically that means putting 1's in every don't care bit position, which (unsurprisingly) results in the "standard" address for that device.
To find a free address for a new peripheral, it's necessary to start from an IO address with all 5 highest bits set (i.e. 0b11111xxx xxxxxxxx or ANDed with 0xF800). All the standard internal devices have at least one of those five bits set to 0. After that it's just a matter of picking an address that doesn't collide with an existing peripheral, which is still pretty easy if you're doing full decoding and only after a couple of addresses.

IMHO that's made too easy for hardware creators. Yes, the way you describe it will work as long as the CPC uses exactly one expansion. Or in few cases maybe with two expansions as long as their I/O addresses are very different.

However, IMHO, good practice is to decode as much as possible of the I/O address. Because only this will enable the user to use different hardware expansions at the same time.

The best practice is of course to decode full 16 bit I/O, only in this case you're on the safe side.

Sadly in CPC world there are lots of examples of incompatible hardware, because the producers only decode a bunch of I/O address bits, but not enough.

This is my personal perspective, the one of somebody who uses multiple expansions at once. And also the perspective of probably most / all good programmers. Of course few guys will look at this topic in a different way.
http://futureos.de --> Get the revolutionary FutureOS (Update: 2024.10.27)
http://futureos.cpc-live.com/files/LambdaSpeak_RSX_by_TFM.zip --> Get the RSX-ROM for LambdaSpeak :-) (Updated: 2021.12.26)

pelrun

#45
Quote from: nicf82 on 09:58, 04 January 21
Thanks pelrun, yes the diode makes sense, so unless I'm pulling LOW, it'll not allow any current to flow. Ill do a bit of digging into an open collector setup Bryce sounds interesting, all good learning for me.
The diode actually gives you an open drain/open collector output without needing to add extra logic. Alternatively you can use a transistor to pull /WAIT low, but that also inverts the sense.

Quote from: GUNHEDIMHO that's made too easy for hardware creators. Yes, the way you describe it will work as long as the CPC uses exactly one expansion.
I didn't advocate for external expansions doing partial decoding at all - I was *only* describing the internal hardware. These days there's absolutely no reason not to do full decoding in expansion devices.

GUNHED

Agreed! But it can't harm to mention it now and then.
http://futureos.de --> Get the revolutionary FutureOS (Update: 2024.10.27)
http://futureos.cpc-live.com/files/LambdaSpeak_RSX_by_TFM.zip --> Get the RSX-ROM for LambdaSpeak :-) (Updated: 2021.12.26)

revaldinho

Any interest here in using the new RaspberryPi Pico as a CPC programmable peripheral ?


Programmable state machines for bit banging on IO pins independently of the two 133Mhz dual cores, looks interesting. And they certainly are cheap. 


rpalmer

Quote from: revaldinho on 21:53, 26 January 21Any interest here in using the new RaspberryPi Pico as a CPC programmable peripheral ?

It needs to be considered that the I/O pins of the Pico must be 5V first, otherwise the Pico could be damaged by direct connection to the CPC.

nicf82

Quote from: rpalmer on 22:14, 26 January 21Any interest here in using the new RaspberryPi Pico as a CPC programmable peripheral ?

Looks interesting, I'll do some reading up in it  - I'd like to create a printer interface to read the Epson codes and output to a modern printer. I have been messing around with an esp32 and printing directly to port 9100 on my laser printer today, but I think it would be easier with an Rpi as there are libs available to convert Esc codes to PDF. I wonder if this would be useful for that.

Powered by SMFPacks Menu Editor Mod