Author Topic: SPI bit banging using the Z80 cpu  (Read 15241 times)

0 Members and 1 Guest are viewing this topic.

Offline commieTopic starter

  • Frequent Contributor
  • **
  • Posts: 278
  • Country: gb
SPI bit banging using the Z80 cpu
« on: September 10, 2015, 01:39:21 pm »
Hi,

I'm trying to find some short z80 assembler code showing how to output one byte synchronously using a 8255 or a z80 pio. I'm not a great expert at z80 assembly code, the problems I have is that although the z80 has bit manipulation instructions they can only be used on internal bytes whereas the 8051 has full bit manipulations on all of its ports aswell, the z80 can only write or read full 8 bit bytes from its ports. 

I have searched everywhere for an example but unfortunately, I cant find anything.

 

Offline lapm

  • Frequent Contributor
  • **
  • Posts: 564
  • Country: fi
Re: SPI bit banging using the Z80 cpu
« Reply #1 on: September 10, 2015, 02:53:54 pm »
It should not be problem unless you overload port output pins so much that voltage drops enough to read as zero when it should be one..

If its output only port then you could use whats know as ghost port. Basically you have variable that contains what port should be and you manipulate that, then at right moment you simple copy value of this ghost port variable to actual port. Cant remember where i heard this ghost port term in early nineties...

Making code comes down to ow exactly is cpu connected to io chips and how address space looks like. If i remember correctly Z80 allowed even to set up separate IO-space or use more usual memory mapped IO...
Electronics, Linux, Programming, Science... im interested all of it...
 

Offline commieTopic starter

  • Frequent Contributor
  • **
  • Posts: 278
  • Country: gb
Re: SPI bit banging using the Z80 cpu
« Reply #2 on: September 10, 2015, 03:15:52 pm »
ghost port

Yep, I thought of that but I just wanted to make sure no one will pull the carpet from under my feet with some easier code, :phew: it's so much easier with the 8051!

BTW, thanks for your reply, I've got a new z80 basic compiler which is quite good except its i/o commands are non existent so what I figured was to send out single floats(4-bytes) to a small AVR connected to a 16x2lcd.
 

Online MarkL

  • Supporter
  • ****
  • Posts: 2131
  • Country: us
Re: SPI bit banging using the Z80 cpu
« Reply #3 on: September 10, 2015, 03:39:23 pm »
As you suspect, the Z80 doesn't have individual bit control for the IO space.

The typical procedure is to read the port, set/reset the bits how you want, and write the byte back to the port.

Peripherals, such as the PIO, keep track of the last byte that was output.  When directed to read the port, it will return the last output byte masked by those pins that are designated as inputs.  The bits that are inputs will be replaced by an actual read of those pins.

For the PIO, this is called "Bit Control Mode (Mode 3)", but it's really still byte-oriented.
 

Offline commieTopic starter

  • Frequent Contributor
  • **
  • Posts: 278
  • Country: gb
Re: SPI bit banging using the Z80 cpu
« Reply #4 on: September 10, 2015, 04:03:54 pm »
As you suspect, the Z80 doesn't have individual bit control for the IO space.

Yeah, it would seem that way, same goes for the 8085 and 6802/6502, I guess. When I was at college, we studied the sdk-85 I wonder what the educational establishments are using today?

Anyway, Mark thanks for your reply.
 

Online macboy

  • Super Contributor
  • ***
  • Posts: 2256
  • Country: ca
Re: SPI bit banging using the Z80 cpu
« Reply #5 on: September 10, 2015, 06:24:52 pm »
It should not be problem unless you overload port output pins so much that voltage drops enough to read as zero when it should be one..

If its output only port then you could use whats know as ghost port. Basically you have variable that contains what port should be and you manipulate that, then at right moment you simple copy value of this ghost port variable to actual port. Cant remember where i heard this ghost port term in early nineties...
...
I would call it a 'shadow' register. I can see how it might be called 'ghost' instead in a different language.
This is also commonly used to avoid read-modify-write issues that can arise when manipulating single bits on the ports directly.
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: SPI bit banging using the Z80 cpu
« Reply #6 on: September 11, 2015, 07:47:29 am »
This is more of a peripheral and/or microcontroller-vs-microprocessor thing than a z80 vs 8051 thing.  I don't THINK you'd find it much easier to bit-bang a pin on an 8255 using an 8051; it's the fact that the internal ports are, well, INTERNAL that makes it easy.  (Certainly you run into the read/modify/write mechanism on something like an AVR, as soon as you start using ports that are addressed outside of the "magic" range.  SBI/CBI for some ports.  IN/MOD/OUT for other ports LD/MOD/ST for yet others :-( )

It looks like the 8255 does have a Bit Set/Reset mode (BSR) that can manipulate single bits (on port C only.)
8085 has an extra serial input and output pin, but it looks like you read/write it via the "interrupt mask", so you still have the RMW inelegance.
 

Offline janoc

  • Super Contributor
  • ***
  • Posts: 3785
  • Country: de
Re: SPI bit banging using the Z80 cpu
« Reply #7 on: September 11, 2015, 09:26:46 am »
Why not to make your own parallel to SPI bridge using e.g. that '51 micro to interface to the Z80 instead? (or use a proper UART/USART chip, but the micro will likely be cheaper today) :-//

Will likely be quite a bit faster and easier to deal with. Z80 isn't designed to do this sort of job, it is a CPU and things like SPI are the job of the peripherals. The CPU only feeds the peripheral with data over its bus.

« Last Edit: September 11, 2015, 09:38:10 am by janoc »
 

Offline T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 21688
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: SPI bit banging using the Z80 cpu
« Reply #8 on: September 11, 2015, 09:42:30 am »
Consider adding some hardware to facilitate the process.  A parallel-load shift register for MOSI and parallel-read for MISO, and a clock divider, counter and gate to transmit a fixed number of clock pulses and shift the registers, following a write cycle.

Or find an SPI peripheral to begin with (can the SIO be configured for synchronous serial?), or get rid of the damn device that you're needing SPI for anyway.

An historically accurate e.g. ADC/DAC would use some registers (plain old '374, etc.) driven from the IO bus, going to an 8 bit (or more) R-2R divider chip (e.g. MC1408) and op-amps, sample-and-hold, analog switches/muxes, etc. for signal distribution, SAR, etc.  (SAR could be done under control of the CPU if you're desperate, but it would be worth adding some logic to implement that on its own.)

You'd be looking at a total sample rate under 100kS/s for the simplest cases (reading from a wave table perhaps?), but most of the time, the process under control would be fine with either 1-10kS/s (e.g., motor control, regulated power supply, etc.), or "too slow to care" (i.e., the S&H's have to be refreshed from time to time to keep stable analog outputs, but other than that..), e.g. setpoints and calibration in an otherwise fully analog system (a spec like the HP 8590A or 141T is largely a fully analog radio, with control inputs for adjusting frequency and timing from the program, that could be done with pots if you were desperate).

Yes, all very involved (a dozen ICs here and there, they stack up quickly!), but this is how embedded systems were made! :)

Tim
« Last Edit: September 11, 2015, 09:48:53 am by T3sl4co1l »
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 

Offline commieTopic starter

  • Frequent Contributor
  • **
  • Posts: 278
  • Country: gb
Re: SPI bit banging using the Z80 cpu
« Reply #9 on: September 11, 2015, 11:30:22 am »
This is more of a peripheral and/or microcontroller-vs-microprocessor thing than a z80 vs 8051 thing.  I don't THINK you'd find it much easier to bit-bang a pin on an 8255 using an 8051; it's the fact that the internal ports are, well, INTERNAL that makes it easy.  (Certainly you run into the read/modify/write mechanism on something like an AVR, as soon as you start using ports that are addressed outside of the "magic" range.  SBI/CBI for some ports.  IN/MOD/OUT for other ports LD/MOD/ST for yet others :-( )

It looks like the 8255 does have a Bit Set/Reset mode (BSR) that can manipulate single bits (on port C only.)
8085 has an extra serial input and output pin, but it looks like you read/write it via the "interrupt mask", so you still have the RMW inelegance.

Yep, spot on westfw, excellent post  :-+
 

Online MarkL

  • Supporter
  • ****
  • Posts: 2131
  • Country: us
Re: SPI bit banging using the Z80 cpu
« Reply #10 on: September 11, 2015, 01:46:30 pm »
If you still want a purely bit-bang approach, you can gain a little speed by using IO decode lines to drive SET/CLR on a couple of flip-flops, one for the SPI CLK and one for MOSI.

This would reduce outputs to one instruction; "OUT xx" to set a 1 and "OUT yy" to set a 0, for example.  Another advantage is that no flags are affected.

Similarly, a single bit tri-state buffer could be used to allow the MISO bit onto the bus at yet another port address.

There's usually no shortage of IO space in Z80 systems, so burning a few to speed things up and make the hardware design simpler is generally not a problem.  There's no need to jam everything in byte-wide ports if it doesn't make sense.
 

Online MarkL

  • Supporter
  • ****
  • Posts: 2131
  • Country: us
Re: SPI bit banging using the Z80 cpu
« Reply #11 on: September 11, 2015, 01:48:31 pm »
Or find an SPI peripheral to begin with (can the SIO be configured for synchronous serial?), or get rid of the damn device that you're needing SPI for anyway.
As far as the SIO goes, yes it can support synchronous serial.  But it's a lot of real-estate, and was primarily meant for SDLC and other sync protocols.  It can probably be coerced into supporting SPI, but I think it would be more trouble than it's worth.
 

Offline commieTopic starter

  • Frequent Contributor
  • **
  • Posts: 278
  • Country: gb
Re: SPI bit banging using the Z80 cpu
« Reply #12 on: September 11, 2015, 03:20:46 pm »
Hi all,

Let me try and explain something here, I have bought a simple basic compiler for the Z80 micro, this compiler has a quite a comprehensive set of basic commands.It's data types are: bit,byte,integer, long(4byte integer) and single float(4 byte or 32 bit).This compiler even has a full transcandential math function support. The problem with the compiler is that it has limited i/o commands and these are 'put' and 'get' to and from ports. It also has  the 'print' command which works exclusively with a uart like the 8251 and it does output floats to the terminal correctly, so the compiler is decoding 4-byte floats to 8/9 digit ascii, when using the 'print' command.The Z80 compiler does not have string support and does not have any commands for outputting floats to a lcd and this is my problem.

The solution seems to be to implement a small avr, of which  can easily be coded, as I already have a very powerful compiler(Bascom-AVR). So I could code  up the AVR  to receive(only) 4byte floats+command byte. So the Z80 would bit bangs 4 +1 bytes to the receive only avr which basically displays the float or anything else for that matter,  on a lcd. And walla, I have a powerful Z80 compiler with lcd support.

My prime interest with MPU/MCU 's is in calculator design, i.e., designing retro cool looking calculators. I already have coded up a HP45 in an AVR '168 and it works great, it is keystroke for keystroke identical to the HP45 but even so it does have some short comings, one is accuracy, I used single floats in the design and there is a lot of i/o string conversions going on which cause a small errors every time processing is done going from number to string and converting back again, causes small errors that grow with more processing.Of course real calculators never did use 32bit/64bit floats, they use/used 12 digit bcd and display 10 of the digits, very wasteful of ram, but this is not a problem anymore and avoids using strings altogether so no accuracy lost there. Anybody with an algorithm to multiply/divide 12 digit packed bcd? Is a compiler powerful enough to build your own data types?

Cheers
Commie
 

« Last Edit: September 11, 2015, 03:26:05 pm by commie »
 

Offline commieTopic starter

  • Frequent Contributor
  • **
  • Posts: 278
  • Country: gb
Re: SPI bit banging using the Z80 cpu
« Reply #13 on: September 11, 2015, 05:10:20 pm »
If you still want a purely bit-bang approach, you can gain a little speed by using IO decode lines to drive SET/CLR on a couple of flip-flops, one for the SPI CLK and one for MOSI.

Mark,

Nice idea and original, I had not thought of doing it that way. If I build a Z80 system though, I'd copy the MPF1 Z80 trainer which has 1x8255 and 1xZ80PIO, so built and working, it will be worth £60~£100 on Ebay.
 

Offline janoc

  • Super Contributor
  • ***
  • Posts: 3785
  • Country: de
Re: SPI bit banging using the Z80 cpu
« Reply #14 on: September 11, 2015, 08:14:13 pm »
Hello,

Hi all,

Let me try and explain something here, I have bought a simple basic compiler for the Z80 micro, this compiler has a quite a comprehensive set of basic commands.It's data types are: bit,byte,integer, long(4byte integer) and single float(4 byte or 32 bit).This compiler even has a full transcandential math function support. The problem with the compiler is that it has limited i/o commands and these are 'put' and 'get' to and from ports. It also has  the 'print' command which works exclusively with a uart like the 8251 and it does output floats to the terminal correctly, so the compiler is decoding 4-byte floats to 8/9 digit ascii, when using the 'print' command.The Z80 compiler does not have string support and does not have any commands for outputting floats to a lcd and this is my problem.


Well, of course it doesn't have those things. How would you imagine a compiler support something like that when the underlying hardware doesn't have such feature?  And almost every computer that used Z80 in the past has implemented these things in their own way (using extra circuitry), so you can't really have something like an LCD library where you just wire few pins to the data bus of the CPU and it will work in any Z80-based system.

Remember, Z80 is a CPU. If you are used to AVRs, with Z80 you have only perhaps 20% of the stuff that is inside any of the AVR chips. 8255s are roughly similar to AVR GPIO, SIO chip is similar to what UART/USART in an AVR does. The same for timers and other hardware. And all these chips can be set up in hundreds of ways, using different address decoding schemes and modes.

The closest thing to what you are after was CP/M - a standardized OS with well defined programming interfaces for things like a printer or serial port. And each hardware implementation that supported CP/M had drivers that actually made those generic functions talk to the specific hardware of that machine. BTW, that's where the concept of BIOS that still exists in PCs is from.


The solution seems to be to implement a small avr, of which  can easily be coded, as I already have a very powerful compiler(Bascom-AVR). So I could code  up the AVR  to receive(only) 4byte floats+command byte. So the Z80 would bit bangs 4 +1 bytes to the receive only avr which basically displays the float or anything else for that matter,  on a lcd. And walla, I have a powerful Z80 compiler with lcd support.

Yes, you can do that. However, if you want to drive something like a standard HD44780 based LCD module, you can do it much simpler. Those modules have a normal 8 bit bus with the regular control signals. You can easily interface that to the data bus directly, the control signals will need to be driven by a simple address decoder and the normal bus control signals - all that can be done using a few logic gates or a small CPLD. It will show up on two Z80 I/O ports, one for writing commands and the other for data. Depending on which address you write to, the address decoding logic will set the signals driving the LCD. The HD44780 is actually simpler to drive in from a Z80 than from an AVR because of the parallel interface.

There are even larger displays using the 8080/Z80 type bus available from eBay.

My prime interest with MPU/MCU 's is in calculator design, i.e., designing retro cool looking calculators.

Um and why are you switching from an AVR to a Z80? AVR is certainly much faster and less complicated to use. Unless you want historically accurate hardware or you are doing it for the learning experience, you will be much better off with an AVR here. Just ditch that BASCOM "compiler" and use normal C (or even assembler if you need speed). Your code will be both smaller and faster.

 

Offline commieTopic starter

  • Frequent Contributor
  • **
  • Posts: 278
  • Country: gb
Re: SPI bit banging using the Z80 cpu
« Reply #15 on: September 11, 2015, 09:15:22 pm »
Um and why are you switching from an AVR to a Z80? AVR is certainly much faster and less complicated to use. Unless you want historically accurate hardware or you are doing it for the learning experience, you will be much better off with an AVR here. Just ditch that BASCOM "compiler" and use normal C (or even assembler if you need speed). Your code will be both smaller and faster.

I am not switching from AVR to Z80, I currently have support for 3 platforms and I'd like to bring on board the 65C02 sometime in the future and make it 4 platforms. As you say, the Z80 is a cpu and not a mcu, I am aware of that, the AVR/PIC's are Harvard, whilst the Z80/6502/8051 are Von Neumann.The latter means all opcodes are 8 bits wide, rom shares the same 8-bit bus with data memory, so I can download software, like an os, into ram and execute it, that has it's advantages over the former.

I can't envisage how ditching Bascom compiler will help me, every project I throw at an AVR ends sweet using Bascom.It doesn't bloat the program memory, in fact trails have shown Bascom matches any c compiler in  memory capacity usage and in some cases uses less memory.Bascom, it's just like a high level assembler.
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: SPI bit banging using the Z80 cpu
« Reply #16 on: September 11, 2015, 10:55:43 pm »
If your basic compiler is any good, you should be able to do a bit-banged SPI in basic.   Yes, it could be faster in assembly, but if you're printing to an LCD read by humans, then speed really isn't much of an issue.

Which basic compiler?  By the time you get to bitwise math and reading/writing IO ports, you're outside of "standard basic."

bit-banging a RMW byte-wide port isn't really much more DIFFICULT than using the nice single instructions on a microcontroller, it just feels a bit ugly.  (Consider all the code written for Arduino that uses digitalWrite() to bitbang some protocol...)
 

Offline T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 21688
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: SPI bit banging using the Z80 cpu
« Reply #17 on: September 12, 2015, 03:47:44 am »
If you want precision math, you pretty much have to do it by hand the old fashioned way.  You could take some serious time to evaluate the expressions using datatypes, but you'll be much better off doing it in assembly, which is fairly easy on Z80 and AVR.  To understand how, research multiplication algorithms (and all the other operations).

It might be easier to do the math in fixed point, or doing a simplified floating point method, then write to the display with a base conversion method rather than doing it in BCD directly.  (Processors that are made for BCD math either do everything in BCD (typical of calculator ASICs), or have BCD conversion instructions.  8086 is such an example.)

Single precision for a calculator sounds pretty awful...

Tim
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 

Offline commieTopic starter

  • Frequent Contributor
  • **
  • Posts: 278
  • Country: gb
Re: SPI bit banging using the Z80 cpu
« Reply #18 on: September 12, 2015, 10:41:28 am »
Single precision for a calculator sounds pretty awful...

I agree, it is, but can you point out any compiler currently on the market, which supports 12 digit or more BCD data types?

Me thinks not.

 

Offline commieTopic starter

  • Frequent Contributor
  • **
  • Posts: 278
  • Country: gb
Re: SPI bit banging using the Z80 cpu
« Reply #19 on: September 12, 2015, 10:50:06 am »
If your basic compiler is any good, you should be able to do a bit-banged SPI in basic.

The Z80 basic compiler might be able to do it, I've not plowed a lot of thought into it but Bascom AVR or 8051 has support for I2C,SPI and uart protocols and bit banging, so no problem with those compilers.

Here's a link to the Z80 basic compiler and I must stress, it was only $30 or so. http://www.oshonsoft.com/z80.html
 

Offline janoc

  • Super Contributor
  • ***
  • Posts: 3785
  • Country: de
Re: SPI bit banging using the Z80 cpu
« Reply #20 on: September 12, 2015, 11:32:21 am »
It might be easier to do the math in fixed point, or doing a simplified floating point method, then write to the display with a base conversion method rather than doing it in BCD directly.  (Processors that are made for BCD math either do everything in BCD (typical of calculator ASICs), or have BCD conversion instructions.  8086 is such an example.)

Z80 has instructions for BCD support as well if I remember right. It was some 20 years ago I have touched one last time, though.
 

Offline commieTopic starter

  • Frequent Contributor
  • **
  • Posts: 278
  • Country: gb
Re: SPI bit banging using the Z80 cpu
« Reply #21 on: September 12, 2015, 03:29:59 pm »
Z80 has instructions for BCD support as well if I remember right. It was some 20 years ago I have touched one last time, though.

Hardly BCD support, only works with adding/subtracting single bytes. What is needed are about 20, 16 digit registers each coupled with a 2-byte exponent that work in BCD only and can perform  adding,subtracting,multiplication and division between registers, as I have mentioned before, do you think the latter job of building bcd digit register data types can be done with a compiler(basic or c)?.How are you going to implement the transcandential math functions, like sin,cos,tan?
 

Offline ale500

  • Frequent Contributor
  • **
  • Posts: 415
Re: SPI bit banging using the Z80 cpu
« Reply #22 on: September 12, 2015, 04:13:01 pm »
The TI-82, 83, 84, 85 and 86 use a Z80 as processor. All floating point operations are done using BCD. The Z80 adds/subtracts two digits at once, not bad. With the help of rld and rrd (really cool instructions)  you shift the significant left/right digit-wise left and right. Of course all fp numbers are in memory... Transcendental functions are calculated using CORDIC methods. TI-85 and 86 have wider significants and exponents but use exactly the same methods :)
 

Offline commieTopic starter

  • Frequent Contributor
  • **
  • Posts: 278
  • Country: gb
Re: SPI bit banging using the Z80 cpu
« Reply #23 on: September 12, 2015, 04:45:26 pm »
The TI-82, 83, 84, 85 and 86 use a Z80 as processor. All floating point operations are done using BCD.

That is correct and yes all floats are done in BCD which is the only way to do it.So it comes to pass that the Z80 is an ace processor to get involved with and we need compilers that support BCD floating point data types. :)
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1346
  • Country: us
Re: SPI bit banging using the Z80 cpu
« Reply #24 on: September 12, 2015, 05:06:01 pm »
Think of your problem a different way.

A variable is an array of byte. Each byte could contain a binary value or a BCD value.

The Z80 like most processors has two instructions
ADC "Add with Carry"
SBC "Sub With Carry"
These two instructions allow Add & Subtract Of any size of binary value. Your output array = the two input arrays using math provided by using ADD & ADC or SUB & SBC.
If you can add or subtract then you can do multiply or divide.

You can do the same using the Z80's BCD instructions and save time converting to or from human.

The Z80 can have a large amount of memory so in place of trying to do floating point math, you could do huge fixed math and output to display in floating point when needed. You could use the internal number not displayed to help prevent rounding errors.

For BCD an array of 256 bytes equals 512 digits
You 20 registers would only be 5k of space.

C
   
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf