Jump to content
  • Advertisement
  • entries
  • comments
  • views

2MHz should be enough for anyone

Sign in to follow this  


LCD Timing
Last time I discussed the hardware I mentioned I had LCD timing issues. I have finally resolved them, but this has been the most time consuming part of the project so far.

The first thing to sort out was the LCD's E pin. Once you have set up the LCD's input pins to a state where they're ready to read or write data, you need to drive this pin high. I had had some success by holding it high permanently and relying on the Z80 to set all the other to the right state at roughly the same moment, but this was inaccurate and resulted in occasional display glitching.

Consulting the datasheet, it appears that once the input pins are ready E needs to be held low for at least 450nS and then needs to be driven high for at least 450nS. Hmm. During an I/O request (and once the Z80 has prepared the address and data bus) there's a delay of 1 clock cycle, then /IORQ is held low for about 2.5 CPU cycles. That is the window of opportunity. I have connected a binary counter to the Z80's clock signal and take the least significant bit of the output - every clock cycle this output toggles between a low and a low, effectively halving the CPU clock rate. I then connect the counter's reset pin (which overrides the clock input and forces it to output zero) to /IORQ. The result is that when the Z80 is not accessing hardware the counter is held in its reset state, and E is held low. When the Z80 holds /IORQ low, the counter starts up and outputs a zero for one CPU cycle, outputs a one for the next CPU cycle, then outputs a zero for the next half clock cycle at which point /IORQ goes high again and it is back to zero anyway. This is exactly what's needed!

This also allows us to calculate the maximum CPU clock rate. If we are generous and allow E to be low for 500nS then high for 500nS, that gives us a CPU clock rate of 1/500nS=2MHz.

Anyhow, that's one problem resolved, but there was still one nasty bug. When reading from the LCD it would occasionally end up writing to the area that was being read or, in worse cases, the Z80 would "crash". The LCD has a R/#W pin that is held high when reading and held low when writing. I had connected it directly to the Z80's /WR pin, which is high normally and low when writing. The problem here is "normally" as the LCD was expecting to be read even when the Z80 wasn't requesting a /RD. When being read, the LCD expects to put something onto the data bus, and it appeared that it kept thinking that it needed to put something on the bus when it wasn't needed. This caused fighting with the other chips that were trying to put their own values on the data bus, hence the crashes as the Z80 received invalid data.

The answer was very easy; simply connect the Z80's /RD pin to the LCD's R/#W pin via a NOT gate. In the default state the pin is held low (LCD expects a write and leaves the data bus alone), and only goes high during a /RD. The LCD interface is now very robust.

CPU Clock
Above I mention the calculation for the maximum clock rate. Rather than use the 555 for timing, I switched to using a 10MHz crystal resonator oscillator. I'm using the serial resonant circuit from z80.info with a 74F04 hex inverter (second circuit down). Fortunately the counter chips I have are decade counters (ie, designed to count from 0 to 9) made up of a /2 and a /5 section. I can connect a 10MHz oscillator to the /5 section and use the output of that to drive the CPU. In the final design I'd like to add a "hardware control port" with a bit that would let the programmer choose 2MHz or 10MHz mode by setting or resetting a particular output bit (other control bits would include switching the LCD backlight on or off and a buzzer for beeping sound output).

PS/2 Ports
As a friend pointed out, the 8-bit open-collector I/O port (which will drive two PS/2 ports, the I2C bus and TI calculator link port) had a flaw - there was no resistor on the base of the output transistors. The result is that if the output latch tries to drive the transistor base high, the transistor switches on and shorts the output of the latch to ground. This was clearly a problem in the design as the LCD backlight dimmed when trying to output to these ports as they drew a excessive amount of current when effectively short-circuited. A 22K resistor between the output latch and base of the transistor fixed the problem.

In the above photo, I've also added two 100K resistors to hold the output high when floating, but only to the foreground PS/2 port for the time being. I don't think I'll be controlling a mouse yet!

Revised OS
With a little modification of the Emerson PS/2 library I've got a basic keyboard driver up and running on the hardware. All the OS does for the moment is check for keys and display them on the screen. It's currently hard-coded to the UK layout, as I haven't yet decided how I'm going to handle storage and by keeping the layout in ROM it at least frees up a few hundred bytes of RAM that would otherwise need to be there for the scancode translation tables.

Click for video (1.76MB WMV)
Sign in to follow this  


Recommended Comments

Y'know, building my own machine architecture has been a dream of mine for a long time, and this is half-way inspiring me to get off my butt and go do it.

Unfortunately, I have no clue what I'm doing when it comes to hardware land.

So where did you learn all this junk from? Any good references?

Share this comment

Link to comment
Original post by ApochPiQ
Unfortunately, I have no clue what I'm doing when it comes to hardware land.

So where did you learn all this junk from? Any good references?
I was fortunate enough to be able to study electronics at secondary school (high school) where it was excellently taught. This covered the important building blocks of digital circuits - logic gates, counters, timers and the like - amongst others. Once you have the basics down the rest is down to reading datasheets and working out how to plug the various bits together. [smile]

Unfortunately, I don't know of any good teaching references outside what I was taught and my A-Level textbook (being a UK textbook it'll probably hard to find outside the UK and expensive).

A microcontroller targetted at the education market (such as my favourite PICAXE) may be a good starting point, as they are often available in starter packs or kits and (at least in the case of the PICAXE) have really good documentation. I hear good things about the Propeller, but have never used one so don't know how beginner-friendly they are (suffice it to say that the Propeller is more powerful than the PICAXE).

Being able to program your microprocessor of choice in assembly is also a useful starting point, as that gives you a feel of what it's doing at the hardware level as well as at the software level, as some of the quirks/features can only be explained from a hardware perspective!

Share this comment

Link to comment

So where did you learn all this junk from? Any good references?

You should check out Digital Design and Computer Architecture. It teaches basic computer architecture along with verilog, an HDL (hardware description language). It's like a programming language for hardware, you write what you want to do in verilog and synthesis tools can turn that into actual hardware (As compilers turn [insert language here] into executable x86). Generally you'll target an FPGA (field programmable gate array) which is effectively a chip that consists of a huge number of logic gates that you can connect up as you wish to produce arbitrary bits of hardware without having to make a custom chip and thus avoiding the huge costs associated with that. You can buy FPGA development boards that have an FPGA along with various peripherals (such as LCDs, Audio and VGA DACs, CF/SD card connectors, USB etc along with external IO connectors so you can plug your own stuff in) though they can get expensive (You might manage to find one for $50 or so but the ones with decent sized FPGAs and a decent number of peripherals on the board generally cost a few hundred). Though if you're serious about playing around with your own CPU architectures it's worth it. I used the XUPV2P to make a multicore processor for my final year project in my computer science degree and I'm currently in the beginnings of designing a GPU for the board (Which I'm planning to start writing a dev journal about soon).

Of course verilog, HDLs, FPGAs and such are a bit more abstract than the stripboard and solder approach used by benryves so you may want to check out the book he recommends as well to get a better idea of the actual physical aspect. Plus writing programs for a computer that's constructed out of wires, chips and stripboard that you built yourself is always good fun [grin].

Share this comment

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!