Z80 Homebrew Computer - fault finding - Page 1
Forum section: electronics / projects

author: nockieboy
author_rank: Super Contributor
timestamp: March 06, 2017, 10:24:27 am
content: Hi everyone,Firstly, apologies if this is in the wrong forum category, but I'd appreciate some help/guidance with a fault I've got on my homebrew Z80 computer that I've been building.It's all built on breadboard currently, but it's at the stage where I should be able to connect it up to my laptop and get it running via a USB/TTL connection. It's heavily based on the design by Grant Searle herehttp://searle.hostei.com/grant/z80/SimpleZ80.html, I've just got bigger SRAM/ROM chips as it seems the smaller ones are harder (and more expensive!) to get these days.The issue is, it's not playing. I had a (pretty serious) issue with it when I first powered it up - it was drawing about 1.2 amps, which isn't great, and after some inspection I realised I'd connected up the 68B50 ACIA backwards to the power supply (!) thanks to a silly mistake I made over Vcc/Vdd/Vss etc labelling. I'm assuming it blew the chip, so I swapped it out for a fresh one. Still no go with the communication with the laptop, though. So I built a simple display for the address and data buses using spare LEDs and a single-step clock to see what was going on at the lowest level.After some investigation, it would appear that the Z80 is starting up just fine and reading/executing the instructions in the first 2 bytes of ROM without error. The problem is when it gets to the 3rd byte, a value that means D0 on the data bus needs to be low. But it seems D0 is high on every single address.I don'tthinkthis is a short circuit as D0 goes low when the rest of the data bus is inactive, but for every read/write, D0 is high.Unfortunately my electronics experience/knowledge is pretty poor, so other than checking the connections to make sure it's wired up properly I'm a little stumped for ideas.I'd appreciate any suggestions/advice at all that'll help me get to the bottom of this. I'll go through the wiring and connections later this week, but if anyone has had this issue before and/or knows what the cause may be (another damaged chip perhaps or a definite wiring error?) then I'd be very grateful for your comments.Thanks!

author: IanJ
author_rank: Unknown
timestamp: March 06, 2017, 11:30:27 am
content: Hi,Back in the 80's & 90's I built a good few Z80 powered system for offshore.......home brewed pcb's and designed and built from scratch. There were quite a few issues and wierd symptoms which sometimes resulted in the fix not being where you first thought. So, from memory here's a few things I'd look at or test......assuming the basic design is good.- Put a cap across the reset switch so that the Z80 gets a soft start.- Run it with a crystal within spec, or divide by 2 (flip flop) in place of U5:B- Is the oscillator double oscillating? Try a 74LS04 rather than HCT......or a different brand, or add a 33pF cap across the clock to test.- Try an HCT version of the 74LS32 for the address decoding.- Remove U3 just incase it's interfering with the core functionality.- Have you thought about extending the capabilities of the memory and IO decoding to allow you to play with the memory and IO map. You might get some ideas from my ZX Spectrum interface here -http://www.ianjohnston.com/images/stories/IanJ/ZXspectrummod/ZXSpectrumMultiIO.pdfAlways great to see new build Z80 systems.........Good luck.Ian.

author: nockieboy
author_rank: Super Contributor
timestamp: March 06, 2017, 01:40:40 pm
content: Thanks for the replies guys.Okay, wilfred, in reply to your post:Quote from: wilfred on March 06, 2017, 10:54:08 amYes, I'm getting results that I would expect from the ROM on the data bus. I can remove the ROM and verify its contents to make sure, but I checked it before removing it from the EEPROM programmer and it was showing the correct data then.Quote from: wilfred on March 06, 2017, 10:54:08 amI'm sure that's precisely what is happening. The first three bytes are F3 C3 B8 - both F3 and C3 are appearing on the data bus as they should do (note that both have D0 high naturally) but the third memory location (B8) is showing as B9 on the data bus as D0 is still high when it should be low. The fourth byte is 00 and is showing as 01 as D0 is high. I've stepped through quite a few memory locations now and every single one has D0 high, whether or not it should be high or low according to the value at that address.I guess the main reason for posting this issue for advice is that two heads are better than one and, as you say, it's easy to get trapped into a very narrow mindset when you're so close to the problem (and, in my case, pretty inexperienced at electronics generally.) I'm supposing it's a bad connection somewhere, but it strikes me as odd that D0 is only high when the bus is active. I'd have thought a short would make it high all the time?In any case, I'm hoping to have a more detailed look at the wiring this evening and make some progress on the issue!Quote from: IanJ on March 06, 2017, 11:30:27 amI was playing games on my Z80-based Amstrad CPC464 and teaching myself to program back in the (mid-late) 80's - funny how I've got the bug now to actually build one. Never realised it was so (relatively) simple! Thanks for the pointers - currently I'm running with a de-bounced switch to step the clock manually so that I can see exactly what is on the address and data buses - it was invaluable in finding the 'permanently high D0' issue which is the major bug I'm trying to fix. All my glue chips are HCT (at the moment that's just a 74HCT04 inverter and a 74HCT00).I'll take the ACIA (68B50) out of action then and see if there's any change. Shouldn't make a difference I wouldn't expect as it's not active all the time (only when the monitor program is trying to send or receive data from the USB/TTL connection which doesn't happen straight away.)So at the moment it's looking like a wiring error do we think?

author: grumpydoc
author_rank: Super Contributor
timestamp: March 06, 2017, 01:51:17 pm
content: Have you checked all the wiring - no shorts on D0 to anything else?Have you checked that the RAM or 68B50 are not trying to drive the data bus, especially if the 68B50 is the same one that you reversed the supply to.If the chips are in sockets you could try removing the RAM or 68B50 and see if that helps.

author: Fungus
author_rank: Super Contributor
timestamp: March 06, 2017, 02:07:05 pm
content: Step to byte 3, break the D0 connection to the ROM, see if it measures high on the ROM chip.If not, work your way back towards the Z80 and find out what's pulling it high.(...and consider getting a current-limited power supply for the next time you power on a prototype like this)

author: nockieboy
author_rank: Super Contributor
timestamp: March 06, 2017, 03:21:49 pm
content: AQuote from: grumpydoc on March 06, 2017, 01:51:17 pmThanks grumpydoc - yes, since my last post I've had a spare 5 mins to check the wiring. I've checked the D0 line with my multimeter in resistance mode - no shorts to any other data lines and as the circuit is fairly simple (it's all on 3 breadboards) it's easy enough to do a visual inspection and confirm there's no wrong connections with the D0 line.Didn't think about checking the RAM or 68B50 to see if they're driving the bus as well. In theory, both should be disabled whilst the lower 8K memory space is addressed, but it's well worth checking I guess.The chips aren't in sockets, but they are in my breadboard... I could remove them if I re-wire part of the address bus (I got lazy and just ran a couple of the address wires over the top of the ROM chip instead of around it. Is there any reason disconnecting them from the +5V rail wouldn't work as well?Quote from: Fungus on March 06, 2017, 02:07:05 pmMarvellous. Why didn't I think of that? Soon as my work is done, that'll be my next plan of attack with this problem. Thanks for the advice re: the current-limited power supply. That's a mistake I've learned from, I can assure you! Thanks Fungus!

author: nockieboy
author_rank: Super Contributor
timestamp: March 06, 2017, 03:53:26 pm
content: Okay, now I'm getting confused.I followed Fungus' advice and stepped to the third instruction, which should be B8. The data bus shows B9, with D0 being erroneously high. I disconnected D0 from the ROM and checked the pin - it was showing HIGH. This would indicate that the value B9 was at that memory address when it should have been B8 - i.e. an error with the ROM. Nothing else was connected to the D0 pin other than the indicator LED I'm using to view the data bus.So I removed the ROM chip from the breadboard, plugged it into my EEPROM and read the data back off of it. As you can see from the attached image, the data on the ROM is fine and the EEPROM programmer is able to read the data without any problems.I'll post a picture of the breadboard setup shortly - although I don't know if that will help, it's a bit of a bird's nest...

author: PA0PBZ
author_rank: Super Contributor
timestamp: March 06, 2017, 03:56:21 pm
content: Quote from: nockieboy on March 06, 2017, 03:53:26 pmAre you sure that your address lines are correct? Maybe you are not looking at address 0002?

author: grumpydoc
author_rank: Super Contributor
timestamp: March 06, 2017, 04:01:18 pm
content: Just noticed thisQuoteWhat did you do with the extra address lines?Also curious to know how you are "stepping to the 3rd byte" on a bare bones Z80 with no working monitor program and no single step hardware?

author: nockieboy
author_rank: Super Contributor
timestamp: March 06, 2017, 04:08:49 pm
content: Quote from: PA0PBZ on March 06, 2017, 03:56:21 pmYes, as sure as can be. Address 0, 1 and 2 are showing up on the address bus LED's correctly in binary, so no reason to think 3 would be wrong?Quote from: grumpydoc on March 06, 2017, 04:01:18 pmThe extra address lines are all tied low to GND.I've got a de-bounced switch that I am using to clock the Z80. Each click of the switch generates a single 1-second high pulse from a 555 timer to the CLK line of the computer. The address bus lines A0-A7 have LEDs on them so I can see the bottom 8-bits of the address bus and the data bus has 8 LEDs on it so I can see the entire data bus in binary.

author: CJay
author_rank: Super Contributor
timestamp: March 06, 2017, 04:25:53 pm
content: Handy that it's a Z80, remove the ROM from your system and make a NOP exerciser, you can then test all address lines to make sure they're all working as expected and wired correctly to the various peripheral chips, glue logic etc.

author: grumpydoc
author_rank: Super Contributor
timestamp: March 06, 2017, 04:35:13 pm
content: Quote from: CJay on March 06, 2017, 04:25:53 pmSadly nockieboy did not socket the chips - always a good idea when building prototypes.BTW have you checked that the D0 line really is hgh and you did not just make a mistake with the LED - do you have a buffer of some sort between the data bus and the LED?

author: nockieboy
author_rank: Super Contributor
timestamp: March 06, 2017, 04:44:41 pm
content: Quote from: grumpydoc on March 06, 2017, 04:35:13 pmIt's all on a breadboard, so not an issue...Quote from: grumpydoc on March 06, 2017, 04:35:13 pmWell, I'm going to go back and test D0 from the ROM again without the indicator LED attached. No, there's no buffer between the data bus and the LEDs... erm... will that make a difference? I'm more a software than hardware person..I'm attaching some images of the prototype - no doubt they'll attract more critical comments than anything else, but please remember I'm a beginner at electronics!

author: spudboy488
author_rank: Regular Contributor
timestamp: March 06, 2017, 04:45:54 pm
content: Maybe D0 is stuck high somehow. D0 is high for the first 2 bytes so you may not see it. Check byte 4 (if possible) to see if the 0x00 reads back as 0x01.

author: nockieboy
author_rank: Super Contributor
timestamp: March 06, 2017, 04:53:23 pm
content: Quote from: spudboy488 on March 06, 2017, 04:45:54 pmD0 is most definitely stuck high - I'm trying to work out why or how. I disconnected the D0 bus from the ROM earlier when address 3 was selected and the D0 pin on the ROM was high when it should have been low - but when I removed the ROM and verified its contents in my EEPROM programmer, it was fine. I'm starting to wonder if I have introduced this issue into the system with the indicator LEDs, thanks to a question from @grumpydoc earlier asking if I'd buffered the address bus before connecting the LEDs...

author: CJay
author_rank: Super Contributor
timestamp: March 06, 2017, 04:53:40 pm
content: Yes, it most definitely can make a difference if there's no buffer but it depends on things like how many chips you're 'driving', the forward voltage of the LED (it may be lower than the guaranteed 'high' input voltage and actually be causing a fault instead of indicating one)The NOP exerciser will only help verify your address lines but that is useful in itself, if you wire the NOP into the ROM position on your board it will verify the databus wiring (but not a problem with levels)

author: nockieboy
author_rank: Super Contributor
timestamp: March 06, 2017, 04:59:29 pm
content: Quote from: CJay on March 06, 2017, 04:53:40 pmHmm.. I think I'll run D0-D3 through an inverter as I have a few spare on the breadboard - that should be okay as a buffer to drive an LED, right? At least that'll show if there really IS an issue with D0 and it's not something I've introduced myself... Failing that, I'll set up the NOP instruction in place of the ROM and see if the address bus is working as expected. In fairness, I did the basic NOP test on the Z80 before I added the RAM/ROM, but that was before the address bus was wired in.

author: grumpydoc
author_rank: Super Contributor
timestamp: March 06, 2017, 05:31:56 pm
content: You definitely need a buffer - the Z80 I/O pins are only designed to drive one TTL load if memory serves - something like max sink current 2ma at logic '0' and max source current 250uA for logic '1'.The RAM & ROM are probably similar.

author: nockieboy
author_rank: Super Contributor
timestamp: March 06, 2017, 09:42:57 pm
content: Quote from: grumpydoc on March 06, 2017, 05:31:56 pmYep, you're spot on grumpydoc.Instead of running D0 through a LED and resistor, I switched it over to one of the 74HCT04's spare inverters (well, two actually so the output wasn't inverted) and then through the LED.Funnily enough, the permanent high on D0 disappeared and the results were fine. I'll have to spend a little time creating a proper buffered address/data bus display (I actually have some 74HCT244's and 74HCT245's as my plan is to fully buffer the address, control and data buses later) so I can view the address/data buses without causing more problems.The reason for wanting to see the address/data buffer was because the Z80 wasn't talking to my computer in the first place. The next thing for me to look at after this is the clock (the 8MHz clock, not the temporary single-stepper I've created) and making sure the 68B50 is is receiving the chip select signal properly.Oh, one other thing - I've got decoupling capacitors on the Z80, RAM and ACIA but not on the ROM - didn't get round to putting it in there. I wonder if that could be causing the communication issue?

author: nockieboy
author_rank: Super Contributor
timestamp: March 08, 2017, 09:16:12 am
content: Okay, progress update. The D0 high bug is fixed. The SBC still isn't talking to my laptop though, which was the original issue that caused me to create the bus display (which introduced the D0 high bug!)I've now taken a look at the 8MHz clock through my old oscilloscope (I say old because I got it cheap off eBay and it's limited in features and probably had a million previous owners and is a little tatty, dodgy and uncalibrated as a result.)Here's a pic of the oscilloscope trace from the 8MHz clock output:image hosting 30 mbThat was taken with the following settings: volts/div: 5, time/div: .2u(micro) seconds.Now, I know next to nothing about oscilloscopes as well as electronics, but it seems to me that the voltage on the clock output could be a little high (although that could be a calibration issue? Trace shows good and accurate on the oscilloscope's built-in calibration connection though) and, most obviously, the signal isn't very clean (is that wave deformation at the leading edge of the on-pulse called 'overshoot'?) Also, from some basic mental arithmetic looking at the signal trace and timebase, it looks like it's running at a frequency around 11MHz, when it should be 7.328MHz (or thereabouts). Now, that was hardly a scientific analysis from an uncalibrated oscilloscope, it's a ballpark figure, but does seem to be too high. Is that right?The clock is set up exactly as per the schematic in Grant Searle's designhttp://searle.hostei.com/grant/z80/Z80SbcSchematic1.2.gif. I don't know if the signal is picking up noise on the leads I'm using (they're just BNC connectors, some wire and crocodile clips on the end - like I said, I'm not a professional!) or if the clock circuit just isn't producing a clean signal.So, two questions arise: -1) Is the clock signal causing problems that would cause the Z80 SBC not to work properly?2) How could I improve the clock circuit to remove these errors when it's set up as per the instructions?3) (Bonus question, or I can't count..) Where else should I start looking for issues if the clock is passable, yet I'm still getting nothing at the terminal on my laptop?As always, thanks for any help/suggestions or just passing the time of day with a scatty and slightly inept hobbyist!EDIT: Actually, thinking about it, that waveform deformation is almost certainly interference or impedance in the oscilloscope wires I'm using, I'd guess? The waveform goes through two inverters before going out to the CLK bus line, so itshouldbe a square waveform, right?

author: PA0PBZ
author_rank: Super Contributor
timestamp: March 08, 2017, 10:06:46 am
content: The waveform is fine as it is displayed on the scope, but the frequency is not, it really looks like 11MHz. In the best case this would mean that your serial timing would be wrong, but you should still see some random stuff on your laptop. Otherwise the clock could be too high for the 68B50 or even for the CPU, I didn't check the datasheets so that is something for you to do if you feel like it. Do you have another crystal? Coud be something wrong with it, or try to increase C5 and C6 to 47p and see what happens.

author: CJay
author_rank: Super Contributor
timestamp: March 08, 2017, 10:45:00 am
content: Mhmm, .1uS or slightly less per full cycle would indicate at least 10MHz, that could be affected by your choice of 'scope lead but I'd find it difficult to believe 2-3MHz so either the crystal is wrong/faulty or your 'scope is *way* out of cal. (suspiciously close to 11.0592MHz though, which is a clock frequency used for serial comms).Can you 'scope the output of the 68B50 and see if it's even attempting to communicate?Check that the vertical and horizontal controls on the 'scope don't have a manual adjust knob on them as well.You can do a rough check of the 'scope's vertical calibration if you have a multimeter (connect it and the 'scope to a battery and see if they agree) and you can check the horizontal timebase if you can find a crystal oscillator module with the frequency marked on it (one of the square or rectangular metal can type that need 5V)Adjusting the 'scope so a waveform fills as much of the screen as you can spare makes it easier to get more accurate measurements, same goes for horizontal timebase, change the timebase so you get fewer full cycles displayed.Definitely buy a 'proper' 'scope probe though, they're not expensive on eBay.

author: PA0PBZ
author_rank: Super Contributor
timestamp: March 08, 2017, 11:27:33 am
content: Quote from: CJay on March 08, 2017, 10:45:00 amIn this case the horizontal setting is fine:

author: CJay
author_rank: Super Contributor
timestamp: March 08, 2017, 01:40:23 pm
content: Quote from: PA0PBZ on March 08, 2017, 11:27:33 amAbsolutely, it's good enough in this case that it's obvious the clock is not 8MHz so that's a handy indication and all we really need to to know to suspect the clock circuit, my comment was more as a general tip for future reference when differences aren't quite so obvious.

author: grumpydoc
author_rank: Super Contributor
timestamp: March 08, 2017, 02:32:49 pm
content: The waveform on the 'scope looks fine, I'm guessing that you have it in the fastest horizontal setting which means (further guess) it is a 20MHz 'scope.Looking at an 8Mhz (or 10, or 11Mhz) square wave on a 20Mhz 'scope is going to allow you to say there is something there and it is oscillating - as the first odd harmonic is 24Mhz it is going to be more than 3dB down so you will get no fidelity in the waveform at all.As to frequency - well, I would not trust a 2nd hand 'scope off ebay (unless I happened to be selling it) to tell the difference between 8Mhz and 11Mhz. I think the possibility of use of the variable timebase knob (accidentally or otherwise) has been mentioned so it is worth checking that the 'scope is correctly set up.I am a little surprised that the design calls for a 7.3728MHz clock. While this is the correct clock frequency for 115200 baud using the 68B50 in clock/64 mode it is too high for the spec which says the maximum Tx or Rx clock is 1.5MHz, it is also pretty high for a Z80 - you can get 8MHz Z80's (the Z80H) but you would have to be careful to order that part and not "just" a Z80.It is also a very ambitious frequency to have on a breadboard!Finally, if you *do* have an 8Mhz crystal I am not too surprised that your serial comms don't work - compared with 7.3728Mhz that is nearly 8% high - generally RS232 needs the total timing error to be within 5%On the breadboard I would drop the clock to 1 or 2MHz (divide the 7.37Mhz clock by 4 to give 1.8Mhz which is still over spec for the 8B50 but probably close enough).

author: nockieboy
author_rank: Super Contributor
timestamp: March 08, 2017, 03:46:44 pm
content: Quote from: grumpydoc on March 08, 2017, 02:32:49 pmYou, sir, are quite spot on. I'm using a Hitachi V-212 20MHz scope.Quote from: grumpydoc on March 08, 2017, 02:32:49 pmI wish I understood all that!I'm getting from it that there'll be no detail in waveform though, so other than roughly guesstimating frequency, I can't rely on much else?Quote from: grumpydoc on March 08, 2017, 02:32:49 pmI'll check that tonight but as far as I can tell, I've got Sweep Var and Position knobs - both are centered. Here's an image of a V-212 - mine is identical, except the Volts/Div knob for Channel 2 is damaged:Quote from: grumpydoc on March 08, 2017, 02:32:49 pmThe build notes provided by Grant Searle on his website quote the design as being 'overclocked', but apparently it has been tested with most variations of the Z80. Mine is a Z84C0008PEG, so should be good for 8MHz at least. I've ordered several 3.6864 MHz crystals so I can try to run the system at 'half speed' (obviously adjusting the USB/TTL baud rate accordingly) to see if that produces any results thanks to PA0PBZ's fault-finding ideas. I'm currently trying to find two 47pF caps to see if I can adjust the timing in the oscillator circuit that way, but I don't think I have any!Quote from: grumpydoc on March 08, 2017, 02:32:49 pmPerhaps. Maybe trying the slower clock with a 3.6864 MHz crystal will yield better results...Quote from: grumpydoc on March 08, 2017, 02:32:49 pmNo, that was just me being lazy and instead of writing 7.3728 MHz clock, I wrote 8 MHz clock. Sorry!Okay, so my plan of attack is as follows:1) Wait for the 3.6 MHz crystals to arrive and make the clock run 1/2 design speed.2) Adjust serial comms baud rate accordingly (57600 baud?)3) Fingers crossed.Whilst waiting for the xtals to arrive, I'll see if I can check that all the chips are getting the right chip select signals and the 68B50 is actually trying to put information out.

author: grumpydoc
author_rank: Super Contributor
timestamp: March 08, 2017, 04:02:26 pm
content: Quote from: nockieboy on March 08, 2017, 03:46:44 pmNothing wrong with that - I used to debug all of my Z80 systems with a 20MHz analogue 'scope (late 70's/early 80's)QuoteSweep Var needs to be fully clockwise so the pointer is in the "cal" position.QuoteYou might be better adding a 74LS74 using the two flip flop's as divide by 2 (to give a total division of 4) to give a 1.8Mhz clock from your existing Xtal.QuoteOK

author: nockieboy
author_rank: Super Contributor
timestamp: March 08, 2017, 04:22:26 pm
content: Quote from: grumpydoc on March 08, 2017, 04:02:26 pmDone. Updated image attached (now looks more like an 8.5 MHz frequency...uploading imagesQuote from: grumpydoc on March 08, 2017, 04:02:26 pmD-type flip flop? Okay - I'm pretty sure I don't have any of those lying around, but will try to source some from somewhere as they look quite handy.

author: CJay
author_rank: Super Contributor
timestamp: March 08, 2017, 04:32:36 pm
content: Damnit, the breadboard is out, I've gone and dug out the big box of TTL and now I'm hunting Z80s in my junkbox.Sometimes I love this forum, other times I sit and wonder what I could do with my life if it didn't keep giving me ideas.

author: nockieboy
author_rank: Super Contributor
timestamp: March 08, 2017, 04:39:37 pm
content: Quote from: CJay on March 08, 2017, 04:32:36 pmHaha! Happy to have given you inspiration!

author: grumpydoc
author_rank: Super Contributor
timestamp: March 08, 2017, 04:41:23 pm
content: Quote from: nockieboy on March 08, 2017, 04:22:26 pmOK, I think we're at the point that we can say your clock is probably OK and your 'scope timebase is off 10% or so.QuoteMuch as I hate to send anybody to Maplin for anything, if you have one nearby they sell them for a not completely unreasonable 49p

author: nockieboy
author_rank: Super Contributor
timestamp: March 08, 2017, 04:58:14 pm
content: Quote from: grumpydoc on March 08, 2017, 04:41:23 pmAh that's not a bad price at all. Farnell are coming in around the 43-odd pence mark for a 74HCT74. But then they add a surcharge for orders under £20, which is always a bugbear if you want a single item in a hurry. I've got a Maplin 15 miles away, so a trip is in order as I could do with another breadboard too (though they are expensive from there.)Do I need to worry about whether it's an HCT or an LS? I've looked at 74HCT74s purely because I'm using HCT's for the glue logic elsewhere. It seems I definitely don't have any in my poorly-equipped hobbyist's TTL drawer..

author: grumpydoc
author_rank: Super Contributor
timestamp: March 08, 2017, 05:07:16 pm
content: Quote from: nockieboy on March 08, 2017, 04:58:14 pmThey do occasionally scratch the "I need itnow" itch, but check stock on the website before setting out.QuoteNot really, 74LS is way more power hungry than 74HCT but for just a few gates it hardly matters, otherwise they are fairly similar in speed, propagation delay etc. A 74HCT output will drive 10 LS TTL inputs which is plenty.

author: CJay
author_rank: Super Contributor
timestamp: March 08, 2017, 06:52:21 pm
content: Quote from: nockieboy on March 08, 2017, 04:58:14 pmAre rswww.com still offering free delivery for online orders? Always feel guilt ordering less than a tenner but they deliver for free anyway.

author: nockieboy
author_rank: Super Contributor
timestamp: March 09, 2017, 01:35:53 pm
content: Quote from: CJay on March 08, 2017, 06:52:21 pmYes, they are it would seem - didn't think to check them. Mind you, they're asking £1.69 for a single 74HCT74. There's your postage there (it's £1.20 more than the one I picked up from Maplin earlier..)Well, I've got one now anyway (and an extra breadboard) so I'll have a go at dividing the clock by 4 and see if that changes anything, as well as checking the 68B50 to see if it's alive and kicking. I don't have a logic probe though, but I guess the oscilloscope should pick up some comms via the TxD/RxD pins.

author: grumpydoc
author_rank: Super Contributor
timestamp: March 09, 2017, 01:40:37 pm
content: This is still the 68B50 that you hooked up the wrong way around isn't it? - you might have fried it

author: nockieboy
author_rank: Super Contributor
timestamp: March 09, 2017, 01:45:14 pm
content: Quote from: grumpydoc on March 09, 2017, 01:40:37 pmNo, I did swap it out for a fresh one.

author: grumpydoc
author_rank: Super Contributor
timestamp: March 09, 2017, 02:41:26 pm
content: Quote from: nockieboy on March 09, 2017, 01:35:53 pmOne big benefit of slowing the clock to 4Mhz is that you can now use your 'scope more easily.I assume that you have a way of writing the to the ROMTo debug write a loop of a few instructions, say just writing and reading back one of the 68B50 registers. Now hook up CH1 to, say, the M1 signal and adjust the timebase, holdoff & trigger level until you have a steady display, probably one or two complete iterations of the loop.You can now probe around with CH2, you can reference back to the Z80 timing diagrams (if you don't have them they are easily found online) and look at what is going on. You can check the address, data and all the select signals one line at a time quite easily doing this.Using a slower timebase and the x10 and horizontal position controls you can actually get quite long sequences of instructions captured.

author: nockieboy
author_rank: Super Contributor
timestamp: March 09, 2017, 03:02:33 pm
content: Quote from: grumpydoc on March 09, 2017, 02:41:26 pmOh yes, and a couple of spare ROMS too. I'll get right onto making a test program this afternoon to get some frequent comms with the 68B50 chip.Quote from: grumpydoc on March 09, 2017, 02:41:26 pmSounds like a plan. I'll struggle with CH2 on the oscilloscope though as I only have one pair of (very basic) test leads, but I'll make do somehow. Hopefully, using both flip-flops on the 74HCT74N, I can get the clock down to around 1.8 MHz which should make it more manageable.

author: nockieboy
author_rank: Super Contributor
timestamp: March 09, 2017, 04:02:16 pm
content: Okay, I've wired up the flip-flop to divide the clock signal by 4 and this is the oscilloscope trace I'm getting now:image hosting freeAs you can see, not only is the frequency quartered but it seems the voltage is much reduced too - I've had to drop the volts/div to .5 to get a clear trace.If there's anything wrong with this signal please let me know (it looks absolutely awful to my untrained eye!) but in the meantime I'm going to get on with testing the 68B50 and rest of the circuit for errors.

author: grumpydoc
author_rank: Super Contributor
timestamp: March 09, 2017, 04:20:28 pm
content: YukMake sure you have decoupling caps 0.1uF as close to the flipflop VCC & ground pins as possible.You have mentioned not having very good probes, are they the "crocodile clip on the end of a piece of coax" type things or do you have at least one x1/x10 (or x10 only) probe to use?

author: nockieboy
author_rank: Super Contributor
timestamp: March 09, 2017, 04:29:41 pm
content: Quote from: grumpydoc on March 09, 2017, 04:20:28 pmUnfortunately they're literally crocodile clips on the end of a piece of co-ax...image postThough for the cost of a set of proper probes, I'm thinking of waiting until I can justify the extra £30 and maybe will get one of these:upload pic

author: CJay
author_rank: Super Contributor
timestamp: March 09, 2017, 06:58:35 pm
content: Nah, these will be fine:http://www.ebay.co.uk/itm/2pcs-High-precision-100MHz-Oscilloscope-Test-Probe-1X-10X-Attenuation-Ratio-R1I7-/232139542147?hash=item360c984e83:g:e6YAAOSwcLxYJEk8

author: nockieboy
author_rank: Super Contributor
timestamp: March 09, 2017, 07:23:00 pm
content: Quote from: CJay on March 09, 2017, 06:58:35 pmAwesome, thanks CJay. How are you getting on with your new-found inspiration? Did you dig out an old Z80 in the end?

author: grumpydoc
author_rank: Super Contributor
timestamp: March 09, 2017, 07:41:53 pm
content: Quote from: nockieboy on March 09, 2017, 04:29:41 pmThe 6022BE is not that great a 'scope, it has a maximum sample rate of 48MS/s which is only barely adequate for the stated 20MHz bandwidth. Although Nyquist says you only need 2x bandwidth most people feel that a 'scope should have at least 5x bandwidth or, better, 10x bandwidth samle rate. Plus having to have a PC or laptop to look at the signal is not all that convenient.Stick with your Hitachi.I would see if we can figure out why that divided clock is, or looks, so awful before proceeding with it though. Check you have VCC and 5V connected and have a decoupling cap. 74HC(T) chips are notorious for powering themselves through gate inputs if you forget to connect the 5V which can cause odd behaviour, LSTTL don't tend to suffer from this but the amplitude that you are getting is very small.

author: nockieboy
author_rank: Super Contributor
timestamp: March 09, 2017, 07:50:51 pm
content: Quote from: grumpydoc on March 09, 2017, 07:41:53 pmRoger wilco.Quote from: grumpydoc on March 09, 2017, 07:41:53 pmI've added a decoupling cap since you mentioned it previously - haven't had a chance to test the circuit since that addition, however - will take another look tomorrow. The scope leads are on order, so hopefully by early next week I'll be able to put up a much more accurate trace for the clock.I was just wondering - the ROM chip is working fine, the Z80 seems fine as it's stepping through the instructions properly, no reason to think the RAM should be an issue, so I'm going to examine the 68B50 more closely tomorrow when I get a chance, make sure it's wired up correctly and confirm the serial port settings are right as well. Even if the serial port settings aren't spot on, I'd imagine I'd be getting garbled information in the terminal window but I'm not getting anything...

author: janoc
author_rank: Super Contributor
timestamp: March 09, 2017, 07:55:36 pm
content: Quote from: grumpydoc on March 09, 2017, 07:41:53 pmThe reason for the 5-10x bandwidth sample rate is that Nyquist being 1/2 of the sample rate is cool - for sinusoidal signal. Good luck looking at any other type of signal. It will be missing all the higher harmonics that give it its shape or, worse, they will alias. So a square wave will look like a badly distorted sine. 5-10x gives you the fundamental frequency + several harmonics, so you can actually see what is the signal like.

author: grumpydoc
author_rank: Super Contributor
timestamp: March 09, 2017, 08:33:32 pm
content: Quote from: janoc on March 09, 2017, 07:55:36 pmI think that this has been discussed at length on the forum in the past.Well, yes but we tend to assume that "100MHz" 'scope has a bandwidth of 100MHz and, for a digital 'scope has an input filter with a 3dB point at that frequency (in practice a little higher) so you will loose the harmonics anyway. To show a reasonable "square wave" you need perhaps the 7th harmonic which looks like this when reconstructed.Are you suggesting that a "100Mhz" 'scope requires a front end bandwidth of 500 or 700Mhz?What sampling at 5-10x the bandwidthdoesdo, as you briefly mentioned, is minimise aliasing where the input contains frequencies over, but close to, the bandwidth such that they have significant amplitude after filtering. Early DSO's were very susceptible to aliasing and this is the main reason modern 'scopes tend to be set up to sample at 5-10x bandwidth.

author: janoc
author_rank: Super Contributor
timestamp: March 09, 2017, 09:16:14 pm
content: Quote from: grumpydoc on March 09, 2017, 08:33:32 pmNo, I am not suggesting that. My comment only concerned the sampling rate, which is terrible on that Hantek (vs the declared 20MHz bandwidth) and the higher harmonics of faster signals (but still within its declared bandwidth) simply won't "fit" under the Nyquist rate. So the limiting factor of usability will be both this and the frontend performance.

author: grumpydoc
author_rank: Super Contributor
timestamp: March 09, 2017, 09:20:43 pm
content: Quote from: janoc on March 09, 2017, 09:16:14 pmI think I said that as wellQuoteAbsolutely.

author: nockieboy
author_rank: Super Contributor
timestamp: March 10, 2017, 05:31:10 pm
content: Uh. Whilst I'm waiting for the oscilloscope probes to arrive, I thought I'd take a look at creating a test program that will cycle the 68B50 output so there's something for me to measure with the oscilloscope at the pins/USB connector.I thought I'd take a shortcut and just modify the monitor program that Grant Searle created to bootstrap the Z80 system and get the serial interface up and running by throwing a JP back to the start of the INIT routine where the startup message is displayed. This should have the effect of the Z80 monitor being caught in a loop, constantly trying to output "Z80 SBC by Grant Searle" to the USB/TTL interface via the 68B50 (and thusly allowing me to test its connections in my own sweet time.)Problem is I can't assemble the modified source file. There seems to be a dearth of Z80 assemblers out there and those that do exist won't touch the assembly provided on Grant Searle's site without throwing over a hundred errors. I'm going to have to edit the raw hex file directly, but was just wondering (without wanting to open a can of worms) if any of you more experienced Z80 systems-builders have a preference or suggestion for an assembler I could use on a Windows system?

author: grumpydoc
author_rank: Super Contributor
timestamp: March 10, 2017, 05:41:41 pm
content: Windows, no idea being a Linux guy for this sort of thing but the zip file with the source on Grant's site includes a dos executable of tasm - can you run that under windows (using something likedosboxif necessary).

author: CJay
author_rank: Super Contributor
timestamp: March 10, 2017, 05:47:29 pm
content: Umm, they compile just fine using the TASM that's included in the NASCOM Basic Zip file from Grant's site, can you not edit the source in the text files and recompile?*edit*Attached modified and compiled hex which has a JP added in line 169 that JP's back to line 167 and should continually print via serial the line:Z80 SBC By Grant SearleI hope.Oh, and yeah, I really need to dig out that box of Z80 chips, this is a little addictive.

author: nockieboy
author_rank: Super Contributor
timestamp: March 10, 2017, 06:51:45 pm
content: Quote from: CJay on March 10, 2017, 05:47:29 pmUh. Epic fail on my part there. I completely forgot about TASM in the zip file. I'm not a lover of the CLI and will actively search out 21st-century GUI-fied versions which is probably why I overlooked it.Quote from: CJay on March 10, 2017, 05:47:29 pmThank you very much!That's great - will get to work on that over the weekend (as well as biting the bullet and trying out TASM)!Yes, you must get the box out and breathe some life into a Z80 again!

author: grumpydoc
author_rank: Super Contributor
timestamp: March 10, 2017, 06:52:51 pm
content: Quote from: CJay on March 10, 2017, 05:47:29 pmFor reference they compile almost unmodified withzasmin Linux, for some reason I had to changeCP (serBuf+SER_BUFSIZE) & $FFtoCP lo(serBuf+SER_BUFSIZE)I'm still not quite sure what it did not like about the original

author: nockieboy
author_rank: Super Contributor
timestamp: March 10, 2017, 07:00:49 pm
content: Quote from: grumpydoc on March 10, 2017, 06:52:51 pmThe couple of interpreters I've tried have all had a fit trying to assemble the original source code. One (8080asm I think) I'm sure was trying to interpet the assembly as Intel code no matter what I did with the Z80 setting in it and didn't like the LD commands, but was happy with MOV instead (that's part of the Z80's compatible instruction set I'm guessing), until I found out it didn't like the Z80 register names - at which point I gave up with it.

author: james_s
author_rank: Super Contributor
timestamp: March 10, 2017, 07:15:07 pm
content: I'm pretty sure I have TASM on my CP/M system, which is another Grant Searle creation. I'm using one of the Altera FPGA boards he used and I made a custom daughterboard that holds the RAM, video and interface connectors.

author: nockieboy
author_rank: Super Contributor
timestamp: March 10, 2017, 07:22:09 pm
content: That compiled nicely CJay - thanks for that. TASM is working fine in DosBox.

author: CJay
author_rank: Super Contributor
timestamp: March 10, 2017, 07:30:41 pm
content: Quote from: nockieboy on March 10, 2017, 06:51:45 pmAh, it's easy to fall into that trap, FWIW, I edited the file using Notepad++ which is an excellent utility, capable of formatting, highlighting and more for an awful lot of source code correctly and there's a Z80 assembler scheme for it.Makes life a lot simpler.

author: nockieboy
author_rank: Super Contributor
timestamp: March 10, 2017, 08:28:52 pm
content: Quote from: CJay on March 10, 2017, 07:30:41 pmAhah, I've been using Notepad++ for years, excellent piece of software and very flexible. Wish I'd written it myself.I'll have a hunt for the Z80 scheme, that sounds handy.In other news, I've burnt a ROM with the test code on it and it seems to be running according to plan (at least as far as I can tell from the address and data bus activity LEDs). Whilst installing the test ROM, I took a closer look at the wiring for the 68B50 and noticed some schoolboy errors in the USB/TTL connection. I'd got /CTS connected to /CTS and TxD and RxD connected to their identical twins.So I've swapped /CTS from the USB to /RTS on the 68B50 and TxD now goes to RxD and vice-versa. I was hoping it'd all magically work after correcting those mistakes, but still nothing from the terminal.Will have to wait for the oscilloscope probes so I can see what activity there is (if any) from the 68B50.

author: nockieboy
author_rank: Super Contributor
timestamp: March 13, 2017, 11:55:17 am
content: Okay, the probes arrived in the post this morning so I've tried them out - what an improvement!Some updated oscilloscope traces follow - I've swapped out the 7.3268 MHz crystal for a 3.6864 MHz one to slow things down slightly and had a look at the clock signal. I'd originally got it divided by 4 through two D-type flip-flops, but strange things were happening so I swapped the clock divider out and the following images were taken at 3.6864 MHz.The issue I'm finding at the moment (and it's probably user error to do with the oscilloscope/probes, maybe) is that when the clock circuit isn't connected to the rest of the computer, I get the following clean trace at 5V:image shareBut if I connect the clock signal to the rest of the computer, the trace looks like this:image hosting siteWhat am I doing wrong?For info, the clock circuit on the breadboard looks like this:free image uploaderI've checked the signal from the TxD pin on the 68B50 and there's a signal on that, so it looks like it's trying to send information.

author: grumpydoc
author_rank: Super Contributor
timestamp: March 13, 2017, 01:01:37 pm
content: It's probably struggling to drive the capacitance/inductance of the breadboard (which is why breadboards are not great for high frequency signals).Just to make sure it is not a probe artefact it will be worth switching to the x10 position (with a corresponding change in the vertical volts/div).It might help to add a small resistor to the output of the clock signal buffer - 33ohms is often about right.Was it a 74HCT04 or a 74ACT04 that you used for the oscillator?

author: nockieboy
author_rank: Super Contributor
timestamp: March 13, 2017, 01:19:27 pm
content: Quote from: grumpydoc on March 13, 2017, 01:01:37 pmSo any attempt to slow the clock is a good thing? I'll try to get the clock divider working nicely again.Quote from: grumpydoc on March 13, 2017, 01:01:37 pmRighto, will get back to you on progress with the resistor and probe changes. I'm using a 74HCT04 for the oscillator.

author: grumpydoc
author_rank: Super Contributor
timestamp: March 13, 2017, 01:22:28 pm
content: Quote from: nockieboy on March 13, 2017, 01:19:27 pmOK, good.It's the edge speed which is the problem. HCT is fairly slow, ACT is really, really fast and will cause more issues on a breadboard - it was just that I vaguely recalled you mentioning something about ACT in a previous post (and confess I was a bit too lazy/busy to go back & look).

author: CJay
author_rank: Super Contributor
timestamp: March 13, 2017, 02:05:34 pm
content: Just as a matter of interest, is the output/input of the 68B50 inverted for use with a typical RS232 driver?Now you're seeing signals on the TX line of the ACIA it could be working just fine but if you're using a TTL to USB adapter it might need inverting.The PC should be more than fast enough to deal with data at 57600bps so you don't need the handshaking signals, hard wire them to the 68B50 perhaps.

author: nockieboy
author_rank: Super Contributor
timestamp: March 13, 2017, 02:58:42 pm
content: Quote from: CJay on March 13, 2017, 02:05:34 pmNo, the 68B50 IO isn't inverted - it makes no mention of inverting the signals in the notes provided by Grant Searle... So we're all on the same song sheet, here's the schematic I've been basically working to (the only changes on my design are the RAM/ROM as mine are larger chips):photo sharing sitesAnd here's what I've been working to with the USB/TTL connection:upload imgSo, aside from the 5V and GND connections (which I'm using to power the SBC), I'm only using three wires from the USB connection - TxDATA, RxDATA and ~CTS. TxD is connected to RxDATA on the 68B50, RxD is connected to TxDATA on the 68B50 and ~CTS is connected to ~RTS on the 68B50. NOTE: I'm not using resistors as I'm powering the SBC from the USB cable.Now, I'm hoping that's connected up as it should be - it's certainly how I'm interpreting the diagrams supplied by Grant Searle. The USB/TTL cable I'm using is identical to this one:http://www.ebay.co.uk/itm/FTDI-FT232RL-USB-to-TTL-Serial-RS232-Cable-6-Pin-ARM-PIC-Pi-Arduino-UK-Seller-/191639851857?hash=item2c9ea01351:g:h9QAAOSwDNdVqi-XThe wire colours / connections pin-out for the TTL connector are what I'm using from that page.If this is wrong and I should have an inverter between the 68B50 and the TTL interface, please let me know and I'll get one connected up ASAP!

author: nockieboy
author_rank: Super Contributor
timestamp: March 15, 2017, 02:19:05 pm
content: Unfortunately I haven't had any time to work on the project since my last post, but a thought occurs to me; initially when I powered up the SBC, it was drawing 1.2 amps.That would have been through the USB/TTL cable - could/would that have blown the FT232RL circuitry in the USB lead? If so, then perhaps the SBC has been working fine (with the exception of the initial 68B50 wiring error causing the short in the first place) and the USB/TTL lead isn't allowing the PC to communicate with the SBC?Other than getting another USB/TTL lead, is there any way I can test the existing lead to see if it's functioning correctly?

author: PA0PBZ
author_rank: Super Contributor
timestamp: March 15, 2017, 02:27:16 pm
content: Quote from: nockieboy on March 15, 2017, 02:19:05 pmJust short TXD and RXD, send some characters using your favourite terminal program and see if it echos.

author: nockieboy
author_rank: Super Contributor
timestamp: March 15, 2017, 02:43:23 pm
content: Quote from: PA0PBZ on March 15, 2017, 02:27:16 pmAh, thanks PA0PBZ - yes, it's working.At least I can exclude that from my list of possible problems.

author: CJay
author_rank: Super Contributor
timestamp: March 16, 2017, 07:47:30 am
content: What current is it drawing now and how are you powering it?

author: grumpydoc
author_rank: Super Contributor
timestamp: March 16, 2017, 08:21:41 am
content: Quote from: nockieboy on March 15, 2017, 02:19:05 pmThat seems quite high - a 10MHz CMOS Z80 should only be 50mA, the ROM/RAM about 10mA each. Even the relatively power hungry 68B50 should only be 100mA max.Do you know where all that current is going?

author: nockieboy
author_rank: Super Contributor
timestamp: March 16, 2017, 08:56:02 am
content: Quote from: grumpydoc on March 16, 2017, 08:21:41 amNo no, I was talking about when I FIRST powered the SBC up originally and realised there was a problem which I then tracked down to the 68B50 being incorrectly hooked up to the power rail (I'd originally powered it the wrong way around thanks to confusion over Vcc/Vdd/Vss labelling in the datasheet) and as a result, the whole SBC was drawing 1.2 amps. That was before I started this post, which I did to seek help getting the system working as it still was effectively 'dead' to the laptop terminal program, even after the 68B50 'fix'.Since correcting the 68B50 wiring error (and replacing the 68B50 with a new one as a precaution) the whole SBC is drawing a very reasonable 0.07-0.10A, which I'm powering via the USB/TTL connection, as per the USB/TTL connection diagram I posted a few comments back.So, currently, this is where I am with the project:* SBC powers up, drawing 0.07-0.10A via the USB/TTL connection, currently clocked at 3.6864 MHz* SBC shows appropriate address & data bus activity for the test monitor program written to the ROM (repeatedly prints a string to the serial interface to make the 68B50 testing easier - thanks CJay) after initial power-on reset (expected behaviour)* I had briefly tested the TxD output of the 68B50 with my oscilloscope and got a repeating signal, indicative of the test monitor program repeatedly printing the string to the serial interface - I need to go back to this when I have some time, do some more testing of the 68B50 and upload a trace of the signal to this post for thoughts* I have checked the USB/TTL lead in isolation and it is echoing characters to the terminal, so is believed to be fully functionalTo test the USB/TTL lead, after shorting TxD and RxD together, I had to turn off all flow control to get the characters I typed echoed to the terminal screen. I've tried the same with the SBC connected to the terminal (i.e. without flow control altogether) and there's still nothing at the terminal where I would expect garbage, so I'm wondering about something CJay mentioned earlier about signal inversion - perhaps the CTS/RTS signal from the 68B50 needs inverting and is holding up communication with the terminal?This is my next line of investigation anyway when I get 5 minutes.

author: PA0PBZ
author_rank: Super Contributor
timestamp: March 16, 2017, 10:48:41 am
content: Quote from: nockieboy on March 16, 2017, 08:56:02 amEven when you have the polarity wrong the PC will see a start bit and will try to come up with something. Only when the baud rate is totally off (like the sbc being much faster than the PC) it will not detect a start bit and you will see nothing. If you modify your program to send "U" (which has a nice 0101 pattern) and then have a look with the scope what the puls width is we can find out what is going wrong.

author: nockieboy
author_rank: Super Contributor
timestamp: March 16, 2017, 11:20:10 am
content: Quote from: PA0PBZ on March 16, 2017, 10:48:41 amSounds like a plan - thanks PA0PBZ - will try that later!

author: nockieboy
author_rank: Super Contributor
timestamp: March 18, 2017, 09:57:09 am
content: This is probably a stupid question, but can I just swap the 7.3728 MHz crystal with the 3.6864 MHz crystal and not have to change the capacitor values in the oscillator circuit to get the 3.6864 MHz clock frequency? At the moment I've just swapped the crystal and left the rest of the circuit.

author: nockieboy
author_rank: Super Contributor
timestamp: March 18, 2017, 10:03:05 am
content: Ah, think I've answered my own question. So I need to swap out the 22pF caps for 33pF and increase R3 to 5K.I really need to sort the clock out before I start measuring the signals from the 68B50.

author: nockieboy
author_rank: Super Contributor
timestamp: March 18, 2017, 12:13:23 pm
content: Okay, some oscilloscope traces from the 68B50 ACIA chip. The SBC was running at 3.6864 MHz (albeit with 22pF caps and a 1K resistor, where these should be 33pF and 5K resistor.)First trace is on pin 8 (CS0) which is the ~M1 signal:image uploadSecond trace is on pin 7 (~IRQ) which is the ~INT signal:image uploadThird trace is the clock signal itself as it arrives at the 68B50 at pins 3 & 4 (Rx CLK and Tx CLK):host image onlineNext trace is TxDATA (pin 6):click image uploadThat was a difficult trace to stabilise - the edge trigger was especially fiddly to get right.Last trace is from ~RTS pin 5:picture uploaderI've tried to get the oscilloscope settings for time/div and volts/div in the images too, but I'm having no luck interpreting these traces. Seems to me the ACIA is working and sending a signal, so maybe it's just a clock/timing issue with the serial port?The interrupt signal seems to be especially mangled though - seems like there's multiple voltage levels on that trace, rather than just +5v an 0v? Also, the last two traces look more like analogue signals than digital/TTL signals...

author: PA0PBZ
author_rank: Super Contributor
timestamp: March 18, 2017, 12:18:02 pm
content: Pin 5,6 and 7 don't make any sense at all, I'd say you have problems but it is not immediately clear to me what's going on.Care to post a picture of your setup?

author: grumpydoc
author_rank: Super Contributor
timestamp: March 18, 2017, 12:36:45 pm
content: M1 & clock look good, very clean & sharp edges actually.INT looks like it is picking up junk from somewhere - make sure it is tied to +5V via a resistor - 2.7k should do and you do not have any inadvertent connections to anything other than the 68B50. For the time being you could disconnect INT and just leave the pullup.The other look like just noiseLeave the 'scope set up so that 5V is one division, the best way is to have the probe in x10 and the 'scope at 0.5V/div.

author: nockieboy
author_rank: Super Contributor
timestamp: March 18, 2017, 12:37:37 pm
content: Quote from: PA0PBZ on March 18, 2017, 12:18:02 pmOkay, here's a few pics of my setup - not that it's very clear due to all the address and data bus wires connecting the LEDs up at end.host image onlineOverall setup above.img hostCloseup of the 68B50 end of the board (USB/TTL lead not attached.)image hosting over 5mbCloseup of the 68B50 end of the board, showing the address and data LEDs, USB/TTL connected and board running. Top right of the board is spare components (resistors, LED, capacitor, crystal)- they're not connected to anything.Blue wires are address bus, orange are data bus, yellow are control bus. Green button (inc LED and 555 timer) is single-step clock. Red button is reset.I've checked and double-checked the wiring for the 68B50 - it's connected up as per the schematic I posted earlier.

author: Bud
author_rank: Super Contributor
timestamp: March 18, 2017, 04:52:21 pm
content: Please pay some respect to your Hitachi scope and clean it, it loks filthy, how you can possibly touch it

author: nockieboy
author_rank: Super Contributor
timestamp: March 18, 2017, 05:03:24 pm
content: Okay I've added a 2K7 pull-up resistor to the ~INT line over by the Z80 as per grumpydoc's suggestion.I know the clock isn't going to be exactly 3.6864 MHz as it's got 2x 22pF caps and a 1K resistor, where it needs 2x 33pF caps (on order) and a 5K resistor, so I'm not even trying to get the serial connection with the laptop working until the caps arrive next week. I am, however, trying to analyse potential connection issues with the 68B50.New traces (all with probe set to x10):Pin 8 - CS0 (~M1 signal)image upload no limitThese next two traces show the ~IRQ, pin 7, with the signal from ~INT - the first with no pull-up resistor on ~INT (as it was before grumpydoc's suggestion). I've dropped the volts/div to .2 for these two traces so you can see there's a superimposed signal on the otherwise live (+5V) line on the second trace:uploading picturesThis second one is WITH the 2K7 pull-up resistor on ~INT:adult image hostingHowever, this is the consistent trace I'm getting for the TxD line now (pin 6):image uploadThat's not looking so good. RxD is identiical - both are high, which implies the chip is in standby?At least I'm getting cleaner signals now...

author: grumpydoc
author_rank: Super Contributor
timestamp: March 18, 2017, 05:48:47 pm
content: Quote from: nockieboyThat's looking much better.Remember that \$ \small \overline{INT} \$ is an input to the Z80, from the 68B50. You don't want spurious interrupts or things are going to be quite confusing.Also, you will always get a bit of noise and pickup from other signals running nearby - it does not matter in digital systems as long as the magnitude is not sufficient to make the system confused about what is a logic '0' or logic '1'. That's why we talk about noise immunityEDIT: PS: If you don't have pullups on all of the other Z80 control inputs - \$ \small \overline{NMI} \$, \$ \small \overline{BUSREQ} \$ and \$ \small \overline{WAIT} \$ I would add them now.

author: nockieboy
author_rank: Super Contributor
timestamp: March 19, 2017, 10:45:16 am
content: Quote from: grumpydoc onTodayat 04:48:47 AMYep, I've had pull-ups on ~NMI, ~BUSREQ and ~WAIT as part of the original design (all are 1K resistors though?) So it would appear that the ~INT line was low before I added the pull-up resistor according to the traces above. That's odd, as the system seemed to be running okay (the Z80 was incrementing the address bus etc.)So now TxD and RxD are high, with no variation. I've checked the connections to the 68B50 and it's all correct, so the chip select signals (CS0, CS1 and ~CS2) should be working as expected and the chip should be active when needed. I'm going to see if I can get the second trace up and see if CS0/CS1 are high at the same time (as they should be) along with E and ~R/W.

author: grumpydoc
author_rank: Super Contributor
timestamp: March 19, 2017, 10:58:25 am
content: QuoteYes, the next step is to make the 68B50 is being written to correctly, trigger CH1 on IORQ and then go looking with CH2 on your 'scope at the CS and RS pins as well as the enable line (pin 14 should be the inverse of IORQ) and that R/W is getting to the UART correctly.Also check that you grounded CTS.

author: nockieboy
author_rank: Super Contributor
timestamp: March 19, 2017, 07:06:43 pm
content: Quote from: grumpydoc on March 19, 2017, 10:58:25 amYes, CTS is grounded along with ~DCD.Getting a nice inverted IORQ signal to pin 14, E. CS0, CS1and ~CS2are all signalling as expected and should be enabling the 68B50 as required as their signals all coincide properly with the IORQ signal.TxD and RxD are both still high constantly.One thing of interest is pin 13 - ~R/W. It is constantly high. Having checked the datasheet for the 68B50, it would appear that this pin is high accessing the read-only registers. This can't be right as the only thing the SBC is trying to do at the moment is print the letter U to the serial bus, so surely this pin should be low? Grant Searle's schematic shows the ~WR pin of the Z80 connected directly to pin 13 of the 68B50, which is what is happening on my breadboard...

author: PA0PBZ
author_rank: Super Contributor
timestamp: March 19, 2017, 07:10:44 pm
content: the ~ or NOT indicates that the function is the inverse of the logic state. So when your ~R/W is high it is in write state, if low it is in read.

author: nockieboy
author_rank: Super Contributor
timestamp: March 19, 2017, 07:32:34 pm
content: Quote from: PA0PBZ on March 19, 2017, 07:10:44 pmOkay, I've gone back to the datasheet for the 68B50 to clarify this. Here's an excerpt from the datasheet: (NOTE: It's actually written as R/~W rather than ~RW as I've written it previously.)QuoteNow, I may be mis-reading that but it seems to me that pin 13 should be LOW when writing to the ACIA to output via the serial bus?

author: PA0PBZ
author_rank: Super Contributor
timestamp: March 19, 2017, 07:45:34 pm
content: Quote from: nockieboy on March 19, 2017, 07:32:34 pmIf you first write ~R/W and then R/~W... well, that is confusingIn your last definition yes, pin 13 should be low for writing (~1 = 0, ~W = also 0).It could be a very short pulse, did you try to trigger on it in normal mode and see if anything happens?

author: grumpydoc
author_rank: Super Contributor
timestamp: March 19, 2017, 07:49:59 pm
content: Quote from: nockieboy on March 19, 2017, 07:32:34 pmIt's labelled \$ \small Read/Write ~ R\overline{W} \$ indicating that the write function is active low. Active low lines can also be shown using ¬NAME ~NAME or -NAME if you can't write an overbar.It should be going low to write to the UART, another clue is that it is connected directly to the Z80 \$ \small \overline{WR} \$ signal.I'd check the wiring.Quote from: PA0PBZ on March 19, 2017, 07:45:34 pm\$ \small \overline{WR} \$ is low for about two clocks in an IO cycle, so plenty of time to see it on the 'scope.

author: PA0PBZ
author_rank: Super Contributor
timestamp: March 19, 2017, 07:53:43 pm
content: @grumpy: I didn't bother to check the datasheet but trusted nockie on this, it will not happen again...

author: grumpydoc
author_rank: Super Contributor
timestamp: March 19, 2017, 08:02:00 pm
content: Quote from: PA0PBZ on March 19, 2017, 07:53:43 pmI think that it was mostly a transcription error.I suspect that the 68B50 \$ \small R\overline{W} \$ is not connected to the Z80 correctly, we'll know when nockieboy has checked the connections.You can generate an overbar using the embedded LaTeX mode \$ \overline{thing} \$, I don't know how it displays on other folk's screens but I find a \small before the \overline is about right as well.

author: nockieboy
author_rank: Super Contributor
timestamp: March 19, 2017, 08:21:33 pm
content: Quote from: PA0PBZ on March 19, 2017, 07:53:43 pmSorry about that PA0PBZ! I am pretty new to this stuff and am only realising through trial and error that I have to be extremely explicit when writing information here.Quote from: grumpydoc on March 19, 2017, 07:49:59 pmYep, I thought it should be low hence raising it as an issue earlier. Unfortunately the wiring consists of one wire which goes straight from \$ \small \overline{WR} \$ on the Z80 to pin 13 R/\$ \small \overline{W} \$. It's definitely not mis-wired. I have just checked the signal on the Z80 \$ \small \overline{WR} \$ pin, with no other wires connected to it (there's normally two - one for the 68B50 and one goes to a 74HCT00 for the memory glue logic) and guess what? The signal is HIGH constantly (with some noise that looks like it accounts for about 1V, certainly not a clean TTL signal.)It appears that the Z80 isn't trying to WRITE anything? I'm getting a nice signal on the \$ \small \overline{RD} \$ pin, but \$ \small \overline{WR} \$ is just giving me a jaggy signal between 4-5V...Here's the signal on the \$ \small \overline{RD} \$ pin (volts/div at .5 with x10 probe):picture shareAnd here's the signal on the \$ \small \overline{WR} \$ pin (volts/div dropped to .2 with x10 probe):free screen captureThat ain't right.

author: grumpydoc
author_rank: Super Contributor
timestamp: March 19, 2017, 09:04:44 pm
content: Time to review the software

author: grumpydoc
author_rank: Super Contributor
timestamp: March 19, 2017, 09:27:43 pm
content: Quote from: grumpydoc on March 19, 2017, 09:04:44 pmSo, the code should be stuck in a loop doing this:DBUG:LDHL,SIGNON1; Sign-on messageCALLPRINT; Output stringJPDBUGPRINT is coded thus:PRINT:LDA,(HL); Get characterORA; Is it $00 ?RETZ; Then RETurn on terminatorRST08H; Print itINCHL; Next CharacterJRPRINT; Continue until $00The software interrupt 08 jumps to the transmit routine which looks like this:TXA:PUSHAF; Store characterconout1:INA,($80); Status byteBIT1,A; Set Zero flag if still transmitting characterJRZ,conout1; Loop until flag signals readyPOPAF; Retrieve characterOUT($81),A; Output the characterRETAs you are not seeing any writes I would guess that it is reading a 0 for the status bit and sitting in the tight loop jumping back to conout1 repeatedly reading the port, rather than executing the longer loop around outputting a whole string - you should be able to follow the loop on your 'scope.The first thing I would check is that the data bus is connected correctly to the 68B50 - D0 from the Z80 going to D0 on the UART etc.EDIT:The 2nd thing I'd check is that the address lines are correctly connected to the chip select pins and the register select line RS2nd EDIT:It's also worth considering whether the CPU is executing the code that we think it is. The best tool would be a logic analyser but as we don't have one the 'scope can be used - trigger on MREQ and get a steady trace on CH1, then go over the other signals with CH2 to see what is happening.In this case it does look as though we are running the read port/test bit/jump loop.IN A,($80) consists of an M1 cycle (4 clocks), a memory read (for the port number) which is 3 clocks and then the I/O operation (4 clocks), 11 clocks in all.BIT 1, A consists of 2 M1 cycles (8 clocks).JR consists of 1 M1 cycle (4 clocks), a memory read (for the offset) which is 3 clocks, then the jump execution, 5 clocks, if the jump is taken.So, you should get the following over 31 clock cycles, forgive the bad ASCII artCode:| IN A,($80) | BIT 1,A | JR conout1| M1 cycle | Mem RD | IO cycle | M1 cycle | M1 cycle | M1 cycle | Mem RD | JumpCLK |`|_|`|_|`|_|`|_|`|_|`|_|`|_|`|_|`|_|`|_|`|_|`|_|`|_|`|_|`|_|`|_|`|_|`|_|`|_|`|_|`|_|`|_|`|_|`|_|`|_|`|_|`|_|`|_|`|_|`|_|`|_|`|M1 |______|````````````````````````````````|_______|```````````|_______|```````````|_______|``````````````````````````````````````So, basically M1 goes low, then there is a bit of a pause, then three M1 low pulses in a row, then a bit of a pause again and then the cycle repeats.Happily the trace that you showed of M1 seems to show the above pattern so hopefully it is running the conout1 loop and you've just got a bit of a miswire somewhere.Otherwise the 68B50 has stuck not transmitting for some reason.

author: nockieboy
author_rank: Super Contributor
timestamp: March 19, 2017, 10:17:19 pm
content: As always, thanks for the guidance grumpydoc.I'll update you when I get the chance to follow this up during the week.

author: nockieboy
author_rank: Super Contributor
timestamp: March 20, 2017, 02:59:09 pm
content: Quote from: grumpydoc on March 19, 2017, 09:27:43 pmWow - thanks for that grumpydoc, awesome detail in your reply!!I had a spare five minutes at lunch to get the multimeter out and test the connections between the Z80 and the 68B50. Unfortunately I haven't found any wiring errors on the address, data or control buses. It does look as though the Z80 is stuck in the conout1: loop from the M1 signal.If I understand it correctly, BIT 1,A is testing to see if the 68B50 is already transmitting something and holding until it says it's clear? So it looks as though the 68B50 is erroneously reporting that it's transmitting when it isn't?

author: nfmax
author_rank: Super Contributor
timestamp: March 20, 2017, 03:29:25 pm
content: Jumping in (feet first) with a couple of comments:Both theCode:CALLandCode:RSTinstructions should generate two write pulses, to write the current program pointer into RAM at the stack pointer location. You aren't seeing these (I think) therfore the fault is not restricted to the ACIA wiring. Check the /MEMWR signalI assume you are using Grant's Z80 circuit: check the wiring to U7A pin 1 actually goes to pin 1. If you have accidentally wired the Z80 /WR output to an LSTTLoutput(which is at a logic high) instead of an input the feeble Z80 output driver will be unable to pull it low. From your screenshot, it might be trying to do this

author: nockieboy
author_rank: Super Contributor
timestamp: March 20, 2017, 03:52:32 pm
content: Quote from: nfmax on March 20, 2017, 03:29:25 pmWelcome nfmax - any input is appreciated, feet first or not!There's some food for thought there - yes, I'm using Grant's Z80 circuit almost to the letter. The only differences are that I'm using the USB/TTL serial connection rather than the RS232 and my RAM/ROM chips are much larger (which just means the higher addresses are grounded so only the lower 64K (SRAM) and 8K (ROM) are used.)

author: grumpydoc
author_rank: Super Contributor
timestamp: March 20, 2017, 03:59:01 pm
content: Quote from: nfmax on March 20, 2017, 03:29:25 pmYes, they should both write the stack but the CPU definitely looks to be stuck in the loop testing the modem status bit and in that loop there are no memory writes.It won't hurt to (double) check the wiring though.Quote from: nockieboy on March 20, 2017, 02:59:09 pmIt says that something has been loaded into the transmit register which has not transmitted yet - normally I would expect that is because it is still being sent. The only reason I can see for the current situation, assuming the Z80 is correctly wired to the 68B50 is that it does not have a transmit clock.I find myself wondering whether this 68B50 does not like being overclocked?What clock are you currently running things at?

author: nockieboy
author_rank: Super Contributor
timestamp: March 20, 2017, 04:10:45 pm
content: Quote from: grumpydoc on March 20, 2017, 03:59:01 pmIt's running at 7.3628 MHz at the moment. I was trying to run it at 3.6864 MHz, but without the correct 33pF caps I switched back up to the 7.3628 MHz crystal. I'm going to have a stab at getting the clock divider (D-type flip flop x 2 to divide the clock by 4) working again to drop the clock speed down to 1.8407 MHz (2 MHz is the quoted top speed for the 68B50 in the datasheet.)I do have a Z80 SIO chip lying around. I was considering swapping it for the 68B50 later once I'd got it all working and was a little more experienced at this sort of stuff. Might have to consider doing that sooner than later at this rate.

author: nfmax
author_rank: Super Contributor
timestamp: March 20, 2017, 04:16:34 pm
content: What do the signals E at the 68B50 pin 14, and CSO at the 68B50 pin 8 (which should just be M1) look like on the oscilloscope?

author: grumpydoc
author_rank: Super Contributor
timestamp: March 20, 2017, 04:22:32 pm
content: Quote from: nockieboy on March 20, 2017, 04:10:45 pmI'd put the clock divider in there and run at 1.84MHz initially then you will guarantee to be within the 68B50 spec.The datasheet says 1MHz for the clocks but also says that the high/low pulse width can be down to 280ns which implies that you can run it OK at 1.8Mhz.Also the data access time might be marginal - the IO cycle gives you about a clock and a half (from memory, I will check when I get home from work) which would be just over 200ns at the 7.3Mhz clock - the 68B50 has a specified access time of 180ns which should be fine but....Where did you get it from by the way? eBay or a reputable source?QuoteThe SIO is a bit more complex to set up so there is more opportunity to get it wrong - I haven't actually used the 68B50 before in a design but in theory it looks relatively simple and dare I say (probably not in the current context) bombproof.

author: nockieboy
author_rank: Super Contributor
timestamp: March 20, 2017, 04:26:04 pm
content: Quote from: nfmax on March 20, 2017, 04:16:34 pmI don't have a trace handy for E but will try to get one later tonight. M1, however, is as below:Quote from: nockieboy on March 18, 2017, 12:13:23 pmQuote from: grumpydoc on March 20, 2017, 04:22:32 pmThe 68B50's were from eBay...

author: grumpydoc
author_rank: Super Contributor
timestamp: March 20, 2017, 04:30:48 pm
content: Quote from: nockieboy on March 20, 2017, 04:26:04 pmOK, well.Now, I have bought a good few NOS chips from ebay for repairing ancient 1980's electronics and they have been absolutely fine but you do have to consider the possibility that someone has remarked a straight 6850 as the higher speed "B" part, maybe not likely, but possible.Slow everything down such that you are well within the spec of the chip and see where you get to.

author: nfmax
author_rank: Super Contributor
timestamp: March 20, 2017, 04:36:36 pm
content: I bought a 68B50 off eBay seller Littlediode, which works fine in Grant's 6809 design. YMMV

author: grumpydoc
author_rank: Super Contributor
timestamp: March 20, 2017, 05:17:36 pm
content: Yes, I've used Littlediode, they seem legit, if occasionally expensive.

author: nockieboy
author_rank: Super Contributor
timestamp: March 20, 2017, 07:59:55 pm
content: Oookay.I've got the clock divider working again. After some messing about and trying to work out why it was producing a lovely clean clock signal when it wasn't connected to the CLK bus line, but a 1V-high line of fuzz on the 'scope when I plugged it into the CLK bus line, I've worked out that I need to disconnect the CLK line from the single-step clock circuit for some reason. Looks like you were right, grumpydoc, the CLK pulse was the issue after all.Once the single-step clock is disconnected, the CLK signal is marvellous (running at 1.84 MHz). So marvellous, in fact, that my serial program, Realterm, logged a 468K text file of garbage from the serial port recorded over about 10 seconds or so.Here's an abbreviated version of the log file:QuoteThe K8 pattern repeats until end of file.Erm.. seems the ACIA is working.All I need to do now is work out the port settings and maybe swap the original monitor program ROM back in.

author: CJay
author_rank: Super Contributor
timestamp: March 20, 2017, 08:11:38 pm
content: Well if that K8 pattern really does repeat then it should be a simple matter to watch the terminal window and step through the serial speeds, if it was meant to be 57600bps at 7.6864MHz though I'd take a guess at 14400...

author: nockieboy
author_rank: Super Contributor
timestamp: March 20, 2017, 08:18:28 pm
content: Yeah, got it - 28800 bps. Took me a little longer as Realterm provides a drop-down list of speeds, of which the one I needed wasn't there. Luckily I was able to type it in and lo and behold, it's working!!Thank you very much everyone for all your help, it has been much appreciated!! No doubt I'll be back later when I start trying to upgrade this or working out how to swap it over to a more permanent PCB.Thank you again.UPDATE: SBC is working at 7.3728 MHz too! One thing I've noticed at this speed, though, is that characters are getting dropped in the terminal:QuoteDoesn't seem to drop chars when listing a program that I've entered, though, but it certainly seems to be a timing issue perhaps. Might roll it back to 3.6864 MHz and see if it's more stable there.UPDATE: It seems that the letters S and R (and likely a few others too) are being dropped. Whilst entering a program, I noticed the letters S and R were being dropped from a line. I rewrote the line, doubling up the S's and R's and when I listed the program, they were present as single characters. Odd, but no doubt something to do with how the characters are represented in binary and transferred across the serial interface, perhaps?

author: CJay
author_rank: Super Contributor
timestamp: March 20, 2017, 09:20:42 pm
content: Quote from: grumpydoc on March 20, 2017, 05:17:36 pm'Occasionally'? If I could get the prices they ask for some of the parts I have here NOS I could retire

author: nockieboy
author_rank: Super Contributor
timestamp: March 20, 2017, 09:22:17 pm
content: Quote from: CJay on March 20, 2017, 09:20:42 pmHave you started on a Z80 build yet then CJay? You mentioned being tempted back into it some posts back...

author: CJay
author_rank: Super Contributor
timestamp: March 20, 2017, 10:45:49 pm
content: I've got about this far:https://goo.gl/photos/WveGmjvTenpGQvp27There's a Z80 in the antistatic box, bottom left corner, all the HC TTL and RAM in the upper section (628128 and 68B50 on order) and a pile of mixed 'other' stuff including a few 6502 parts, some 805x parts inc a couple of BASIC52 EPROMS.Planning to build it on this cheap Chinese proto board:https://goo.gl/photos/Bq7zDLMv7fRAb59q8

author: nockieboy
author_rank: Super Contributor
timestamp: March 20, 2017, 11:15:51 pm
content: Quote from: CJay on March 20, 2017, 10:45:49 pmThat looks like a little treasure trove of parts!I've never used proto board (strip board is the closest) - do you use a wire pen to link the component legs on those? Almost tempted to try it myself.My next steps are to build a PCB once I'm happy the extra bits I want to add work (bus buffers, extra IO, maybe keyboard/monitor interface) - I'm thinking of getting a commercial company to build it from my design (I use DipTrace). I doubt my PCB-etching skills are up to it!

author: CJay
author_rank: Super Contributor
timestamp: March 21, 2017, 06:44:19 am
content: Quote from: nockieboy on March 20, 2017, 11:15:51 pmOh that's just one box. There are many more where that came from, if pressed I might have to admit to being a bit of a packrat but I've been salvaging components from boards since the 80s, there are boxes and boxes of parts that were tested and stored away 'for projects'.Home etching is easy at this scale, I'd encourage you to practice a little because it really is very satisfying to be able to take a design and manufacture it from start to finish.While not my design, the board under the 6502 stuff is one of a batch I etched back in the early 90s (it's a board for an Elektor 8052 BASIC computer).I etched a few for friends but never used that one as it was a little scruffy, there's nothing wrong with it electrically it just wasn't as good as the rest.The better examples have probably long since passed into the dustbin of history as friends moved away or, in a couple of cases, died but I do have all the bits to build that one up...https://goo.gl/photos/7M6VcVUfee9SJZVQ6

author: nockieboy
author_rank: Super Contributor
timestamp: March 21, 2017, 08:13:37 am
content: Quote from: CJay on March 21, 2017, 06:44:19 amI've only ever really tried very small circuit designs when I was at school, with the traces drawn in pen. Seem to recall the etching results being very variable and so am a little anxious about trying it with a board as complicated (to me anyway) as the Z80 SBC would be.Clearly transfers are the only way to go to lay the tracks and pads down. Maybe I'll give it a few tries and see if I can make something myself before going the expensive route.Quote from: CJay on March 21, 2017, 06:44:19 amLooks good to me - certainly better than anything i could produce!You've persuaded me though - I think I'll give it a go myself. Still got the drill and some old copper boards (though I'll probably get some new ones to work on).It'll be a while before I need to worry about the board, I've got some additional work to do with the prototype first (such as an SD card reader) but when I do are there any supplies or design tips I need to keep in mind?

author: CJay
author_rank: Super Contributor
timestamp: March 21, 2017, 11:40:56 am
content: It's not expensive to have them made if you use one of the Chinese fabs but when you've got an idea or need to respin a prototype waiting three weeks or longer is a pain in the nethers.Mikeselectricstuff has a good tutorial (we disagree about etchant though, I loath FeCl, persulfate is much nicer)http://www.electricstuff.co.uk/pcbs.htmlFind a local office services place that can copy your design from an inkjet printout onto transparency (the Elektor board was made from a direct photocopy from magazine to transparency) or, if you've a decent laser printer, print it direct to transparency, don't dick about with pens unless it's a trivially simple design, ditto transfers unless it's onto a transparency.A nail curing UV lamp will do the job for exposing the board but it's a good idea to experiment with exposure times, I think BigClive had a video about that too. You can make a UV box for not much money.Fresh UV laminate is always best so try and get it from somewhere that's got turnover, it degrades with age and takes longer to expose, develop and strip.I've got a roll of the dry film UV resist stuff you find on eBay but I haven't used it myself yet, I believe it works well though.Don't be tempted to use sodium hydroxide for processing PCBs, it's dangerous stuff and a PITA to get right anyway. Sodium Metasilicate is much safer and way simpler to get reliable results.eBay is your friend for chemicals, you can buy all you need there, common or garden kitchen plastic tubs work well as process tanks but obviously don't use them for food afterwards.I reckon you could be up and started for under £20 in materials, tools (basic) and trays, you'd need a PCB drill (with stand if you use carbide bits) but the very simple ones can be had for a couple of quid.

author: grumpydoc
author_rank: Super Contributor
timestamp: March 21, 2017, 02:03:03 pm
content: Glad to see things are now workingI confess I'm not that great a fan of home etching.. I admit that his is mostly my fault but I just have not managed a set-up which gives consistent results. I did acquire a UV box (for a whole £5it works but boy does it need a clean) which I haven't tried yet so that might be the magic key to good results.But even then safe handling of etchants and developers in a domestic environment is something which bother me quite a bit.I think I just need to learn a PCB design tool and use the cheap Chinese PCB houses - the results will be way better than I can achieve and not that much more expensive given the price of PCBs (especially with photoresist on) and chemicals. It also means that 2 layer and even 4 layer boards are possible.The latter is probably significant for something like a Z80 SBC - having finally decided I really need to address this as a prject I have finally sat down to design a system (still need to finish the I/O bits but there is a separate post with the main system). I've got this far on laying it out on a 6"x4" perfboardI haven't quite finished but it looks like I have enough board room for the passives that I need plus 1 or 2 MAX232's, some 9-pin D connectors, power in and a bit more glue logic if needed. 6"x4" is a nice size for the project so I'd like to keep it at that. Sadly I don't think I can quite squeeze in two extra 74xx74's to add in the Nascom-2 style hardware single step but we'll see.But I don't think I could route it on a single sided PCB that side, maybe on double sided but that's much harder to do at home and lack of through hole plating is a pain (there's a guy somewhere on the 'net who shows how to do double sided with plated holes and solder mask - I'm amazed at his work but know I'm just not skilled enough to replicate it).

author: nockieboy
author_rank: Super Contributor
timestamp: March 21, 2017, 03:01:38 pm
content: Quote from: grumpydoc on March 21, 2017, 02:03:03 pmThanks in no small part to yourself. It was a step-by-step fault-finding process and what you said about the 68B50 Tx/Rx clock that revealed the problem in the end.Quote from: grumpydoc on March 21, 2017, 02:03:03 pmHmm - well my experiences of home etching have been very inconsistent (and it's something I've not done in about 20 years) so I'm a little reticent about the whole process. I don't recall the UV method of doing it back at school, so that's new to me and seems pretty good - but it's the initial outlay of trying to get hold of (or make) a UV box etc. Offset that against the high-quality wonder of having a double-sided (or more) PCB with silk screening and solder masking and I'm still on the fence about getting one made professionally - they don't seem that expensive really.Quote from: grumpydoc on March 21, 2017, 02:03:03 pmI've been using DipTrace to design my Z80 board, can't recommend it enough. It is much easier to use than Eagle or KiCAD. The full software isn't free, but the free version will go up to 300 pins and, if you write a nice e-mail to software company asking for a home licence, you can use it to design up to 600-pin circuits and boards.Quote from: grumpydoc on March 21, 2017, 02:03:03 pmLooks awesome.The link CJay posted earlier about PCB etching might be worth a look - it mentions vias using pins and things, but I'd be surprised if you weren't already aware of the options.I'm starting to think that having an I2C interface on my board will be useful - could certainly simplify adding things like an SD-card reader, etc. Anyone have any experience of interfacing this with a Z80?

author: james_s
author_rank: Super Contributor
timestamp: March 21, 2017, 03:33:40 pm
content: I use toner transfer from a laser printer to etch at home, usually using that blue transfer film. I routinely do 10 mil traces, 0603 and SOIC parts with consistent results and on a few occasions I have managed 0.5mm pitch SMT ICs but that is pushing the process.If I don't mind waiting or need more than one board I usually just send it off to China though. Especially if if needs to be double sided.

author: CJay
author_rank: Super Contributor
timestamp: March 21, 2017, 04:41:22 pm
content: I've never tried toner transfer, mainly because I think the setup I have/had worked well enough (haven't used it for a while) but I've seen great results from it.It has the same inherent problems for double sided as pretty much any other home method, you still need some way to get signals from one side to the other and alignment is awkward though I have considered etching two 0.8mm boards and then somehow fixing them together using some alignment holes and a thin layer of epoxy but it all seems rather fiddly when you can get such high quality boards for cheap nowadays.I'd still recommend it as a learning experience and would still prototype on home etched stuff if it needed to be done on a PCB, I'm just not patient enough to wait for a PCB from China if I know I can make it at home, once I know a design works I'll order boards, I usually go from protoboards to fab though I confess I've not done anything for a while now and most of the 'things I've worked on are still at proto stage.

author: james_s
author_rank: Super Contributor
timestamp: March 21, 2017, 06:01:25 pm
content: The best way I've found to get the alignment right is to take the two sheets of transfer film, place them face to face and align over a strong light, then tape one edge. Slip the board in and make sure the seam is straight so the layers stay aligned, drill vias, poke a piece of stripped wire-wrap wire or a scrap of resistor lead through the hole, snip on both sides and the cut will usually deform the wire enough to keep it in place. Then I crimp or punch it to mushroom the ends flat with the board and solder. It's a pain but it's doable.

author: CJay
author_rank: Super Contributor
timestamp: March 29, 2017, 01:02:53 pm
content: My 68B50s arrived today, I now have all the parts I need and a large enough breadboard to test it all on before committing to solder and wiring on proto board.Or, perhaps, it might get a PCB.*potters off to find EPROM programmer and eraser*

author: nockieboy
author_rank: Super Contributor
timestamp: March 29, 2017, 01:29:51 pm
content: Good luck with the project, CJay!I've cut a 7404 chip from my board (down to more efficient positioning of the clock circuit and better usage of an existing 74HCT04) but I'm mostly playing with the software at the moment.Does anyone know a good forum where I can help modifying Microsoft BASIC? My biggest task at the moment is sorting out the line buffer - each new line is entered into a buffer before being tokenised or executed, depending on if the line is a numbered program line you've entered or a command entered in direct mode. The issue I'm having is that the line length is limited to 74 characters. I'm trying to increase it to 90 as a particular type-in I'm entering has a couple of lines longer than 72 chars.Yes, I can modify the program to make the offending lines shorter, but that defeats the object of me learning Z80 assembly.I'd have though extending the line length would be easy, but hey ho, apparently not. It seems whatever I change the max line length to, it still cuts short at 74 characters.Anyhoo, I've probably gone into too much depth already as it's not really an electronics-related question!

author: CJay
author_rank: Super Contributor
timestamp: March 29, 2017, 02:58:01 pm
content: Damnit, I'm missing a 74LS32.I have found the EPROM programmer along with a prototype 6502 board I started and I'm looking at a pile of GAL chips and wondering about sticking all the glue into one of those.As for line buffer, why off topic? It's a technical board and software is a part of it so ask away unless anyone can offer a concrete reason why not.I'll apply my limited Z80 skills if possible and maybe we can come up with a solution.

author: grumpydoc
author_rank: Super Contributor
timestamp: March 29, 2017, 03:52:49 pm
content: OK, input buffer:This is defined, as with a lot of assembler source code not in the way you do in C code by saying the buffer is so many bytes long but by saying where it starts and then saying where the next thing starts, the lines which do this are:BUFFER .EQU WRKSPC+61H ; Input bufferSTACK .EQU WRKSPC+66H ; Initial stackCURPOS .EQU WRKSPC+0ABH ; Character position on lineThe input buffer starts at offset 0x61 in the workspace and extends to the byte before CURPOS ie. 0xAA.0xAB - 0x61 is 0x4A or 74 bytes.So, to expand you need to look carefully at the whole of the workspace layout beyond that and adjust every offset afterwards to take into account the increase.You also need to work out what is happening with "STACK" which seems to be in the middle of the buffer.The buffer length is hard coded in at least one other place that I spotted which is during initialisation when the end is marked with a '\0' by this codeCALL PRNTCRLF ; Output CRLFLD (BUFFER+72+1),A ; Mark end of bufferLD (PROGST),A ; Initialise program areaA will be zero here following the call to PRNTCRLF.In short it will be a bit of a pain.It is better to set up storage with db, dw or ds (or equivalent in whatever assembler you are using) as it is then much easier to add an item or change the size of an item.

author: nockieboy
author_rank: Super Contributor
timestamp: March 29, 2017, 05:13:07 pm
content: Quote from: grumpydoc on March 29, 2017, 03:52:49 pmGrumpydoc, you are - as always - a mine of information!I was halfway there with some of the changes I'd made. I'd gone through the code and replaced the (two) occurrances of the hardcoded line length with a variable specified at the start of the code, so it could be changed easily in one location.I then found out that changing the value didn't make much difference. The line length was originally 72 as you found hardcoded and after I'd tried to lengthen it, it topped out at 74. I had looked at the BUFFER, STACK and CURPOS locations at the top of the code but hadn't really stopped to think about what was going on there.I'm just wondering how I'd go about finding a 'safe spot' in the RAM that I could use for the BUFFER instead - so instead of it being at WORKSP+61H, I could point to 02100H or something similar without worrying about it getting overwritten by a user program?EDITWould this be the line to change to bump the user program space up a little in the RAM and allow me to move the BUFFER here instead?Code:PROGST .EQU WRKSPC+0F9H ; Start of program text area

author: PA0PBZ
author_rank: Super Contributor
timestamp: March 29, 2017, 05:22:47 pm
content: Also, see:Code:PUTCTL: LD A,B ; Get number of bytes in bufferCP 72+1 ; Test for line overflowLD A,CTRLG ; Set a bellJP NC,OUTNBS ; Ring bell if buffer fullthis is not really made to be modified easily...

author: nockieboy
author_rank: Super Contributor
timestamp: March 29, 2017, 05:26:21 pm
content: Quote from: PA0PBZ on March 29, 2017, 05:22:47 pmI've just replaced the hardcodedCode:72+1with this:Code:PUTCTL: LD A,B ; Get number of bytes in bufferCP LINEBUFFER+1 ; Test for line overflowAnd specified LINEBUFFER at the start of the code with the other EQU statements.

author: nockieboy
author_rank: Super Contributor
timestamp: March 29, 2017, 05:43:27 pm
content: Sorted it. I've moved the BUFFER to here:Code:BUFFER.EQUWRKSPC+0F9H; Input bufferPROGST .EQU WRKSPC+154H ; Start of program text areaSTLOOK .EQU WRKSPC+1B8H ; Start of memory testAnd moved the following PROGST and STLOOK away from it by another 10H, so it now has 5AH space (90 chars) and I can continue my type-in without messing with splitting long lines up.For info, the line buffer size is hardcoded twice in the assembly - I've replaced both instances with a variable and specified it at the top of the code:Code:LINEBUFFER.EQU5AH; Maximum line lengthAll works nicely.

author: grumpydoc
author_rank: Super Contributor
timestamp: March 29, 2017, 05:45:26 pm
content: Quote from: nockieboy on March 29, 2017, 05:43:27 pmWell, done.As a purely stylistic thing I would have called something which pertains to the length of a buffer BUFLEN or similar rather than LINEBUFFER.

author: grumpydoc
author_rank: Super Contributor
timestamp: March 29, 2017, 06:00:34 pm
content: Just another thought.If you edit any of the code watch theWRKSPC .EQU 2045HThe original Nascom implementation had the interpreter itself in ROM up in the top 8k starting at 0xE000 and the workspace started at 0x1000, Grant Searle seems to have switched this around to have the interpreter start at 0x150 (not sure why that address) with the workspace presumably immediately above that. However he has just hard-coded the workspace start address. If you expand the code at all without moving the workspace you will wind up with corruption of the end of the interpreter code.

author: nockieboy
author_rank: Super Contributor
timestamp: March 29, 2017, 06:47:48 pm
content: Quote from: grumpydoc on March 29, 2017, 06:00:34 pmOooh good point. The interpreter starts at 0150H because immediately before that is the bootstrap code that handles the UART initialisation and serial IO. I guess he thought it'd be simpler to have the code starting at the bottom of memory as the Z80 starts reading instructions from 0000h.

author: grumpydoc
author_rank: Super Contributor
timestamp: March 29, 2017, 07:51:45 pm
content: Quote from: nockieboy on March 29, 2017, 06:47:48 pmEither in low memory with the BASIC program code above it and perhaps the stack at the top of RAM or at the top of RAM with the workspace starting in low memory and the stack just under the interpreter machine code are be equally sensible.The difficulty with placing the interpreter at the top of RAM is that the top 8k might not always be 0xE000 - 0xFFFF - it was common for systems to not have a full 64k of memory - any absolute jumps or calls would have to be changed, putting your code in low memory avoided this problem so mostly that's where programs loaded. ISTR that part of the process of installing CP/M is to relocate the BDOS code high in memory (I'm probably about to find out).It's just that in switching the memory map around without changing the code to be a bit more robust means that there is a good chance of things going pear shaped if you forget to move the workspace.I suspect that the code is not the original Microsoft source anyway but was reverse assembled from the Nascom ROM.

author: nockieboy
author_rank: Super Contributor
timestamp: March 30, 2017, 07:44:54 am
content: Quote from: wilfred on March 29, 2017, 11:34:49 pmYes, good point wilfred. It looks like the jumps are catered for in the initial block of code. At the moment I've no plans for anything to do with interrupts directly as far as I know. The next big thing for me is to get a CompactFlash card connected via an 8-bit IDE interface as per Grant's CP/M implementation and see if I can get some permanent storage set up.

author: grumpydoc
author_rank: Super Contributor
timestamp: March 30, 2017, 09:10:50 am
content: Quote from: nockieboy on March 30, 2017, 07:44:54 amUsually the first page is kept clear, CP/M starts the TPA (transient program area) at 0x0100, but it uses some of page zero for a buffer and BDOS vector, plus probably a couple of other things that I can't remember.0x0150 just struck me as an odd place to start the BASIC image.One pain in my own designhttps://www.eevblog.com/forum/projects/z80-single-(perf)board-computer/is that the memory expansion method will make it difficult to keep all the jumps etc in the 1st page consistent between banks. That said the bank scheme itself not much worse than the Z80180 family but on those chips I believe the DMA (which can copy blocks) has access to the full expanded address space.I'm somewhat drawn to using 2x 74F189 to create a mapped system where any 4k page in the Z80 physical address space can map to any 4k page in the 1M expanded space but they are getting hard to find, and expensive, even on everyone's favourite supplier of tat and obsolete parts.

author: nockieboy
author_rank: Super Contributor
timestamp: March 30, 2017, 09:31:43 am
content: Quote from: grumpydoc on March 30, 2017, 09:10:50 amThe more I look at your design, the more I realise I've got alotto learn!I'd like to implement something like I2C (or even SPI - could use SD cards then) on my system too, so I could just add an LCD display, an EEPROM or realtime clock later, but I'm finding it hard to get concrete information on how to build one (other than the standard specifications which, on their own, aren't much use to an electronics luddite like me.) Without spoonfeeding me a design (though feel free if you have any examples), is there anywhere I can go online to find an example of an I2C bus implemented on a Z80 system or some documentation that'll point me in the right direction?From what I can gather, it seems to be primarily a software-based standard, so in theory I could implement it with something as simple as a couple of IO lines and some programming?

author: grumpydoc
author_rank: Super Contributor
timestamp: March 30, 2017, 10:33:04 am
content: Quote from: nockieboy on March 30, 2017, 09:31:43 amI haven't tackled I2C yet but as far as I can see it just needs a couple of open drain outputs and a couple of inputs so should be pretty easy electrically. After that it's all software, as you say.https://learn.sparkfun.com/tutorials/i2cmight be a good place to start.

author: nockieboy
author_rank: Super Contributor
timestamp: April 14, 2017, 09:49:18 pm
content: Okay, well I haven't made much progress on the I2C front yet - I'm still holding off on rebuilding my SBC to the CP/M-spec version that Grant Searle outlines, which is my main goal before I start adding too much other stuff, though I've got the parts I need to do it.In the meantime, I've added an IO output port to the system with 8 LEDs and written a basic (geddit?) program to do stuff with the LEDs, like a Cylon's visor animation, binary number quiz (which I'm successfully using to teach my 5-year old daughter binary!!) and, today, a reflex game where you have to stop the program (CTRL-C) when the end LED (D7 on the bus) is lit. Each level increases the speed that the light 'scans' up and down the row of 8 LEDs, making it harder to do. Little'un loves it.Then another thought occurred. Instead of breaking the program execution with CTRL-C to stop the light, and the following hassle of RUN-ing the program again and going through the options to get to the reflex game, why not add an input port to the SBC and wire a switch up (with the requisite red button!) to the IO port that would pause the program or otherwise fire a subroutine to check if the light was stopped on the right LED?I've got no issues with wiring up an IO input port (have some 74HCT245s I can use) with the switch. The question is, can I set up an interrupt-driven trigger that will call a subroutine in the BASIC program when the button is pressed?I can poll the IO input to see if the button is being pressed with each step in the light animation (it uses a simple FOR..NEXT loop to light up a single LED in sequence on the IO port) but this seems a bit clunky. Then again, perhaps I'm overthinking or over-engineering the problem and a simple input poll after the output has been set would be enough?

author: grumpydoc
author_rank: Super Contributor
timestamp: April 15, 2017, 12:05:06 pm
content: If you want to use interrupt driven I/O it is easiest to use the Z80 peripherals rather than "raw" buffers and latches - however I'm pretty certain that the BASIC interpreter has no way to tie a subroutine to the interrupt.

author: netdudeuk
author_rank: Frequent Contributor
timestamp: April 15, 2017, 12:50:14 pm
content: Quote from: grumpydoc on April 15, 2017, 12:05:06 pmAgreed.You could write some assembly language to do these simple things and then polling would be instantaneous.

author: nockieboy
author_rank: Super Contributor
timestamp: April 15, 2017, 03:32:14 pm
content: Quote from: grumpydoc on April 15, 2017, 12:05:06 pmYeah, thought as much. No matter, I've written a simple check into the routine that delays the next light in the sequence lighting up. It slows the whole thing down noticeably (easy to forget how powerful modern computers are!) but it works a treat.I'd love to be able to modify the Nascom basic a little myself and add a couple of extra commands. Top of my list would be a RENUM command. I've got a copy of the assembly for Locomotive BASIC as used on the Amstrad range of 8-bit computers, but I've got some work to do before I can understand Z80 assembly well enough to translate a command like that over!

author: C
author_rank: Super Contributor
timestamp: April 19, 2017, 12:24:34 am
content: This might help with BASICMicrosoft BASIC Decodedhttp://www.classiccmp.org/cpmarchives/trs80/mirrors/pilot.ucdavis.edu/davidk/documentation/62-1001.htmThis is about the Microsoft ROM basic used on TRS-80 that would get extended to Disk basic when using an OS. Quick note about TRS-80, 12k ROM starting at 0H, 4K IO space followed by ram. Low address things like INT & restart instructions were redirected to ram so that they could be changed.Also you might like to know that HPL which was a HP interpreted language would let you program interrupts in the interpreted language. Was a simple thing done. Between the execution of two lines, it would check for a flag to see if an interrupt had happened during previous line an do a gosub if this was true. Note that between two lines you have a good machine state as far as basic is concerned. Think some versions of Basic also had this capability.

author: nockieboy
author_rank: Super Contributor
timestamp: April 19, 2017, 01:39:26 pm
content: Quote from: C on April 19, 2017, 12:24:34 amThanks C, that link was fantastic and full of information for me to work my way through!I've solved the interrupt issue in BASIC by not using an interrupt, but it's working fine. I'm now fully engaged on studying the BASIC assembly and working out how I can hack it to include new instructions (note: I'm customizing the interpreter assembly itself, rather than adding extensions through any other means. Grant Searle managed it, so I won't let it beat me!)I've got an AY-3-8912 chip on its way over from China, so I'm hoping I've got enough time to work out how to add my own commands to the BASIC before it arrives and I start adding sound capabilities to my SBC and replacing the clunky IO system I have at the moment.

author: C
author_rank: Super Contributor
timestamp: April 19, 2017, 05:23:40 pm
content: In your reading of that and other books, you might want to keep some ideas in mind.Dartmouth Basic was the start of Basic. What you see when you type LIST was in memory as text. Microsoft was trying to save space as well as making basic faster. A token for Print is faster to interpret then the text "Print" and also saves space.Microsoft Basic uses tokens when running a program. Microsoft also changed some other things to make program faster and smaller. One change was to convert Line numbers to binary. There are many more changes to make it possible to load & run larger programs faster using less memory.For Microsoft Basic when you type LIST one step in the process is convert token back to text. This then requires a Convert text to token so that you can enter a program. So you have three data items, The Text(print), The Token for print and where code to do print is located.The TRS-80 12k rom Basic could do the Text to token & Token to Text of some commands for Disk Basic but was missing the code to do that command. With Disk Basic loaded, code for command is in memory. With out Disk Basic loaded, Return error.The nice thing about the Rom Basic was that it was very patch able. There was locations where you could change locations in Ram that you could change to allow adding more commands & get the needed code to run.One of the first steps on power up with out a disk system was to copy some data from rom to an area of ram. Microsoft used an assembler command that says, "Assemble this code to run at location X but store the binary at location Y. This step is very powerful as it allows patching.Note that where the Basic program that was converted to tokens did change in Ram. The OS used overlays & some versions of Basic used overlays also. If you want to get a better understanding concept you could look at source for LDOS which you should be able to find.One extreme Z80 system back then was the LOBO MAX80 which only had 512 bytes of rom. Just enough Rom to load code from hard disk or floppy.One thing that you might want to add to your bag of tricks is to connect some memory to IO space. With 3 IO addresses data used as addresses to IO Memory and one IO address data used for data, you would have 16MB of storage.Put above together. On power up, CLEAR a FF. With FF cleared low memory is ROM, You can now run some boot code. With FF SET low memory is Ram. Keep it simple, On power up, copy a block of code from Rom to Ram. Jump to block of code in RAM and SET FF. This RAM code can again be simple and just copy a block of code from IO Memory to RAM and jump to new code just loaded. Note that this code does not need to change as you improve or add to system, Code changes are made to IO memory storage which could easily be EEROM. The Z80 could write to EEROM IO Memory so you would have equal of a Flash disk drive,The RAM boot code could easily read an IO port to allow loading of different blocks from IO storage. You could use this to switch from what works to a new untested block of code to try and easily go back if it did not work.

author: nockieboy
author_rank: Super Contributor
timestamp: April 19, 2017, 08:49:06 pm
content: Thanks C - there's plenty for me to be getting on with there!Here's where I'm at with the customisation of the NASCOM BASIC - I'm experimenting at the moment trying to add a custom command. For experimentation purposes, I'm trying to create a command called TEST which displays a simple string before returning execution back to the Input Phase.The code in the Verb Action Routines isn't the issue (I can display the text without any problems) - the issue I'm having is getting the interpreter to recognise the new command. I've added the keyword TEST to the Reserved Word List and Verb Action Address List, as below:Code:; RESERVED WORD LISTWORDS: .BYTE 'E'+80H,"ND".......BYTE 'C'+80H,"LEAR".BYTE 'C'+80H,"LOAD".BYTE 'C'+80H,"SAVE".BYTE 'N'+80H,"EW".BYTE 'T'+80H,"EST"And the Keyword Address Table:Code:; KEYWORD ADDRESS TABLEWORDTB: .WORD PEND.WORD FOR.........WORD TEST ; Should have an offset of A5But, if the keyword address table works as I think it should (and the Microsoft Basic Decoded book outlines it) then the TEST keyword should have an offset of A5. But the next bit of code causes problems with that due to specific allocation of offsets to keywords (the TAB keyword is assigned an offset of A5...) (NOTE that offset = token, I think.)Code:; RESERVED WORD TOKEN VALUESZEND .EQU 080H ; ENDZFOR .EQU 081H ; FORZDATA .EQU 083H ; DATAZGOTO .EQU 088H ; GOTOZGOSUB .EQU 08CH ; GOSUBZREM .EQU 08EH ; REMZPRINT .EQU 09EH ; PRINTZNEW .EQU 0A4H ; NEWZTAB .EQU 0A5H ; TABZTO .EQU 0A6H ; TOZFN .EQU 0A7H ; FNZSPC .EQU 0A8H ; SPCZTHEN .EQU 0A9H ; THENZNOT .EQU 0AAH ; NOTZSTEP .EQU 0ABH ; STEPSo, I've managed to get my custom code to work by redirecting an existing command (in this case CLOAD, which is redirected to the REM function anyway by Grant Searle's edits) to it, but I'd really like to be able to add my own commands without overwriting (and thus being limited in the number I can use) existing commands.Any suggestions? All I can get is a Syntax Error when I try to add a command.

author: C
author_rank: Super Contributor
timestamp: April 20, 2017, 03:27:26 am
content: Note that there were a large number of books about TRS80 that could help you. Microsoft's rom basic for the TRS80 was called Level II Basic.Just a quick guess & from rusty memory. Think that some token values where used for other purposes. Think some could only be at start of a basic line while others could only be in middle of line. Exp "FOR" at first while "NEXT" has to be in the line.Expect to find constants that separate different ranges of tokens.So as a guess your new command is not fully hooked in to all places needed or the token value falls out of range. You may need an entry in ; RESERVED WORD TOKEN VALUESJust the quick look at Grant Searle's Basic source, Think source was a disassembly with a missing the step to be rewritten to be easy to change. Think of this, Why have a powerful assembler that could compute locations and sizes and not use this power to make source easer to change.Keep in mind that Microsoft should have used it's most powerful assembler{macro-80 or better} to create Microsoft Basic.In "; BASIC WORK SPACE LOCATIONS" you have a lot ofEQUIn my thinking each of these should be a data statement that reserves some space.So a good first step could be to modify the source to use the assembler more.Note also that there are Z80 emulators that run on linux that would let you run powerful old tools for Z80 on PC.

author: C
author_rank: Super Contributor
timestamp: April 20, 2017, 05:54:30 pm
content: In "Microsoft BASIC Decoded" chapter 4 is some information about the structure of some of the tables.In "Microsoft BASIC Decoded" chapter 5 is A BASIC SORT Verb program using data from romFacts:You want to add new statements (test) and have modified statement (CLOAD)Most Basics have a PEEK & POKE statements to read and change memory.HistoryIf the past it was not uncommon to write a Z80 disassembler or other tool in basic. A disassembler in basic could using PEEK disassemble the Roms in a system or output the data in a format that an external disassembler could use.Idea:Use Basic or some assembly that is started with Basics "CLOAD" command to dump out the tables that basic uses to do it's job. This would give you the information that the Z80 was actually using at the time. If you make the output great, then you should be able to easily spot what went wrong.The above two chapters should be some help to do this.Note that from what I see some token values get changed from array index value as token to a lookup token value.Using this information, I would add comment blocks in front of each block of code that processes a basic statement. Then when you come back a year from now and want to add something new you just have to read the comments and not have to relearn by reading source code how it works.In reading the books you might not have cough on to the idea of a non basic program using parts of rom basic to make a program smaller and less work. If you have floating point math in rom why not use it in a non basic program?Don't forget to use your tools against themselves. Think of this, Start with original source, get listing and binary. Make changes to source and get listing and binary. If original binary = changed binary, then your changes will probably fall in to better source for assembler category.Have you compared the many different NASCOM Basic sources to see what is different between the different versions?

author: nockieboy
author_rank: Super Contributor
timestamp: April 21, 2017, 08:20:16 pm
content: Quote from: C on April 20, 2017, 05:54:30 pmNo I haven't. To be honest, I've not had much luck findinganyother versions of BASIC (or their source) that I could try in place of the NASCOM BASIC I currently have.

author: C
author_rank: Super Contributor
timestamp: April 23, 2017, 03:34:16 pm
content: Some of the values below are used as token values, while some are used to compute a range of token values.Some are NOT used at all!Code:; RESERVED WORD TOKEN VALUESZEND .EQU 080H ; ENDZFOR .EQU 081H ; FORZDATA .EQU 083H ; DATAZGOTO .EQU 088H ; GOTOZGOSUB .EQU 08CH ; GOSUBZREM .EQU 08EH ; REMZPRINT .EQU 09EH ; PRINTZNEW .EQU 0A4H ; NEWZTAB .EQU 0A5H ; TABZTO .EQU 0A6H ; TOZFN .EQU 0A7H ; FNZSPC .EQU 0A8H ; SPCZTHEN .EQU 0A9H ; THENZNOT .EQU 0AAH ; NOTZSTEP .EQU 0ABH ; STEPZPLUS .EQU 0ACH ; +ZMINUS .EQU 0ADH ; -ZTIMES .EQU 0AEH ; *ZDIV .EQU 0AFH ; /ZOR .EQU 0B2H ; ORZGTR .EQU 0B3H ; >ZEQUAL .EQU 0B4H ; MZLTH .EQU 0B5H ; <ZSGN .EQU 0B6H ; SGNZPOINT .EQU 0C7H ; POINTZLEFT .EQU 0CDH +2 ; LEFT$Suggest you comment out all the above lines and let the assembler generate some errors if one is needed.When you get an error for lines like the followingCode:CALL CHKSYN ; Make sure "=" follows.BYTE ZEQUAL ; "=" tokenchange toCode:CALL CHKSYN ; Make sure "=" follows.BYTE TEQUAL ; "=" tokenadd the followingCode:.BYTE '='+80HTEQUAL .EQU 0B4H ; Token value.....Do the same for ones likeCode:CP ZFOR ; Is it a "FOR" tokenSome are used to compute a range like thisQuoteFor these I would uncomment the Z____ EQUHere I would move the ZEND EQU to beforeCode:WORDS: .BYTE 'E'+80H,"ND"and ZNEW after the proper lineNote that ZEND = First token valueZNEW is Last statement token value with the following tokens being part of a statement.Between ZSTEP & ZPLUS is a shift to reserved words as operatorsZSGN marks start of functions as reserved words.Code:[ZSGN .EQU 0B6H ; SGN FIRST FUNCTION TOKENThe result of these changes lets you easily tell what is just a token value that can be changed and what is a range of tokens.Something like thisCode:.BYTE 'N'+80H,"EW"; Add new statements hereZNEW .EQU 0A4H ; NEW: ZNEW should be last statement token value above.BYTE 'T'+80H,"AB("TTAB .EQU ZNEW+1;0A5H ; TAB TOKEN.BYTE 'T'+80H,"O"TTO .EQU TTAB+1:0A6H ; TO TOKEN.BYTE 'F'+80H,"N"TFN .EQU TTO+1;0A7H ; FN TOKEN.BYTE 'S'+80H,"PC("TSPC .EQU TFN+1;0A8H ; SPC TOKEN.BYTE 'T'+80H,"HEN"TTHEN .EQU TSPC+1;0A9H ; THEN TOKEN.BYTE 'N'+80H,"OT"TNOT .EQU TTHEN+1;0AAH ; NOT TOKEN.BYTE 'S'+80H,"TEP"TSTEP .EQU TNOT+1;0ABH ; STEP TOKEN; Operators below

author: nockieboy
author_rank: Super Contributor
timestamp: April 23, 2017, 07:09:28 pm
content: Right, I think I see what you're doing there - will give it a try over the next few days.I've successfully renamed the CLOAD command to TEST and got it calling the TEST: code - the issue seems to be around the token value/offset value of new commands; perhaps your suggestion is a technique that will work.

author: C
author_rank: Super Contributor
timestamp: April 23, 2017, 07:44:05 pm
content: Would strongly suggest you make changes to a copy and verify that the binary from assembler stays the same for both. If you get it correct, before and after binary will match.When you get this to match, then you can start opening up some space for new commands.Try to turn your program source into a book. Add things you learn, leave yourself notes in the source. Will save time in the long run.You can add comment lines between lines of the reserved word section.

author: nockieboy
author_rank: Super Contributor
timestamp: May 20, 2017, 10:36:15 am
content: Okay, it's been a while but I've been busy learning assembly, adding commands to BASIC and writing my own command interpreter that the system boots into to provide a streamlined assembly-code running area, with the option to boot into BASIC if you want.I've now started building version 2 of the SBC, based (currently) almost entirely on Grant Searle's CP/M version - schematic below for reference:The only differences in my design so far are that I'm not using an RS232 interface, I'm using the TTL one which connects to an FT232RL USB/TTL adapter on the board before connecting to a standard USB cable to connect to the computer. The FT232RL adapter provides power to the computer via the USB lead.I've got the board all wired up and ready for power up, but (holding with tradition so far) it's not working. There's nothing on the serial window. The board is powered, all bits are getting power and the current draw is 0.08-0.10mA, well within expected range.I've done some initial testing - the clock signal is fine and getting to the Z80 and SIO/2 - but I think I've got an issue with the reset circuit (the bit immediately to the bottom-right of the word 'system' in the image title above. The CPU reset pin is hovering around 0.2V, which is clearly not enough to get it out of the reset state. Below is a close-up of the reset circuit as built on the SBC:The voltage at the power rail (below the resistors in the above image) is 4.84V. But this drops to 0.2V on the top side of the resistors. The yellow wire that connects to the right pin of the red button (warm reset) connects to the SIO/2 and CPU reset pins, as per Grant's schematic. There's no shorts that I'm aware of (they'd show up on the power usage anyway, wouldn't they?) so I'm a little stumped. My electronics knowledge isn't quite up to debugging this one. I've swapped out the 4K7's for a couple of 1k resistors, but that made no difference... so aside from directly wiring the reset circuit to live to try and get the voltage up to 4.8V, I don't know what else to try.Any advice?

author: PA0PBZ
author_rank: Super Contributor
timestamp: May 20, 2017, 10:54:15 am
content: If you remove the yellow wires, what do you measure?If you pull the switches, what do you measure?

author: Andy Watson
author_rank: Super Contributor
timestamp: May 20, 2017, 11:11:52 am
content: Check the wiring of the push button. It looks like at least one of them is wired into the wrong input of the cross-coupled nand gates. I.e. it is wired to an output and the real input is left floating.

author: nockieboy
author_rank: Super Contributor
timestamp: May 20, 2017, 01:23:06 pm
content: Quote from: Andy Watson on May 20, 2017, 11:11:52 amYep, that's spot on Andy - thanks for spotting that. A bit annoyed I didn't see it myself!Okay, the reset circuit seems to be working fine now - the reset pins on the CPU and SIO/2 are high now unless either of the reset switches are pressed. Still no sign of life though, so there's obviously some other problem (most likely a wiring error) somewhere. Out with the trusty multimeter to do some continuity tests and make sure everything is wired up to what it should be.

author: Andy Watson
author_rank: Super Contributor
timestamp: May 20, 2017, 02:18:32 pm
content: This is probably not going to make it work but I think I should mention the decoupling caps - they're conspicuous by their absence!My usual routine for checking is to check for power supplyon the actual pins of the ICs, then check for clock signal and then the reset and wait lines etc. are at an appropriate level.

author: nockieboy
author_rank: Super Contributor
timestamp: May 20, 2017, 05:34:07 pm
content: Quote from: Andy Watson on May 20, 2017, 02:18:32 pmI haven't had a chance to look at the issue since my last post, other than checking the address and data bus and control bus from the CPU. There was a bad connection on D2 from the CPU, so that was a problem that I've found and fixed (no change though - still doesn't work) but the decoupling capacitors (or lack thereof) was next on my to-do list. I wasn't sure if they'd make that much difference, they're almost referred to as 'optional' in the Grant Searle construction notes, but as you've mentioned it as well, I'll get them added in tomorrow and see if that makes any difference!

author: nockieboy
author_rank: Super Contributor
timestamp: May 21, 2017, 03:11:16 pm
content: Okay, I've added decoupling caps to all the chips except the ROM, as it's sitting in a ZIF socket and I haven't got room to fit a cap to it (it works fine without a decoupling cap on the ROM on my previous build).Still no signs of life in the terminal.I've started looking at the serial interface on the SBC, as I'm getting nice signals on my oscilloscope for M1, CLK, IOREQ, RD, WR and even the address and data buses, showing that the processor is running a program (and no-doubt looping through the code that displays the "Press <SPACE> to continue..." text and awaits user input to determine which serial interface on the SIO/2 to use) but there's absolutely nothing coming out on the terminal program (PuTTY) on my laptop.Whilst examining the FT232 sitting on the SBC, I noticed that I'd made a(nother) rooky error and wired Tx to Tx and Rx to Rx. Swapped them around, still nothing on the terminal.So here's a pic of the FT232 on the SBC. I'm using RTS and CTS, Tx and Rx and the 5V and GND supply on the FT232 to communicate and power the SBC.I'm wondering if there's something up with the FT232, especially considering I've never tested it (got it to make a very basic Arduino/ATMEGA programmer but couldn't get it working) so my next step is to remove it and wire up the USB/TTL lead I use on the mk1 SBC. For info, the FT232 board originally had the right-angle pins on the end which I removed and soldered in pins along the bottom and top edges instead to make it more stable with the breadboard.

author: grumpydoc
author_rank: Super Contributor
timestamp: May 21, 2017, 03:46:59 pm
content: QuoteEasy enough to test, just wire the TxD to RxD and DTD to CTS and fire up your favourite terminal program. Anything that you type should be echoed.

author: nockieboy
author_rank: Super Contributor
timestamp: May 21, 2017, 07:58:13 pm
content: Hi grumpydoc!Thanks - yeah, just wired it up as suggested and it's echoing text nicely. So looks like there's an issue with the SIO/2 chip or its wiring. I've just made an edit to the monitor assembly so it'll just constantly print 'U' to the serial port. When I get the chance tomorrow I'll burn it to the ROM and start testing the SIO/2. Fingers crossed!

author: nockieboy
author_rank: Super Contributor
timestamp: May 22, 2017, 08:15:15 pm
content: Okay, so I've checked the connections to the SIO chip and they're all okay it would seem. I'm running a slightly modified monitor program which will go into a loop and print the letter 'U' to both serial ports on the SIO constantly (edit shown below):Code:conout:conoutA:PUSHAFconoutA1:CALLCKSIOA; See if SIO channel A is finished transmittingJRZ,conoutA1; Loop until SIO flag signals readyPOPAF; RETrieve characterOUT(SIOA_D),A; OUTput the characterconoutB:PUSHAFconoutB1:CALLCKSIOB; See if SIO channel B is finished transmittingJRZ,conoutB1; Loop until SIO flag signals readyPOPAF; RETrieve characterOUT(SIOB_D),A; OUTput the characterRETCode:; Debug routine to test serial interfaceDBG:LDA,'U'RST08HJPDBG; Display the "Press space to start" message on both consolesLDA,$00LD(primaryIO),ALDHL,INITTXTCALLPRINTLDA,$01LD(primaryIO),ALDHL,INITTXTCALLPRINTStill, there's no signs of life on the SIO TxDA pin. Here's some oscilloscope traces from various pins on the SIO chip. I'm at a loss currently as to what and how to test further.

author: grumpydoc
author_rank: Super Contributor
timestamp: May 22, 2017, 09:36:48 pm
content: Check all the things that you checked last time.Use M1/MREQ to trigger from and see if you can figure out what bit of code is being executed.The one thing you haven't shown is the SIO WR line.

author: nockieboy
author_rank: Super Contributor
timestamp: May 24, 2017, 09:00:34 am
content: Okay, some more traces - these are all tripped by the /WR line from the Z80 as /M1 and /MREQ are not following a simple enough pattern to reliably trigger the oscilloscope and show one clear trace. I've marked the image so you can see which traces belong to which pins. My next step is to strip the monitor code down completely to just the SIO 'driver' (i.e. the setup code) and a simple loop to output a character of text to try and make the other traces simpler and more readable (and hopefully make the problem easier to debug!)

author: C
author_rank: Super Contributor
timestamp: May 24, 2017, 03:54:25 pm
content: With your test code, are you still setting up the SIO to proper config?In monitor code this is at comment " ; Initialise SIO "

author: nockieboy
author_rank: Super Contributor
timestamp: May 24, 2017, 04:04:54 pm
content: Quote from: C on May 24, 2017, 03:54:25 pmYep, the monitor code is almost untouched except for the loop I created to help debug the problem:Code:;Initialise SIOLDA,$00OUT(SIOA_C),ALDA,$18OUT(SIOA_C),ALDA,$04OUT(SIOA_C),ALDA,$C4OUT(SIOA_C),ALDA,$01OUT(SIOA_C),ALDA,$18OUT(SIOA_C),ALDA,$03OUT(SIOA_C),ALDA,$E1OUT(SIOA_C),ALDA,$05OUT(SIOA_C),ALDA,RTS_LOWOUT(SIOA_C),ALDA,$00OUT(SIOB_C),ALDA,$18OUT(SIOB_C),ALDA,$04OUT(SIOB_C),ALDA,$C4OUT(SIOB_C),ALDA,$01OUT(SIOB_C),ALDA,$18OUT(SIOB_C),ALDA,$02OUT(SIOB_C),ALDA,$60; INTERRUPT VECTOR ADDRESSOUT(SIOB_C),ALDA,$03OUT(SIOB_C),ALDA,$E1OUT(SIOB_C),ALDA,$05OUT(SIOB_C),ALDA,RTS_LOWOUT(SIOB_C),A; Interrupt vector in page 0LDA,$00LDI,AIM2EI; Debug routine to test serial interfaceDBG:LDA,'U'RST08HJPDBG

author: C
author_rank: Super Contributor
timestamp: May 24, 2017, 05:30:57 pm
content: Sending a character and getting it received requires a lot to work.You might want to write a bit of test code that can change some of the pins on the SIO to see if you are even talking to SIO.For example make RTS go high for a while and the low for a while and check with the scope.If you then connect RTS to a SIO input that you can read in a status register. You could then change the timing of RTS based on what you get from status register.The result of doing this is knowing you can talk to and read from the SIO.You might also want to check out how the init code is setting up the SIO.Some comments in the init code could help in future.

author: nockieboy
author_rank: Super Contributor
timestamp: May 24, 2017, 05:58:13 pm
content: Quote from: C on May 24, 2017, 05:30:57 pmHmm okay, there's a plan there. Thanks C. I've got some work to do on the monitor program then - I want to strip it down to the bare essentials and then I'll do what you're recommending.I was hoping the oscilloscope traces would reveal something, but I don't know enough about the system to be able to look at them and easily spot anything.I'll be back when I've got some bare-minimum monitor code set up and am able to get some results from testing RTS setting etc!

author: C
author_rank: Super Contributor
timestamp: May 24, 2017, 07:17:22 pm
content: You can also do some testing by connecting Tx to Rx on SIONote that there will be a time delay between send and receive and that it will work as long as Tx & Rx settings match.With you doing assembly language programming you might also like some simple I/O ports. An I/O output port could be used to show what step has started in code. An I/O input port could be used to switch to a different chunk of code based on what is read from that port.In some cases simple is better, with one output latch like 374 & one tri-state input like a 244 connected to an I/O address here there is no initialization needed other then clearing the power up garbage that the latch could capture.You could do the same as above using a PIO or 8255 but then you have added the need for initialization of that chip,

author: nockieboy
author_rank: Super Contributor
timestamp: May 24, 2017, 08:11:09 pm
content: Thanks C, I'll bare that in mind for further testing down the line, but I think I'll keep it simple for the moment until I exhaust all the possibilities for testing the SIO with the existing setup.

author: grumpydoc
author_rank: Super Contributor
timestamp: May 24, 2017, 08:54:21 pm
content: Quote from: nockieboy on May 24, 2017, 09:00:34 amYour loop's a bit long for oscilloscope debugging. AFAICS there is an absolute minimum of 170 clocks, 16 M1 cycles, 19 memory reads (not counting opcodes), 10 memory writes, and 2 I/O writes - and that's just the code I can see because you missed the definition of the CKSIOA/B routines.To follow what is happening on a 'scope cut out all the calls and returns and just loop testing the transmit status, then when it is clear to send a byte, then do so and loop to the top again. Set the baud rate as high as possible so that you are not waiting too long to send the byte and you might be able to to capture a whole loop on the 'scope. Unless you get a whole loop you can't be certain of the timing relationship between the various signals.I reckon you should be able to work from about 1 M1 cycle per division - so you could set the 'scope at 500ns/div and have max 10 instructions - which isn't really enough. So set the timebase 10x slower at at 5us/div. Now you have up to 100 M1 cycles which is more like it but it will be a bit hard to see them in detail - so pull out the x10 horizontal knob and you will be back at 500ns/div and will be able to see things better.It is also useful to to toggle an I/O bit once around the loop so that you can use that as the 'scope trigger.

author: nockieboy
author_rank: Super Contributor
timestamp: May 24, 2017, 09:35:53 pm
content: Thanks grumpydoc - I knew you'd be able to cut through the confusion and quote some hard facts!I've cut the monitor code down to what I think is the bare minimum - it's 250 lines (give or take a few) long now with all the CF driving code removed and other extraneous functions deleted.I'll edit in an IO call to help trigger the scope and post the entire code tomorrow. Got a busy couple of days so may not have time to get any more scope traces up before the weekend.

author: nockieboy
author_rank: Super Contributor
timestamp: May 25, 2017, 08:51:07 pm
content: Okay, below is the entire monitor code that I'll be using to debug the SIO/serial issue. It's pretty much the monitor assembly that Grant Searle uses for the CP/M version of the SBC on his website, but I've cut it down massively to remove non-essential routines and created a debug loop (DBG:) at the end, after the SIO setup sequence, to repeatedly print the U character to the SIO A output, which is the one connected to the FT232 on my SBC.I haven't sorted out the IO code for the oscilloscope trigger properly yet, I think I'll need to wire one of the outputs from the HCT138 to a spare logic gate to combine with the IORQ signal before I can use an oscilloscope probe to trigger from it (actually probably not - the loop will be much higher in memory than address $08, so I shouldn't get false triggers from memory access at that location), but I've just added some pseudo-code to the listing below to show how I intend to set that trigger up. Happy for comments/advice on implementation as I've literally just thrown those commands in there as I've written this post.(Apart from the IO trigger edit I've made as above) the code compiles just fine, but I've been too busy to test it on the SBC - that'll hopefully happen this weekend!Thoughts and comments are always appreciated!Code:;------------------------------------------------------------------------------;; SIO Serial Test ROM;;------------------------------------------------------------------------------CR.EQU0DHLF.EQU0AHESC.EQU1BHCTRLC.EQU03HCLS.EQU0CHSER_BUFSIZE.EQU40HSER_FULLSIZE.EQU30HSER_EMPTYSIZE.EQU5RTS_HIGH.EQU0E8HRTS_LOW.EQU0EAHSIOA_D.EQU$00SIOA_C.EQU$02SIOB_D.EQU$01SIOB_C.EQU$03.ORG$4000serABuf.dsSER_BUFSIZEserAInPtr.ds2serARdPtr.ds2serABufUsed.ds1serBBuf.dsSER_BUFSIZEserBInPtr.ds2serBRdPtr.ds2serBBufUsed.ds1primaryIO.ds1secNo.ds1dmaAddr.ds2stackSpace.ds32STACK.EQU $; Stack top;------------------------------------------------------------------------------; START OF MONITOR ROM;------------------------------------------------------------------------------MON.ORG$0000; MONITOR ROM RESET VECTOR;------------------------------------------------------------------------------; Reset;------------------------------------------------------------------------------RST00DI;Disable INTerruptsJPINIT;Initialize Hardware and goNOPNOPNOPNOP;------------------------------------------------------------------------------; SIO Vector = 0x60;------------------------------------------------------------------------------.ORG$0060.DWserialInt;------------------------------------------------------------------------------; Serial interrupt handlers; Same interrupt called if either of the inputs receives a character; so need to check the status of each SIO input.;------------------------------------------------------------------------------serialInt:PUSHAFPUSHHL; Check if there is a char in channel A; If not, there is a char in channel BSUBAOUT(SIOA_C),AINA,(SIOA_C); Status byte D2=TX Buff Empty, D0=RX char readyRRCA; Rotates RX status into Carry Flag,JRNC, serialIntBserialIntA:LDHL,(serAInPtr)INCHLLDA,LCP(serABuf+SER_BUFSIZE) & $FFJRNZ, notAWrapLDHL,serABufnotAWrap:LD(serAInPtr),HLINA,(SIOA_D)LD(HL),ALDA,(serABufUsed)INCALD(serABufUsed),ACPSER_FULLSIZEJRC,rtsA0LDA,$05OUT(SIOA_C),ALDA,RTS_HIGHOUT(SIOA_C),ArtsA0:POPHLPOPAFEIRETIserialIntB:LDHL,(serBInPtr)INCHLLDA,LCP(serBBuf+SER_BUFSIZE) & $FFJRNZ, notBWrapLDHL,serBBufnotBWrap:LD(serBInPtr),HLINA,(SIOB_D)LD(HL),ALDA,(serBBufUsed)INCALD(serBBufUsed),ACPSER_FULLSIZEJRC,rtsB0LDA,$05OUT(SIOB_C),ALDA,RTS_HIGHOUT(SIOB_C),ArtsB0:POPHLPOPAFEIRETI;------------------------------------------------------------------------------; Initialise hardware and start main loop;------------------------------------------------------------------------------INITLDSP,STACK; Set the Stack PointerLDHL,serABufLD(serAInPtr),HLLD(serARdPtr),HLLDHL,serBBufLD(serBInPtr),HLLD(serBRdPtr),HLXORA;0 to accumulatorLD(serABufUsed),ALD(serBBufUsed),A;Initialise SIOLDA,$00OUT(SIOA_C),ALDA,$18OUT(SIOA_C),ALDA,$04OUT(SIOA_C),ALDA,$C4OUT(SIOA_C),ALDA,$01OUT(SIOA_C),ALDA,$18OUT(SIOA_C),ALDA,$03OUT(SIOA_C),ALDA,$E1OUT(SIOA_C),ALDA,$05OUT(SIOA_C),ALDA,RTS_LOWOUT(SIOA_C),ALDA,$00OUT(SIOB_C),ALDA,$18OUT(SIOB_C),ALDA,$04OUT(SIOB_C),ALDA,$C4OUT(SIOB_C),ALDA,$01OUT(SIOB_C),ALDA,$18OUT(SIOB_C),ALDA,$02OUT(SIOB_C),ALDA,$60; INTERRUPT VECTOR ADDRESSOUT(SIOB_C),ALDA,$03OUT(SIOB_C),ALDA,$E1OUT(SIOB_C),ALDA,$05OUT(SIOB_C),ALDA,RTS_LOWOUT(SIOB_C),A; Interrupt vector in page 0LDA,$00LDI,AIM2EI; Debug routine to test serial interfaceDBG:LDA,'U'PUSHAFconout:SUBAOUT(SIOA_C),AINA,(SIOA_C); Status byte D2=TX Buff Empty, D0=RX char readyRRCA; Rotates RX status into Carry Flag,BIT1,A; Set Zero flag if still transmitting characterJRZ,conout; Loop until SIO flag signals readyPOPAF; RETrieve characterOUT ($08),1 ; IO oscilloscope trigger (PSEUDO-CODE - happy for comments/suggestions on this!)OUT ($08),0 ; As aboveOUT(SIOA_D),A; OUTput the characterJPDBGFINIS.END

author: C
author_rank: Super Contributor
timestamp: May 25, 2017, 11:22:10 pm
content: You are currently creating a chip select signal for the SIO.Chances are this chip select is coming from one output of a 138 or something like this.If you have a UN-used output of the 138 you can use that to trigger your scope, you would just doOUT trigger address, anydatado this before something you want to look at with the scope with scope's trigger connected to 138 output.If you want to scope SIO INIT then put an OUT trigger address before that batch of code.Note that you can do the SIO INIT many times.You could loop repeat the init so that you have many chances to catch things on your scope.This code is fancy and looks to be doing interrupts. Fine if it works but much more then needed for a simple test.I would set the SIO up to 8-bits no parity and then for a send to PC check the SIO for output buffer empty and if so send a character. loop back to the check to send more charactersOutput:read SIO statusif transmitter buffer not empty jump to Output: when you get here you know SIO transmitter output is empty, last character has been sent.write character to SIO transmitter regester.loop to Output to send more characters.So for a simple test to find hardware problemsInit the SIOtoggle the SIO RTS outputRead the SIO CTS InputOutput a characterjump back and start INIT again.You can then use the scope to look at signals on SIOYou are trying to find a simple problemIs the SIO connected properly?When You know this is true then start with the fancy software.

author: C
author_rank: Super Contributor
timestamp: May 26, 2017, 01:18:52 am
content: If your design still matches Grant's CP/M then you have a 138 as U5U5hexY0 00-07 SIO CSY1 08-0FY2 10-17 CF CardY3 18-1FY4 20-27Y5 28-2FY6 30-37Y7 38-3F Disable romAll the other outputs from this chip could be used to assist in your testing.An Inp or Out with the proper address will cause that output to go low briefly.You might use Y1's address range to trigger your scope.It would be nice to know that you can read from the SIO and get valid data.The CTS pin is an input. Your test program could read this bit from the status register. If the CTS in the register is high do an output in address range for Y6 and if low then Y5's range.Scope would see a short low output when connected to pin..This leaves Y3 Y4 & Y5 ranges to be used for other scope test triggers or output Z80 information like Y5 & Y6 above.The above assumes that Z80 is running and U5 is wired correct..When you do start getting changes on SIO's TX pin and you do not get a character on PC, Use scope to look at the bit width of data from SIO's TX pin and compare to width of what you see when connected to USB to serial's TX pin when you type a key on PC.

author: nockieboy
author_rank: Super Contributor
timestamp: May 26, 2017, 01:14:22 pm
content: Thanks C. Yeah I wasn't sure about the interrupt routine so thought it best to leave it, but I'll strip it out if it's definitely not needed. The only thing that is different with my SBC from Grant Searle's design so far is that I haven't connected up the CF card adapter yet (and I haven't wired up the SIO/2's B port to an RS232 interface as I won't be using that.)

author: nockieboy
author_rank: Super Contributor
timestamp: June 14, 2017, 06:19:02 pm
content: Okay, back after a week or two hiatus which has done loads for my sun tan, but very little for progress on sorting out the issue with my V.2 SBC...I'm starting to lose my way a little in debugging this contraption. Finding the time (and space) to get the oscilloscope out isn't easy. Still, I've managed to strip the monitor code down to what I think is the bare minimum. I know literally the square root of diddly squat about interrupts, but have (I think) correctly removed the interrupt from the monitor code and simplified it as far as I can.I've even removed the SIO B port setup and references (and before anyone asks, the FT232 is definitely wired to the A port on the SIO/2!)Would appreciate an experienced eye to scan over the test monitor code that I intend to use below. Before I went on holiday I did a quick test with the oscilloscope on the HCT138 output that selects the SIO/2, but wasn't getting very clear readings.So I'd be really grateful if someone could confirm that the code below will/should work and be suitable for creating a trace I can use to debug the circuit.Here's the monitor code:Code:;------------------------------------------------------------------------------;; SIO Serial Test ROM;;------------------------------------------------------------------------------CR.EQU0DHLF.EQU0AHESC.EQU1BHCTRLC.EQU03HCLS.EQU0CHSER_BUFSIZE.EQU40HSER_FULLSIZE.EQU30HSER_EMPTYSIZE.EQU5RTS_HIGH.EQU0E8HRTS_LOW.EQU0EAHSIOA_D.EQU$00SIOA_C.EQU$02.ORG$4000serABuf.dsSER_BUFSIZEserAInPtr.ds2serARdPtr.ds2serABufUsed.ds1primaryIO.ds1secNo.ds1dmaAddr.ds2stackSpace.ds32STACK.EQU $; Stack topMON.ORG$0000; MONITOR ROM RESET VECTOR;------------------------------------------------------------------------------; Reset;------------------------------------------------------------------------------RST00DI;Disable INTerruptsJPINIT;Initialize Hardware and goNOPNOPNOPNOP;------------------------------------------------------------------------------; Initialise hardware and start main loop;------------------------------------------------------------------------------INITLDSP,STACK; Set the Stack PointerLDHL,serABufLD(serAInPtr),HLLD(serARdPtr),HLXORA;0 to accumulatorLD(serABufUsed),A;Initialise SIO ALDA,$00OUT(SIOA_C),ALDA,$18OUT(SIOA_C),ALDA,$04OUT(SIOA_C),ALDA,$C4OUT(SIOA_C),ALDA,$01OUT(SIOA_C),ALDA,$18OUT(SIOA_C),ALDA,$03OUT(SIOA_C),ALDA,$E1OUT(SIOA_C),ALDA,$05OUT(SIOA_C),ALDA,RTS_LOWOUT(SIOA_C),A; Debug routine to test serial interfaceDBG:LDA,'U'PUSHAFconout:OUT($08),1; DEBUG TRIGGER FOR Y1 PIN ON 74HCT138OUT($08),0; Clear the debug triggerSUBA; Check to see not TXingOUT(SIOA_C),AINA,(SIOA_C); Status byte D2=TX Buff Empty, D0=RX char readyRRCA; Rotates RX status into Carry Flag,BIT1,A; Set Zero flag if still transmitting characterJRZ,conout; Loop until SIO flag signals readyPOPAF; RETrieve characterOUT(SIOA_D),A; OUTput the characterJPDBGFINIS.ENDAny help/advice is always greatly appreciated - I don't have to experience to sort this myself, unfortunately. One line in the code above is vexing me somewhat though - not sure if it's a typo I've created or carried over from the original source.Code:STACK.EQU $; Stack topIs that valid assembly?Thanks in advance. My next step is to write this code to the ROM and hook up the oscilloscope and see if I can get some traces that might aid in diagnosing the problem. If that doesn't work, I'm likely to rip the SIO/2 off the breadboard entirely and replace it with a 68B50 as used in the V1 SBC that started this thread. With a little monitor code rewriting, should be able to get that up and running and see if it is really the SIO that's the problem.

author: grumpydoc
author_rank: Super Contributor
timestamp: June 14, 2017, 07:23:37 pm
content: Quote from: nockieboy on June 14, 2017, 06:19:02 pmYes '$' means 'current address'SostackSpace .ds 32STACK .EQU $ ; Stack topMeans reserve 32 bytes for the stack and define the symbol STACK to be the address just after that space (which is what you need to load the stack pointer with initially).

author: C
author_rank: Super Contributor
timestamp: June 14, 2017, 11:41:36 pm
content: Just a quick look at your codeCode:; Initialise SIO ALD A,$00OUT (SIOA_C),A; select regester 0LD A,$18; D3 D4 command 3OUT (SIOA_C),A; Command 3 ( Channel Reset )LD A,$04OUT (SIOA_C),A; select regester 4LD A,$C4; 0b11 00 01 0 0; D2 + D3 1 Stop bit; D6 + D7 X64 clock modeOUT (SIOA_C),ALD A,$01OUT (SIOA_C),A; select regester 1LD A,$18; 0b11000; D3 + D4 INT on all RXOUT (SIOA_C),ALD A,$03OUT (SIOA_C),A; select regester 3LD A,$E1; 0b11 100001; D0 RX enable; D5 Auto enable; D6 + D7 Rx 8 bits charOUT (SIOA_C),ALD A,$05OUT (SIOA_C),A; select register 5LD A,RTS_LOW; RTS_LOW .EQU 0EAH 0b11101010; D1 RTS; D3 Tx Enable; D5 + D6 Tx 8 bits char; D7 DTROUT (SIOA_C),AFor simple testing, I would want simple polled mode for send and receive. This means that before transmitting a character you make sure that the transmitter output is empty before character output ( looks like your test code is doing this.For receive you would check if there is received character before reading the character.When your simple SIO output code is working, I would modify a copy of the test code to just echo received character to the output. Then you should see what you type on the PC echoed back to PC. A simple step.=======For SIO register 1 you are enabling Rx interrupts.Might not matter when Z80 has disabled interrupts, but?Then for SIO register 3 you have D5 Auto enableThis enables DCD & CTS to control receive and transmit enables. You will not transmit(CTS) or receive(DCD) unless the pin is lowMake sure that Z80 SIO pins 18,19 & 31 are all connected to gnd.If you change this setting then 18 & 19 are just status bits in SIO register..Just to summarize your code.ORG $4000 should be RAM.ORG $0000 should be ROMSIO A data register is at I/O address $00SIO A command register is at I/O address $02DTR & RTS pins should go low when you write to SIO register 5 and stay lowNow this is not an easy design to test. The way the 74LS138 is currently connected only an address match is needed to make an output to go low. A read or write to memory of address range of XX00 to XX07 will also cause 138's pin 15 to go low for that memory access.You do not have to have complete address decode for a computer to function. Said a different way now you should have many Address What SIO will respond to (SIO CS pin goes low)$00 SIO A data register$01 SIO A command register$02 SIO B data register$03 SIO B command register$04 SIO A data register$05 SIO A command register$06 SIO B data register$07 SIO B command registerTo make testing easer I would make a change to 138's connections.If you were to connect Pin 5 to Z80 IORQ instead of A7 then the outputs of the 138 would only go low for valid I/O access. The side effect is that more I/O addresses will cause a output to go low, but this is not a problem.After change with the SIO connected to 138's pin 15 like now, the SIO could be accessed from some additional addresses, but you gain a great output to trigger your scope.After the change the Address what SIO will respond to (SIO CS pin goes low)I/O $00 SIO A data registerI/O $01 SIO A command registerI/O $02 SIO B data registerI/O $03 SIO B command registerI/O $04 SIO A data registerI/O $05 SIO A command registerI/O $06 SIO B data registerI/O $07 SIO B command registerI/O $80 SIO A data registerI/O $81 SIO A command registerI/O $82 SIO B data registerI/O $83 SIO B command registerI/O $84 SIO A data registerI/O $85 SIO A command registerI/O $86 SIO B data registerI/O $87 SIO B command registerThe code should work fine.After this change OUT ($08),x will cause 74ls138's pin 14 go low for a short time while the instruction is executed. The actual data does not matter. Your current code will cause two short low outputs. I would remove the second.If you add aOUT ($20) just before the POP AF then you will get a short low on 138's pin 12 just before sending a character to output register.Note:Don't rip out the SIO if you go back to 68B50. Add it to what you have so you could use it to test and get the SIO working. If the SIO's CS pin is high then it's the equal of NOT THERE.

author: nockieboy
author_rank: Super Contributor
timestamp: June 20, 2017, 06:38:09 pm
content: Thanks C - just to let you know, I've not given up on the project yet (or fixed it either!) I've just been away on holiday and busy since I got back.I've had an hour or so tonight to take another look, made some changes to the code, but still not getting a stable trigger on a clean trace - the processor just isn't following a short enough loop to display on my 'scope.I like the idea of linking the IORQ to the '138 though - don't know why it wasn't done in the original design tbh, but it's my next step. If I really don't get anywhere with that, or your other suggestions, then I'll try linking in a 68B50 on another breadboard and hotwiring it into the SBC to see if I can get that to work. At least I know for sure the 68B50 works.

author: C
author_rank: Super Contributor
timestamp: June 21, 2017, 03:52:25 pm
content: Think of making it easy on your self to get this working.A scope is not a logic analyzer, need to use it as a scope if possible.Where could be the problem?1. SIO Chip you have will not function properly with this CPU clock input.What SIO chip do you have? Think the chance of a 2Mhz SIO chip working properly at 400%+ clock speed is small.2. Wrong or missing connections to SIO.One wrong connection and data to and from SIO chip is also all wrong.This is easy to check!!!Make a net list of connections ( this pin on this chip connects to this pin on this chip).Start with ZILOG data and make your list.For a few pins you will need to look at Grant's stuff to get more specific. B/a and C/D pins are examples of this.Then check your list many ways against the hardware so that the chance of error becomes small.Check from the medal of pin on one chip to medal of pin at other end.3. test softwareCode:; Read SIO reg 0; output scope trigger $08 (138 Y1)out ($08),xTest bit 5 (CTS) pin in SIO StatusJr Z SIO_Status_3;lFor one level make 138 Y2 pulse lowout ($__),xSIO_Status_3:Test bit 3 (DCD) pin in SIO StatusJr Z SIO_Status_2;lFor one level make 138 Y3 pulse lowout ($__),xSIO_Status_2:Test bit 2 (DCD) pin in SIO StatusJr Z SIO_Status_1;lFor one level make 138 Y4 pulse lowout ($__),xSIO_Status_2:Test bit 2 (Tx_Empty) pin in SIO StatusJr Z SIO_Status_1;lFor one level make 138 Y5 pulse lowout ($__),xSIO_Status_1:Test bit 1 (Int) pin in SIO StatusJr Z SIO_Status_0;lFor one level make 138 Y6 pulse lowout ($__),xSIO_Status_0:Test bit 0 (RX_char) pin in SIO StatusJr Z SIO_Status_done;lFor one level make 138 Y7 pulse low NOTE REQUIRES CURRENT Y7 CONNECTION TO BE DISCONNECTED!!!out ($__),xSIO_Status_done:Think of what above code does.Trigger scope with 138-Y1 and a short time later pulse on pin _ if that bit = _.Each Status bit has a pin, you have a low or no low on 138 pin.Two of the 138's outputs you can make pulse or not pulse by changing states of CTSA(pin 18) and DCDA(pin 19).If you can not make this happen then problem most likely #1 or #2 above.The time between pulse on Y1 to possible pulse on Y2 is short with time increasing to max delay of Y7 pulse.If even this time is too much for your scope, then add a Y1 trigger output just before the JR instructions.The SIO has some outputs you can control. Again a great way to test if you are talking properly with SIO chip.

author: nockieboy
author_rank: Super Contributor
timestamp: July 05, 2017, 09:34:35 am
content: Okay, quick progress update. I've found some time to test the system (and specifically the FT232RL interface) and have made some major progress.Firstly, I've discovered an intermittent problem with the FT232RL USB-TTL adaptor. I've tested it on the v1 SBC and it works for a few minutes, before it seems to go crazy and either ignores key presses or spits out corrupted information, causing the SBC to crash. It works fine with the USB-TTL lead that I normally use (which has an FT232 in it, strangely) so I'm wondering if there's an issue with the little adapters not being original FTDI chips?Anyway, after re-wiring the serial end of the v2 SBC to take the USB-TTL lead, I am now able to power-on the SBC and get the initial message from the monitor - "Press  to activate console"The issue I'm having now is that no matter what I press, nothing else happens. The SBC doesn't seem to be receiving data.I've checked the USB-TTL lead in another breadboard by connecting RxD to TxD and getting what I type echoed back to the serial terminal, so the lead seems okay. However, when I connect RxD to TxD directly on the v2 SBC board, I'm not getting any echoed characters at all. I'm wondering if CTS/RTS is the issue? I've tried setting up the terminal to ignore flow control entirely, but that makes no difference.To be clear, I've checked the connections on the SIO - CTSA is connected to RTS on the USB-TTL lead, and RTSA is connected to CTS on the USB-TTL lead, RxDA to TXA and TxDA to RXA. The SIO is clearly able to send data, as the initial monitor message is being displayed when the SBC is cold-reset, but for some reason I'm unable to send data to the SBC (or it's unable to read it.)I've tried the serial terminal (PuTTY) with CTS/RTS flow control and with none, doesn't seem to make a difference. The monitor program in ROM is identical, unchanged, from the Grant Searle code available on his website for the CP/M SBC. Any ideas what else I can test or where I should be looking?

author: PA0PBZ
author_rank: Super Contributor
timestamp: July 05, 2017, 11:28:41 am
content: Do you still see the initial message if you connect RX and TX from the SBC together and leave the TX from the cable unconnected?

author: nockieboy
author_rank: Super Contributor
timestamp: July 05, 2017, 11:34:53 am
content: Quote from: PA0PBZ on July 05, 2017, 11:28:41 amYes, the message still appears.

author: PA0PBZ
author_rank: Super Contributor
timestamp: July 05, 2017, 11:39:47 am
content: Next step: Do you see echo characters on the PC if you connect RX and TX from the cable together and leave the TX from the SBC unconnected?

author: nockieboy
author_rank: Super Contributor
timestamp: July 05, 2017, 11:45:04 am
content: Quote from: PA0PBZ on July 05, 2017, 11:39:47 amYes, it's echoing correctly.EDIT:I'm just wondering if the correct serial port is being selected on the SIO? Is there a chance it's receiving input on A, but selecting B as the main console interface by some mixup in the hardware or software selection? The monitor program checks both A & B receivers for a space - when it receives one, it sets the variable primaryIO to $00 or $01 if it has received the space char on A or B respectively... What if it's receiving the input on A, but selecting B as the primary IO? That would explain why nothing happens after the initial message perhaps?

author: PA0PBZ
author_rank: Super Contributor
timestamp: July 05, 2017, 12:05:46 pm
content: Quote from: nockieboy on July 05, 2017, 11:45:04 amAre you sure that it receives anything?Does it set primaryIO?Can you output for instance hex 30 +primaryIO to both SIO's after it has been set?

author: nockieboy
author_rank: Super Contributor
timestamp: July 05, 2017, 02:22:53 pm
content: Okay, I tweaked the conout: routine to ALWAYS print the output to BOTH A & B outputs, so whatever is printed to primaryIO will go to both serial ports no matter what.Code:;------------------------------------------------------------------------------; Console output routine; Use the "primaryIO" flag to determine which output port to send a character.;------------------------------------------------------------------------------conout:;PUSHAF; Store character;LDA,(primaryIO);CP0;JRNZ,conoutB1;JRconoutA1conoutA:PUSHAFconoutA1:CALLCKSIOA; See if SIO channel A is finished transmittingJRZ,conoutA1; Loop until SIO flag signals readyPOPAF; RETrieve characterOUT(SIOA_D),A; OUTput the character;RETconoutB:PUSHAFconoutB1:CALLCKSIOB; See if SIO channel B is finished transmittingJRZ,conoutB1; Loop until SIO flag signals readyPOPAF; RETrieve characterOUT(SIOB_D),A; OUTput the characterRETSo it shouldn't matter what primaryIO is set to, it should print the contents of the A-register to both serial ports. I'm still not going any further than the initial message to press the spacebar.I've also added in the suggested change to show what primaryIO is set to + 30H, here's the code below where the monitor waits for a spacebar press:Code:; Wait until space is in one of the buffers to determine the active consolewaitForSpace:CALL ckincharAjrZ,notInALDA,$00LD(primaryIO),ACALLconinCP' 'JPNZ, waitForSpaceJRspacePressednotInA:CALL ckincharBJRZ,waitForSpaceLDA,$01LD(primaryIO),ACALLconinCP' 'JPNZ, waitForSpaceJRspacePressedspacePressed:LD A,$30+primaryIO; DEBUGCALLconoutA; DEBUGCALLconoutB; DEBUGStill no further in getting it working though. (I haven't yet tried the change to the last bit of code above to show primaryIO - I figure it's not necessary as the monitor should be sending to both serial ports anyway.)

author: PA0PBZ
author_rank: Super Contributor
timestamp: July 05, 2017, 02:44:44 pm
content: Some thoughts:Are both SIO's initialized?Do you have scope (sorry, can't remember). If so, can you observe a change in pattern on the data/address lines when you press a space?Is the full code you are using somewhere on the net?

author: nockieboy
author_rank: Super Contributor
timestamp: July 05, 2017, 03:40:55 pm
content: Quote from: PA0PBZ on July 05, 2017, 02:44:44 pmYes, both SIOs should be initialized. Have a scope, but won't be able to check it for a day or so - will try your suggestion re: data/address lines as soon as possible.Yes, the full code is available here:http://searle.hostei.com/grant/cpm/z80sbcFiles.zipThe zip file contains everything for the CP/M SBC, but the file you're wanting to see is in /source/monitor.asm.

author: PA0PBZ
author_rank: Super Contributor
timestamp: July 05, 2017, 05:19:34 pm
content: Are you using this monitor.asm file or are you using your stripped-down version? I read something about removing the interrupt routines but these are essential to receive characters.

author: nockieboy
author_rank: Super Contributor
timestamp: July 05, 2017, 05:25:06 pm
content: I'm using the full monitor program as provided on Grant Searle's website and linked previously.

author: PA0PBZ
author_rank: Super Contributor
timestamp: July 05, 2017, 05:41:05 pm
content: Quote from: nockieboy on July 05, 2017, 05:25:06 pmJust checking...Anyway, if you get the scope out also check the INT line for activity when you send a char to the sbc.

author: C
author_rank: Super Contributor
timestamp: July 05, 2017, 06:40:47 pm
content: If you have two USB to serial connect both,orI would strap the unused Z80 SIO Rx input to a level if it's not already been done.Test this.If you are making changes to grants code, then make minor change to code so that the SIO port you want now is always selected.If you are using port A then make space test always act like is received a space on port A and select A.Thinking you may have noise being received on other port

author: C
author_rank: Super Contributor
timestamp: July 05, 2017, 07:02:54 pm
content: Do not remember if you are using the MAX232 for second port.StrapIf you are using RXDA for receive, then look at level on this pin with USB to serial adapter connected while not sending from PC.This is not sending level, for serial when held to the other level it is a BREAK and the SIO will detect this.Connect RXDB to this level if not connected to a powered USB to serial adapter or max232

author: nockieboy
author_rank: Super Contributor
timestamp: July 05, 2017, 07:35:29 pm
content: No, I'm not using anything on the second port (B) - it's currently floating, I guess.I intend to use it later on for expansion - most likely to connect a keyboard/display circuit. Currently, however, it's not connected to anything...

author: C
author_rank: Super Contributor
timestamp: July 05, 2017, 08:00:58 pm
content: Last I lookedon cold boot grant's software sends output from both.looks for a space from one portwhen space received uses that port for remaining time.You do not care what port output is sent toWhat you really want is that input comes from the port you want.When this is true then Z80 sends output to this portSo during testinginitial output sent to bothoutput only sent to selected port after selection is made. This output tells you proper selection made. If output stops then Z80 likely selected other port.Great code would send to unused port a message" this is port B, Input is from port A".If you force output to continue to both ports then you have no idea what port was selected for input unless the Z80 sends a message stating what port was selected for input.Before sending any character from PCRXDA & RXDB should be at same level.While sending a scope should only see changes to one of these pinsIf RXDA level not the same as RXDB then strap second port RXDB to same level to prevent noise creating a character.Quote from: PA0PBZ on July 05, 2017, 05:41:05 pmImportant test to do.

author: C
author_rank: Super Contributor
timestamp: July 05, 2017, 08:25:33 pm
content: These daysUSB to serial TTL comes in versions for 5 volt logic and 3.3 volt logic.Could be that you have a 3.3v one and the outputs are not making the SIO inputs happy.Compare a high level output from the SIO to a high level output from the USB to serial TTLWith scope you could look at levels of SIO TXDA while Z80 sends message to PC.Then look at USB to serial TTL Tx output while sending from PC and see if levels match.Z80 SIO should swing about 5vA 3.3v USB to serial TTL Tx pin would only be 3.3v or a little less.An SIO input greater then 2v to see a high level and more is better up to 5v

author: nockieboy
author_rank: Super Contributor
timestamp: July 06, 2017, 10:16:24 am
content: Okay, I've made a few debugging changes to the monitor code. To be clear on those changes:* Only port A on the SIO/2 is connected to the USB/TTL lead* Output from the SBC is only sent to port A* Input to the SBC is only checked for against port AThe initial string is still displaying properly.I have added debug strings to key parts of the code and have tracked down the execution to the following loop:Code:waitForCharA:LDA,(serABufUsed)CP$00JRZ,waitForCharAThis is around line 220 in the monitor.asm file and is a loop within the conin: subroutine to get input from the SIO. The SBC is locked in this loop on startup waiting for an input that never seems to come from port A. For info, serABufUsed is defined in monitor.asm as:Code:serABufUsed.ds1I was interested to note that Grant seems to have set up an interrupt on port B, but not A. I'm not really familiar enough with Z80 assembly or the SIO/2 to understand why he has done that and not with port A as well/either. I've removed it from the assembly and added it for port A (in the hope a simple cut 'n' paste and change of SIOB_C to SIOA_C will do it!)Here's how it was:Code:;LDA,$02;OUT(SIOB_C),A;LDA,$60; INTERRUPT VECTOR ADDRESS;OUT(SIOB_C),AI've removed that and added this:Code:LDA,$02OUT(SIOA_C),ALDA,$60; INTERRUPT VECTOR ADDRESSOUT(SIOA_C),APlease let me know if that's wrong as well. I'm reverting the interrupt vector back to SIOB_C as it is in Grant's original monitor.asm next to see if that makes any difference to my debug output (I'm sure it won't - it wasn't working before I made this change.)

author: PA0PBZ
author_rank: Super Contributor
timestamp: July 06, 2017, 10:52:22 am
content: It is very strange that it ends up in that loop because serABufUsed is already checked in waitForSpace and should never go to conin if serABufUsed is zero:Code:waitForSpace:CALLckincharA;LDA,(serABufUsed);CP$0;RETjrZ,notInALDA,$00LD(primaryIO),ACALLconin;PUSHHL;LDA,(primaryIO);CP0;JRNZ,coninB;coninA:;waitForCharA:;LDA,(serABufUsed);CP$00;JRZ, waitForCharAI also noticed the interrrupt set on port A only but I assumed that it was valid for both ports this way and did not go after the datasheet.

author: nockieboy
author_rank: Super Contributor
timestamp: July 06, 2017, 11:03:22 am
content: Quote from: PA0PBZ on July 06, 2017, 10:52:22 amAh, that's because I removed the code that checks for a zero in A as I wanted it to default to the A buffer... looks like that edit wasn't such a good one.Here's what I had:Code:waitForSpace:;CALL ckincharA;jrZ,notInA;LDA,$00;LD(primaryIO),ACALLconinA; DEBUG - only checking A for inputCP' 'JPNZ, waitForSpaceJRspacePressedAfter your comment, I've changed it to:Code:waitForSpace:CALL ckincharAJRZ,notInALDA,$00LD(primaryIO),ACALLconinACP' 'JPNZ, waitForSpaceJRspacePressedEDIT:Looks like it's still stuck in a loop waiting for a character to appear in SerABuff or SerBBuff.You asked previously to connect TXA and RXA together on the USB/TTL lead. Doing that whilst connected to the SBC doesn't echo any characters, but if I don't connect the USB/TTL lead to the SBC and connect TXA/RXA together with no flow control on the terminal, I get echoed characters. Is there something stopping the SBC from receiving data?

author: PA0PBZ
author_rank: Super Contributor
timestamp: July 06, 2017, 11:20:08 am
content: I asked you (or was trying to ask) to connect the TX and RX on the cable and leave the connection to the RX of the sbc intact but disconnect the TX of the sbc.Does it echo?CABLE TX---------SBC RX|CABLE RX---x SBC TX

author: nockieboy
author_rank: Super Contributor
timestamp: July 06, 2017, 12:07:30 pm
content: Quote from: PA0PBZ on July 06, 2017, 11:20:08 amIt does echo, but only after a cold reset of the SBC.

author: PA0PBZ
author_rank: Super Contributor
timestamp: July 06, 2017, 12:12:29 pm
content: Quote from: nockieboy on July 06, 2017, 12:07:30 pmSo when you have it powered up and connected normally, and then move the wire from SBX TX to CABLE TX it does not echo?

author: nockieboy
author_rank: Super Contributor
timestamp: July 06, 2017, 12:35:52 pm
content: Quote from: PA0PBZ on July 06, 2017, 12:12:29 pmOkay, I powered up the SBC with the USB/TTL lead connected normally. After the normal initial cold-reset, the 'Press space to continue' string is displayed. I then disconnected the SBC TX from the cable and connected the cable TX and RX together and characters are being echoed.

author: PA0PBZ
author_rank: Super Contributor
timestamp: July 06, 2017, 12:52:36 pm
content: Ok, so the sbc is not shorting the received data, that is all I wanted to know.Since I don't think it is a software issue I suspect your hardware, either a problem with the SIO or the interrupt handling.You probably need to get the scope out to find out if it is the INT.Is this still on a breadboard? Can you post a high-res picture of the complete board?

author: nockieboy
author_rank: Super Contributor
timestamp: July 06, 2017, 01:07:23 pm
content: Quote from: PA0PBZ on July 06, 2017, 12:52:36 pmI'll be able to get some time on the 'scope this weekend, but until then here's some pictures as requested. Not sure they'll help much as the SBC is still on breadboard and is a bit of a rat's nest of wires... The SIO/2 is the chip in the middle of the SBC.First picture is taken without the USB/TTL cable connected. SIO/2 is the chip in the middle.The second is a close-up of the SIO/2's control connections.Third image shows a closeup of the USB/TTL connection.Fourth image - SBC powered up, from different angle.Last image shows a closeup of the Z80.

author: nockieboy
author_rank: Super Contributor
timestamp: July 06, 2017, 01:13:28 pm
content: Just a thought, but should SYNC/A and WRDY/A be held low? Doesn't show a connection in Grant's original schematics so it's floating on the SBC, but it mentions in an SIO programming document I found that it should be?Here's the document:http://www.blunk-electronic.de/train-z/pdf/howto_program_the_Z80-SIO.pdfAlso, here's a link to the hires versions of the SBC images above:https://goo.gl/photos/p6Q3DVP2TBrZBFC79

author: C
author_rank: Super Contributor
timestamp: July 06, 2017, 01:26:18 pm
content: Still reading to catch upOn thing I saw wasInterrupt vector for SIO only being for channel BThere is only one Regester to store the vector address for the whole chip and it is set and read via The be regestersThink grant uses a vector of 60So the code and the vector must match

author: PA0PBZ
author_rank: Super Contributor
timestamp: July 06, 2017, 01:27:37 pm
content: WRDY is an output so it can be left alone. SYNC seems to be an input but if this is TTL technology an open input will be high. Use a pull-up if it makes you feel safer, pull-down seems the wrong thing to do.From the linked document: "SYNC not used, pulled high by 10k resistor"

author: nockieboy
author_rank: Super Contributor
timestamp: July 06, 2017, 01:29:08 pm
content: Quote from: PA0PBZ on July 06, 2017, 01:27:37 pmMy apologies, I meant high.

author: PA0PBZ
author_rank: Super Contributor
timestamp: July 06, 2017, 01:35:46 pm
content: Why is your 74138 missing the address line inputs?

author: nockieboy
author_rank: Super Contributor
timestamp: July 06, 2017, 01:37:15 pm
content: Quote from: C on July 06, 2017, 01:26:18 pmI wondered about this myself, C. I don't know enough about the SIO or interrupts in general to know what's going on there. It seems to me from Grant's code that he's just setting up the interrupt on port B. In his design, he's primarily using port B to interface to a computer. I'm wondering if he's mentioned the use of a TTL connection on port A, but forgotten to create the necessary interrupt for it in case it is the primary means of communication with a host?So, should I remove the interrupt on B (as I'm not using it - but may later down the line to implement an I2C interface, but let's not get ahead of myself!) and copy/paste the interrupt code to set up the interrupt on A? Would the code be the same, except for referencing SIOA_C instead of SIOB_C? i.e.:Code:LDA,$02OUT(SIOA_C),ALDA,$60; INTERRUPT VECTOR ADDRESSOUT(SIOA_C),AWould that work, or does the command ($02) need to be changed too?I've checked the monitor code - $60 is a valid address for an interrupt:Code:;------------------------------------------------------------------------------; SIO Vector = 0x60;------------------------------------------------------------------------------.ORG$0060.DWserialIntThing is, I've inserted a debug print into the interrupt code and it's never called;Code:;------------------------------------------------------------------------------; Serial interrupt handlers; Same interrupt called if either of the inputs receives a character; so need to check the status of each SIO input.;------------------------------------------------------------------------------serialInt:PUSHAFPUSHHLPUSHAF; DEBUGLDA,'X'; DEBUGRST08H; DEBUGPOPAF; DEBUG; Check if there is a char in channel A; If not, there is a char in channel BSUBAOUT(SIOA_C),AINA,(SIOA_C); Status byte D2=TX Buff Empty, D0=RX char readyRRCA; Rotates RX status into Carry Flag,JRNC, serialIntBAs you can see, I should be seeing the letter 'X' every time the interrupt routine is called, but I'm getting nothing like that from the SBC. It's getting as far as checking serABuff and getting stuck in the loop I mentioned previously.

author: nockieboy
author_rank: Super Contributor
timestamp: July 06, 2017, 01:38:58 pm
content: Quote from: PA0PBZ on July 06, 2017, 01:35:46 pmThey're the blue wires connected to pins 1-6 on the 74138?

author: C
author_rank: Super Contributor
timestamp: July 06, 2017, 01:39:10 pm
content: Quote from: nockieboy on July 06, 2017, 10:16:24 amWay back in this post you state changing from writing the chips vector address fromchannel B register 2 with a value of 60TochannelAregister 2 with a value of 60This is a ProblemThe Vector register only exists in channel B bank of registersONLY ONE VECTOR FOR WHOLE CHIPput is back

author: PA0PBZ
author_rank: Super Contributor
timestamp: July 06, 2017, 01:40:34 pm
content: Quote from: nockieboy on July 06, 2017, 01:38:58 pmMy bad, got fooled because it's upside down in the picture

author: nockieboy
author_rank: Super Contributor
timestamp: July 06, 2017, 01:44:53 pm
content: Quote from: C on July 06, 2017, 01:39:10 pmYes, I returned this to normal a while back, so the interrupt is being set up for B as per the original code.

author: nockieboy
author_rank: Super Contributor
timestamp: July 06, 2017, 01:46:24 pm
content: Quote from: PA0PBZ on July 06, 2017, 01:40:34 pmDarn - was hoping there was an easy solution I'd missed.

author: PA0PBZ
author_rank: Super Contributor
timestamp: July 06, 2017, 01:47:45 pm
content: Quote from: nockieboy on July 06, 2017, 01:46:24 pmYou are not alone

author: C
author_rank: Super Contributor
timestamp: July 06, 2017, 01:48:03 pm
content: Fine print or what is happingThe contents of of B channel Regester #2 is used as the lower part of the Interrupt vector addressRegister #2 only exists for channel BSo right now I have know idea where an interrupt is jumping toCode:LD A,$02OUT (SIOB_C),ALD A,$60 ; INTERRUPT VECTOR ADDRESSOUT (SIOB_C),Ais what makesCode:;------------------------------------------------------------------------------; SIO Vector = 0x60;------------------------------------------------------------------------------.ORG $0060.DW serialIntwork properly

author: C
author_rank: Super Contributor
timestamp: July 06, 2017, 01:57:06 pm
content: Think PA0PBZhas been checking normal connections for SIOAIf you have checked all to the Port to PC then the only thing I can think of that effects receive and not TX is receive clockCheck that pin 13 is connected to pin 14 of SIOThis goes other places but should be the Clock for all channels

author: nockieboy
author_rank: Super Contributor
timestamp: July 06, 2017, 02:03:45 pm
content: Quote from: C on July 06, 2017, 01:57:06 pmPins 13 (RxCA) and 14 (TxCA) are both connected to each other AND to pin 20, CLK. I have checked the clock signal to 13 & 14 previously and it is fine.Grant seems to think the interrupt is triggered by both ports (A & B) according to a comment in the monitor code. I can confirm that the interrupt is set up on my SBC as per Grant's code:Code:LD A,$02OUT (SIOB_C),ALD A,$60 ; INTERRUPT VECTOR ADDRESSOUT (SIOB_C),APulling SYNC/A high doesn't make any difference - same problem as before.

author: nockieboy
author_rank: Super Contributor
timestamp: July 06, 2017, 02:08:22 pm
content: I think my next step (until I can get the oscilloscope out) is to connect up port B to the USB/TTL cable and see if that makes any difference. The code is checking for I/O on both ports, so it shouldn't matter.

author: C
author_rank: Super Contributor
timestamp: July 06, 2017, 02:13:44 pm
content: Do you have port B on a header so it's easy to connect?Have you tried connecting the currently un+used RXDB to a level so that no noise can get in?

author: nockieboy
author_rank: Super Contributor
timestamp: July 06, 2017, 02:18:22 pm
content: Quote from: C on July 06, 2017, 02:13:44 pmNot yet, but I'm make it so I can just plug the USB/TTL cable into another part of the board to get to port B.Yes, I have tried pulling RxDB high and low - neither makes any difference.

author: PA0PBZ
author_rank: Super Contributor
timestamp: July 06, 2017, 02:21:41 pm
content: Here's the deal with INT:(For INT mode 2)Low address from the interrupting device, here the SIOCode:LDA,$02OUT(SIOB_C),ALDA,$60; INTERRUPT VECTOR ADDRESSOUT(SIOB_C),AHigh address from the I register:Code:; Interrupt vector in page 0LDA,$00LDI,AIM2EIINT routine then set up at correct address:Code:.ORG$0060.DWserialIntSIO activates INT when it feels like it and offers the low address on the bus, Z80 jumps to address constructed from I for high 8 bits and bus address fro low 8 bits (maybe 7, low address seems to be even)

author: C
author_rank: Super Contributor
timestamp: July 06, 2017, 02:30:51 pm
content: If you are wired correctly?thenGrant's Code should work if he really tested the code for channel A only opIf this is case that he did test it, then he could have had the MAX232 always connected.So If grant tested channel A with MAX232 on B then state of inputs to B that are connected to Max232 only remain. That is just RXDBHave you tried grant's un+modified code lately?Quote from: PA0PBZ on July 06, 2017, 02:21:41 pmGood summaryFrom what I have read, D0 of a vector must equal 0

author: nockieboy
author_rank: Super Contributor
timestamp: July 06, 2017, 02:48:16 pm
content: Okay well I've burned an original copy of the monitor code, with no edits or debugging in it.I've tried it connected to port A and to port B, both yield exactly the same results - the initial 'Press  to continue' message is printed to the terminal, but nothing after that.Assuming the monitor code uses interrupts to trigger the appropriate code to receive data from the USB/TTL connection, then the only assumption I can make is that the interrupt isn't working for some reason. I've checked the connection between the SIO INT and Z80 INT pins and there's no issues there...

author: C
author_rank: Super Contributor
timestamp: July 06, 2017, 02:57:24 pm
content: Try something dumbStart sending SPACES from PC and continue sendingThen press the cold reset to restart Z80should still get 'Press  to continue'but might see a change in what is sent from Z80

author: C
author_rank: Super Contributor
timestamp: July 06, 2017, 03:33:41 pm
content: The SIO uses M1This tells when to put a vector on busWhen interrupt service is done.If M1 is not connected properly then No vector on busBus could be anything during vector read.Grant's drawing is SIO pin 8 to Z80 pin 16IEI SIO pin 6 also

author: C
author_rank: Super Contributor
timestamp: July 06, 2017, 04:24:59 pm
content: From what I read in Grant's codeSIO Output characterssent from any place in program, not interrupt drivenSIO Input charactersInterrupt to buffer storeif too many characters in buffer then RTS_High and when connected to USB_CTS should stop more characters being sent.At some point in main code there should be a SET RTS_Low to enable USB to send more characters.Main code gets characters from buffer.Putty like programsMost programs like this have an option to echo characters sent. This should be OFF.To Test your putty program only echoes when you have USB_TX Connected to USB_RXFor Grants software you want hardware handshake. This enables USB_CTS input to stop the sending of more characters. No handshake should work with loss of characters in Z80 when buffer is too full.If you turn off hardware handshake the the risk is talking to fast to Z80 and causing a buffer overflow. This should only trash some received characters or cause some characters to be dropped.With the problems being the Z80 receiving characters,USB_CTS could stop the sending of characters to Z80, just to be complete.USB_RST is control used to stop Z80 sending characters.If you strapped both CTS Low then both sides should always transmit characters.You would only haveUSB_TX to Z80_RXUSB_RX to Z80_TXUSB_Ground to Z80_Groundbetween USB & Z80If Z80 is powered from USB then USB+5 to Z80+5Putty could them be set to8 bits 1 stopWith CTS strapped the hardware handshake setting will not matter.Software handshake should not be used.Think that PA0PBZ may have tested thisIn any caseYou can disconnect the wires to USB_CTS and strap to low level(ground) to guarantee the sending of characters to Z80 with settings of no handshake or hardware handshake in putty.

author: nockieboy
author_rank: Super Contributor
timestamp: July 06, 2017, 05:24:40 pm
content: Quote from: C on July 06, 2017, 03:33:41 pmM1 is connected to the Z80 and both pins are showing continuity with each other.IEI is connected to +5V.I think you mean SIO pin 8 to pin 27 on the CPU for M1? Pin 16 is INT.No luck with pressing the spacebar constantly prior to cold starting the SBC either.

author: nockieboy
author_rank: Super Contributor
timestamp: July 06, 2017, 05:42:19 pm
content: Quote from: C on July 06, 2017, 04:24:59 pmI've just tried this:* SIO CTSA tied to ground* USB CTS tied to ground* RTS disconnected (and later also tied to ground)* Just TXA and RXA and power connected.* No handshake on the terminal.Powered up the SBC - no chars echoed. Cold reset the SBC. Initial message displayed (press space etc). No chars echoed.INT is tied high as per the schematic, but I've just checked the resistor and it's a 470 ohm one. NMI and HALT are pulled high through 1k resistors. Just wondering the Z80 or SIO has enough to pull the line low with that resistor? I note it's a 4k7 resistor in the schematic. I think I might have gone colourblind or just used the wrong resistor....EDIT:Nope, I've swapped the 470R for a 4K7 resistor on the INT line, still not working.

author: C
author_rank: Super Contributor
timestamp: July 06, 2017, 06:16:03 pm
content: Yes470 is way to low4K7 or greaterNow I am wondering if you might have fried the INT output of the SIOIf you can still see SIO INT pin changing the should still be ok.

author: C
author_rank: Super Contributor
timestamp: July 06, 2017, 06:25:41 pm
content: YesM1 is on Z80 pin 27Int is on Z80 pin 16checked Z80 datasheet again just to be sure, Grant's drawing is correct.Was a typo.If you have a working USB to serial TTL adapter it should just work.I would guess that you have checked continuity of all the connections by now many times. Are you checking actual pin on chip to pin on chip when doing this?You receiving text on PC suggests that most connections between Z80 & SIO are correct.If you had a data bit swapped then you could program SIO wrong, but the receive text would also be changed if it worked.A miss wire for SIO pins 34 & 33 B/A & C/D should also mess up text.The special pins for interrupt for receive isIEI pin 6 to +5VM1 pin 8SIO INT pin 5 to Z80 pin 16 with a pull-up to +5You should see +5v on both these pins when there is not an interrupt in progress.Think you have connected USB properly and thenRemoved connection to USB_RX & connected USB_TX to this pin (USB_RX). This should give you an echo of what is typed on PC. If you then remove just the USB_TX to USB_RX, then echo should stop. This should be a fair test of your USB adapter is working.Might check the level of USB_CTS pinJust in case you do not understand.When you send characters out a serial port, the device at other end will echo them back if needed.So the test above is sending out to the end and the connection at end causes what is sent to come back.Some devices never echo back. In this case to see what you are typing you turn on putty's ECHO

author: nockieboy
author_rank: Super Contributor
timestamp: July 06, 2017, 06:36:31 pm
content: Quote from: C on July 06, 2017, 06:16:03 pmIs that likely? (That I've fried it?) I've got another SIO but changing it will be a pain with all the wires over the chip.Yes, I've checked continuity repeatedly from pin to pin, but won't hurt to look again tomorrow as I feel I'm running low on options now. Will get the scope out and try to get some levels on INT etc.

author: C
author_rank: Super Contributor
timestamp: July 06, 2017, 06:44:22 pm
content: Think you might say that 470 was a dumb error.From what is happening, think you have something else dumb.When checking pins is good to do it many times as very easy to miss count.Pick a chip or connection jack, then check every pin in orderSo by checking Z80 in order you would have checked each connection to SIOWhen checking the SIO in order you will check again pins from Z80By testing medal of pin on each chip, you are checking breadboard connections and wires.=======If you see a level change on INT should be ok.Hint for breadborddon't go over chips.this design is easer if you create a bus at the end of board where you can.If you put Z80 on bread board and waste some of the end of that breadboard to create a bus then in future you can do an easy add or change.Keep checking back using Grant's UN-modified code in case there is an error in your code changes.

author: C
author_rank: Super Contributor
timestamp: July 07, 2017, 03:44:12 am
content: Easy to make a dumb error, I have made many.You are so close to have a working SIO that a small error or poor connection could be the cause.One thing that you need to be careful of when building on a breadboard is that you do not harm the chips you are trying to use.This requires some careIf you look through Grant's stuff you should see some chip labels, This can help some.One thing you need to be very careful of the what type of pin on a chip you are dealing with.Some are Tri-State like Z80's data & address pins.Some are Input only like Z80's INT pinSome are Open collectorIt would not be a bad Idea to color code the pin on the drawing you are working from. If you use chip labels, color code those also.This way you will easily be able to see that you are not connecting one output to another output, ground or +5vA chip could be still working, but in general I think the more stress you put on a chip the shorter it's life.Now looking at old SIO datasheetLow level output 0.4v @ 1.8ma later datasheet 2.0ma this is for NMOS SIOThe cmos SIO lists 2.0 ma

author: nockieboy
author_rank: Super Contributor
timestamp: July 07, 2017, 11:14:27 am
content: Quote from: C on July 06, 2017, 06:44:22 pmYeah, I was trying to avoid that at the start, but towards the end I was running low on the right colour wire, so cut corners (literally.)Will get to testing the connections later today hopefully and get the scope on it at some point over the weekend. Was considering the practicalities of re-writing the monitor program so that it didn't use interrupts to read input and see if it worked, as it seems everything is pointing to an issue with the INT signal not working correctly.

author: PA0PBZ
author_rank: Super Contributor
timestamp: July 07, 2017, 12:09:02 pm
content: Quote from: nockieboy on July 07, 2017, 11:14:27 amPlease don't. We will have to assume for now that Grant's software is working and that you have a hardware problem. If you now introduce new software then we have another suspect...

author: C
author_rank: Super Contributor
timestamp: July 07, 2017, 05:28:12 pm
content: Quote from: C on July 06, 2017, 06:44:22 pmWhen trying to find a problem, you should not add more possible problems.When you have a working system, you can make small changes and see if those changes created a problem.Grant's design is all working or no help.No test software for hardware, No feedback until most of circuit is working.A low chip count was more important then a good system that can grow or your time when there was problems.While adding the ROM to Z80, you should have been adding a simple 8-bit output port connected to LEDs. You could then have had feedback that should just workNext an 8-bit input port so that you can talk to program and have program change what it is doing.Then RAMOnly then add the SIOWas a big fail to even try connecting a over clocked 68B50 to a Z80. But to then rip it out and put in a SIO to progress is even bigger fail. At a min it should have been add the SIO to existing 68B50, test SIO is working and then and only then remove the 68B50. This change cost you big time as you lost all feedback again from Z80.So keep it simpleMatch Grant's circuitUse Grants's softwareWhen it's working then you can make it better.

author: nockieboy
author_rank: Super Contributor
timestamp: July 07, 2017, 07:06:56 pm
content: Quote from: C on July 07, 2017, 05:28:12 pmJust to be clear, this SBC is entirely different from the first one with the 68B50 (which still works perfectly - overclocked or not - and has allowed me to learn a lot about Z80 assembly while I've been modifying the BASIC and monitor code.)Okay, I'll check and re-check the connections. Once I've done that, I'll see if the oscilloscope shows any activity on the INT line. If that's still dead, I'll replace the SIO/2 with the backup and see if that clears the problem. If not, I'll swap the Z80 out as well (in case the INT on the CPU has been damaged too.)That's my plan of action - let me know if there's things I should be considering inbetween any of those steps.EDIT: Just a thought - I'm looking for a low pulse on the INT line. If I hold down SPACE on the computer whilst the SBC is waiting for input on ports A & B, then Ishouldsee some sort of repeating pattern on the INT line, presumably?

author: PA0PBZ
author_rank: Super Contributor
timestamp: July 07, 2017, 07:13:26 pm
content: Quote from: nockieboy on July 07, 2017, 07:06:56 pmYes, set the scope to negative slope trigger and the trigger around TTL/2 (2V will be ok)

author: C
author_rank: Super Contributor
timestamp: July 07, 2017, 07:40:35 pm
content: Load Grant's original codeThen yes you should see a low pulse on the INT line for each character sent from PC.. The upper limit for a Logic Low input is 0.8v for Z80. The SIO outputs a logic low around 0.4v @ a load of 1.8ma.If you see higher levels then 0.8v for a low then SIO INT pin is Bad.The SIO_INT pin is open drain, It can only pull output low, the resistor pulls output high.You should also seeUSB_Tx going high & low, both at the USB_Tx Pin and at the SIO_Rx pin. The amount of level change should be greater then 2.4v and should be around 4v.If you look at SIO_Tx pin while Z80 is sending The level change should close to what you see on USB_Tx..When looking at the bit times on scope, USB_TX & SIO_TX should be very close to same width.If you do NOT see level changes on USB_TX when sending characters from PC then look at level on USB_CTS, should be low and go high only if Z80 program is not reading characters out of interrupt buffer fast enough..

author: nockieboy
author_rank: Super Contributor
timestamp: July 08, 2017, 06:49:47 pm
content: I'm not really sure my oscilloscope (or my knowledge of how to use the scope) is up to this task, but with a little perseverance I think I'm interpreting the poor results correctly. The INT line is high, CTSA and RTSA are low and, whilst I can't get a stable trace on the oscilloscope, the trace is disappearing on RxDA when I hold down the spacebar or briefly disappearing on TxDA when I reset the SBC (and it transmits the 'press space..' string). That seems to indicate that data is being received at the SIO (I know it's being transmitted from the SIO as I get the initial 'press space...' string in the terminal window.)The INT line, however, remains permanently high. I've tried a variety of voltage ranges, time bases and trigger level/slope settings, but I can't get anything on the INT line other than the high voltage. Unless anyone has any other suggestions, it looks like I've got to consider the possibility that the SIO can no longer pull the INT line low due to damage from having a 470R resistor on it previously.I've also checked the connections and can find no further faults.So my next step is to replace the SIO, unless anyone suggests anything else?

author: PA0PBZ
author_rank: Super Contributor
timestamp: July 08, 2017, 07:00:52 pm
content: What model scope is it? Do you know the difference between continuous and single shot mode?

author: C
author_rank: Super Contributor
timestamp: July 08, 2017, 07:10:05 pm
content: Scopeset scope to free run, You have a trace showing.When you touch your scope probe to a ground connection on Z80. The trace should change little. this is your ground refference 0v. this is the min of a signal.Touch you scope probe to 5v connection. this is max of a signal.Now adjust voltage range on scope so that both levels stay on screenAt 2v setting the above two levels should change 2.5 grids in vertical direction. Use vertical position to move what you see in vertical direction.If you have this then when you look on TxDA or RxDA you should see the top and bottom of trace. Horizonal time base lets you addjust time so that sizes increases.The triggerYou pick direction and level. When level is above or below signal you have a trace. when between then direction selects which edge starts trace.From what you are statingreplace SIO

author: nockieboy
author_rank: Super Contributor
timestamp: July 08, 2017, 07:16:35 pm
content: Quote from: PA0PBZ on July 08, 2017, 07:00:52 pmIt's a Hitachi V-212 - quite an old 'scope I think. Has a knob to adjust the trigger slope, not sure about continuous or single shot selector though...? Don't think it has that feature. I did read, however, an interesting tidbit about the sweep and triggering - looks like I may have had it in NORMAL mode as the sweep disappeared when there was a signal I thought should have triggered the scope. Will get it back out tomorrow and take another look. In any case, can't see anything that would cause the INT line not to show a repeating LOW signal..Quote from: C on July 08, 2017, 07:10:05 pmYes C, I think that's the next step. I have the backup out already.

author: PA0PBZ
author_rank: Super Contributor
timestamp: July 08, 2017, 07:17:19 pm
content: I think it is this one?First adjust your vertical scale like C suggested.When you set the MODE switch to auto it will always show a trace, but if you set it to normal then it will only show a trace if the trigger condition is met.If you are looking at the INT line you are looking for a downwards going slope, so pull the LEVEL switch out. Now if you hook it up to the INT line, send spaces and slowly turn the LEVEL switch you should see a trace whenever the SIO receives a character and pulls the INT line down. Set the TIME/DIV around 1mS so you wont miss the trace, and if it starts working then you can decrease the time to make the pulse visible.If this fails then one last thing you can try is remove the INT wire from the processor, make sure there is a pull up resistor on the INT line and try again. If you still don't see anything prepare to replace the SIO.

author: PA0PBZ
author_rank: Super Contributor
timestamp: July 08, 2017, 07:21:08 pm
content: Quote from: nockieboy on July 08, 2017, 07:16:35 pmIt is a very short pulse, and with the scope in auto mode you will likely miss it. That is where the normal mode comes in, every time the scope is triggered you will see a trace.You can practice by using a pull up to +5V and then a push switch to ground. Connect the scope to where the switch is connected to the pull up. This point is normally 5V but will go to zero when you press the switch, so that is the point where you want to see a (single) trace on the scope. Start with a slow time base like .1 second.

author: C
author_rank: Super Contributor
timestamp: July 08, 2017, 07:27:54 pm
content: After doing what PA0PBZ says with switchWith scope connected to look at the received spaces.you should see no trace until you send a spaceCheck INT againThen If you want to play someYou could replace the 4k7 with a much higher value10k 20kSee if you get a twitch on INTTransistor of output might not be total gone and work under very low load.Remember that Z80 INT pin is a load like the resistor.

author: C
author_rank: Super Contributor
timestamp: July 08, 2017, 07:38:10 pm
content: V-211 V-212 Operation Manual.pdfhttps://mpe.berklee.edu/documents/studio/manuals/testingmet/Hitachi%20V212/V-211%20V-212%20Operation%20Manual.pdfIn case you do not have it.

author: nockieboy
author_rank: Super Contributor
timestamp: July 09, 2017, 07:26:53 am
content: Thanks for the advice guys - I'm struggling to get much done at the moment as I only have brief periods of time I can look at this, which is making it much harder to progress.I did swap out the SIO for the spare this morning, however. Exactly the same problem - shows the initial message on cold reset, but doesn't seem to be accepting input (or it's not pulling INT low enough...)I think maybe more resistance for the INT pullup is required as C has suggested - maybe swap the 4K7 for a 10K? I'll get the scope out again next and do some more examination of the INT line - thanks for the help with that, PA0PBZ.EDIT: Swapped the 4K7 pullup on the INT line for a 10K resistor. Still no change. Will see if I can get some more detailed testing done on the INT line later today with the oscilloscope...

author: nockieboy
author_rank: Super Contributor
timestamp: July 09, 2017, 02:53:28 pm
content: Okay, after a little more testing with the oscilloscope, I've got the following to report:USB Tx line seems to be just under 4 volts when nothing is being transmitted/received.USB Rx line seems to be just under 4 volts when nothing is being transmitted/received.USB CTS is low (0v or as close as.)USB RTS is low (ditto.)I know the USB Rx line is working as I'm getting the initial 'press spacebar to continue' message, but just to make doubly sure I tested the line with the scope and can briefly see the low pulses of the data being transmitted to the terminal to display the initial text.When I cold-reset the SBC and get the prompt to press the space bar, I hold the space bar down and monitor the USB Tx line (and later also the SIO's RxDA pin). After some fiddling with controls on the scope, I'm getting signs of life on the USB Tx line - there's a definite low pulse, although I can't get a stable trace I can see for sure that there is a repeating low pulse on the USB Tx line (and at the SIO's RxDA pin.)So, data is definitely reaching the SIO's RxDA pin.Next to test is in the INT line. I've tried this with the scope connected directly to the SIO INT pin. There appears to be a lot of noise on the line - I'm not getting a clean trace even at the lowest time/div setting, it's blurry - seems to oscillating at a very high frequency (>20MHz as that's the fastest my scope will go) between 4 and 5 volts. Holding down the space bar whilst the SBC is awaiting input is not causing any change in this trace whatsoever - even if I was unable to get a good trigger, I'd still see the line flicker with the repeated LOWs on the INT line as the character buffer fills.Remember, this is the second SIO - not the first one where I had the 470R resistor pulling INT high. Should I consider looking at the Z80? Maybe it has an issue with INT at its end?

author: nockieboy
author_rank: Super Contributor
timestamp: July 09, 2017, 03:00:40 pm
content: Quote from: PA0PBZ on July 08, 2017, 07:17:19 pmJust tried this with the 10K pull up resistor - still lots of noise on the line, but got a solid trace on the noise this time! It's obviously picking up signals from other wires.More importantly, INT didn't go LOW at all, despite the space bar being held down...What are the chances both SIO's are faulty? (Theywereobtained from eBay...)

author: C
author_rank: Super Contributor
timestamp: July 09, 2017, 03:24:22 pm
content: Both sio bad, possible.Wrong software could be cause of no Z80 INTThis has to be programmed to happen.Just to be safe, you might want to load ROM with a new copy of Grant's software.From what I read this is ROM.HEXOne thing you saidSounds like you have a bad USB_TXYou should not need to make any changes to scope when you shift the probe from USB_TX to USB_RX or SIO_RX to SIO_TXThe bit time of signals should be sameThe voltage change should be close, you should see on scope no problemOnly trigger level might need changed nothing else.

author: nockieboy
author_rank: Super Contributor
timestamp: July 09, 2017, 04:41:22 pm
content: Quote from: C on July 09, 2017, 03:24:22 pmWas struggling to understand what you meant here, but realised it was because of how I wrote my previous post. The paragraph about testing the Tx line was originally before the one about testing Rx, but I swapped them round. So the fiddling to get a trace was the first thing I did and I didn't have to change anything to view the Tx line. Sorry about that!I've ordered a couple more SIOs, 8MHz ones, in case that's the problem. If it's not, they're still more compatible I guess.

author: C
author_rank: Super Contributor
timestamp: July 09, 2017, 04:47:34 pm
content: SerialWith async serial which is what you are using, The stop bit is same level as when nothing is being sent. The Start bit is the other level and when held at this level is a special condition called BREAK and is used to get attention of receiver.I say it this way as you find the levels reversed at some points when testing serial, the driver chips that put SIO signals on long cable are inverters.Now the SIO is being set for 8N1 this means you have 10 bits for each character. The start bit(always low), 8 data bits, Stop bit(always high).Depending on how the serial port is programmed each character or chunk of data could have between 7 bits to 12 bits. Data field could be between 5 to 8 bits. The stop bit has an option to be two bits wide. And you have option of adding a parity bit.Here you are using the common 8N1, 8 data bits, no parity & one stop bit.On your scope you could have a any amount of bit time showing.A space could take any amount of with of screen. Almost full screen with is fine. You adjust this with time base of scope.What you care about is the width of the bits is close to the same when you shift from looking at Tx to Rx Close here is 1% difference or so, If you see a difference there could be a problem.Second thing is Voltage levels you see on scope.The Z80 uses 5 volt logic. If you set the vertical controls of scope such that with DC coupled input, 5v and 0v are on screen you should not need to change vertical settings.Keep in mind that 0.8v us max voltage you can have for a logic 0 at an input.Having A 0V to 5v change on scope while needing to see if parts are less that 0.8v suggests using 5 grids with a need to know where 0v is. So Adjust vertical position so trace is on a grid when touching probe tip to a ground on Z80 circuit.Now if you connect scope to SIO_Tx then you should see signal changes during message.The Tx output wants signal low to be less than 0.8v at detestation, so it tries to output 0.4v or less for a logic 0.The Tx output wants signal High to be greater than 2.2v at detestation, so it tries to output 2.4v or more for a logic 1.The voltages can be different for different chipsYou will find the exact limits when looking at datasheetVIH Input High Voltage = ____ The 2.2v aboveVIL Input Low Voltage = ____ The 0.8v aboveVOH Output High Voltage =_____ the 2.4v aboveVOL Output Low Voltage = _____ the 0.4v aboveNote that load currents can change the levels and Capacitance can change the speed of change.So with all the above in mindYou should see little difference betweenUSB_Tx, USB_Rx, SIO_Tx & SIO_RxIf you are seeing a difference, then there could be a problem.Noise is not a problem unless it causes a noise change past input levels.Wrote above before last post.One additional bit of test InformationIEO should go low while interrupt in SIO is pending and back high after service.So If I am reading you latest postsAll Tx & Rx signals are changing as listed above & You see no logic low on the Z80 INT pin.

author: C
author_rank: Super Contributor
timestamp: July 09, 2017, 05:16:09 pm
content: Starting with strait from Grant's ROM.HEX is important step to try.Software not setting SIO for interrupt mode could stop INT output.Note that you might not see INT great with out changing some settings on scope, But if you only see a trace when space is sent from PC, Then with same settings when connected to INT you should get a trace on screen for each Low on INT.INT is a to LOW transition sane as Start bit.IEO is also a to LOW transition.What is labeled on the two SIO chips that you have?Just to be complete what is labeled on your Z80 CPU's?

author: PA0PBZ
author_rank: Super Contributor
timestamp: July 09, 2017, 05:52:00 pm
content: @nockieboyPlay with your scope, this will be a good learning experience not only for fault finding in this sbc but also for the future.Did you try the experiment with the switch? Did you see the difference between normal and auto mode?Next, try to adjust the scope so that 1V is 1 vertical division and then monitor the data that comes out of the USB TX line.Set your scope to normal mode and make it trigger on the start bit.Now adjust the timebase to have 1 bit per division, use TIME/DIV and SWP VAR for this. Does the setting make sense for the baud rate you are using?If you succeed you will see that you can decode the ASCII characters by just looking at the scope and see which bits are high and which are low.I think being able to do the above and know what you are doing is essential for debugging these kind of problems, so please invest some time in this.

author: nockieboy
author_rank: Super Contributor
timestamp: July 10, 2017, 08:47:15 am
content: Quote from: C on July 09, 2017, 05:16:09 pmI'm using the original monitor code, unchanged, from Grant's website.The SIOs I've been using are marked Z8442B1 - I think these are original 80's fab chips, designed for 2.5MHz operation. Not sure if that is important as Grant Searle doesn't seem concerned about overclocking the chips in his SBC designs, but they're NMOS rather than CMOS chips so I'm wondering if there's an incompatibility caused by the system clock speed or levels? The chips are Tx-ing data to the serial terminal with no issues, though.The CPU is a Zilog Z84C0008PEG.Anyway, I've ordered a couple of Z84C42008PECs, CMOS 8MHz SIO/2s - hopefully these will work!

author: C
author_rank: Super Contributor
timestamp: July 11, 2017, 08:49:26 pm
content: You see a lot of big trucks running down the road at the speed limit. Most have to slow down when the load gets to great. Now how many can even get to a speed that is 25% greater then the speed limit? Here you are asking a chip to work at 3 times it's datasheet speed.At some point the digital electronics can not change from one state to the other fast enough before being commanded to change back. At the extreme you have a signal that never gets to an amplitude to change states. This increased speed normally results in more heat, heat that can shorten the life of the chip.Digital you want perfect, one error in a billion can be a huge error.In most logic there are slow spots where the logic is just fast enough to function properly. When you speed up the clock these areas no longer function correctly.In old logic it is not unusual to see one or more chips of a different logic family just for this reason and even then be critical.I would think that the serial transmit is the simple logic area of the chip. Each other area takes more logic and has stricter time requirements.Think of ZILOGIf Zilog could have proved the chip worked at a higher speed, why would they not state this fact. It took some time for ZILOG to get a working set of chips for 4Mhz and again more time to get 6Mhz.If ZILOG could have produced 8Mhz chips earlier then there was no need for 6Mhz setNow like most chips, the chip is a black box. You have no idea what part is the slow area. The next mask used to build the chips could have a different slow area. Just a different MFR can make a huge difference.So you have wasted a lot of time trying to use a chip out of speck. Worse would have been it worked part of the time, like trashing one received character out of thousands received.While waiting for proper chips, I would strongly suggest following PA0PBZ and learn all you can about your scope. This will pay off big time in long run.

author: nockieboy
author_rank: Super Contributor
timestamp: July 18, 2017, 05:47:32 pm
content: Okay, brief update. The Z84C4208PECs (replacement 8MHz SIO/2s) arrived today and I've plugged the first one into the SBC in place of the old SIO/2 that was there and... it works!Just goes to show - I needed to be a little more careful with the parts I chose for the SBC. Was a strange problem with Tx on the SBC working but Rx not, but as you said C it would appear that the receive circuits are more complicated and couldn't keep up with the 7MHz clock.Thank you so much for your time and patience, C and PA0PBZ!

author: PA0PBZ
author_rank: Super Contributor
timestamp: July 18, 2017, 05:57:19 pm
content: Congrats that you got it working finally, so now it's time for a mark 3 version?Oh, and don't forget to play with your scope!

author: C
author_rank: Super Contributor
timestamp: July 18, 2017, 06:02:12 pm
content: While it is semi fresh in your mind, would not be a bad idea to use your scope and look at the signals.You had INT that did not work, but you had the Z80 reading from that SIO chip. I would think you might see a difference when looking at the Data pins.When Z80 talks to SIO I would expect that the logic level changes are fast. When the SIO talks back, The old SIO could be slower and delayed more then the new SIO.Where before you saw two signal shapes on a data line, now you have something that matches better between read and write on data line.

author: nockieboy
author_rank: Super Contributor
timestamp: July 18, 2017, 08:56:57 pm
content: Quote from: PA0PBZ on July 18, 2017, 05:57:19 pmHaha! Not quite - next is to get the CF card storage up and running so I can load CP/M... When (if!) that's done, I've got an AY-3-8912 I want to connect up and get some sound and IO going.I will definitely spend some time with the scope thought to get more competent with it! Thanks again for your help.

author: nockieboy
author_rank: Super Contributor
timestamp: July 18, 2017, 09:00:18 pm
content: Quote from: C on July 18, 2017, 06:02:12 pmI've got two 2.5MHz SIO/2s with no particular use at the moment, so I think some experimentation and scope practice is called for with them. Thanks for your help C.

author: C
author_rank: Super Contributor
timestamp: July 20, 2017, 05:54:28 pm
content: Forgot to sayCongrats on it working.Now that it is working, What things do you want to do or add?

author: nockieboy
author_rank: Super Contributor
timestamp: July 20, 2017, 06:57:47 pm
content: Quote from: C on July 20, 2017, 05:54:28 pmThanks.Well, the next thing to get working is the CompactFlash drive - I'd completely left it off the SBC until I knew it was working properly (which it now is!)I'm using a 40-pin IDE to breakout adaptor with a CF card adaptor plugged into it. I've just been working out which pins on the CF card map to which pins on the breadboard. Next step is to wire it up as per the schematic and hope it works...After that (and I've no doubt there'll be huge problems getting it to work - Grant Searle indicates that wire length can be critical in getting certain cards to work) the next thing I want to get working is the AY-3-8912 chip, for sound and IO. That'll require more software effort than hardware I'm thinking, but there's libraries I've found that I'll be able to tweak to work with my setup.EDIT:Also, I'm keen to learn how to setup an I2C interface from the spare port on the SIO (perhaps) so I can connect up more things.

author: C
author_rank: Super Contributor
timestamp: July 20, 2017, 08:26:53 pm
content: Quote from: nockieboy on July 20, 2017, 06:57:47 pmI think I would connect wires direct to chip that outputs or inputs data from CF card.For example CF D0-D7 & A0-A3 connect at Z80 chip.Some separation of control signals would also be good.One thing that helps when using ribbon cable is to have a ground wire between each control signal.Note that you have a bunch of grounds on CF end A3 to A10, On ribbon cable, these would be between each signal on lower side of the connector.This cuts out some cross talk between signals.Am I making sense?

author: nockieboy
author_rank: Super Contributor
timestamp: July 20, 2017, 09:24:11 pm
content: Quote from: C on July 20, 2017, 08:26:53 pmYou are.I'm not using any ribbon cable though - I'll post a pic of the setup when I'm in front of a computer, but I've got a CF card adapter plugged into an IDE-breadboard adapter (says it's an Arduino IDE breakout adapter) - it's also right next to the CPU on the SBC, so I'll be doing as you've suggested and using minimum-length wires to connect direct to the Z80.I've also got some microSD adapters that connect via SPI. Was wondering if I can't get the CF drive working maybe I could set up an SPI bus somehow and use a MicroSD card instead. Have been having trouble finding detailed guidance on setting up SPI or I2C with a Z80 SBC though.EDIT: Pics of what I'm using for the CF card:

author: C
author_rank: Super Contributor
timestamp: July 20, 2017, 10:19:53 pm
content: CFQuote from: nockieboy on July 20, 2017, 09:24:11 pmOne big difference between a microcomputer or microprocessor and a micro-controller is how IO is done. To keep software overhead low you add hardware while on micro-controller you might bit-bang.Using simple chips you might have a 74xx374 as an output port. In the process of writing to 74xx374 you can easily create a Data strobe or new data signal so what is connected knows when new data exists. Micro-controller you software bit-bang a pin.Getting to the point, I have seen a circuit for SPI, but it's been a while. Think it was 5 or 6 chips. For Z80 SPI is two chips (parallel in- serial out & serial in - parallel out) with some control logic.Think I2C would be harder in hardware.Think the best way would be to connect a micro-controller to Z80 to get some new things like SPI 7 I2C. Might want to look athttps://www.eevblog.com/forum/microcontrollers/help!-how-to-make-a-nsc800-computer/msg1243666/#msg1243666Way back the parallel SCSI bus was used to connect computers & IO. Not hard to do in simple hardware and software can be easy. One of my Z80s has only 256 bytes of rom & the SCSI boot is in that rom along with many types & sizes of floppy boot.Go extreme, put a SCSI interface on both of your Z80's and on a micro-controller and all can talk.So many ways to do great hardware that has low impact on software speed.

author: nockieboy
author_rank: Super Contributor
timestamp: July 20, 2017, 10:29:16 pm
content: Quote from: C on July 20, 2017, 10:19:53 pmSo a 74HCT165 and a 74HCT164 would be suitable for that? Hmm.. Well, the SPI seems the better option as I have a couple of bits that use it - a clock module, the microSD card adapters etc. Seems that's the way to go with it. I'll start looking into it in more detail once I've sorted the CF drive (or not, as the case may very well be.)Err.. just had a thought though - wouldn't the SIO do the job of both the chips mentioned above? It DOES do parallel to serial (Tx) and serial to parallel (Rx) quite well!

author: C
author_rank: Super Contributor
timestamp: July 20, 2017, 11:05:23 pm
content: For SPI you just have 8 data bits, SIO adds a start & stop bit.Z80 Write 8-bits to 74HCT165 serial out is SPI outWrite causes 8 clocks on SCK & causes interrupt or status flag after 8 clocksSPi In to serial input of 74HCT164 & serial input of 74HCT165Z80 can Read 8-bits from 74HCT164Now if you look at a micro-controller interface, You can chose to invert or not the clock & data.For this you need a XOR chip.The above is for a MASTERFor SLAVE SCK is input and clocks both chips.Need a few more minor details.

author: nockieboy
author_rank: Super Contributor
timestamp: July 21, 2017, 09:10:45 pm
content: Quote from: C on July 20, 2017, 11:05:23 pmOkay - have been looking around the usual suppliers I have access to and found this:http://uk.farnell.com/microchip/mcp23s08-e-p/8bit-expander-i-o-spi-i-f-dip18/dp/1332091Would the MCP23S08 be any use with a Z80 SBC to create an SPI interface with minimal programming, I wonder?Then there's this one:http://uk.farnell.com/microchip/mcp23s09-e-p/ic-i-o-expander-8bit-spi-18dip/dp/1699843It's an MCP23S09, major difference from the '08 is that it has open drain I/O pins... Not sure which would be more appropriate, or even if they'd be any use at all instead of bit-banging through 74HCT165/4's?

author: C
author_rank: Super Contributor
timestamp: July 21, 2017, 09:34:51 pm
content: NO, NO NOYou connect those to the microcontroller's SPI or I2c interface to get more bits you can control.You are thinking microcontroller, not microprocessor.74HCT374One 74HCT374 connect to an IO port of Z80 gives you 8 bits output.You connect the D0-D7 to data bus, Q0-Q7 is output, OE low and generate a clock(CP) by a 74hct138 or 74hct139.You have some unused outputs on your 138,With a second 138 connect as followsE1 to unused output of your 138E2 to Z80 WRE3 highyou now have 8 outputs that you can connect to clock(CP) of 74HCT374One 74HCT138 and with 8 74HCT374 you have 64 output bitsFor inputYou connect Q0-Q7 to data bus, D0-D7 is input.Change E2 to Z80 RDEO is connected to 138 in place of CPClock Cp when input data changes.Replace input 74HCT374 with 74HCT244 for input with out clock.

author: C
author_rank: Super Contributor
timestamp: July 21, 2017, 10:28:52 pm
content: NowReading my last you should see some problems if your thinking microcomputer.The Z80 does not know when output data has been read.Think of an old parallel printer & the printer does not know when there is new data.The signal to clock( CP) of 74HCT374 is a new data signal and with a FF you can store this so printer can see there is new data. Printer After reading new data can clear FF. With FF output also connected to input 244 Z80 has a status bit for when printer has read the data. In addition you have 7 more bits on 244 that can be used. One could be paper out, One could be ERROR, one could be printer off or not connected.so far you have to keep reading input ports for a change, need interrupts to get better.InterruptsZ80 has a fancy interrupt mode, vector interrupts. The SIO is using this.Using vector mode is not hard.The interrupt vector is put on data bus during an interrupt acknowledge cycle.Nothing fancy M1 & IORQ = interrupt acknowledge & a 244 can put vector on bus.You could use a 244 for each vector or You can get 8 using a priority encoder chip like 74LS148.The 74LS148 has 8 inputs for interrupts (1-8)A0-A2 get connected to input 1.2.3 of 244GS is interrupt out to Z80244 output is connected to z80 data bus244 output is enabled on interrupt acknowledge with some simple logic that connects to IEI & IEO interrupt chain (SIO)244 input 0 is low244 input 4-7 is upper part of vector.Need more interrupt vectors? Just add more 74LS148'sThis does not take in to account what you could do with a fast memory chip.Now in place of this you could use a PIO, but at a cost of less interrupt vectors & more programming needed..

author: nockieboy
author_rank: Super Contributor
timestamp: July 22, 2017, 10:24:22 am
content: Yeah, I think I'll stick to the solution you're suggesting, C, for the SPI interface - still, that's a long way off yet and I'm getting ahead of myself thinking about it just yet.Quick question to do with crystal oscillators - at least, the all-in-one packages that I seem to have found, like this one:Could that be used as a straight replacement for the oscillator circuit on the breadboard? (i.e. replace the xtal, both caps, resistors and first logic gate in the clock section of the schematic)?In the meantime I'm going to try and connect up the CF card to the SBC this weekend.

author: C
author_rank: Super Contributor
timestamp: July 22, 2017, 03:11:21 pm
content: First you should note that clock input to Z80 is not TTL level.Some oscillators do not produce a great square wave. The cure is to use 2x osc to clock a FF.Z80 needs nice square clock at max speed. But at lower speeds can be not square, the Z80 clock high time can be different from Z80 clock low time. You can change between cycles of clock. You have a 8m part, 8M needs to be square, but slower un-square is ok, note clock high & clock low are min times.Now your thinking of SPI, do you want a faster clock for that serial data out?Note that with proper hardware handshake the SIO baud clock can be higher and the character data rate still not overload the Z80. EASY to use different OCS for this.If you are going to connect an AVR or some other micro controller it's sometimes nice to have same clock source for all, and divide to get what you need for each.Think ahead 2x, 4x, 8s, 16x osc are easy to work with and some times can be very nice to have. In places in place of a delay line, you can use a shift register if you have the clock source. When you go faster like this you need logic that can work/function at that speed. It is harder to work with 3x,5x,7x ect but not impossible.breadboard can limit max clock, but you could have High speed on pcb that plugs into breadboard.You have a 8M max limit for Z80, but can divide to this.You have a need to match standard baud rates to 1% or less. but again can divide to to need OR use different osc.If I was building, I would do X__ for the clock, probably from 2x,4x, might to 8x.So can type osc is fine, CMOS type is good here. Question is what speed for what cost $. Cost is why you often see just see the crystal with osc circuit.If you are going to order some, might want to think on some other parts that would be nice to have to add to order.Your needs might change based on memory speed also.You have one working OSC now, both Z80's could use same osc just use different driver to each z80, II would use it and think on this as future step.

author: C
author_rank: Super Contributor
timestamp: July 24, 2017, 06:19:42 am
content: This post is about learningYou have been asking a lot of questions which is good way to learn.Way back Z80's were used for a lot of different things.More questions with ideas of what you want to learn or do can help alot and could save you time also..You just had some fun or pain with an SIO, How much of what the SIO can do did you look into.SIOThe SIO is a Universal Synchronous/Asynchronous Receiver/Transmitter.with Z80 vector interrupt generator added.Universal Synchronous/Asynchronous Receiver/Transmitterhttps://en.wikipedia.org/wiki/Universal_Synchronous/Asynchronous_Receiver/TransmitterYou Might want to do a quick read of this first.https://en.wikipedia.org/wiki/Universal_asynchronous_receiver/transmitterIf you look at the first chips like WD1402A or AY-5-1013, you would see part of what is inside the SIOAY-5-1013http://www.rogtronics.net/files/datasheets/uarts/AY-5-1013.pdfThere is no software initialization needed with this chip, Some pins were set high or low by a dip switch an pull up resistor. The baud rate clocks often by another chip. Fancy was using software to set pins in place of dip switch which then needed software.One reasion for SIO was to reduce the logic needed to connect this chip to Z80.You would use 374's and 244's and some more chips to interface this chip.The SIO is a Universal Synchronous/Asynchronous Receiver/Transmitter.IBM and many others used the Universal Synchronous part. This removes the start stop bits and lets you transmit/receive data packets with known packet start. This makes software easer at the cost of transmitting complete packet at speed or aborting packet.When you understand the basics used here, you can see parts of this used many places.So while you may not care about HDLC, SDLC or Synchronous it is not a bad idea to look up and try to understand the terms you come across while building your Z80So as you were looking at the SIO data sheet did you look up some or all of this?Software flow controlhttps://en.wikipedia.org/wiki/Software_flow_control

author: C
author_rank: Super Contributor
timestamp: July 24, 2017, 07:00:59 am
content: How are you getting along with CF card interface.?would be good idea to make a spreedsheet or text file of all the connections.You have the CF card, CF card adapter, the breakout board & Z80 to deal with.For quick SD Card interface,in your position I would want a working CP/M system if at all possible first.Z80, You need software & hardware. For Z80 you would need to find the software or translate from some existing software that works with a microcontroller interfaceYou would need to add hardware to Z80, test it and get software working. .Right now you are playing shuffle and have to move Code to Z80.You should look and understand each option grant has to get code to Z80.No CF card changes this some. If your rom is larger then grants you have more options.Option #1AA 4$, 4ICs, Z80 homemade computer on breadboardhttps://www.eevblog.com/forum/projects/a-4$-4ics-z80-homemade-computer-on-breadboard/You might think of this as a Z80 development systemHe is using a MEGA32A, with some Adriano programming. The mega32a is 40-pins Cost and breadboard plays a large part of choice.Something with even more pins could be better.Note this is using I2S memory for drives. SPI pins are used and have not looked how hard it would be to change so SD Card possible.Option #1BA Arduino Mega 2560 would be nice due to more pins, but real at $45.95 but I would not pay that price. This is used in a some/lot of 3D printers. It is ok for 3d printer but not great. Arduino Mega 2560 Clones are much cheaper and have some parts used above on a PCB. Would need some Arduino side software changes to use this.The extra pins should allow I2C, SPI or SDcard use as drives.1A & 1B dos not prevent you from adding more hardware on Z80 side.If memory serves Grant's basic exists for this.You could have Arduino Mega boot Z80 and with software changes add Z80 hardwareOr with some software changes you could have Z80 boot from rom and then start using Arduino Mega for its IO.Option 2:You could treat a micro-controller as a disk drive controller.You could then use existing software on micro-controller. .You could have Z80 using raw data space of SD card or a file per drive on SD Card.At the simple level the Z80 is going to ask to read or write block # on drive xI would think a quick simple version of SCSI interface on Z80 connected to a microcontroller that has a SPI interface would be a good starting point.You would then have hardware that adapts to differences in speed of CPU's and hardware based control of data flow speed between the two systems.This would let you use a lot of the existing software for SPI Interface and SD Card on microcontroller.This one interface on Z80 would let you add hardware & software on micro controller side with just software changes on Z80. Full SCSI interface on your two Z80 & micro controller and you have a network.An operating system like CP/M just wants a drive to look like a collection of blocks. CP/M programs work with blocks of 128 bytes. When this does not match drive block, a part of CP/M will adapt to put many 128 byte blocks into a drive block. Small block size = smaller disk and less memory CP/M needs as a drive buffer to do this. The great thing about CP/M 3 and turbodos is that it can swap in banks of memory to hold these and other buffers.When you have a working CP/M systemYou can do all parts of software development on Z80. While this can be slower, it could still be faster then moving code to Z80. I think some of the Assemblers are even better on z80.A lot of possible options where a micro-controller can help on Z80 side.

author: nockieboy
author_rank: Super Contributor
timestamp: July 24, 2017, 12:46:36 pm
content: Quote from: C on July 24, 2017, 07:00:59 amHmm.. well, I was able to wire up the GPIO adapter on the breadboard, but that's as far as I've gotten. If I plug the CF adapter into the GPIO's IDE slot, the SBC won't boot or show the 'Press <space> to continue...' prompt. If I remove the CF adapter, it will boot - so there must be a problem somewhere with the wiring. As soon as I've got some time I'm going to go through the connections (I'm pretty sure they're all correct) and also check for shorts or unexpected connections between pins - I'm not sure that the CF adapter is providing clear connections between the IDE connector and the CF card's pins - one of the wires (~WE - Write Enable on the CF card) is connected to Vcc through a 1K3 resistor in the adapter, for example. There's probably something else in the CF-IDE adapter not wired as it should be for the SBC.

author: C
author_rank: Super Contributor
timestamp: July 24, 2017, 12:57:29 pm
content: (WE) A pull-up resistor should be same as strapped highFirst thought is power problemThe CF card needs power, normal IDE cable no powerHave you connected power to the power jack on CF Adapter?

author: nockieboy
author_rank: Super Contributor
timestamp: July 24, 2017, 01:29:07 pm
content: No, I haven't connected anything to the power connector on the CF card adapter (the power LED illuminates when power is on to the SBC) - but a quick check with the multimeter and I'm picking up +5V at the Vcc pin for the CF card. As I had to take the CF card out of the adapter to check the voltage on Vcc, I thought I'd turn the SBC on with the adapter plugged in to see if it would boot... No. So it seems the CF adapter is causing the issue, but I'm a little confused as to how or why it would prevent the SBC transmitting anything to the console.EDIT: Here's a pic of the setup so far...

author: C
author_rank: Super Contributor
timestamp: July 24, 2017, 01:38:41 pm
content: Need to test power with card plugged inI would just connect grounds and +5 from power jack to breadboard.Their is a chance that you are using more power then USB supplies.Might try disconnecting CF chip select and putt this high and see if things change.

author: nockieboy
author_rank: Super Contributor
timestamp: July 24, 2017, 01:52:33 pm
content: Quote from: C on July 24, 2017, 01:38:41 pmPower draw for the SBC is 20mA according to my USB power monitor, well within the specs for the USB port if that is correct...Yes, the next thing I'll try is to disconnect the CF adapter - probably one connection at a time to see if I can pinpoint which one is causing the problem.

author: nockieboy
author_rank: Super Contributor
timestamp: July 24, 2017, 02:00:59 pm
content: Hah! Didn't expect to find the problem with the first wire I disconnected, but I did..It seems there's a problem with the reset wire/pin. If I disconnect it, the SBC works fine with the CF card in/out. The minute I connect it, it freezes the SBC.With a minute or two investigation with my multimeter, it seems the RESET pin for the CF adapter is connected straight to GND. This was pulling the RESET pin to the ENABLE ROM gate low, causing the SBC to freeze. Seems I need to find another pin that functions as RESET for the CF adapter...

author: C
author_rank: Super Contributor
timestamp: July 24, 2017, 02:14:03 pm
content: As I said the CF adapter is adapting CF Card so that it looks like IDE drive.Quick test would be CF CS High at CF card.All outputs should then be tri-state from CF card.Chip select would be Drive select on IDE Cable. and adapter could be built to do/not do Cable select drive selection a second difference.If this does not work, I would start a spread sheet and list all the connections on all the parts used for this..Better chance to see a conflict.Some pins will be different on IDE vs CF card slot.Could be many differences.Normal 40 pin IDE cable does not do power.In laptops they sometimes use a 44 pin connector to connect drive power & IDE signals to a drive.Check power with all connected. Power up could be a big load.Could also need some cap's on power bus.For reset, adapter could be built for software reset of CF card.I would still do a spreed sheet to verify

author: nockieboy
author_rank: Super Contributor
timestamp: July 24, 2017, 06:51:45 pm
content: Okay, well, here's how I did this so far:1) I connected the CF card adapter into the IDE breakout/GPIO board, which is plugged into the SBC breadboard.2) With no CF card inserted so I could get to the pins, I set about testing continuity using my multimeter between the CF pins and the pins in the SBC breadboard from the IDE breakout board. That way I would know exactly which pins on the breadboard to connect up to the Z80's ADDRESS and DATA bus, along with the control lines as detailed in Grant Searle's schematic.3) Connected up the buses and control signals accordingly.4) Discovered that the RESET pin in the CF adapter card is also connected directly to GND. If I connect the IDE GPIO breakout RESET pin to the appropriate place on the SBC (Enable ROM logic input from RESET button), that line is pulled LOW and the SBC is held in a permanent RESET state.So I have a CompactFlash to IDE adapter that has a permanent connection from CF RESET to GND for some reason. I will take a closer look at the adapter tomorrow, but I can't work out why it would be made this way. If I can break a trace on the CF/IDE adapter to stop this short, then maybe I can get it working.

author: grumpydoc
author_rank: Super Contributor
timestamp: July 24, 2017, 07:36:27 pm
content: Quote from: nockieboy on July 24, 2017, 06:51:45 pmIf you are following Grant's design then he connects the lower three bits of the address bus and the data bus directly to the CF card - IMO this is a mistake because it's too easy to disturb the Z80 buses that way and get unreliable operation. I would aim for a buffer between the two.As for the reset thing have you identified pin 1 and the pin ordering correctly - if you are 180oout then the corresponding pin on the CF card is pin 10 or A9 which should, indeed, be grounded.

author: nockieboy
author_rank: Super Contributor
timestamp: July 25, 2017, 09:33:05 am
content: Quote from: grumpydoc on July 24, 2017, 07:36:27 pmI've checked and double-checked the orientation of the CF card pins against Grant's schematic here:Using the guides at the edges of the connector (one is thin on the left, the one on the right is thicker) there seems to be only one interpretation of the pin positions, so I'm pretty sure I'm not getting them mixed up - this is the RESET pin I've identified in the CF card connector.... (I've marked it on the image below, but unfortunately it's a bit small/faint - click on the image for a much larger version.)I've also checked continuity between the CF RESET pin and pin 1 (IDE RESET) of the IDE connector on the CF adapter - they are indeed connected. Unfortunately, there is a definite short between IDE RESET pin 1 and GND. There's no obvious damage to the adapter PCB or traces - I just can't work out WHY it would be connected to GND like that.

author: C
author_rank: Super Contributor
timestamp: July 25, 2017, 12:11:19 pm
content: Think you have an adapter from CF to ATAi IDE driveParallel ATAhttps://en.wikipedia.org/wiki/Parallel_ATAYou have a 50-pin CompactFlashYou have a 40-pin Parallel ATAYou have Power jackyou have 3 leds.This is more then just change pin #Trace out what is on adapter , reverse engineer it.

author: grumpydoc
author_rank: Super Contributor
timestamp: July 25, 2017, 12:42:54 pm
content: Quote from: C on July 25, 2017, 12:11:19 pmReset on the CF card (pin 41) should go (I think) to pin 1 on the IDE interface.Note that the IDE interface numbers pins in a different order to the CF interface

author: nockieboy
author_rank: Super Contributor
timestamp: July 26, 2017, 09:21:58 am
content: Well, it's not pretty, but I got it working last night.As you can see in the image above, I swapped out the CF-IDE adapter that I had initially been using (and associated IDE-GPIO adapter that plugged into the breadboard) and have used an alternative CF adapter I had lying around - unfortunately the IDE pins on this one are too close-pitched (and male) so they won't fit the IDE-GPIO adapter. Instead I've had to use the short length of IDE cable that came with the CF adapter and plug the breadboard connections directly into the ribbon cable connector. Like I said, not pretty (or particularly stable) but it works.It now has CP/M 2.2 installed and runs BBC BASIC in CP/M (as well as my modded NASCOM BASIC in ROM). Work finished late last night, so I've yet to get hold of more CP/M software to test, but it's almost complete for this stage of development. I just need to look at the code in my own monitor ROM - I had to swap out the ROM last night for Grant's original ROM monitor as mine was having trouble with the Intel HEX pasting into the console.So what's next? I have a nice little space on the breadboard for an AY-3-8912 that you may have noticed in previous post images - the next step is get this in and working and sort out some sound and IO for the SBC.Then after that - an SPI interface perhaps?

author: C
author_rank: Super Contributor
timestamp: July 26, 2017, 01:45:07 pm
content: Quote from: nockieboy on July 26, 2017, 09:21:58 am:-+Great to here you are running.Lots of places to get CP/M software. In general any CP/M software works on any CP/M machine.BUT You can have differences in many areas that can make it fail.Displays:There were many different ways to work with a display. Go to X.Y on screen was often different for example.Printers:Same problem as above when doing fancy prints.Hardware:You have some software that is special for Grant's, Things like this could have problems.AY-3-8912I would suggest that when you can you use a separate breadboard for things like this.Think of building to a bus based breadboard system..Think of future some, If you have memory on separate breadboard with easy connection to a bus, It becomes easer to change in future.IF all of SIO special was on a breadboard, again easy to change. Connections can be easer to connect or disconnect.As a hint of what you might want on your bus, look at bus used for Radio Shack/Tandy Model II. There is a technical service manual on web. This was a great Z80 system. Note also what boards plugged into this bus. A bus lets you expand to bus limits and more. You might not want or need all the signals now, but if you leave space you can more easily add signals later to the bus. Note the IEO/IEI chain of signals that let you add more vector interrupts to system.You can see how expandable this system is when you look at Model 16B or Model 6000. Here a 68000 processor board is plugged into a Model II. The Z80 boots the 68000 and after boot does the IO reducing load on 68000.Programming takes space & run time. In future you might like the AY-3-8912 connected to your second Z80 so that you have more memory for CP/M and less load on CP/M's CPU. Bus makes this an easer change.If you put one breadboard the other direction(vertical in picture), it could be your Z80 bus.

author: nockieboy
author_rank: Super Contributor
timestamp: July 26, 2017, 02:07:12 pm
content: There's no denying a separate bus board would make future development a lot easier. I was just looking at the board and wondering where I'd get the address and data bus signals from for the PSG - looks like I can get data from around the SIO and address from around the ROM ZIF socket, but it'd be so much easier with a dedicated bus board as you've suggested, C.I wanted this iteration of the SBC to be compact and solid - version 1 was wide and spread across four breadboards and, as a result, it was flimsy and didn't take too well to being moved around the house (it has actually stopped working currently, I think because of a disturbed connection somewhere.)I'm wondering about the virtues of prototyping board. My prior electronics and soldering experience was entirely based on veroboard (stripboard?) many years ago and I've never used prototyping board, but I've seen many dense and neatly-created SBCs online using protoboard, so I might consider giving that a chance as the next step away from breadboard... any thoughts?

author: C
author_rank: Super Contributor
timestamp: July 26, 2017, 02:30:46 pm
content: The big thing is having a bus that you can plug into.Cost is a problem. With many changes you can have to replace things to keep going.Using a breadboard is ok first step.You can find a design on youtube that uses headers on stripboard to create system. Bus is on a stripboard. Should take a look.Think build it on breadboard and test it. Then move it to stripboard. Keep it logical & have modules. After you have made one module it is easer to make the second.Big problem is the need of a lot of signals on a good Z80 bus. Look at that Model II and get an idea of what might be needed.The Z80 is only 40 pins, but needs a lot more pins on the bus.To do it right you need to add IEI & IEO for interrupts. Can need same idea for Busgrant.Now is a good time to do some clean up to make things easer in future.You have thought of Z80 clock.You now have Grant's CP/M working, so with software changes you can improve on it.My first change would be to replace Rom disable circuit with a 273.You need to get to CP/M3 or TurboDos. This gives CP/M programs more ram to work with. You need memory to do this.

author: C
author_rank: Super Contributor
timestamp: July 26, 2017, 03:02:39 pm
content: The 274 could give a simple memory management with the extra bits with known state at power on.You may not know, to shift from CP/M2 to CP/M 3 or Turbodos you just run a CP/M2 program.

author: nockieboy
author_rank: Super Contributor
timestamp: July 26, 2017, 03:16:14 pm
content: Quote from: C on July 26, 2017, 03:02:39 pmSorry C, a 273 or 274? I'm assuming you mean the 273 (8-bit register)?So I could use the 273 to control the ROM and the remaining 7 outputs to page in 16 or even 32K sections of RAM, say from 3000-AFFF (as an uneducated guess)? Bare in mind I know next to nothing about the CP/M memory space (and especially memory paging in general), so please forgive me if I come out with some real nuggets.How does CP/M 3 page the memory? Via IO space?

author: C
author_rank: Super Contributor
timestamp: July 26, 2017, 04:13:37 pm
content: Sorry 273You have a clear input for power up.You have a low to high input to latch new data.Note that this puts the latching of data at the end of a Z80 write where data is valid.To me when using single chips like this where Z80 OUT sets the data to use a 138 or 139 with WR as one of its signals.For Z80 input Use one with Z80 RDOne of the inputs would come from your existing 138273 gives 8 bits logic 0 on power up.Grant is using 1 bit.You have option of1. read from rom, write to nothing.2. read from rom, write to ram3. read from rom, write to eeromQuote from: nockieboy on July 26, 2017, 03:16:14 pmPaging can be almost any way with CP/M3 & turbodosBoth want some high memory common.Keep in mind that first 128 bytes is important also.For 32k banks you use one Z80 address line while adding more.For 16k banks you use two Z80 address lines while adding more.Some use a data selector IC to select output address.Some use a tri-state latch to output address.One you select the bits while other you select the chip.These are simple.Fancy is using very high speed memory.One of my Z80's uses a 8 bit magnitude comparator chip and has a movable bank location.

author: grumpydoc
author_rank: Super Contributor
timestamp: July 26, 2017, 07:16:16 pm
content: Congratulations on getting it workingI must get back to my own Z80 build

author: nockieboy
author_rank: Super Contributor
timestamp: July 26, 2017, 07:18:19 pm
content: Quote from: grumpydoc on July 26, 2017, 07:16:16 pmThanks grumpydoc. I'm sure you'll be fine with your build!So let's say I want to page a 16K block of RAM. I'm using a 128K SRAM chip, with A16 grounded so only the lower 64K is used currently. The memory map would look something like this:FFFF ----------------------------| Reserved for CP/M |DC00 ----------------------------| TPA |D000 ----------------------------| || 16K TPA PAGE AREA || |9000 ----------------------------| || TPA || |0100 ----------------------------| 'Low Storage' area |0000 ----------------------------Hmm.. how would I go about mapping the middle of the block of RAM to another block of RAM? (That's a rhetorical question, btw - I'm sure there must be documentation on how it's done out there, I just haven't found any in the short time I've had to search for it!) It would be simplicity itself to swap out the entire 64K of RAM by making A16 go HIGH, but that wouldn't work all as CP/M and the stack etc would be swapped out with the lower 64K... So what's the best way to switch the middle of the lower 64K block with any 16K block from the upper 64K in hardware?

author: grumpydoc
author_rank: Super Contributor
timestamp: July 26, 2017, 08:06:40 pm
content: Quote from: nockieboy on July 26, 2017, 07:18:19 pmWith luck, it might be a bit ambitious on the clock speed front.QuoteDepends on whether you want the switchable block to be arbitrary or at a fixed location and whether the addresses line up nicely with address bits.If you are targeting CP/M 3 you want a common block at the top of RAM and then switchable banks in the remaining space.Let us suppose that you choose to implement an 8k common area at the top of RAM (which is a bit more convenient than 16k) - in this case feed the top three bits of the address bus into an AND gate. That combination will give you an active high signal when the address that the Z80 is trying to access is between 0xE000 and 0xFFFF.As you have 128k RAM use whatever means you fancy to decode a single output bit.The RAM needs 17 address bits - A0to A12come direct from the processor. For A13to A16drive the outputs from 4 OR gates. One input of each OR gate will come from the active high signal described above. Then for the OR gates connected to A13to A15on the RAM the other input comes from the corresponding CPU address line and the final OR gate is connected to your I/O bit.The result is that any access by the Z80 in the range 0xE000 to 0x FFFF will cause the top 4 address bits on the RAM to be '1' and so will go to the last physical 8k block in the RAM. If your I/O bit is '0' then accesses in the range 0x0000 to 0xDFFF will go to RAM addresses 0x00000 to 0x0DFFF, when your I/O bit is '1' accesses in the low 56k of Z80 address space will go to 0x10000 to 0x1DFFF in the RAM (i.e your bit give you two banks).You can see how it should work in the schematics for my build.The slight disadvantage in the above scheme is that you loose a page of memory (because you can't access 0x0E000 to 0x0FFFF in the RAM - any address in that range gets mapped to 0x1E000 through 0x1FFFF). Consequently my design is a bit more complex in that it uses an adder to do the mapping without loosing any RAM (which works out nicely with 512k - you get an extra bank).More complicated schemes might involve using a fast SRAM to create a mapping between Z80 address and physical address (old cache SRAM chips can be useful for this) or even using an EPROM to set up a mapping. I've posted schematics for this sort of thing in the past.You could replicate a similar scheme to direct all accesses in the range 0x00 to 0xFF to the bottom 256 bytes of physical RAM but I chose to avoid the extra gates that would require and will work around keeping all the interrupt vectors the same in all banks in software,If you really want an arbitary block anywhere in memory to be remapped then you need t think about using RAM to implement a "page map" as above or implement something similar to the Z180 line of CPUs with registers, comparators and adders to juggle the memory map around.

author: nockieboy
author_rank: Super Contributor
timestamp: July 26, 2017, 09:23:12 pm
content: I think when I get a moment I'm going to have to hunt through your previous posts grumpydoc and look up these schematics.I'm not looking to reinvent the wheel - I'm not experienced or knowledgeable enough to design my own memory mapping system, just want to include the simplest system compatible with CP/M 3 that will allow me to make use of the upper 64KB of my SRAM.On a complete side note - I've been hunting for a female PCB header that'll accept the 44-pin 2" IDE male pins from the CF adapter I'm now using (thinking ahead to if/when I get a proper PCB made up for the SBC so I can just slot the CF adapter into it without the IDE cable and wire rat's nest I've got going on at the moment.) Is there such a thing I can search for? The pins are obviously closer together than the 2.54 pitch breadboard holes.

author: C
author_rank: Super Contributor
timestamp: July 26, 2017, 11:19:12 pm
content: First do not think small.You have a 128k ram now, why design something so limited?It would be nice to be able to easily add a lot more ram.Think a moment, Think your CF card adds many drives with large disk blocks. If the Drive block size is not equal to 128 bytes, when you need a File buffer to use disk drive. With out enough memory for file buffers, you can end up when updating a 128 byte CP/M block to disk having to do a Read from disk, Modify the 128 byte block in the buffer and the writing to buffer back to disk.In addition you need more buffers to handle directory updates.With CP/M3 and turbodos, both try to keep common high memory space small.Also at times Both would like to copy from one block to a second block.So 128k can work, but more memory is better.Think you are thinking one swap area to save lo logic.For example, Just because hardware can swap all memory in X size blocks, That does not mean you have to swap and area.Simple 16k systemYou have four 374's with Z80 IO write to inputs. You now have 6 more address lines, you lose two to replace the two used to select one of four chips. This gives you any 16k block from a 1m address space.One of the four 374 is selected based on outputs from a 138.138 A & B are connected to Z80 A14 & A15One address input of 138 is not needed & 138 has many inputs to control outputs.So you have four 374's with all outputs connected to A14-A21.Now the problem with above. At power up the state of the four 374's is unknown.By changing C input of 138 you could switch to a second set of four outputs.Or you could use one of the other inputs to disable all outputs of 138In both cases you have a tri-stated upper address bus A14-A21.Final step us connect one output of 273 do disable this 138 by one of the two methods above. A low from 273 gives no valid output from 138 which does not enable a output of 374's, leaving A14-A21 in tri-state..8 pull-up resistors connected A14-A21 can give a known state with both of above. When not driven A14-A21 will be high.Your existing rom program needs to exist at the address with A14-A21 all high.You have a 128k ram chip. If my math is correct, then 8 of these memory chips will fit in 1meg. If you use a 138 to decode 1 of 8 then just attach your 128k ram to Y0 & your Rom to Y7.Said a second way1. 138 chip selects which 16k space the Z80 wants( only two address inputs used and 4 outputs are used).2. 4 374 chips. The 138 enables output of 1 of 4 374's. This gains 6 address bits.3. The 273 disables all outputs of #1 138 on power up. this leaves A14-A21 in tri-state.4. 8 pull-up resisters pull A14-A21 high when in tri-state.This is the memory mapper for 16k. Each 16k area can come from a 16k block in the 1 meg memory space.5 138 or 139 This is chip that is used durring Z80 write to select one of the four 374's.So the 16k memory management takes 6 chips1M address space.1. 138 decodes 1meg space into 8 128k spaces for your Ram chip.2. 128k ram chip is connected to Y0 from #1.3. ROM is connected to Y7 from #1. Power-up boot program has A14-A21 high during boot. Your existing boot program needs to be written to correct area of rom so that it is present with A14-A21 high. A rom smaller then 128k will repeat in memory, this is ok.Now you need a software change to boot rom to set the 374's to a known state at some point.For Rom basic you just write proper value in first 374 to keep rom in memory map and set remaining to point to ram. Then do output to enable.If Rom is larger then 16k you can have many rom programs to chose from.First step for CP/M is use rom to read CP/M boot from disk. Switch to all ram and jump to CP/M boot now in ram.Note this has been edited many times.Note above the use of a 1 of 8 decoder(138) to do a 1 of 4 decode. This is just to have extra inputs for when you need a valid output. A 139 is two 1 fo 4 decoders so it could select which 375 is used on Z80 IO write & select which 374's output to become extended address.If you want to have many Z80 IO outputs you have four ready to use with 138.The 139 with it's dual 1 of 4 outputs is a great chip if you need Four input addresses and four output addresses.Now this all fails if it takes too long in time. You have memory address delay of 138 connected to Z80 + 374 output enable delay + 138 delay selecting which chip from 1meg memory. This is added to memory chip times.Would be great if 1meg 138 output was enabled by MREQ. If this is not the case then a two inverters in series can add some delay to MREQ.Logic has to be good & times valid for your 8meg Z80 at clock speed.

author: grumpydoc
author_rank: Super Contributor
timestamp: July 27, 2017, 07:36:48 am
content: Quote from: CReasonable commentQuoteBut why muck about with 8x128k RAMs to get a meg when you can simply get a a couple of 512k x 8 or 1M x 8 chips (the latter if you don't mind SMD packages)?

author: nockieboy
author_rank: Super Contributor
timestamp: July 27, 2017, 08:47:23 am
content: Hey grumpydoc - slight diversion from the current memory mapping discussion, but I was trawling your posts for hints and tips on said subject when I found this image:That's exactly the same PC-IDE adapter card I was having trouble with... I'm assuming it's working fine for you? Maybe I've got a dud card with the earthed RESET pin?If I can get one of those cards that actually works, the connection to the SBC would be much better via the IDE-GPIO than the current IDE cable and rat's nest of connecting wires.EDIT: It'll also make finding a PCB connector a damn sight easier to find, too!

author: grumpydoc
author_rank: Super Contributor
timestamp: July 27, 2017, 09:02:34 am
content: Quote from: nockieboy on July 27, 2017, 08:47:23 amDon't know yet.The board moved on slightly since then - I've changed it so that I can flip the CF card above the PIA/SIO. I've also finished placing all the sockets and power routing and am about 1/3 of the way through wiring the logic together. It ground to a halt a bit while I looked at the PM3394B CPU and digitiser boards for EHT

author: C
author_rank: Super Contributor
timestamp: July 27, 2017, 09:36:52 am
content: Quote from: grumpydoc on July 27, 2017, 07:36:48 am128k as that was stated ram size OP has.

author: grumpydoc
author_rank: Super Contributor
timestamp: July 27, 2017, 10:28:26 am
content: Quote from: C on July 27, 2017, 09:36:52 amYeah but 8 of them is a pain to wire up.It's even a bit of a pain to solder into a PCB, compared with a single package.

author: nockieboy
author_rank: Super Contributor
timestamp: July 27, 2017, 12:05:58 pm
content: Yeah I think for simplicity and cost a (couple of) 512Kx8(s) is the better option. I understand where you're coming from regarding the 1MB of memory space, but in reality I'm never likely to use anything close to that (my original intention was to build something roughly equating in size and power to my old Amstrad CPC464 that I had as a kid in the 80's. That was just a 4MHz Z80A-powered machine with 64KB memory. I've already doubled the processor speed and included CP/M which never factored into the stock 464.)Of course, since starting the project I've been hooked by learning huge amounts about digital electronics and the 'what if' and 'how much else can I squeeze onto this' mentality.There I was thinking I'd make a start on integrating the PSG, or SPI (yeah, the 464 never had that either), and instead I'm looking at massively increasing the available RAM. This isn't going to be a short project, but the amount of learning I'm doing is awesome.

author: C
author_rank: Super Contributor
timestamp: July 27, 2017, 04:13:54 pm
content: As to memory, it is easy to change if you make it that way. Your on a breadboard so some what already easy.Think of my solution above. It is just one way of doing it. It does the rom to ram change. You could have many banks of rom. Now break it down some.To change 0-16k from rom to ram for me is one added chip. You have Grants version. The 273 version of grant's for number of chips. Think you might find the 273 easer to understand. The point is powerful can be simple. And always many ways to do something.If you have looked at some of the expandable computers. Some you set jumpers to change hardware settings..Some use an 8-bit magnitude comparator such that a dip switch can change settings like address range.Now a logic signal can disable the 16k mapper. You would be using this to handle power up. But you could also use this another way.Grab a gate that 8 low inputs gives an output. Connect the inputs to A8-A15 on Z80 and you have a signal for 0-255 bytes address. This could disable mapper and enable common memory.One of my Z80's uses a 8-bit magnitude comparator to change address of common memory and memory based IO.A disable signal could let you have a second set of memory or put a IO port in middle of your ram..Quote from: nockieboy on July 27, 2017, 12:05:58 pmMight want to think on the areas you want to learn more about.How much could something your learning here help you in the future.Good to look at other ways to do things.For the 8080 an interrupt is forcing a call instruction on bus.The Z80 could do this, but Z80 chips like SIO are built for Vectors. And a vector is one byte where a call is 3 bytes.Most old computers with Video output used dual port memory built from normal memory. A dual port memory chip is great, With great cost for small size memory in one chip.In simple, There are many things you could learn from a Z80 & 68000.When you pick something to learn and do. look at other ways also. You might also think about how much what you learn could help in future.SPI is good for a CPU talking to Fast IO over few signals. But you have to read a byte to get status in place of reading a port. SPI slave has no way to slow the data rate but a status bit or status message.An SD card can function with High data rate, Can an ad Arduino supply or receive data at these rates as a slave?AY-3-8912 I would leave this chip to collect dust. Think most you learn here is just AY-3-8912 knowledge. But it's your choice.You are at a point where you can learn a lot about software.You are also at a point where many things hardware can be easer to do now.Think of this as a project, Connect your two Z80's so that it becomes more then a single Z80. To start with connect the two serial ports. Then add a port so one Z80 can reset the other. Each time when you add more RE think the hardware and Software. Can a change make it faster or more powerful?

author: C
author_rank: Super Contributor
timestamp: July 27, 2017, 05:34:56 pm
content: Now that you have Grant's CP/M running, what TPA size do you have for CP/M programs?

author: nockieboy
author_rank: Super Contributor
timestamp: July 27, 2017, 05:44:51 pm
content: Quote from: C on July 27, 2017, 05:34:56 pmGood question. Hmm... according to his documentation, the TPA area is 0100-D000. That equates to CF00, or just under 53KB. When I run Microsoft BASIC-85 Rev 5.29 under CP/M, it's reporting 29,752 bytes free.

author: C
author_rank: Super Contributor
timestamp: July 27, 2017, 06:10:49 pm
content: There is a software way to ask CP/M and it should show on CP/M boot also just so you know.53k Not real bad but not great.What you don't know is how much limited system space is slowing system.I would guess buffer sharing is being used which slows disk use.If your not going to do much that size TPA can work.You could learn a lot getting CP/M3 or turbodos running, both hardware & software.For me the important thing is to help you learn. To really do this you need to understand what is happening in software & hardware. How it works, What other options are there.It can be a real pain when you do not know something exists.So have fun and let me know how I can help.

author: nockieboy
author_rank: Super Contributor
timestamp: July 27, 2017, 06:55:22 pm
content: Quote from: C on July 27, 2017, 06:10:49 pmThanks C - certainly will do. For the moment I'm going to focus on the software and getting my monitor program rock solid (I still have much to learn with assembly, it seems!) Hardware-wise, I'm going to tidy up the breadboard a little and replace the jumper wires with more permanent wires. I've added in the FT232RL board already, so I don't need the flimsy USB/TTL lead any more and can use a standard USB cable. Having seen grumpydoc's image of the same CF-IDE adapter I was having trouble with, I'm considering getting a replacement in the hope that mine was, for some reason, faulty (with the earthed reset pin) as it will connect to the SBC much more easily than the current solution.No doubt I'll be back soon - but thanks for the memory management info, I'll certainly be looking into expanding the RAM in the system.

author: C
author_rank: Super Contributor
timestamp: July 27, 2017, 07:18:20 pm
content: Software wise the same thing can sometimes be done many ways.Grant's SIO initHe is using a series of OUT instructions. This makes a settings change to SIO hard( not need here just example)A different way would be to put in a data table and use a loop to output to SIO.When writing software, think of writing a book.When you write C you gain a little data of what goes in and comes out a function.Try to to better when writing assembly. Will save time later.Big comment blocks before each sub.

author: nockieboy
author_rank: Super Contributor
timestamp: August 04, 2017, 08:56:28 pm
content: Okay, preliminary schematic for the PSG (AY-3-8912) expansion for the SBC. This is being built on a separate breadboard.I'd welcome any feedback at all on the design - it's partly based on what I could find elsewhere on the interweb, but the interfacing control signal logic (such as it is) is my own creation. Looks like the AY-3-8912's BDIR, BC1 and BC2 are active high, so I've run the IOWR, IORD and signal from the Y1 pin on the '138 through an '04 inverter so they make sense to the PSG, whilst not confusing me too much.By my rough calculations, an OUT to address 08H (or anywhere in the 08H-0FH address range) will write to the PSG. An IN to address 08H will read from the PSG.However, whilst writing the above sentence I've spotted a possible issue. I need to get BDIR and BC1 both HIGH to latch an address in the PSG - which effectively means I have to get IOWR and IORD LOW at the same time which, if I'm not mistaken, isn't possible?!Here's the logic table for the PSG functions:IOWR IORD Y1BDIR BC1 BC2Inactive 0 0 1/0Read 0 1 1Write 1 0 1Latch Addr 1 1 1Any ideas how I can control the PSG as per the logic table above? There's another pin, A8, on the AY-3-8912 that acts as an additional pin for DA0-DA7 to double the memory range, but I'm not sure if I can use that at all to control access to the PSG... I'm a little stumped at the moment.

author: nockieboy
author_rank: Super Contributor
timestamp: August 04, 2017, 09:54:39 pm
content: Oh - turns out A8 CAN be used as an extra chip select as it has to be high, otherwise the bidirectional buffers go into high impedance.Still not sure how to solve the latch address control problem though.

author: grumpydoc
author_rank: Super Contributor
timestamp: August 04, 2017, 10:53:27 pm
content: Quote from: nockieboy on August 04, 2017, 09:54:39 pmBDIR is WR (i.e \$\overline{WR}\$ inverted so it is active high), BC1 and BC2 can be from A0and A1- you might need to gate them so that they are all 0 if the chip is not selected.Treat A8 as an active high chip select and drive it from the inverted output of a 74xx138 connected to the higher order address lines.EDIT: The datasheet notes that you can pull BC2 high and just use BC1 and BDIR.

author: nockieboy
author_rank: Super Contributor
timestamp: August 05, 2017, 11:01:55 am
content: Quote from: grumpydoc on August 04, 2017, 10:53:27 pmThanks grumpydoc - I'd forgotten I could use the address lines to control the chip too...Yes, I've got \$\overline{IOWR}\$ going to BDIR and \$\overline{IORD}\$ to BC1, both inverted, with \$\overline{Y1}\$ from the 138 going through an inverter to BC2. I'll pull A8 high by connecting it to Vcc through a 1K resistor (is the resistor is necessary?)I like your solution of using A0and A1to control BC1 and BC2, though for my setup I'd use A0to control BDIR and A1for BC1 as per my logic table earlier, with \$\overline{Y1}\$ controlling BC2 through an inverter.So, with that setup, the following should be true?* An OUT 09H should WRITE to the PSG* An IN 0AH should READ from the PSG* An OUT 0BH should LATCH ADDRESS in the PSG

author: grumpydoc
author_rank: Super Contributor
timestamp: August 05, 2017, 05:39:25 pm
content: Quote from: nockieboy on August 05, 2017, 11:01:55 amNow that I have had 5 minutes to think about this, the following should work:With A8 and BC2 pulled high and assuming \$\overline{SELAY}\$ is a suitable active-low decoded I/O select line.When \$\overline{SELAY}\$ is inactive (high) then BC1 and BDIR will be low, when the select is active BDIR will be WR as required. The fact that A0 is inverted does not matter - it just changes the address map so that it becomes:Base+0x00 (write) - latch addressBase+0x01 (r/w) - read/write to PSGWhich is IMO actually more logical.EDIT: the above is slightly wrong - see later posts.Have you thought about timings - your 8MHz Z80 is going to have \$\overline{WR}\$ active for a little over 250ns, for example, whereas the AY-3-8912 wants a minimum write pulse of 500ns.

author: nockieboy
author_rank: Super Contributor
timestamp: August 05, 2017, 08:16:39 pm
content: Quote from: grumpydoc on August 05, 2017, 05:39:25 pmI agree - but my way means one less logic chip and space is at a premium.In any case, at the moment it's likely circumstantial as your next comment leaves me some concern:Quote from: grumpydoc on August 05, 2017, 05:39:25 pmNo, I hadn't considered timings at all.I suppose getting a theoretically-working design was the first hurdle. I've even got it set out on breadboard and connected up to the SBC and have started on the assembly to get it making noise... Which presumably it won't be doing as the timings are going to be an issue..Okay, I'm off to start researching what I can do to sort this new problem out. Some sort of latch, perhaps, to hold the \$\overline{WR}\$ low for the requisite time? Remember though that I'm using \$\overline{Y1}\$ from the 138, A0and A1(for the time being.)EDIT:Something like this, perhaps to extend the pulse by RxC (or some proportional factor of RxC)?Or better still, something involving a 74HCT123 retriggerable monostable multivibrator?Is this the only timing problem that I'm likely to come across, though? I'm going to have to extend the pulses both address lines and Y1? Will the data bus be okay?

author: grumpydoc
author_rank: Super Contributor
timestamp: August 06, 2017, 07:06:01 am
content: Quote from: nockieboy on August 05, 2017, 08:16:39 pmFair enough.QuoteNo, you need to generate wait states.You could build it and try out with a Z80 clock speed of 4MHz - if that works you can go back to 8MHz and see what happens.

author: nockieboy
author_rank: Super Contributor
timestamp: August 06, 2017, 08:49:56 am
content: Quote from: grumpydoc on August 06, 2017, 07:06:01 amWait states? Something new to learn about there!Okay, so you're suggesting before I get too wrapped up in timings I should confirm it all works at 4MHz then try it at 8 as there's a chance it could still work and either way would save me a lot of hassle by not jumping the gun? I really need to change my methodology as I'm in too much of a rush to get it working all the time!The only consideration I can think of is that the serial comms speed will need to be halved if I do that, otherwise it should be pretty straightforward, I'm hoping?Will let you know how it goes!

author: grumpydoc
author_rank: Super Contributor
timestamp: August 06, 2017, 09:50:38 am
content: Quote from: nockieboy on August 06, 2017, 08:49:56 amWe have seen with some of Grant's designs that he has run older peripheral chips much faster than their design speeds but has got away with it - so you might be lucky.That said you should probably budget a couple of 74xx74's and a couple of gates to generate the wait states if necessary.Or drive the whole thing from a Z80 PIO and bit-bang the control signals.

author: grumpydoc
author_rank: Super Contributor
timestamp: August 06, 2017, 03:42:00 pm
content: OK.The following will add two wait states to any I/O cycleIt is based on the circuit in the Z80 user manual for adding wait states to the M1 cycle - but with an extra 1 clock cycle delay before de-asserting \$\small\overline{WAIT}\$. I'm not sure if it is possible to do two wait states with just two flip-flops.The timing is as follows, TW0is the automatically inserted wait state generated by the CPU TW1and TW2are the two additional wait states.EDIT: Oops, the 2nd "T1" should, obviously, be "T2"This stretches the active length of the I/O cycle with an 8MHz CPU clock to about 550ns - which should be fine for the AY-3-8912.If you don't want to slow all I/O cycles use a select signal generated from \$\small\overline{IORQ}\$ and relevant address lines rather than just \$\small\overline{IORQ}\$ as input to the 1st flip-flop.

author: nockieboy
author_rank: Super Contributor
timestamp: August 06, 2017, 06:48:34 pm
content: Quote from: grumpydoc on August 06, 2017, 03:42:00 pmWow, thanks grumpydoc, that's awesome!I've just written a test routine in my monitor ROM code to write a value to the PSG IO port and read it back. I've yet to burn it to the ROM and test it, but I'm guessing it'll be a quick test (without writing the routines to play sounds) to see if the AY-3-8912 can handle 8MHz. If not, I'll run the SBC clock through a divide-by-2 flip-flop to drop the clock under 4MHz (it'll be 3.62..blah MHz instead, but the pulse widths should be fully compatible with the PSG then.) If and when it works at that speed, I'll get to work on your wait-state solution and bump the clock speed back up to 8MHz.Out of interest, are there any more modern versions/alternatives of the AY-3-891x PSG chip?

author: nockieboy
author_rank: Super Contributor
timestamp: August 07, 2017, 12:14:50 pm
content: Hmm, okay, it seems that it doesn't like 8MHz - no surprises there, really. I've tried reading and writing to the IO port on the 8912, but it's not playing. If I read Port A I'm getting FF or 00, seemingly randomly, as values no matter whether I ground one of the IO pins or not. Writing to the IO port after setting it up as an output also seems to have no effect - the pins are all high irrespective of what values I write to the port.Just for info (and in case I'm making an error in the way I'm accessing the PSG), below is the code I've written to test reading/writing to the IO port:Code:CPSGOUT:POPHL; Get command line pointerCALLGETBYTE; Get 1-byte value from command line into ELDHL,AYPWRITE; Display the port write textCALLMPRINTLDA,E; Load value into ACALLPHEX; Display it as a hexadecimalLDA,'H'; ...with an 'H' on the endCALLTXA; Set IOA to OUTPUTLDA,07H; Select address R7 (ENABLE register)OUT(AY_LATCH),A; Latch address R7LDA,40H;OUT(AY_WRITE),A; Set R7 to 40H (IOA set to output - bit 6 HIGH); Set value in IOALDA,0FH; Load A with Register 16 (IO Port A)OUT(AY_LATCH),A; Latch Register 16 in PSGLDA,E; Load A with value from GETBYTEOUT(AY_WRITE),A; Write value to PSGJPCOMMAND; Return to Direct Mode CLICPSGIN:POPHL; Dump command line pointerLDHL,AYPREAD; Display read textCALLMPRINT; Set IOA to INPUTLDA,07H; Select address R7 (ENABLE register)OUT(AY_LATCH),A; Latch address R7LDA,0OUT(AY_WRITE),A; Set R7 to 0 (IOA set to input - bit 6 LOW); Read IOALDA,0FH; Load A with Register 16OUT(AY_LATCH),A; Latch Register 16 in PSGINA,(AY_READ); Read register R15CALLPHEXLDA,'H'CALLTXAJPCOMMAND; Return to Direct Mode CLI

author: nockieboy
author_rank: Super Contributor
timestamp: August 08, 2017, 07:00:38 pm
content: After a little more playing around and dropping the SBC's clock to 3.6864 MHz, changing the BC2 input from just an inverted Y1 to Y1 AND IORQ to reduce false activations of the PSG and re-writing the IO routines slightly (IOA is 0Eh, or register 15 not 0Fh, register 16) I have managed to get some values read from IOA that match up to what I've set up on the breadboard.Here's the rewritten code I'm using:Code:CPSGOUT:POPHL; Get command line pointerCALLGETBYTE; Get 1-byte value from command lineLDHL,AYPWRITE; Display the port write textCALLMPRINTLDA,E; Load value into ACALLPHEX; Display it...LDA,'h'; ...with an 'H' on the endCALLTXA; Set IOA to OUTPUTLDA,$07; Select address R7 (select ENABLE register)OUT(AY_LATCH),A; Latch address R7LDA,40H;OUT(AY_WRITE),A; Set R7 to 40H (IOA set to output); Set value in IOALDA,0EH; Load A with Register 16OUT(AY_LATCH),A; Latch Register 16 in PSGLDA,E; Load A with valueOUT(AY_WRITE),A; Write value to PSGJPCOMMAND; Return to Direct Mode CLICPSGIN:POPHL; Dump command line pointerLDHL,AYPREAD; Display read textCALLMPRINT; Set IOA to INPUTLDA,$07; Select address R7 (select ENABLE register)OUT(AY_LATCH),A; Latch address R7LDA,0OUT(AY_WRITE),A; Set R7 to 0 (IOA set to input); Read IOALDA,0EH; Load A with Register 16OUT(AY_LATCH),A; Latch Register 16 in PSGINA,(AY_READ); Read register R15CALLPHEXLDA,'h'CALLTXAJPCOMMAND; Return to Direct Mode CLISo it seems reading IOA is working, albeit not quite 100% of the time (sometimes I just get FF returned instead of a smaller value determined by the grounding resistors I've placed on the IO pins).Setting IOA to output and sending a value to it doesn't seem to be doing anything - so I'd appreciate some comments from anyone who knows anything about interfacing an AY-3-8912 to the Z80. All the IO pins seem to be high, no matter what value I send to the IO port. I'm wondering if I'm using the wrong value (40h) to send to Register 7 - it should be specifying bit 6 high to set IOA into an output state, but I'm not sure that's happening, or even if 07h is the right address to latch to set the enable values in register 7....?

author: grumpydoc
author_rank: Super Contributor
timestamp: August 08, 2017, 08:43:08 pm
content: Can you post the exact arrangement for driving BDIR, BC1, BC2 and A8/9 if applicable?

author: nockieboy
author_rank: Super Contributor
timestamp: August 08, 2017, 09:13:52 pm
content: Quote from: grumpydoc on August 08, 2017, 08:43:08 pmSure.. see below:First, the image above shows the '138 setup (IO addressing) on the SBC as per Grant's CP/M schematic. My SBC IO is identical to Grant's schematic. I'm using Y1 on the '138 to control chip select on the AY-3-8912 (via pin BC2) - this equates to an IO address range of 08h-0Fh, if my calculations are correct.Next - the PSG circuit (focusing on the SBC interface):Above is a closeup of the interface for the PSG. As you can see, BC1 is driven by A1, BDIR by A0, and BC2 (which should be HIGH for the PSG to do anything) is driven from an inverted signal from ~IORQ and ~Y1.This should, if I'm right (a big if I know!), give me the following addresses for the following commands:So, to write to the PSG, I'd use OUT (09H),value. Address 09 is within the IO range of the PSG (being 08-0F), so Y1 will go low (which is high after the inverter) and BDIR will go high as it's driven by A0, providing the WRITE command to the PSG.That's the plan, anyway...

author: grumpydoc
author_rank: Super Contributor
timestamp: August 08, 2017, 09:43:43 pm
content: OK, so BC2 will be low unless both \$\small\overline{IORQ}\$ and \$\small\overline{Y1}\$ are low - that's fine.But BC1 and BDIR are just driven from A0 and A1, lets have a look at the command table in the manual:BDIRBC2BC1000Inactive001Latch address010Inactive011Read100Latch address101Inactive110Write111Latch addressJust concentrate on the entries with BC2 = 0BDIRBC2BC1000Inactive001Latch address100Latch address101InactiveAs you can see even when BC2 is low you can latch an address, in fact any time A0 != A1 - so there's a good chance that the LD A after the write that youintendedto latch the address for the register will cause a different address to be latched. There are three opportunities for doing so - the M1 cycle of the LD, the refresh, and the read of the operand - in fact either the M1 or the opcode read is guaranteed to have A0 != A1 and the refresh will have that pattern two cycles out of four. And if that instruction doesn't mung things it will probably happen (again) as you read the opcode for the OUT and then as you read the operand for the port number.You need to make sure that an inactive combination is presented on BDIR, BC1 and BC2 any time the AY-3-8912 is not selected. I think I suggested as way of doing that a couple of posts back.EDIT - I did but I got it wrong, it should have beenBC2 and A8 should be tied high.If the select ( \$\small\overline{IORQ}\$ + \$\small\overline{Y1}\$ in your case) is active low then when inactive (high) it will force BC1 and BDIR low, i.e when the chip is not selected.For some reason I drew it out for an active high select then wrote an active low one in

author: nockieboy
author_rank: Super Contributor
timestamp: August 09, 2017, 09:12:43 am
content: I overlooked my inexperience with this stuff and didn't think of the obvious - that the PSG was being latched/read/written to inadvertently by the ungated A0and A1lines!Thanks grumpdoc, as usual you're spot on.Question though regarding the proposed solution - given my existing setup, would it be sufficient to take the inverted input to BC2 and connect that to A8, and instead pull BC2 high by connecting to Vcc?That way, A8 will be held low all the time the PSG isn't being accessed (and, if I've read the manual right, should effectively disable the PSG). When the CPU wants to latch, read or write the PSG's registers, A8 will go high and the PSG will be available (as BC2 is permanently held high), leaving A0and A1to select the correct function through the BC1 and BDIR pins...?That way I can save adding any extra logic chips and just swap a couple of wires...EDIT: Hmm... no, that appears not to be working either.

author: grumpydoc
author_rank: Super Contributor
timestamp: August 09, 2017, 09:40:02 am
content: Quote from: nockieboy on August 09, 2017, 09:12:43 amI was going to say give it a goThe way I read the datasheet it wasn'tcompletelyclear that having A8 low deactivated the chip, rather than just the data bus buffers.Edit: Though I suppose it should given the intended CPU interfacing. However to be certain I'd make sure that BDIR/BC1/BC2 are forced inactive when you don't want to talk to the chip.

author: nockieboy
author_rank: Super Contributor
timestamp: August 09, 2017, 11:03:37 am
content: Quote from: grumpydoc on August 09, 2017, 09:40:02 amI don't seem to be getting any consistency in the results or even results that I would expect. With the change I made in my last post, I'd have thought the IO from the chip would at least be predictable - having A8 low should make the buffers inactive and thus prevent any miscellaneous signals from reading/writing or latching the PSG unintentionally. Instead, I'm just getting 00 as a result from the IO port.It doesn't help that I'm not sure which IO register I should be addressing... According to the datasheet, Registers R16 and R17 control IOA and IOB. I'm using an 8912 which only has IOA, so R16 is the logical register for addressing the IO port, which should be 0F. However, I've read elsewherehttp://forum.6502.org/viewtopic.php?f=4&t=3339&sid=9ab9958abd00ad39541ab00a72050380&start=15that the registers should be dropped by 02 - so R16 for IOA becomes 0D??So I should do the following to read from IOA:Code:LDA,$07; Select address R7 (select ENABLE register)OUT(AY_LATCH),A; Latch address R7LDA,0OUT(AY_WRITE),A; Set R7 to 0 (IOA set to input); Read IOAOUT(AY_LATCH),0DH; Latch Register 14 in PSGINA,(AY_READ); Read register R14But that is just returning 00 as well. (I'm reading a value from memory for the IO register, so I can just POKE 0D, 0F, or whatever to that location and when I read the IO port it gets that value and uses it as the register to latch, making testing different register values much quicker.) I can't seem to replicate my results yesterday when I was (albeit not totally reliably) able to get values from the IO port.I'm running the clock through a flipflop configured as a clock divider, which is halving the SBC clock from 3.68 MHz down to 1.84 MHz, well within the stated 1-2 MHz clockspeed for the PSG. The audio circuit is circumstantial as I'm testing the PSG's IO first. The PSG is otherwise a simple data bus connection to the SBC and control signals for BC1, BC2 and BDIR. I'm hoping it's just very particular about how those control signals are managed.I'm going to implement your suggestion, grumpydoc and see if that works.

author: nockieboy
author_rank: Super Contributor
timestamp: August 09, 2017, 03:20:59 pm
content: Okay, this is how I've interpreted your solution, grumpydoc - I hope it's correct. Ironically, if I'm reading your solution properly, it means I can drop the inverter and replace it with the NOR gate, so the chip count remains the same.Is this what you're suggesting? So long as ~Y1 and ~IORQ remain high, BC1 and BDIR will be low. But when the PSG is being accessed, ~Y1 and ~IORQ will go low, allowing either (or both) A0and A1to pass a high through to the PSG to read/write/latch as appropriate - am I right?

author: grumpydoc
author_rank: Super Contributor
timestamp: August 09, 2017, 03:59:11 pm
content: I'd drive BDIR from \$\small\overline{WR}\$ but I don't see why driving it from A0would not work.

author: C
author_rank: Super Contributor
timestamp: August 09, 2017, 04:04:02 pm
content: Am I messing something or are you?Grant's 138 is just address decode. So any time Y1's address range appears on bus then Y1 goes low. This could be anything and includes the time from one address changing to a different address.Y1 output is noise or garbage.This only becomes valid when gated with more signals.Each IO access to AY-3-8912 must have two of three signals valid low to be a valid IO read or IO write..IORQ & RD is one and IORQ & WR is second.IORQ by it's self is not enough as IORQ goes low at other times then just IO read & write.Now think about what is happening now!What is keeping two things from responding when RD is low and only one device on data bus should be active?Is the AY-3-8912 being told to drive the data bus for a memory read of ??08H to ??0FH?Even this is not correct because only IOWR is used.So AY-3-8912 drives data bus any time IOWR is high and ??08H to ??0FH is on address bus.I see no use of RD in access of AY-3-8912.Grant creates two signals that must be used if you are not using the Z80 signals directly. IORD & IOWRI see you needing to use 138 Y1 low AND ( IORD low OR IOWR low ) as a chip select signal.A0 should be used to select between the two data bus ports on AY-3-8912You have a read & write data port.You have a write address port with read address port not used.Quote from: nockieboy on August 09, 2017, 03:20:59 pmHere you are not using RD or WR, so what address is used sets data bus direction of PSG.You would look at all states of Z80 to verify that when PSG is driving bus nothing else will.When is data bus written to PSG?A low to high of WR is the Z80 normal transition. Here you have IORQ going high as a PSG write transition and end of PSG read. Again timing matters and needs to be checked

author: grumpydoc
author_rank: Super Contributor
timestamp: August 09, 2017, 04:25:15 pm
content: Quote from: C on August 09, 2017, 04:04:02 pmUsing A0 to drive the bus direction is unusual, certainly, and I would choose to use WR as I have said a couple of times but it would actually work - as long as one address is always used for read and one for write.QuoteAh, yes - I was forgetting something myself. IORQ is active with M1 to indicate an interrupt acknowledge so, yes, you are right as it stands there can still be problems. I get so used to running IORQ and M1 into the enable pins on I/O decode that I didn't think about this - Grant's design does not do so and you need to make sure that the select is not active if M1 is low.

author: nockieboy
author_rank: Super Contributor
timestamp: August 09, 2017, 04:35:38 pm
content: Quote from: grumpydoc on August 09, 2017, 04:25:15 pmI was wondering if something else was going on, but don't know enough about the system to have spotted it. One question I have about Grant's I/O decode design though - and it's been bugging me since I moved from the v1 (non-CP/M) SBC to the v2 one - and that's why doesn't he have IORQ and M1 going to the enable pins on the '138?Anyhow - the SIO/2 is interrupt driven on the Rx side, so that's likely causing problems with the interrupt causing chaos with the PSG. So, another gate is required for the PSG select signal (currently ~Y1 and ~IORQ) to ensure the PSG is not active when M1 is low?

author: nockieboy
author_rank: Super Contributor
timestamp: August 09, 2017, 04:39:27 pm
content: Quote from: grumpydoc on August 09, 2017, 04:25:15 pmI only went with using A0and A1as it was the first solution that sprang to mind with needing to be able to read, write AND latch using only 2 lines. If there's benefits to using ~WR instead of A1(presumably) then let me know and I'll change the design - it's only a few equates I need to change in the assembly.

author: C
author_rank: Super Contributor
timestamp: August 09, 2017, 05:33:38 pm
content: Quote from: nockieboy on August 09, 2017, 04:35:38 pmThere is a lot about Grant's design I do not care for.When using 374's for IO the common practice is to have two 138's used. One would have RD as final signal to enable 138 outputs, while other uses WR.In front of this would be an additional 138. Timing then determines where IORQ is connected. Connected to first two is great as you have most time for a stable address.But if you are using chips like SIO, it can be better to connect IORQ to the last 138.So first two 138's gives you 8 input & output ports jusing A0-A2Third 138 uses 3 more address lines A3-A5Now if you look at 139, you see a dual 1 of 4 so 1 139 can give you 4 IO read write ports. This matches better with chips like SIO that need two address lines and makes using some SIO,PIO and others along with ports based on 374'sThe above is built to expand while working with the Z80.There are good reasons to have separate WR & RD signals like Z80 uses compared to one signal like some CPU's use. One problem is when is the combined RD/WR valid. With separate signals valid & signal are one.Like I saiduse IORQ & RD for IO Readuse IORQ & WR for IO Write.and you will not need to worry about other times IORQ goes active with a good design.When you do not do this then you have to worry more about things like PSG read driving data bus while the Z80 starts driving the data bus for next bus step..Need to look real close if your logic can create a glitch.For example PSG can go from idle to write mode with no actual write then read mode for a Z80 read.It is BAD For example to have PSG go from idle to read mode then write mode for a Z80 write. You have Z80 & PSG both driving bus for a time.Best to us RD to enable PSG to put data on Data bus.Best to use WR to write data into PSG with the actual write happening on rise of WREdited to add Problem above

author: grumpydoc
author_rank: Super Contributor
timestamp: August 09, 2017, 07:36:47 pm
content: Quote from: nockieboy on August 09, 2017, 04:39:27 pmIt violates the law of least surprise (but only a little) as it means that you have to read/write the same data at different addresses.It also means that a software bug has the capacity to damage the hardware (by writing to a "read" address) - which isnever a good ideaQuote from: C on August 09, 2017, 05:33:38 pmAgree but he is mostly aiming for a minimalistic design, so corners are going to be cut.QuoteIf you only have to interface to a few LSI peripheral chips then the scheme you propose is overkill - and most Z80 systems being designed today are going to be fairly modest, not complex systems on acres of PCB with loads of I/O built from discreet buffers and latches.A single 138 arranged to split ports 0x00-0x7F into 8, 8 port chunks is a very good starting point. It should use M1 and IORQ iinto the enable pins to ensure the select lines thus generated are only active during an I/O cycle to that address block.QuoteOK, but the AY-3-8912 has a single input specifying bus direction, not two. You can drive it from either RD directly or WR inverted but not both.Driving it from A0is not great because if you try to write to an even address you will have a bus contention at that point - however if you are careful to always choose the correct address it will work - but I have never proposed driving it from an address line.As a generalisation you do not always need to look at \$\small\overline{WR}\$and\$\small\overline{RD}\$ - if you have decoded the I/O cycle correctly you can assume "if not a read then it's a write" and also "if it's not a write then it's a read".As to glitches - OK, well the 8MHz Z80 guarantees 75ns of address set up time and 20ns of address hold time relative to \$\small\overline{IORQ}\$ - the start of the I/O cycle is safe enough as is the end with "typical" 74LS138 propagation delays but if you want to design to cover worst case you might want to stick a 74ALS138 in there or a 74AC(T)138.For a read cycle there is no additional delays to consider - \$\small\overline{WR}\$ will be high throughout, for a write cycle there is the fact that the Z80 spec does not say anything about the edge of \$\small\overline{WR}\$ compared with \$\small\overline{IORQ}\$ - just that both are referenced to the rising edge of the clock at the start of T2 (max 55ns delay for \$\small\overline{IORQ}\$ and 60ns for \$\small\overline{WR}\$) - so \$\small\overline{WR}\$couldfall after IORQ and generate a short glitch where the AY-3-8912 is being told it is a read cycle and asked to drive the bus when the Z80 is also doing so. However the delay through the LS138 should save us here because we apply \$\small\overline{WR}\$ directly to the NOR gate but (effectively) \$\small\overline{IORQ}\$ delayed through the '138 - thus, in practice, \$\small\overline{WR}\$ will have settled before we gate it through to BDIR.

author: nockieboy
author_rank: Super Contributor
timestamp: August 10, 2017, 01:55:37 pm
content: Okay guys, I have to admit to half of the conversation so far completely going over my head.So I just need to redesign the interface, using ~WR and A0for BDIR and BC1 respectively, and gate those two signals with ~IORQ and ~M1 somehow to ensure that BDIR and BC1 are held LOW, no matter what ~WR and A0are doing, if ~M1 is LOW or ~IORQ is HIGH?

author: grumpydoc
author_rank: Super Contributor
timestamp: August 10, 2017, 02:30:19 pm
content: I think what I would suggest is the followingConnect \$\small\overline{M1}\$ to the active high enable of the 138, OR together A6and A7and connect the resulting signal to one of the active low inputs to the 138, and connect \$\small\overline{IORQ}\$ to the other.That will give you a set of clean I/O select lines to use and will not change the decoded address ranges.Then gate A0and \$\small\overline{WR}\$ to BC1 and BDIR as suggested, with BC2 and A8 tied high, A9 tied low.That should give you clean signals to drive the sound chip - note that with BC1 and BDIR both low the AY-3-8912 buffers are high impedance so you don't need to use A8/A9 as additional chip selects.If you can't make the modifications to the 138 enable inputs then youcouldconnect M1 to A8 but it would be better to have all the I/O address select lines active only during an I/O cycle and not accidentally during an interrup acknowledge.

author: C
author_rank: Super Contributor
timestamp: August 10, 2017, 03:01:29 pm
content: data sheet[http://map.grauw.nl/resources/sound/generalinstrument_ay-3-8910.pdf/url]I see some problems with DA7-DA0 when directly connected to Z80 data bus.#1 a Z80 Read from AY-3-8912Fig. 11 Tristate Delay Time (Tts) = 400 nsPSG driving data buss after Z80 read#2 a Z80 Write to AY-3-8912Fig. 10 Write Data Hold Time (Tdh) = 400 nsPSG needing data stable after end of Z80 Write#3 a Z80 Write address to AY-3-8912Fig. 9 Address Hold Time(Tah) = 50 nsPSG needing data stable after end of Z80 WriteI should not leave out the Write to PSG time of 1950 ns.For #1 A Tristate buffer between Z80 & PSG DA7-DA0 might work.For #2 & #3 a data latch between Z80 & PSG DA7-DA0 might work.A latch is probably needed for PSG's Bus Control Decode.This now looks more like what a 8255 or PIO does, but could be done with standard logic. You might think of this as bit-banging or creating the interface bus.Quote from: nockieboy on August 10, 2017, 01:55:37 pmWhen things are going over your head, Say something & ask questions.1. As long as you use the Z80 as it is designed to be used, then M1 is not needed for a IO read or write.WR's rising transition is when actual write should happen. Data direction is fromZ80. The data written should be stable before this time and meet timing needs of chip being written.RD is used to put data on data bus with direction to Z80 One driver per line of data bus. For example for memory that is many chips, only one can have and enabled path back to Z80. This is normally one 8-bit wide memory chip.MERQ & IORQ are selectors of which address space is to be used. These signals also specify when address bus becomes a valid stable address.Quote from: nockieboy on August 10, 2017, 01:55:37 pmWith the timings above and need of latches, buffers, a PIO is low chip count interface. The Z80 software working with PIO needs to create proper timing for PSG.

author: grumpydoc
author_rank: Super Contributor
timestamp: August 10, 2017, 04:38:40 pm
content: Quote from: C on August 10, 2017, 03:01:29 pmI'm not clear where you get 1950ns from - the write pulse for the AY-3-8912 is 500ns. The AY-3-8913is much slower, needing a 1800ns write pulse.For the record I also suggested a PIO and bit banging the interface as a possibility but I don't see why interfacing direct to the Z80 should be a problem. Largely because that is the way I did it as a teenager and it worked just fine. At least it did with a 4MHz Z80, it will need wait states at 8MHz though, as previously noted.I'll try to look at the timing diagrams in detail this evening, but have a few other things to sort first.

author: C
author_rank: Super Contributor
timestamp: August 10, 2017, 05:32:09 pm
content: In scrolling around got the values from AY-3-8913 section#1 a Z80 Read from AY-3-8912Fig. 11 Tristate Delay Time (Tts) =400 ns200 nsPSG driving data buss after Z80 read#2 a Z80 Write to AY-3-8912Fig. 10 Write Data Hold Time (Tdh) =400 ns100 nsPSG needing data stable after end of Z80 Write#3 a Z80 Write address to AY-3-8912Fig. 9 Address Hold Time(Tah) =50 ns100 nsPSG needing data stable after end of Z80 WriteI should not leave out the Write to PSG time of1950 ns650 ns.650 = Tdw + Tds+ Tdh

author: nockieboy
author_rank: Super Contributor
timestamp: August 10, 2017, 07:58:33 pm
content: Quote from: grumpydoc on August 10, 2017, 02:30:19 pmWhat I'm getting from all this is the existing IO decoding setup in Grant's design, whilst fine for the job it is designed for, isn't up to the task of handling the sort of IO I'm planning to implement.I'm not entirely sure why he went with the design he did and didn't keep to the non-CP/M design which seemed much more robust, but I can't ask him and may never know.In any case, a redesign of the IO decoding is in order and I intend to follow grumpydoc's suggestion, at least if it doesn't change any of the existing address functionality.So I'm going to make some changes to the IO decoding and then will come back to the PSG problem after I've fully tested the new IO setup. I'm away this weekend though so it might be a few days into next week before I can update progress.

author: nockieboy
author_rank: Super Contributor
timestamp: August 10, 2017, 09:06:14 pm
content: Okay grumpydoc, if my interpretation is correct, the image below should show the correct schematic for the improved IO decoder:If this is correct, I'll get to work on it next week. I'm assuming this will still play nicely with the existing peripherals, namely the SIO/2 and CF card as per Grant's circuit?

author: grumpydoc
author_rank: Super Contributor
timestamp: August 10, 2017, 09:31:06 pm
content: Looks OK.

author: grumpydoc
author_rank: Super Contributor
timestamp: August 10, 2017, 11:15:29 pm
content: RightI have had a look in detail at the timing and I now agree that C has some valid points regarding interfacing with an 8MHz Z80. Some of these issues also affect the 4MHz Z80 somewhat so in practice might not be show stoppers given that I had a working sound card despite technically violating the timing constraints.Now we are definitely going to need wait states at 8MHz so I am discussing the timing with that in mind - the I/O cycle timing (loosely to scale with typical propagation delays) looks like this.Compare this with the AY-3-8912 timing diagrams, first of all the latch address timing.The address is obviously latched as BC1 and BDIR switch back to the inactive state, there are just two timing valuesTAS- the address set up time before the data is latched andTAH- the hold time for which the DA0-DA7must remain valid.TASis easily met, the AY-3-8912 spec is 400ns and we have 4\$\small\frac{1}{2}\$ clocks or 560ns at 8MHz so that is fine.TAHhowever,isa bit of a problem because the 8MHz Z80 only guarantees 15ns of data hold time and the AY-3-8912 wants 100nsLet's look at the write data timingHere we have TDS- data setup, TDW- the write pulse width and TDH, the data hold time.The write pulse width is OK, we have 560ns and need a minimum of 500ns - that box is ticked.Then it starts to fall apart. The data setup time is 100ns and, well, the Z80 does not, in fact guarantee that the data is valid when \$\small\overline{WR}\$ goes low. The data hold time has the same problem as the address hold time.Finally read timingThe access time is actually just about OK - the maximum is 500ns and we do just have 500ns to the point where we need the data to be valid, typical is 250ns though which is plenty fast enough.The tristate delay does mean we could be pushing data onto the Z80 bus well into T1 of the next cycle at 8MHz.So we have three problem areas, the data hold time on a latch address or data write cycle, the data setup time on a write and the tristate delay - so that's the three places that C identified plus the data setup time issue.Do these matter?Well, we would design to these times if we want a robust system but I have the following thoughts.First off I don't think the tristate delay is significant, at least not for the typical value of 100ns - the cycle following the I/O read will be an opcode fetch - the only way it can be anything else is if you are executing an INI or INIR in which case it will be a memory write (you could take an interrupt, of course) - but nothing very interesting happens on the bus in T1 so the sound chip not having got around to turning its output buffer off is not that big a deal. At 4MHz or slower it definitely isn't going to be an issue, at 8Mhz it should still be OK but I don't think I would push it any further.Then there is the data hold time. Well, that could be an issue but I "got away" with it with a 4MHz CPU where the Z80 guarantees 60ns of data hold time. In fact if I have calculated it correctly the 8MHz part is better when run at 4MHz as it then has a data hold time of 80ns - and don't forget nockieboy went down to 1.8MHz at which point I think he will actually meet the 100ns.Finally that data set up time - why is it in the spec in the first place? There isn't an equivalent on the address latch cycle and it's clear the data is latched as BC1/BDIR switch to "inactive" so I find that just odd. It might be worth noting that I "got away" with that one as well.So I think it is still worth pursuing the current build (I must get back to my own system build as well). At 1.8Mhz I think that all of the PSG timing constraints will be met except the data set up time but I genuinely can't see why the PSG needs that. If it works at 2 or 4MHz and fails at 8 then you know the issue is clock speed.If it won't work at 8MHz then answer probablyisto use a PIO to talk to it.

author: C
author_rank: Super Contributor
timestamp: August 11, 2017, 01:08:16 am
content: Quote from: grumpydoc on August 10, 2017, 11:15:29 pmZ8400, Z84C00 Specificationhttp://www.zilog.com/docs/z80/ps0178.pdfpage 31 Number 33Data stable prior to WR fail range is -10 to -55 nsThis is for IO WriteThe Write Data is on data bus while WR is low.nockieboyWhile working on address decode, you might want to take a Quick look at some other chips.74HC139; 74HCT139. Dual 2-to-4 line decoder/demultiplexerassets.nexperia.com/documents/data-sheet/74HC_HCT139.pdfSN54/74LS682, 684, 688 8-BIT MAGNITUDE COMPARATORShttp://www.uni-kl.de/elektronik-lager/417899Back in the day, you might have many boards all the same but at different addresses. By using a Comparator you could have a dip switch to set the address in place of a patch field or jumpersYou could also set the address with logic.

author: grumpydoc
author_rank: Super Contributor
timestamp: August 11, 2017, 07:25:53 am
content: Quote from: C on August 11, 2017, 01:08:16 amI've never been 100% sure how to interpret those negative numbers but the times given for the memory write cycle start out positive which I have interpreted as the data being stable for that amount of time before \$\small\overline{WR}\$ goes low - so I read those negative numbers as indicating that the data might not be stable at the falling edge of the write pulse - after all the business end of write is the rising edge.

author: nockieboy
author_rank: Super Contributor
timestamp: August 11, 2017, 07:56:09 am
content: Quote from: grumpydoc on August 10, 2017, 11:15:29 pmHoly cow, you weren't kidding!What do you use to produce those timing diagrams, grumpydoc?It's pretty clear the AY-3-891x series weren't created with the Z80 specifically in mind (the manual mentions a CP1610 or something similar - a CPU made by GI, anyway, and clearly the interfacing was setup for direct connection to that CPU.) Thinking about it, the schematics for my old CPC series of computers show the AY connected via an 8255 PIO.Quote from: grumpydoc on August 10, 2017, 11:15:29 pmJust for the record, I've got an 8MHz Z80 (currently) running at 3.6864MHz. The clock to the PSG is halved down to 1.8432MHz, though I'm not entirely sure if the clock affects anything in the PSG other than tone/noise/envelope generation frequencies? I could be wrong though - I suppose it needs some sort of clock pulse to time the IO and bus control circuits?C - you mentioned looking at other parts like the 74HCT139? I've got to take an excited 6-year old to the beach for some rock pooling shortly so I haven't got time to check the datasheets out yet. Would that offer benefits with regard to the timing or something else?As always - thanks for the help guys, I really appreciate the expertise and time you're providing to an electronics luddite like me.

author: grumpydoc
author_rank: Super Contributor
timestamp: August 11, 2017, 11:57:55 am
content: Rockpooling sounds much more fun.I generally draw diagrams inInkscape, I guess I should use a better tool and it was a pain at first but I have a fair few diagrams drawn now so I can just cut 'n' paste between them.The AY-3-891x diagrams are just cut from the datasheet and resized.I need to learn to use a decent electronics CAD package but haven't found a free one which I'm comfortable with.Timing diagrams are modelled on the ones in theZ80 User Manualwhich are nice and free of clutter.The timings that C refers to come from theZ80 datasheet- those have much more detail and extensive annotations giving precise signal delays but are quite a bit harder to follow.Quote from: nockieboy on August 11, 2017, 07:56:09 amAh, that was where the 1.8MHz came from - I still suspect that the interface should work at 3.6MHz, 8MHz might be pushing it.QuoteIt's very similar to the 138 except that it is a dual 2-line to 4-line decoder, timing is going to be the same. Sometimes splitting the function into two two bit halves is useful but it limits the enable input to a single active low input for each half.

author: nockieboy
author_rank: Super Contributor
timestamp: August 11, 2017, 12:40:44 pm
content: Quote from: grumpydoc on August 11, 2017, 11:57:55 amThat may well be, but I've come back with a nasty case of crabs...Quote from: grumpydoc on August 11, 2017, 11:57:55 amHave you triedDipTrace? I've had a go with most of the free electronics CAD programs (well, Eagle and KiCAD) and have gotten on far better with DipTrace than either of the other two. The pin count in the free version can be a little restrictive (you're restricted to 300 pins), but I sent them a nice e-mail asking about a home hobbyist (non-commercial) licence, and they sent me a registration key that upped the limit to 500 pins. Not a great difference, but enough for me to be able to completely plan out my Z80 SBC. It just seems a lot more logical and easy to use than the competition too, but each to their own.It doesn't do chip timings though - I don't know if any of the free CADs would do that - but now you've given me the nugget of an idea for a program to write, if I ever get enough spare time to write it.Quote from: grumpydoc on August 11, 2017, 11:57:55 amWell, we'll find out fairly soon hopefully.Quote from: grumpydoc on August 11, 2017, 11:57:55 amOh okay, I thought C was mentioning it as the timings would assist. Well, anyway, there's a chance I can get the IO decoder changes sorted today, so that's the most pressing task on my to-do list at the moment.

author: C
author_rank: Super Contributor
timestamp: August 11, 2017, 01:20:20 pm
content: 1 of 2Dual 1 of 4 1391 of 8 1381 of 16 _____Just knowing others exist is goodThe 139 attached to your 138 could give you 4 inputs & 1 outputs using RD & WRWhere a 138 would be input or output only when you attach one of TD or WRMAGNITUDE COMPARATORSKnowing they exist and can make things easerFor example, An 8-bit MAGNITUDE COMPARATORS would let you select a 256 byte block of Z80 memory and a program could change what 256 byte block

author: nockieboy
author_rank: Super Contributor
timestamp: August 11, 2017, 01:38:26 pm
content: Hmm okay, I've made the changes to the IO decoder as outlined previously and the SBC now won't boot or show anything on the terminal. Doesn't seem to be receiving or sending from the SIO, so it would appear that the IO address range has changed or the reset circuit has been affected somehow by the changes perhaps?

author: grumpydoc
author_rank: Super Contributor
timestamp: August 11, 2017, 01:47:39 pm
content: Quote from: nockieboy on August 11, 2017, 01:38:26 pmPoopIt shouldn't have affected anything - the 74ls138 is still decoding ports 00-3F in 8 groups of 8 ports and each select should correspond to the same range as before, could you have disturbed anything else?It will have very subtly changed the timing for the select signals but I doubt the design is that marginal.

author: C
author_rank: Super Contributor
timestamp: August 11, 2017, 02:09:00 pm
content: Remove M1 from 138 and strap to a level.

author: grumpydoc
author_rank: Super Contributor
timestamp: August 11, 2017, 02:30:16 pm
content: Quote from: C on August 11, 2017, 02:09:00 pmTemporarily right?Check that \$\small\overline{M1}\$ is going to the active high enable, not one of the others and maybe make sure the signals look OK but the point of running \$\small\overline{M1}\$ is to have selects that are active for I/O cycles but not INT acknowledge cycles.

author: C
author_rank: Super Contributor
timestamp: August 11, 2017, 02:42:44 pm
content: In grant's drawing I haveE1 pin 6 connected to +5 active HIGHE2 pin 4 connected to A6 active lowE3 pin 5 connected to A7 active lowTI data sheetE1 pin4active lowE2 pin5active lowE3 pin6active HIGHFound above so farnockieboy's matches TI for 138Quote from: grumpydoc on August 11, 2017, 02:30:16 pmYesHaving M! connected should be ok but is not a normal connection for all the many Z80's I have seen.

author: C
author_rank: Super Contributor
timestamp: August 11, 2017, 03:14:37 pm
content: nockieboyMight want to test what you have to see where the problem is.Valid bootup is goodtest #1E1 pin 4 Connect to 0VE2 pin 5 Connect to 0VE3 pin 6 Connect to 5VThis should boot, just reduced Granttest #2E1 pin 4 Connect as last decoder U2.1 pin 3E2 pin 5 Connect to 0VE3 pin 6 Connect to 5VThis should boot if not U2.1 is wrongtest #3E1 pin 4 Connect as last decoder U2.1 pin 3E2 pin 5 Connect to IORQE3 pin 6 Connect to 5VThis should boottest #4E1 pin 4 Connect as last decoder U2.1 pin 3E2 pin 5 Connect to IORQE3 pin 6 Connect to MIThis should boot but you said failIf this still fails at this pointtest #5Connect as #1changeE2 pin 5 Connect to IORQtest #6Connect as #1changeE3 pin 6 Connect to MIif #2, #5 or #6 fails strap that pin as in #1 with other pins connected.

author: nockieboy
author_rank: Super Contributor
timestamp: August 11, 2017, 04:55:17 pm
content: Quote from: grumpydoc on August 11, 2017, 01:47:39 pmPoop. Yes, it seems I did - D2 had become disconnected from the ROM. I'm getting the "Press <SPACE> to continue..." message now, but no further. No amount of key presses are moving it on from there.If I hold the spacebar down on the computer and reset the SBC, I get random chars on the terminal sometimes. But otherwise, it resets normally and shows the initial message but doesn't seem to be Rx-ing anything.. I've checked and am checking again all the connections to make sure nothing else is lose..EDIT:Cancel that, it's working perfectly again. Nothing wrong with your design, grumpydoc, it was my eyesight that was the problem. I'd failed to notice a jumper from Vcc to E3. M1 had effectively been pulled high. It's working fine now, though - I've even checked CP/M and that has loaded fine.

author: nockieboy
author_rank: Super Contributor
timestamp: August 11, 2017, 05:50:15 pm
content: Okay, so now the new and improved IO decoder is all working, I'm thinking about wiring up the PSG once more. Piecing together what grumpydoc has said on the previous page, I've come up with the below interface for the PSG - is this likely to work?

author: C
author_rank: Super Contributor
timestamp: August 11, 2017, 07:10:05 pm
content: http://map.grauw.nl/resources/sound/generalinstrument_ay-3-8910.pdfnockieboyWhen you look at PSG there is no chip select.The chip was built for a multiplex address & data bus.On page 2 in section "REGISTER ARRAY"10-bits of addressIn drawing note High order(chip select)DA7-DA4 are normally 0000 but can be mask programmed.DA8 is active highDA9 is active Low"The high order address bits function as chip selects to control the tri-state bidirectional buffers"I think at a min you should have a chip select signal and not just count on BC1 &BDIRQuote from: nockieboy on August 11, 2017, 05:50:15 pmIn addition to what you have connect DA9 which is active low to Y1 which is active low.This should put PSG in TRI-State when Y1 is highDid not look at logic for BC1 & BDIRStill do not like the timing between PSG & Z80.

author: grumpydoc
author_rank: Super Contributor
timestamp: August 11, 2017, 07:21:30 pm
content: Quote from: nockieboy on August 11, 2017, 05:50:15 pmYes it should do - subject to the caveats above about timings.Quote from: C on August 11, 2017, 07:10:05 pmFrom the same data sheet"INACTIVE The PSG/CPU bus is inactive. DA7-DA0 are in a high impedance state"That applies to all "inactive" combinations of BDIR, BC2 and BC1 - you don't need to separately use A8/A9 to control the buffers.In fact:QuoteCould do but again from the data sheet that you quote ".... may be left unconnected as each is provided with an on chip pull-down (A9) or pull up (A8)..."Clearly the chip designers did not feel that you need to use A8/A9 as chip selects.QuoteAgree, but for reasons discussed and past experience I think it should work on a Z80 clocked at 4MHz or below.To go to 8MHz wait states will be needed but might not be enough and things could get complicated.For various reasons will have less time to contribute for at least two weeks but will try to keep an eye on proceedings when I can.EDIT:QuoteInactive (Y1 high) will drive BC1 and BDIR low whatever is on \$\small\overline{WR}\$ and A0A write cycle with A0=0 will drive BC1 and BDIR high for a latch address cycleA write cycle with A0=1 will drive BC1 low and BDIR high for a write register cycle.A read cycle with A0=0 will drive BC1 high and BDIR low for a read register cycleA read cycle with A0=1 will drive BC1 and BDIR low which will do nothing.That could be better as the registers write on $BASE+1 and read on $BASE+0 but it only takes two gates to implement and there are no "dangerous" combinations.

author: nockieboy
author_rank: Super Contributor
timestamp: August 11, 2017, 10:30:35 pm
content: Just had another look at the datasheet for the AY as the thought occurred about whether the IO pins could drive an LED? I'm probably not reading the sheet right, but it looks to me like the maximum current the IO pins can deliver is 100uA? That's not enough to drive an LED, is it? In which case, I'll need to set up something more involved using transistors to drive the LEDs while I'm testing IOA?

author: C
author_rank: Super Contributor
timestamp: August 11, 2017, 11:43:43 pm
content: TTL logicCan do more current to 0v but much less to 1I readlow 0-0.5 at 1.6 MaHigh 2.4 to Vcc at 100 ua.This is normal for TTLCommon practice is to use Pull UP resistors with ttlMost logic makes a low the active state so that pull ups can be usedLook at your Z80 and see it's currentsNot a good idea to connect LEDs to Z80 computers directly.If you look at a 244 you will see a higher current output.So best ideaIf you want an active low signal to light an LED use an Inverter to drive LEDif signal is normal then a buffer drive LED

author: nockieboy
author_rank: Super Contributor
timestamp: August 12, 2017, 05:30:26 pm
content: Okay, Z80-PSG interface is completed. I have tested the IO for input and am successfully reading values across the full range (0-255) on IOA.Output, however, seems to be a different story. There seems to be a constant 3.6V on each of the IO pins when configured for output, no matter what value I write to the PSG IOA port.Code below is what I'm using to write to the port:Code:AY_IO_ADDR.EQU0EH; AY-3-8912 IOA addressAY_WRITE.EQU09H; AY-3-8912 write addressAY_READ.EQU08H; AY-3-8912 read addressAY_LATCH.EQU08H; AY-3-8912 latch address; Set IOA to OUTPUTLDA,$07; Select address R7 (select ENABLE register)OUT(AY_LATCH),A; Latch address R7LDA,40H;OUT(AY_WRITE),A; Set R7 to 40H (IOA set to output); Set value in IOALDA,AY_IO_ADDR; Load A with IOA Register addressOUT(AY_LATCH),A; Latch register in PSGLDA,E; Load A with valueOUT(AY_WRITE),A; Write value to PSGIs 40H the right value to use to set IOA to output, I'm wondering?

author: C
author_rank: Super Contributor
timestamp: August 12, 2017, 06:48:22 pm
content: Quote from: nockieboy on August 12, 2017, 05:30:26 pmThe 3.6v could be the internal pull-up.R7 B6 is probably a direction control of IOA. Have not found if it's 1 or 0 for output.40H would set B6 & clear other bits.Try with just a voltmeter or scope connected to output and40H And also 00H to R7

author: grumpydoc
author_rank: Super Contributor
timestamp: August 12, 2017, 07:10:27 pm
content: Are you writing to the correct register for the port. The data sheet says port 16 but you are writing to 0E (14)

author: nockieboy
author_rank: Super Contributor
timestamp: August 12, 2017, 07:24:45 pm
content: Quote from: grumpydoc on August 12, 2017, 07:10:27 pmYup - this was identified in this forumherethat the documentation for the AY isn't spot on, as the registers are actually 2 lower than those printed in the datasheet.I've also verified this myself by reading from 0F and 0E to get the value at IOA. Only 0E works - 0F is for IOB (which doesn't exist on the 8912), but thinking about it 0F must be IOB as there's no way of passing 10h or higher to the register as the most significant 4 bits are all masked in hardware (so no way to address R17.)Quote from: C on August 12, 2017, 06:48:22 pmThat is indeed the case - R7 B6 sets the direction of IOA. Below is a screenshot of the documentation I've been using (goes into more detail than the datasheet does for the AY-3-891x series):Sorry for the quality - the original is a scanned document which isn't great. The following information should also help:

author: grumpydoc
author_rank: Super Contributor
timestamp: August 12, 2017, 07:32:31 pm
content: That's what I get for looking at the data sheet on my phone - no context. The register addresses are in octalI think all of the data sheets are scans but the link C posted a while back is better quality.

author: nockieboy
author_rank: Super Contributor
timestamp: August 12, 2017, 07:36:05 pm
content: Quote from: grumpydoc on August 12, 2017, 07:32:31 pmAh yes, that was it. Just noticed the jump from R7 to R10 in the docs myself. Who in binary hell uses octal?

author: C
author_rank: Super Contributor
timestamp: August 12, 2017, 07:52:49 pm
content: Quote from: nockieboy on August 12, 2017, 07:36:05 pmYOU if you really want to understand the Z80!!!!There are 8 RST instructionsThere are 8 Condition codesThere are 8 8-bit registers. Note that here 110b is specialLook at the Specification sheet, 3 bit fields all over the place.

author: nockieboy
author_rank: Super Contributor
timestamp: August 12, 2017, 08:02:42 pm
content: Quote from: C on August 12, 2017, 07:52:49 pmThanks for the M. Night Shyamalan moment, C!I'm still no closer to getting output working though. Will have to take a break for a few days.

author: C
author_rank: Super Contributor
timestamp: August 12, 2017, 08:29:52 pm
content: Find a numerical order list of Z80 instructions and add a octal field for instruction values.in octal FFh is 377Their is 4 8x8 arrays of instructions.16-bit instructions are in the above with 2-bit fieldsSome instructions like CB & ED are toggles to expanded instructions.Blanks in what Zilog lists for these tables are often working with IX or IY in place of DE or HL

author: grumpydoc
author_rank: Super Contributor
timestamp: August 13, 2017, 07:40:55 am
content: For each of the registers, can you read back the data that was written, do you get the value you expect?

author: nockieboy
author_rank: Super Contributor
timestamp: August 16, 2017, 02:55:27 pm
content: Quote from: grumpydoc on August 13, 2017, 07:40:55 amYup - I'm getting the results I expect now that I'm using the more basic IN and OUT commands I created in my custom monitor program. In fact, having been away for a couple of days and come back to it, it seems to be working ok, if sometimes a little intermittently, but I think the PSG isn't totally happy with the reset circuit so I'm going to go away and test that a little more.In any case, the IO is working so no reason not to expect the sound output to work too (famous last words!) - I've got some work on my hands to get it playing chiptunes, but it's a start.

author: nockieboy
author_rank: Super Contributor
timestamp: August 16, 2017, 05:10:25 pm
content: Okay, as part of getting the PSG up and running for sound generation, I'm adding a Z80 CTC to the SBC for clocked interrupts and so on. It's mostly connected up now from what few bits of information I can find online, but I'm not sure about IE0 and IE1.Obviously I'm using an SIO/2 which generates interrupts when characters are received via the serial interface, so daisy-chaining the interrupt according to priority is important and I'm not sure how to wire up these two pins - I can't find any schematics that use a CTC in that way and the datasheets/manuals that I do have for the CTC don't explain how to do this.I'm off to go read through the documentation in more detail, but thought I'd see if anyone has any advice about how best to integrate the CTC into the design.EDIT:Oh, okay, found this which seems to clarify the situation somewhat:The question is, do I disconnect the ~INT line from the Z80? At the moment it's connected to ~INT on the SIO as per Grant's schematic and pulled high through a 1K resistor.

author: C
author_rank: Super Contributor
timestamp: August 16, 2017, 06:06:45 pm
content: in simple termsIEO & IEI form a daisy chainThere is a time limit on daisy chain length. Memory says 4 Z80 IO chips chained before need to add helper logic.The device closest to CPU prevents lower devices from interrupting if the device has a pending interrupt.For Z80 chips like CTC and SIO, intack is generated internal to CTC or SIOJust so you knowA daisy chain like this can be used when you have many DMA devices.Your picture is wrong in some pointsRedraw it with IEI close to Z80. IEO goes to lesser devices in priority chain.The Interrupt output of each device chip goes to an OR gate with the output of OR connected to Z80 INT. A logic low OR.This is a good place to use open collector logic.

author: nockieboy
author_rank: Super Contributor
timestamp: August 16, 2017, 06:32:14 pm
content: Quote from: C on August 16, 2017, 06:06:45 pmAh no worries about that - I think the CTC and SIO are going to be only peripherals in the interrupt chain, or maybe a PIO or 8255 when I get around to that.Quote from: C on August 16, 2017, 06:06:45 pmOh? I thought it was the other way around? It would appear the referencehttp://www.z80.info/1653.htmI was reading was incorrect then (also the source of the daisy chain image.)Quote from: C on August 16, 2017, 06:06:45 pmSo I don't need to worry about connecting ~INTACK up from the Z80 to the CTC or SIO?Quote from: C on August 16, 2017, 06:06:45 pmWell I think in that image, the DART, PIO and CTC are prioritised in that order. Not my work, but your comments are noted. So you're saying that ~INT from the Z80 goes to IEI of the highest priority device, then its IEO to the next device's IEI and so on until the last device, whose IEO is connected to +5V?Quote from: C on August 16, 2017, 06:06:45 pmOh, so IEO for each device is OR'd to Z80 ~INT? Sorry, I'm a bit confused now...

author: C
author_rank: Super Contributor
timestamp: August 16, 2017, 06:47:30 pm
content: Let me rewrite what I saidZ80 INT input pinYou connect all interrupt outputs to this pin. To do this you need a OR gate.Any low input = Low output.Using Open collector logic you have a wired OR where any output can create a low.IEI & IEOThis is a separate daisy chain.You start with first IEI input pulled to +5V. This is Highest end of chain.You just connect to IEO output to next IEI input.Nothing else is in this chain but IEI & IEOAll the good stuff is already inside the Z80 IO chips, so you do not need to worry about it with Z80 IO chips until you have a long chain.+5V to CTC IEICTC IEO to SIO IEISIO IEO no connectionZ80 Int pin = CTC Int pin OR SIO Int pinAn you are done.

author: nockieboy
author_rank: Super Contributor
timestamp: August 16, 2017, 06:53:44 pm
content: Quote from: C on August 16, 2017, 06:47:30 pmAha! Crystal clear, C. Thank you!

author: nockieboy
author_rank: Super Contributor
timestamp: August 16, 2017, 09:02:18 pm
content: So, something like this?EDIT: Oh wait, the NOR gate is wrong - need an AND gate instead?0 | 0 = 01 | 0 = 00 | 1 = 01 | 1 = 1

author: netdudeuk
author_rank: Frequent Contributor
timestamp: August 16, 2017, 09:09:58 pm
content: I believe that you want an OR gate there.

author: nockieboy
author_rank: Super Contributor
timestamp: August 16, 2017, 09:21:52 pm
content: Quote from: netdudeuk on August 16, 2017, 09:09:58 pmReally? An OR gate doesn't match the truth table required according to C's previous comments though?Quote from: C on August 16, 2017, 06:47:30 pmI know C's stated an OR gate is required but what he says after that matches an AND gate...?

author: netdudeuk
author_rank: Frequent Contributor
timestamp: August 16, 2017, 09:27:29 pm
content: Quote from: C on August 16, 2017, 06:47:30 pm

author: nockieboy
author_rank: Super Contributor
timestamp: August 16, 2017, 09:29:34 pm
content: Quote from: netdudeuk on August 16, 2017, 09:27:29 pmAh yeah, fair point - thanks netdudeuk!

author: nockieboy
author_rank: Super Contributor
timestamp: August 17, 2017, 03:37:12 pm
content: Right, well that doesn't work - taking a look at the logic tables, either I'm missing something or the circuit needs an AND gate, not an OR gate?In my case I have two devices attached in the interrupt daisy chain - an SIO and a CTC. I have no issue with how the IEI-IEO daisy chaining works, I've got the IEI for the CTC at +5v, CTC IEO -> SIO IEI and SIO IEO is not connected to anything.That way, the CTC should take top priority for any interrupts with the SIO taking second place to it.The ~INT connections from the SIO and CTC need to connect to the ~INT pin on the Z80. Obviously they need to be gated somehow, otherwise (e.g.) the CTC may try to pull the ~INT line low to trigger an interrupt but the SIO will keep it high as it's not needing the CPU's attention.So the ~INT line to the CPU needs to go low whenever the ~INT pins on either the SIO or CTC go low, or both, but stay high if SIO and CTC ~INT pins are high, like below:CTC SIO CPU ~INT0 0 01 0 00 1 01 1 1That's the truth table for how the ~INT line to the CPU should behave, based on the possible combinations from CTC and SIO ~INT pins. Remembering that ~INT is active LOW (0).Here's the truth table for an OR gate:A B OUT0 | 0 = 00 | 1 = 11 | 0 = 11 | 1 = 1How does that match what is required by the CPU's ~INT line? In that case, the only time ~INT would be pulled LOW (active) is when BOTH the CTC and SIO are pulling ~INT low?Am I missing something?An AND gate truth table, however, matches what is required to make the circuit work:A B OUT0 | 0 = 00 | 1 = 01 | 0 = 01 | 1 = 1So can anyone explain why I'm being told to use an OR gate instead of an AND gate?

author: C
author_rank: Super Contributor
timestamp: August 17, 2017, 04:04:10 pm
content: SimpleINT is active lowThe logic you want is to OR all interrupt outputs to the Z80 int pin..Because INT is active low, this is negative logic where A 1 = low voltage and a 0 = high voltageA Positive logic AND gate is a negative OR gate.Missed the fine printBoth the SIO and CTC state this about INT pinInterrupt Request (output, open-drain, active Low).You can just connect all the int pins.There is a reason I forgot about Z80 IO INT pins being Open-drain (open-collector).First is I worked more with big systems where you always had a driver at card connector.The Second reason is better.If you want to put your scope on the CTC INT pin and see if it is generating an interrupt.With the wired connection( all connected) you would see all interrupts not just CTC INT by putting your probe on CTC INT pin.I like testable circuits, not one that is harder to trouble shoot.

author: grumpydoc
author_rank: Super Contributor
timestamp: August 18, 2017, 09:23:29 pm
content: I hope that you are getting to grips with the Z80 daisy-chained interrupt priority control.One thing which travel affords is time to mull things over, consequently I had the opportunity to think more about the interface with the AY-3-8912 and faster Z80's. After all I expect nockieboy will not want to halve the speed of his system just to have it make a few squeaks and pops. Unfortunately being away from home and my usual desktop environment makes it harder to draw pretty diagrams to make the ideas a bit more concrete.It has been suggested that the sound generator could be connected via a PIO/PIA and this is certainly a possibility but it is an extra (large) package to accommodate and the interface brings its own problems. Also, it increases the complexity of the code needed to talk to the sound chip (though, to be fair, this should be a solve once and forget issue).However it ought to be possible to interface the 3-8912 to a Z80 directly, after all this is a not uncommon problem with modern, faster spins on classic processors - we can buy a faster CPU than in 1980 but the retro interface chips that one might want to use are more often than not unavailable in a more modern guise.Looking at the timing diagram for the version with wait states it struck me that the \$\small\overline{WAIT}\$ signal is about the right timing for driving the 3-8912 bus control signals to give the necessary set-up and hold times.However we need to extend the interval that \$\small\overline{WAIT}\$ is active to allow for the typical 500ns pulse that the 3-8912 needs so the first thing we need is a more flexible wait state generator. Some googling and browsing through 7400 series data sheets suggests the 74xx165 parallel to serial shift register can be used as a wait state generator so we'll go with that.As we are going to finish the 3-8912 read cycle "early" (to allow for the tri-state delay) we need a latch to grab the data and hold it for the Z80 to read. Given the need for a latch we also need a buffer during write cycles so we can activate the latch during a read cycle and the buffer during a write cycle - the 74ACT646 is rather useful in this scenario - it is a bidirectional buffer/register in a single package.We also need - well, not much actually, just an inverter, plus the two NOR gates that are already in use to generate BC1 and BDIR.Here is the schematic\$\small\overline{SELAY}\$ is the active low select signal for an I/O cycle to the PSG, as discussed previously.There's a big caveat in that I haven't built this so there might be the odd mistake in the diagram but I think that it should work OK. (remember, always, however, the difference between theory and practice)The timing is as follows (\$\Theta = 8MHz\$)All of the 3-8912 timing requirements are met with the exception of the data setup time - if we accept that the negative numbers in the Z80 timing information mean that the data is not guaranteed to be stable when \$\small\overline{WR}\$ falls then an 8MHz Z80 might not get it's act together until 10ns before the rising edge of the clock at the end of T2 (TdCr(WRf)-TdD(WRf)IO - 60 - -55ns = 115ns), add in the propagation delay through the 74ACT646 and the data is not guaranteed to be stable at the PSG until pretty much the rising edge of the clock at the end of T2. That edge clocks the data to drive \$\small\overline{WAIT}\$ low and start the bus cycle on the 3-8912, there is an additional delay through the NOR gates before BC1 & BDIR change state so there should be a guaranteed 20ns or so of data set-up time - not officially enough but better than -55ns.The wait sates can be extended by changing which of the 74ls165 inputs are tied high and which tied low. Up to 7 wait states can be generated to this should be good up to a 14MHz clock for the Z80. Beyond that the wait state generator, at least, will need a rethink.Enjoy.

author: nockieboy
author_rank: Super Contributor
timestamp: August 18, 2017, 10:55:21 pm
content: Quote from: grumpydoc on August 18, 2017, 09:23:29 pmWell actually, no... My focus is on getting the CTC up and running currently as a regular interrupt is a key requirement for the PSG to get it playing sound. I had it set up with the OR gate as C outlined previously, but ~INT was low constantly and the SBC wasn't getting past the 'Press <space> to continue...' message as the SIO was unable to get the Z80's attention to read the Rx buffer (presumably).I haven't, unfortunately, had any time to look at what could be causing the problem since discovering it, but my next step is to check the CTC to see if it's pulling ~INT low all the time and if not, just connect it up to the SIO and Z80 ~INT without the logic gate (and double check all the wiring of course!)Quote from: grumpydoc on August 18, 2017, 09:23:29 pmAbsolutely awesome - thanks grumpydoc!Looking forward to getting started on the high-speed interface - now it's working at 4MHz, the PSG is on hold until I get the CTC (and by extension, the interrupt system) working. Hopefully will have an update over the weekend if I get some time to test it.

author: C
author_rank: Super Contributor
timestamp: August 18, 2017, 11:04:26 pm
content: nockieboyAs stated in outer post INT is active low, you need a negative logic OR gate.In positive logic this is an AND gate.grumpydocAs stated PIO is easy out but has problems, the part I do not like is the bit banging in place of simple read or write..I would think that most of the time a program would be writing to the 3-8912.This lead to How fast can the Z80 write to the 3-8912. I see two Z80 IO writes as the fastest ( a set address & write data). With this in mind, The data pins on 3-8912 can take from the Z80 starting IO cycle until just before Z80 starts next IO cycle, spanning the Instruction fetch and refresh..Does this give enough time for zero Z80 waits?For read you could do a start read followed by get data as two Z80 instructions or a wait state read.

author: nockieboy
author_rank: Super Contributor
timestamp: August 18, 2017, 11:12:58 pm
content: Quote from: C on August 18, 2017, 11:04:26 pmSorry C, I obviously misunderstood that post. And a 74HCT08 is the one logic chip I don't have.

author: C
author_rank: Super Contributor
timestamp: August 18, 2017, 11:16:34 pm
content: For now just connect all the INT pins.PIO & CTC are open collector so this is allowed.

author: nockieboy
author_rank: Super Contributor
timestamp: August 19, 2017, 11:47:54 am
content: Quote from: C on August 18, 2017, 11:16:34 pmSorted - marvellous.The SBC is booting up now with the CTC/SIO interrupt daisy chain setup. Just need to test the CTC in software now to make sure it's working as expected when I get some free time.

author: nockieboy
author_rank: Super Contributor
timestamp: August 19, 2017, 04:18:04 pm
content: OK - seems the CTC is working as I'm able to reset the SBC after a predetermined time. The problem is I'm not trying to reset it, I'm trying to print a '.' every time the interrupt is serviced!I think my understanding of how the interrupt vector is passed to the CTC on Channel 0 is a little lacking.I was following an example where the interrupt vector table was at $20 and the vector passed to Ch0 was 10h. Problem I've got is that I can't put my vector table there as it's already occupied, so I went for $24 and passed 18h as the vector. That's obviously incorrect as, instead of printing a full-stop every time the interrupt is called, the SBC just resets. I'm making a silly error somewhere, but I'm not sure where...Here's some of the code I'm using:Code:;------------------------------------------------------------------------------; CTC Vector = 0x24;------------------------------------------------------------------------------.ORG$0024.DWCTC_Int;------------------------------------------------------------------------------; Initialise CTC;------------------------------------------------------------------------------INIT_CTC:LDA,00000011b; int off, timer on, prescaler=16, don't care; ext. TRG edge, start timer on loading constant,; no time constant follows, sw-rst active, this; is a control commandOUT(CTC_0),A; Channel 0 is on hold nowOUT(CTC_1),A; Channel 1 is on hold nowOUT(CTC_2),A; Channel 2 is on hold nowOUT(CTC_3),A; Channel 3 is on hold now; Set up the interrupt vector in Channel 0LDA,18h; int vector defined in bit 7-3, bit 2-1 don't care,; bit 0 = 0 (for vector)OUT(CTC_0),A; and loaded into channel 0; Interrupt codeCTC_Int:PUSHAFPUSHHL; CTC test routine - just print a . to the command lineLDA,'.'CALLTXAPOPHLPOPAFEIRETIWhat am I (obviously) doing wrong?

author: C
author_rank: Super Contributor
timestamp: August 19, 2017, 05:26:13 pm
content: First break it apart.You need to initialize the chip. Not in interrupt code.Then You talk to CTC to setup a channel like you want.AndProcess interrupts.You almost need to think that Interrupt code is a separate computer.You need to be careful of what code the interrupt code uses.For exampleMain code could be in process of adding a character to output buffer when the interrupt happens. Both sets of code could write to same location and you lose a character.Good interrupt code passes data in memory.Interrupt code writes data and main code only reads.Main code writes data and interrupt code only reads.Question #1How many different interrupt vectors does the CTC use?Question #2 Why put new code in mess?Vectors go up to 127With Vector interrupts the Z80 uses a table in memory of the starting address of each vectorThe I register is the High byte address of the tableThe vector from device is low byte of tableIf I = ____ thenatORG (I value) 00H is vector zeroEach vector is a .DWGrant by using I = 0 is making things harderIf memory serves the SIO vector is at 60Easy thing to do is to put CTC vector just above vectors the SIO needs Or just below the SIO by the number of vectors the CTC needs.A table with all vectors in a group.So in your code you have an interrupt table: Interrupt tableOrg _____.DW SIO_interrupt 0 : vector 60.DW SIO_interrupt 1 : vector 62.DW SIO_interrupt 2 : vector 64.DW SIO_interrupt 3 : vector 66.DW SIO_interrupt 4 : vector 68.DW SIO_interrupt 5 : vector 6A.DW SIO_interrupt 6 : vector 6C.DW SIO_interrupt 7 : vector 70.DW CTC_interrupt 0 : vector 72.DW CTC_interrupt 1 : vector 74.DW CTC_interrupt 2 : vector 76.DW CTC_interrupt 3 : vector 78Need to know how many interrupts SIO and CTC can use and adjust this.Note that the actual interrupt code can be anywhere in memory

author: nockieboy
author_rank: Super Contributor
timestamp: August 19, 2017, 05:29:21 pm
content: Yeah, the code I pasted isn't how it's presented in the assembly - I just pasted the relevant parts into one block for the forum post. It's just the vector I'm having trouble with - I've clearly misunderstood how the interrupt address is put together. My interrupt table is at $24, but passing 18h as the vector isn't directing the CTC to the correct location in memory.

author: C
author_rank: Super Contributor
timestamp: August 19, 2017, 05:39:02 pm
content: Think you are reading things wrongWith Grants codeI = 0HSo the interrupt table starts at 0000hThe Table is 256 bytes in size.When a Interrupt happens The Z80 reads the vector at interrupt ACKThe Z80 then uses the I register value as the high byte of a memory access.The Vector read is the low byte of a memory access.The Z80 reads a word at that address and does you might think of as a Call instruction with the RetI as a return from sub.Grant is cheating and putting some code in areas where the vectors are not used as vectors.

author: nockieboy
author_rank: Super Contributor
timestamp: August 19, 2017, 07:15:33 pm
content: Hmmm... okay, must admit to being a bit confused by all this at the moment.Here's the start of the monitor code as it stands, from 0000H effectively:Code:MON.ORG$0000; MONITOR ROM RESET VECTOR;------------------------------------------------------------------------------; Reset;------------------------------------------------------------------------------RST00DI;Disable INTerruptsJPMINIT;Initialize Hardware and goNOPNOPNOPNOP;------------------------------------------------------------------------------; TX a character over RS232 wait for TXDONE first.;------------------------------------------------------------------------------RST08JPconoutNOPNOPNOPNOPNOP;------------------------------------------------------------------------------; RX a character from buffer wait until char ready.;------------------------------------------------------------------------------RST10JPconinNOPNOPNOPNOPNOP;------------------------------------------------------------------------------; Check input buffer status;------------------------------------------------------------------------------RST18JPCKINCHARNOPNOPNOPNOPNOP;------------------------------------------------------------------------------; CTC Vector = 0x24;------------------------------------------------------------------------------.ORG$0024.DWCTC_Int;------------------------------------------------------------------------------; SIO Vector = 0x60;------------------------------------------------------------------------------.ORG$0060.DWserialIntI inserted the CTC interrupt vector (table?) before the SIO vector that Grant made, following what he's done as I don't really know what I'm doing.Originally I added the 5 NOPs after RST18 (they aren't there in Grant's original code) thinking that I could just put the .DW after them, but then thought that explicitly setting the address via an ORG statement would be better. I chose $24 as it's in an unused part of the ROM and $24 only has bits set in bits 7-3, which seem to be the only bits the user can set if I'm reading the Z80 Peripherals User Manual properly (almost certainly not though!)So... the vector 18h appears incorrect for the code above. What should I use instead to get the Z80 to call CTC_Int?

author: C
author_rank: Super Contributor
timestamp: August 19, 2017, 07:45:59 pm
content: Looking at Grant's Monitor.asmIt is a mess to add code to.One programming error leads to a big mess.Just not good programming practice for a Z80These should all be in source:RST 0 ,org 00h:RST 08 ,org 08h:RST 10 ,org 10h:RST 18 ,org 18h:RST 20 ,org 20h:RST 28 ,org 28h:RST 30 ,org 30h:RST 38 ,org 38hAll it takes is a typo in source to start running code at these addresses.As these act like a call instruction, an error message followed by a RET should be in place of unused RSTIn addition should be notes or entries for other interrupt mode addresses.Interrupt mode 1 starts at 38HNonmaskable Interrupt starts at 66HLook at an Assembly listing printoutwhat instruction is at 66Hwhat will happen if you start running code from 66HSoMy read of CTC, It uses 4 interrupt vectors.Nice to have all interrupt vectors in a group, so60H - 8 is CTC channel 0 Vector in table60H -6 is CTC channel 1 Vector in table60H -4 is CTC channel 2 Vector in table60H -2 is CTC channel 3 Vector in tableSo.org 58H.Dw : channel 0 vector.Dw..Dw.Dw.Dw : SIO vector located at 6Code:: Interrupt vector table starting at Vector 58.ORG$0058; CTC channel 0 Vector in table.DWCTC_ch0; CTC channel 1 Vector in table.DWCTC_ch1; CTC channel 2 Vector in table.DWCTC_ch2; CTC channel 3 Vector in table.DWCTC_ch3;------------------------------------------------------------------------------; SIO Vector = 0x60;------------------------------------------------------------------------------.DWserialInt; Start of :NMI interrupt.org 66.org 70H;------------------------------------------------------------------------------; Serial interrupt handlers; Same interrupt called if either of the inputs receives a character; so need to check the status of each SIO input.;------------------------------------------------------------------------------serialInt:PUSHAFProgram the CTC to use vector 58H for channel 0

author: C
author_rank: Super Contributor
timestamp: August 19, 2017, 08:50:01 pm
content: Quote from: nockieboy on August 19, 2017, 05:29:21 pmWhat you state here is not correctYour interrupt table is not at $24Grant sets the I register to 0H, so the interrupt table starts at 0000HNote that if you set the I register to 01H then the interrupt table would start at 0100H.What you are trying to do is add or change a vector in the table.The Interrupt table is an array with a size of 256 bytes of 16-bit integers.The index of this array goes from 0-127 or 00H to FEH by words.Each of the 16-bit integers is a starting location for interrupt code.In C this would be a Pointer to Code.In assembly language for a complete Interrupt table, You have 128.DW entries with the data being interrupt code starting addresses.If you can guarantee that a vector will go un-used then the two bytes of that vector can be used for other purposes like storing data or program code.You should note that when the Z80 does an INT_ACK cycle, it expects D0 to be Zero for a vector.For Most or all Z80 IO chips you program the Vector in the upper 7-bits. Some or all have the capability to create more then one vector and modify the lower bits of the programmed vector leaving D0 as Zero and the upper bits unchanged..The CTC with four timer channels uses four vectors. This lets interrupt code be simple and just process one channel's interrupt needs. So D1 & D2 in vector are the Channel.

author: nockieboy
author_rank: Super Contributor
timestamp: August 19, 2017, 09:42:11 pm
content: Thanks for your help with this, C - it's clear that Grant's code isn't the best starting point for learning about interrupt tables. Can you suggest any sites, books or other resources that would be a good place for me to read up on this (aimed at beginners of assembly/Z80 programming ideally?)

author: C
author_rank: Super Contributor
timestamp: August 19, 2017, 10:27:34 pm
content: Most of the beginning assembly language books I know of are1. For a computer like the TRS-80 that has a rom and shows the Assembly using a lot of ROM code.2. For a system like CP/MIn both cases little about Interrupts are not mentioned.I would lean towards you taking control of all the source you have and making it better. In the process you would gain an understanding of how the system works making it easer to do your thing.For exampleI think you are burning new roms to test your code changes.You said you got CP/M working.You can edit, assemble and run programs on CP/MWould not need to burn code.Even with the boot roms in place with some small changes you could run your new code and test it.Problem is grant's whole thing is a mess. Learn this and then forget most of it with a new change.Think of what you have done. Build a basic computer using an overclocked serial chip for a different microprocessor family. then scrap it and switch to the SIO.Grant's programming is the same. What you learn about Monitor.asm helps little when you shift to CP/M. No great need to make you jump through hoops.So You are trying to hack on to a mess. This makes it much harder for you while saving little programming space.You are really trying to write not beginner code and Grant's mess makes it harder.Stage one of gaining control of this.You need assembly printout listings of grant's code.For you to play with interrupts easy, you need the Interrupt table in ram.The easy place would be to put Interrupt table at top of rem.Grant does this with his Cbios but then clutters it up with code and data just like he does in the monitor rom.So want to make it easer for you and take control of grant's code and fix it?.

author: nockieboy
author_rank: Super Contributor
timestamp: August 20, 2017, 09:16:23 am
content: Quote from: C on August 19, 2017, 10:27:34 pmYes, that's exactly what I've been doing, though the process is a little more difficult as I'm learning assembly at the same time as improving the existing code.Quote from: C on August 19, 2017, 10:27:34 pmYes, I'm using an EEPROM for the ROM so I'm able to make changes to the code very quickly (<60 seconds from source compile to SBC switch-on). I've learned an awful lot from modifying Grant's monitor code though and have a monitor that functions more like a BASIC interpreter now (albeit without indirect mode) with a full CLI and custom commands for viewing and editing memory locations individually or en-masse to aid me with my assembly learning.I would like to start learning more about CPM though - obviously the hardware side has been top of my priority list currently, but you're right I'm itching to get into CPM and start writing software for it.Quote from: C on August 19, 2017, 10:27:34 pmYep, definitely.As the CTC is working nicely now, my next step is to write a system clock (similar to the old IBM XT/AT MS-DOS one that asks you for the time when you turn it on) which won't take long (I'll use the interrupt to increment 16-bit value in a memory location every second, then have a CLI command read that value and translate it into a human-readable time to show the user time since switch-on) then start working on re-integrating the PSG again (it's going to be rebuilt as I'm going to use an AY-3-8910 for the extra IO port as I'm having to use a larger breadboard for the interface and delay logic that grumpydoc has created - thanks grumpydoc) and getting the synth software working now that I've got an internal clock to call the waveform generation routines frequently.

author: C
author_rank: Super Contributor
timestamp: August 20, 2017, 11:30:05 am
content: What Ram and eeprom are you using now?For CPMI liked wordstar as my editor. could make documents and write source code with it.There are many AssemblersSome are relocating macro assemblers.From microsoft there was M80 assemblerL80 is a linker so you can link different assemblys together.many others.You could do all your programming & testing on the Z80.Now If you can modify Cbios you could get CP/M3 running and have a larger space for programs.You could also modify Cbios and get turbodos running. This is a networking systemBoth CP/m3 & turbodos want more memory.---------------------------In monitor romyou have capability of download of intel hex format programs.You just write your programs so they exist in ram.ORG 4000h I think is your ram start location.If you modify your hardwareYou could have writable ram starting at 0H with reads from eeprom at boot. A simple program could then read from rom and write back to same address making a copy of eeprom in ram. You could then switch reads to come from ram.The programs you are writing could then modify ram when needed.A 74xx273 is the chip to use for this.I would not mess with PSG for IO ports, You can do a Port with a 374 very easy.This would be a faster port then PSG with nothing but an IN or OUT required for software.If you want or need interrupts for an IO port a PIO would be best choice. A 8255 will also work but will need help for interrupts.monitor.asmAs long as monitor.asm code does not go up to 2000H you should be fine.You can change the SIO vector with little problemsDo following1. put an .org 100 before serialInt. The serial int code will now start higher at 100.This change will not effect anything but leave more unused space before this code.2. With NMI starting at 66h, would be smart to use vectors higher then this so that future NMI code will have some space.Need to make two changes in code to keep SIO interrupt vector workingA. change the vector you write to SIOB. Position the"DW serialInt" at vector address.If you write F0H to SIO as a vector address the above DW is at 00F0HIf you write 80H to SIO as a vector address the above DW is at 0080HThat is all there is too it.Note that you can change the I regester which moves the interrupt vector table.If you write F0H to SIO as a vector address the above DW is at (I register value)F0HIf you write 80H to SIO as a vector address the above DW is at (I register value)80HIf i = 2 then example for vector F0H above DW is at 02F0HNow I am not a fan of PSG.But how you write your program can make a big difference.Look at grant's "initialixe SIO" code.This is simple code but hard to change using a program. If the data is in a table then much easer to changeThis is the data sent to SIOA_C00H.18H,04H,C4H,01H,18H.03H,E1H.05H,RTS_LOW,Code just needs to output these bytes to the port.You could have a byte that specifys the number of bytesZ80 has an instruction to do this easy.When you go to programming your PSG having data separate from code would make things easer.This is using a CPU for what it is good at, processing data.

author: nockieboy
author_rank: Super Contributor
timestamp: August 20, 2017, 07:44:05 pm
content: Quote from: C on August 20, 2017, 11:30:05 amFor the ROM I'm using a39SF010Aand the RAM is anAS6C1008-55PCN.Quote from: C on August 20, 2017, 11:30:05 amYes, I'd like to upgrade to CP/M 3 but haven't even started looking at where to get it from, let alone its system requirements etc. yet. Still working on (and learning) the hardware currently.Quote from: C on August 20, 2017, 11:30:05 amYes, I'm using (a slightly modified version of) Grant's Intel Hex Loader routine, so I can load hex files anywhere in memory easily and execute code anywhere in RAM from my monitor CLI using a CALL command.Quote from: C on August 20, 2017, 11:30:05 amWell, I want to add sound capabilities to my SBC with an AY-3-891x, so I may as well make use of the IO port/s it provides. I have a 4MHz PIO, that will likely be the next thing I'll add once the PSG is up and running.Quote from: C on August 20, 2017, 11:30:05 amYes, I didn't realise the vector addressing was that simple. When I was putting the CTC interrupt vector at $24 and writing 18H to it as the vector address, that was because the example I was following did something similar. Didn't realise it was as easy as ORGing the interrupt at an address and writing that same address to the CTC as a vector.Quote from: C on August 20, 2017, 11:30:05 amYes, got that the I register holds the MSB for the vector table addresses. So I could just copy the vector table to a place in RAM, say A000h, and modify the I register to hold A0h and hey presto! the vectors are moved into writable RAM?Quote from: C on August 20, 2017, 11:30:05 amNot so good for code commenting and readability though?Quote from: C on August 20, 2017, 11:30:05 amAbsolutely. I have some libraries for the AY that I'm going to be implementing which are based more on modern OOP programming than 80's assembly, much better code than Grant's monitor code. I've written the interface to link the libraries to my specific hardware, I just need to rebuild the PSG circuitry on the larger breadboard so there's room for grumpydoc's 8MHz wait-state injection interface and anything else I want to do with the IO ports.

author: C
author_rank: Super Contributor
timestamp: August 20, 2017, 08:46:34 pm
content: Quote from: nockieboy on August 20, 2017, 07:44:05 pmTurbodos & CP/M3 and much more are on the web for down loadhttp://www.retrotechnology.com/dri/turbodos.htmlhttp://www.mirrorservice.org/sites/www.bitsavers.org/pdf/ims/turboDos/turboDos1.4_Z80impl_Jun84.pdfturboDos1.4_Users_Guide_Jun84.pdfBig thing for both is extra memory. With turbodos, If you link your two Z80's with SIO or other hardware You have two computers and both can access your CF card.Scan read the Implementor's guide first.CP/M3 is a harder read but works on same hardware less the network part.Note that TurboDos can run CP/M programs and was used as a business networked computer system. 100's of Z80's in some systems in many buildings.QuoteYESOr you could switch between two different tables.QuoteYou can make data tables like this very easy to read. You do not have to put all values on one line, you can use many lines.

author: C
author_rank: Super Contributor
timestamp: August 20, 2017, 08:57:20 pm
content: Quote from: nockieboy on August 20, 2017, 07:44:05 pm128k ram will work for CP/M3 & Turbodos, More is better.Simple is 74??273 and some data mux chips.While I am thinking of itThe Z80 has limited pin drive capability, Might want to keep an eye on this.

author: nockieboy
author_rank: Super Contributor
timestamp: August 22, 2017, 10:00:44 am
content: Quote from: C on August 20, 2017, 08:57:20 pmWell I'm hoping that eventually, if I ever get this off breadboard and onto a proper PCB, I'll be adding bus drivers/buffers to ease the load from the Z80. Other than a PIO and keyboard/display modules though, the only other major additions I'd be looking to add would be an SPI/I2C bus (likely via the PIO).It seems most of the components I've got, like the CTC and PIO, are all 4MHz components so the clock speed is going to be staying at 3.68MHz for the foreseeable until I can replace the CTC and PIO with 8MHz parts. As it's not essential, it's not a priority though.I'm itching to get the PSG up and running, but it's going to involve a lot of effort on the software side, so I've been thinking about getting the Z80 access to the remainder of the 128K SRAM before I start writing the PSG software, as it might mean I have to go back and re-write routines if I do it the other way around.So, I want to get my head around memory paging now. Let me see if I understand the principle - the upper 64K of the SRAM (or anything above 64K in an arbitrarily-sized RAM space) is effectively divided up into 16K (for example) 'pages' by the memory addressing hardware, able to be swapped into the Z80's addressable RAM space via clever memory address switching and IO calls?The area that's switched in/out resides in the TPA somewhere for CP/M, leaving low and high RAM either side to retain things like the stack, CP/M, drivers and space for the program making use of the paged memory?So how do we choose the memory addresses for the paged memory block? Does CP/M/TurboDOS have specific requirements? There must be a section of the OS that will need to be modified to my specific hardware to allow it to page the memory at a program or user request?And most importantly - what is thesimplestway to implement memory paging in (and with the minimum additional) hardware? I'm not an electronics expert (or even experienced at it) and my requirements for the SBC are modest, so I don't need to be able to page 1MB of RAM or anything - I'd just like to implement it to use the full 128K SRAM that I've got already. Seems I've got some research to do.

author: C
author_rank: Super Contributor
timestamp: August 22, 2017, 01:37:47 pm
content: Read the section in Turbodos.You have a software driver to write for CP/M3 or TurboDos.Os tells driver what it wants, driver switches hardware.For memory, Easy way to think is Huge memory, 0-? meg ramSo you wire up memory to be huge with x number of address lines.You do not have it now but think ahead as more address lines can be cheap and easy.Easy way to think is all memory chips same size. You have 8 same size chips when using a 138.If you do not have same size chips, then pretend it is same size to keep it simpleTake a look at different 512K 32-pin memory chips. There are different types, what pins are used for what?Then look at what you have for chips.At most a few jumpers lets all work in socket.

author: C
author_rank: Super Contributor
timestamp: August 22, 2017, 08:19:41 pm
content: Memory managementTo keep is simple to do and simple for me to say, You have0- 128K rom128-256k ramThis is Memory map for your memory chipsYou are going to put a circuit before the address inputs of memory.74xx273https://assets.nexperia.com/documents/data-sheet/74HC_HCT273.pdfCold boot clears chipZ80 Writes data to chip with OUT instruction.74xx153https://assets.nexperia.com/documents/data-sheet/74HC_HCT153.pdfInputs to chip are outputs of 74xx273Outputs of chip are high address lines t0 memory.Select inputs are Z80 A14 & A15This two chip solution is just two output address lines and uses two z80 address lines. A gain of 0, Need a second copy of circuitYou now have two 74xx273 & 2 74xx153This circuit is using the two Z80 address lines to select 4 address lines for output, A gain of two address lines for an address range of 0-256k.At cold boot, 0-16k from rom shows four times in Z80 address space.After the Z80 does two Output instructions, You can have any 16k block of memory showing in the four 16k blocks in Z80 address apace.Grant's Rom/Ram circuit is not needed.You need to add one more chip to handle the two output addresses. A 74xx138 will work and leave some select lines for more IO output.74xx138https://www.diodes.com/assets/Datasheets/74HC138.pdfOne low enable input is connected to existing 74xx138Second low enable input is connected to Z80 WRNow for CP/M3 and TurboDos, you will want to change the two center blocks most of the time. Suggest putting these 8-bits on same 74xx273.If you want to cripple this design a little, the upper 16k bank will stay the same, so you could strap these inputs to 74xx153 & gain 4-bits for other use in one of the 74xx273This will work with what you have.It is possible to add another pair of 74xx273 & 74xx153 and gain 2 more address lines and expand the memory range to 0-1024kDMABoth CP/M3 & TurboDos talk about DMA moving areas of data. With No DMA device the Z80 does this.If the area to be moved is inside the source bank & destation bank then one move will work. But you can not expect all programmers to make it this easy. Normally the OS will keep one end of move in same bank, but programmer controls other end. In this case DMA could be two smaller moves with a bank change between the moves.I state this now so you know some care is needed when this is programmed.When you go looking at changes & improvements to this, you need to ask "will it give an improvement?"If you are using CP/M3 or TurboDos, can the improvement be used?

author: nockieboy
author_rank: Super Contributor
timestamp: August 22, 2017, 10:14:08 pm
content: Thanks C - some awesome information there that I'll need to go away and digest. I'm a visual learner when it comes to this stuff, so expect me to come back in a few days with a schematic representation of how I've interpreted your instructions for feedback and corrections.

author: C
author_rank: Super Contributor
timestamp: August 22, 2017, 10:37:24 pm
content: Never a great artist.What I listedThat mess is a simple 4 pole 4 throw switch with the Z80 address lines controlling the switch.The Switch is just selecting the outputs of latches that the Z80 can write to with an OUT instruction.Two address lines in = 4 address lines out.Out 0 sets four bit address of Z80 0-16k & four bit address of Z80 48-64kOut 1 sets four bit address of Z80 16-32K & four bit address of Z80 32-48kSoftware should store a copy of what is written in common memory.

author: grumpydoc
author_rank: Super Contributor
timestamp: August 28, 2017, 05:50:57 pm
content: Quote from: C on August 18, 2017, 11:04:26 pmWhen I first saw your suggestion I admit that I thought it wasn't that great an idea.Having thought about it further I can see it has some merit, especially as clock speeds increase making the CPU very much faster than the PSG - so you'd start to need a lot of wait states to get the interface to work..Given that OUT (X), A is 11 t-states I get the argument that while the IO read or write might not allow enough time, being only 4 t-states, we would need a clock speed of 22MHz before the whole instruction would take less than 500ns. So, yes, if one could arrange that the write completes while the Z80 is doing the next instruction there should be enough time even if it is a further write (as you say the most common access pattern will be one write to latch the address and one to write into the PSG register).Doing it this way would mean the Z80 was not held up by wait states - but, to be fair even if you add 7 you will not even double the time for the whole I/O cycle.However that will be at the cost of a more complex hardware interface. I haven't really tried to come up with a schematic but I can't quite see that you can do it with two main chips plus a couple of gates as I proposed.Read seems like it would be more complex than with my suggested interface as well.Why not support your suggestion with the details of the hardware interface and the timing. It seems only fair as I put the effort in to do that

author: nockieboy
author_rank: Super Contributor
timestamp: August 29, 2017, 08:15:25 pm
content: Firstly C, thanks very much for the schematic - makes it much easier for me to understand.Unfortunately I haven't got the ICs to implement memory mapping at the moment and I've also gotten a little sidetracked with another task. I've had a PIO sitting around doing nothing and as an I2C interface is on my wishlist, I've wired it into the SBC and hooked it up. All good so far.I've been following this guide -http://www.blunk-electronic.de/train-z/pdf/howto_program_the_Z80-SIO.pdf- page 28 outlines an I2C interface using the PIO, which goes on to include some simple assembly routines to cover the basics. It doesn't quite go as far as setting up a working I2C interface in software, but it seems to be a good starting point.I was just wondering if anyone had any thoughts on the PIO/I2C design in the document above? Is it a good implementation or is there a simpler way I can do it? I've looked into getting a proper parallel/I2C chip, like the PCF8584, but I'm limited (mostly by soldering skill) to DIP packages - I don't really want to touch SMT unless I absolutely have to. So, as a result, these DIP chips are prohibitively expensive (and limited to eBay.) One reason for going with the PIO setup was that I could use the second port to create an SPI interface (also on my wish list) maybe.

author: C
author_rank: Super Contributor
timestamp: August 30, 2017, 09:13:31 pm
content: Quote from: nockieboy on August 29, 2017, 08:15:25 pmThink about memory mapping a moment.The important thing is add little delay to a memory access as possible.. For My schematic that is switching time of the 74xx153. You loose this much time when accessing memory.There are many ways to do this. Look at my schematic for ways you could modify it. What do you gain with the change, what do you loose?Note that you could plan ahead to make adding memory management easy.You could inset a memory breadboard between Z80 & memory.Quote from: nockieboy on August 29, 2017, 08:15:25 pmWhat are you wanting to build,A microcontroller or A microcomputer?If you want to build a microcontroller, save a lot of time and money and start with a microcontroller.If you want to build and learn about a microcomputer,Get in the micorcomputer mind set, thinking the computer way of doing things.First look at PIOYou have two signals that most microcontrollers do not have, ARDY & ASTB.These two signals let bytes of data flow at rate both z80 & connected circuit can handle. Because you are handshaking at byte, you can send many bytes in a row with the same value. At the same time software load on Z80 is lower.Signals like these are easy to get in hardware with a microcomputer.Look at a chip that was built to make it simpler to do I/OIntel 8212http://blog.copcea.ro/files/datasheets/diverse/8212.pdfThe dashed box is around a 74xx273 & a 74xx244 logic equal. You have the clear input of the 273 and the tri-state output of 244.Best idea is not to do I2C with out adding a proper I2C master like PCF8584.To do I2C with anything less wastes more and more CPU time just to run the interface.Then you talk about SPI, again best done in hardware. If the only thing SPI is a SD card used for storage then this might be worth the chips needed.When you shift to bit-banning you loose a huge amount of speed and need a huge number of instructions on CPU to make up for missing hardware.Keep in mind that you can only do a single thing at a time on an I2C or SPI bus.So step one, cross off I2C & SPI from your lists of wants and instead list the function of the chip that you would attach.Then think smart,That PCF8584 costs about $4. It is cheaper to add an interface on Z80 that can talk to a microcontroller and let the microconrtroller then talk to I2C & SPI. This also lets Z80 do more with less software overhead.If you are wanting to learn microcontroller stuff, use a microcontroller to start.If you are wanting to learn microprocessors then look at areas that microprocessors are good at.If you want something to interface, how about a HD44780 LCD controllerMany used the HDLC mode of SIO to link systems. This gives you a packet like interface with 8-bit transparency for data and command/status. IBM called this SDLC and had huge networks.Many used SCSI as a parallel interface between 8 systems. Not hard to do in hardware/software and supports 8-bit transparency.If you want really extreme, Connect an ESP32 to your Z80.Think about many CPU's.One TurboDos system I worked with had over 200 uses running CP/M programs. That is 200 Z80's for the users + more.One 68K system with 8 users used a Z80 to do all IO.The basics areMemory managementMulti-port memoryMulti-processor shared busProcessor with Many buses.

author: nockieboy
author_rank: Super Contributor
timestamp: August 31, 2017, 11:15:12 am
content: Quote from: C on August 30, 2017, 09:13:31 pmYes, I'm going to need to put a little more time and thought into this modification.Quote from: C on August 30, 2017, 09:13:31 pmAh okay, I'll have to consider getting some PCF8584s then. Frankly the PIO method seemed a bit of a hack and I'm not having much luck getting it working currently, I was just put off by the prices of PCF8584s on eBay and the lack of availability of the DIP packages. I'm waiting on some SOIC/DIP converters from China - when they arrive I'll take a closer look and see if I stand a chance of soldering an SMT version of the PCF8584 to one.Quote from: C on August 30, 2017, 09:13:31 pmI've got an Arduino nano sitting around doing very little at the moment, I guess I could swap out the PIO and replace it with the nano, which would give me SPI and I2C in one hit. It'd spur me on to learn more about microcontrollers, but it goes against the grain in terms of what I was originally trying to achieve with an 80's tech SBC, though there's been some feature creep with the addition of I2C and CompactFlash, admittedly.Okay, a question about replacing the PIO with the nano (remember - I'm very inexperienced with electronics); the nano will take a non-trivial amount of time to service an IO request - it'll have to, for example, read the I2C bus and return data retrieved from the bus to the Z80's data bus. What's the best way to tell the Z80 to wait? Insert ~WAIT states? Or am I getting way ahead of myself?EDIT:Okay, so some quick research indicates that I can't (or shouldn't) replace the PIO with the Nano, but use the PIO to interface the Nano to the Z80's bus and interrupt system?

author: CJay
author_rank: Super Contributor
timestamp: August 31, 2017, 12:58:34 pm
content: Hold your fire on those PCF8584 chips in DIP, I may have some still sealed in bags from way back when...I'll have a look later this evening if i remember.

author: nockieboy
author_rank: Super Contributor
timestamp: August 31, 2017, 01:08:33 pm
content: Quote from: CJay on August 31, 2017, 12:58:34 pmThat'd be awesome if you can, CJay - and massively appreciated!

author: C
author_rank: Super Contributor
timestamp: August 31, 2017, 07:24:23 pm
content: If you want to achieve an 80's tech SBC you can.I have an 80-s tech computer. It has a parallel printer port, some serial ports, floppy disk drive bus ports & a SCSI port.Great software & hardware is what makes a great computer.BufferThink of a serial or parallel printer. For some compute tasks the Z80 can generate characters much faster then the printer can print. But for some programs or places in a program the Z80 is slower then printer.So before talking electronics lets look at this problem. A buffer in printer can help here. A buffer in Computer can help. But this is not a free change. One software error and you have printer printing a low of garbage. A good setup looks at all the problems created when a buffer is added and has ways to the best it can to reduce or fix the problem. When Printing garbage you want to stop the print & clear the buffers. The point I am trying to make is adding something like a buffer is not free and needs more control options. Most improvements are the same, gain something & loose something.Hardware handshakeLook at serial ports. One big difference between a nano and your Z80 SIO is that your SIO can use RTS & CTS to stop receiving more characters, This is simple. For software, the common method is XON & XOFF. This requires transmitting these characters before characters in the buffer when needed, more complicated. A lot of nano programs only work because the PC only sends a small amount of characters before waiting for a response from nano.So best choice is to have hardware that will handle speed difference between the two ends. This does not prevent using the other two ways above. You could have all three working.Speed differenceNow You caught that a nano will be slow to respond. You might not have caught that even a PC will be slow to respond. The way to handle this is to shift to a request & response method.So at low level you want hardware that can send & receive with out loss and a higher level doing requests with delayed response9-bit dataNow you have already seen the hints of what is needed, you are missing details. For Z80, you need to keep it simple or you loose a lot of computing time. When you look at the connection of SIO to Z80, what are you seeing?Each SIO port is using two addresses. One for command/status & second for data. You have 9-bits to/from the SIO so that you have 8-bit transparent data & 8-bit transparent command/status.To have a remote SIO, you need to send/receive this 9-bit data. For a picture think of this.Your Z80 is going to use a SIO attached to a second Z80.Your Z80 using the serial port of the nano.You have already been using something like this. On PC's, they have stopped using direct connected serial ports and are using USB connected serial ports. The PC is remote controlling the USB device that acts like a serial port. An as you can see if done right, you can have many. To have many, you need more bits so you can select which device should work with the 9-bit data.So far we have buffers, 9-bit data & handshake signals for flow control.You need a send path and a receive path.Here it might be good to say that a 8-bit asynchronous serial interface is not a good choice to send this 9-bit data. You only have one choice of adding software on both ends of connection to get the needed 9-bit transparent data. A big software overhead for Z80.Now lets go back an look at SCSI. First versions were very simple.Back in the day a SCSI hard drive controller could normally attach to 4-hard drives.A SCSI bus could connect 8 devices with one being my old computer. So my old computer could connect to 28 hard drives. But notice a SCSI bus connects to devices. You could have a device that was a hard drive & floppy drive controller.All kinds of things could be connected to the SCSI bus, drives, scanners, printers, terminal servers and more. in addition you could have a 8 device network.Now you might like to know that first SCSI hard drive controllers used a Z80 on controller board.My Z80 uses 2 x 74xx273, 2 x 74xx240, 1 x 74xx132, 1 x 74xx74 & 2 x 74xx06 for SCSI interface. The boot rom is 512x8So what makes SCSI so powerful of an interface?It is an open collector bus(74xx06). This lets many devices use same signal line at same time. All devices would wait for the slowest device when needed.The C/D signal could be thought of as the 9-bit from above.Has handshake signals for speed difference between devices.Has I/O signal for bus direction.Has additional signals to handle problems and errors.A total of 9 signals in addition to 8 for data.Now one trick my Z80 uses is that it actually sends 9-bits with each z80 out instruction. A0 becomes the 9th bit(C/D). This makes software simpler and also data faster on the bus. Using a PIO would be a little slower.When sending a SCSI command it is specifying WHO, WHAT WHERE, This is a request.This is just a stream of bytes with C/D set for control.You could think of Packets.For ethernet, you have a known packet starting point, so you can assume that first bytes are control. The control bytes can then specify if more control bytes follow and where and how much data is in packet.For HDLC, SDLC you have a unique frame start bit sequence which again gives you a packet.For CAN bus you also have a unique packet start bit sequence.Do I need to state that USB is packets also.A packet is just a stream of bytes and is not normally hard to add more bytes to control part of packet.So by coping SCSI bus and ideas you have something to follow to make a powerful interface to your Z80 <-> nano while handling problems.Both nano & Z80 can use interface status to decide when other end is ready so no Z80 wait states are needed. Both can continue to run instructions while waiting.You can expand adding more Z80's, NANO's or other to SCSI bus.Now the software side.Back in the old days to read/write storage you needed to specify what drive, what track, what side, what sector. Each of these was a register in the controller, each had an IO address. For SCSI this becomes a byte stream. Instead of writing to an Output port you write each byte of data in a specific memory location that will be part of the command stream. When this array of data is ready you just copy the bytes to SCSI port.Today with smarter drives it's what drive & what logical block address.SCSI used logical blocks for storage from the start.As with many things, there are many ways of doing things. If you understand the concepts, then you have more options.I showed one way to have 16k blocks of memory. There is a thread that uses fast ram that can be better if you understand concept. A few address lines becomes many.Keep looking for basic concepts to build with.Will stop here, Ask questions.

author: nockieboy
author_rank: Super Contributor
timestamp: September 05, 2017, 08:27:37 pm
content: Okay, so I've caved in to the idea of adding an Arduino Nano to the SBC, with the intention of using it to provide I2C and SPI buses to the Z80.Currently, the Nano is providing a 4 Mhz clock (8 MHz selectable by pulling D12 on the Nano high) and is linked to the Z80's ~RESET line, so it can pulse it during startup and save me a button press when turning the SBC on.I'm now trying to work out how to create a meaningful interface with the Z80, bearing in the mind the Nano is restricted on the number of pins it has. Initially I thought I could just link up the Z80's data bus to the Nano, but only certain pins can be used as a 'port', which is clearly the preferred method to read and write an entire byte to the bus as efficiently as possible, but using a 'port' isn't really an option due to pin feature constraints, such as the Nano appears to only have one pin which will take interrupts - and that's the serial Rx pin, which I need to communicate with the Nano directly.So, I'm now considering using an 8-bit bi-directional shift register (CD74HCT299E) to take the 8-bit data bus contents and pass it to the Nano via a serial connection, taking up only 3 pins instead of 8. It will also be used to pass data from the Nano back onto the Z80's data bus.I'm thinking of using an IO select line from the '138, almost as a 'chip select' for the Nano, but also connected to the '299 to latch the data on the bus and, when the Nano is ready, to pass the data over via the serial connection. I'm supposing I'll need another connection between the '299 and the Nano as a 'DATA_RDY' to control communication over the internal serial connection.So.. in theory, I could pass data to the Nano via an IO call. Not sure how I'd get data back though - unless I connect the Nano to the Z80's interrupt circuit and see if I can get the data onto the bus that way, ready to be read by the Z80's interrupt routine. Or I suppose I could use WAIT states to let the Nano pause the Z80 while it gets the data ready on the bus?Hmm.. not sure of the best approach, or even if I've considered all the possibilities. Any thoughts?

author: C
author_rank: Super Contributor
timestamp: September 05, 2017, 09:38:57 pm
content: With you currently building on breadboard, how about stupid simple to start with with the idea of later improving it.You said you have a Z80 PIO, why not connect that for Z80 side. Note that PIO has a full duplex mode if that works better..This lets you learn some about PIO software interface also. Look some at how you are writing your software. It is possible to have one software driver to control/use many SIO's for example. Same can be done for CTC & PIO in some cases.On nano side, you could use pins or SPI. I would guess both. Would need some parallel in serial out & serial in parallel out shift registers.After you have simple connection to PIO then look at other signals that exist on parallel scsi to add to make connection better.

author: nockieboy
author_rank: Super Contributor
timestamp: September 05, 2017, 09:52:25 pm
content: Ah okay so stick with running the Nano through the PIO (via the '299 shift register obviously).Another thought occurs - I (currently) have a spare serial port on the SIO. This is eventually intended for use with the keyboard/monitor circuit (as detailed in Grant's designs) but I'm wondering if it'd be easier at the moment to just connect the Nano up to the spare serial port and communicate with the Z80 that way?Aside from using the spare serial port that I'll eventually need later for other IO (aforementioned keyboard and monitor), I'd like to include some DMA capability in the Nano too if at all possible. This would make connection via the PIO or SIO impossible though...

author: C
author_rank: Super Contributor
timestamp: September 06, 2017, 01:06:25 am
content: Quote from: nockieboy on September 05, 2017, 09:52:25 pmTo make it easy, you need more then 8-bits.If you are using 8-bit shift registers then you need to use two to get bits needed to separate what is passing over connection to keep software simple and fast.QuoteA usart or SIO is not a great interface between computers. You have a lot of different types of 8-bit data.Read past posts.Between two Z80 SIO's if you use HDLC then it's good. HDLC is a synchronous mode with packets.Between nano's or other micro-controllers you could use 9-bit mode asynchronous.SIO & windows do not like 9-bit mode asynchronous.Need to look at how fast the Z80 can read or write the data. The more computing you do the slower it gets.QuoteZ80 DMA controller can work with PIO & SIO

author: nockieboy
author_rank: Super Contributor
timestamp: September 10, 2017, 03:38:21 pm
content: So I've got a '299 to try to interface with the Nano now - I'm hoping that it's going to be possible this way rather than having two 8-bit shift registers; I'm trying to minimise space so I'd like to use the 299 if at all possible, plus I don't have both types of serial shift register (SIPO/PISO) in separate packages.What I'd like to be able to do:* interface the Arduino Nano to the Z80 SBC via the 74HCT299 (and PIO if necessary)* enable the Nano to read a byte from the data bus via a Z80 OUT instruction, and* place a byte onto the data bus in response to a Z80 IN instructionThat's the minimum I'd like to achieve - I can build it up from there to send sequences of bytes etc later.What have I tried so far?I've connected the '138 IO mapper to an interrupt-enabled digital pin on the Nano so that any IN/OUT commands from the Z80 to the 28-2F address space pulls the Nano's pin low and triggers the interrupt on a falling edge, so I can see when the Nano is being addressed in the IO space. I've also connected up A0 to another digital pin and have tried reading it to see if I can get a 0 or a 1 when I'm doing an OUT 28 or OUT 29 instruction. The results are inconsistent - obviously because of the delay between the interrupt firing and the digitalRead instruction grabbing the data from A0 is much longer than the Z80 is keeping the address bus stable for the OUT instruction.Now what I'm thinking is that if I link that same select line to the '299 via an inverter, I can use the select signal (transitioning to HIGH after the inverter) as a clock pulse to cause the '299 to latch the data bus contents and start sending the data to the Nano via the serial connection (pins DS0 & DS7 on the '299) whilst the Z80 carries on with executing further instructions.Now I know very little about the '299 and the image above shows how far I've gotten with developing the interface.In fairness I'm a bit lost in it all. I've taken a look at the datasheet for the 299 and am trying to work out how to control it via the Nano, but I'm struggling with the whole concept currently, not to mention the problems that the timings are causing (although the Nano is running at 16MHz, it's clearly not quick enough to sample the data bus at the right time without using WAIT states.)I'm going to go do some research on the PIO as I think maybe that could help with the timing/sampling issue. Just can't believe no-one has done this sort of thing before and not documented how to do it - I've searched high and low online and cannot find anything that explains in a way that is helpful to me. If anyone can point me in the right direction, that'd be appreciated.

author: nockieboy
author_rank: Super Contributor
timestamp: September 10, 2017, 08:11:50 pm
content: You know what, for simplicity I think I'm just going to use the second SIO serial port to connect to the Nano. Just requires a couple of wires and the software will be simplicity itself...

author: C
author_rank: Super Contributor
timestamp: September 10, 2017, 09:04:10 pm
content: Quote from: nockieboy on September 10, 2017, 08:11:50 pmYes simple to start with but then you get in a big mess when you start trying to use it for more then just one stream of data and even one stream of data is a problem if you do not use the hardware handshake of serial port.