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

0 Members and 2 Guests are viewing this topic.

Offline ale500

  • Frequent Contributor
  • **
  • Posts: 415
Re: SPI bit banging using the Z80 cpu
« Reply #25 on: September 12, 2015, 07:44:07 pm »
Something like... (assume that the least significant digit is on the highest addressed byte)

Code: [Select]
    ld hl,ptr_to_first_significant+15
    ld de,ptr_to_second_significant_and_result+15

    ld c, 16  ; 32 digits
    ld b, 0
    ccf
loop:
    ld a,(de)
    adc (hl)
    daa
    ld (de),a
    dec de
    dec hl
    djnz loop
    ld a, 0
    ld b, 0
    adc b  ; get MSD from carry if any
    ld (hl), a ; reserve extra byte for carry

more or less :)
« Last Edit: September 12, 2015, 07:50:45 pm by ale500 »
 

Offline commieTopic starter

  • Frequent Contributor
  • **
  • Posts: 278
  • Country: gb
Re: SPI bit banging using the Z80 cpu
« Reply #26 on: September 12, 2015, 08:35:20 pm »
Something like... (assume that the least significant digit is on the highest addressed byte)
more or less :)

I don't think this code is right, the Z80 uses the B reg  as its DJNZ loop instruction counter, you have got the C reg loaded with your count of 16, it seems that must be the B reg only.

Also, you are only adding two 16 byte(unpacked) bcd numbers, that's easy, try multiplying them and don't forget to add exponents and shift the result accordingly. :)
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1346
  • Country: us
Re: SPI bit banging using the Z80 cpu
« Reply #27 on: September 12, 2015, 09:58:29 pm »
look at example 3 and 4 in the Z80 users manual.

For multiplying & dividing  you do it the same way a grade school kid would do it.
Repeated addition or repeated subtraction.
A lot of CPU's do not have built in hardware multiply and divide.

For binary multiply this becomes a shift and add if bit is set.
For BCD multiply you shift and do repeated adds based on that BCD digits value.

Floating point
This is where you get a lot of errors in math. You may save some time if the logic is not bad.
Think of the steps
First you un-float the number.
do the math
re-float the number.
Part of the UN-float step is setting the decimal point position.
When you are limited in size for the UN-float's integer value then you are dropping bits when you try to get alignment correct.
If you are using BCD then steps are same as a kid would do.

Look at how easy it would be to change ale500's code to do more digits.

yes for DJNZ  it's the B register.

C







 

Online T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 21686
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: SPI bit banging using the Z80 cpu
« Reply #28 on: September 12, 2015, 11:03:46 pm »
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.

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?

I don't think this code is right, the Z80 uses the B reg  as its DJNZ loop instruction counter, you have got the C reg loaded with your count of 16, it seems that must be the B reg only.

Also, you are only adding two 16 byte(unpacked) bcd numbers, that's easy, try multiplying them and don't forget to add exponents and shift the result accordingly. :)

Well if you're just going to shoot down every serious suggestion ever offered to you, you can just close the thread, please.

If you're going to constrain yourself to a compiler of rather limited numerical capability, that's your problem, not ours.

The TI-8x and related examples were most likely programmed directly in assembly, at least for the low level routines.  You cannot deny that such operations are possible, you must come to terms with whatever you're holding yourself back with.  And we can't help you there.

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

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: SPI bit banging using the Z80 cpu
« Reply #29 on: September 13, 2015, 01:20:55 am »
Quote
but can you point out any compiler currently on the market, which supports 12 digit or more BCD data types?
There is a multi-precision library written in C (for gcc, but I don't think it contains compiler dependencies.)
It has for example, been ported to Arduino.
http://www.gammon.com.au/forum/?id=11519

A calculator can get away with taking a good fraction of a second to perform one operation, and writing 12-digit code that performs at that scale isn't all that difficult, regardless of number format.  (and standard IEEE 80bit floating point is a bit more than 12 digits, so any compiler that supports that should work OK.  (hmm.  gcc "long double" on most x86 systems?))

It might be interesting to implement a trivial set of digit-based calculations that implement grade-school longhand mathematical algorithms.  Everything but division should be easy.
 

Offline ale500

  • Frequent Contributor
  • **
  • Posts: 415
Re: SPI bit banging using the Z80 cpu
« Reply #30 on: September 13, 2015, 06:33:10 am »
commie:

it was an example using the BCD arithmetic (bc will be loaded with 16 meaning 16 packed BCD i.e. 32 digits). FYI, adding exponents and shifting significants is not particularly difficult. Multiplying is also easy once you have an add significants routine at hand. I have done it also for the AVR... that was a pain but not because the algorithms are complicated, the implementations are complicated due to the lack of BCD instructions...
There is a better way of doing fp. instead of packed BCD you use binary numbers from 0 to 99 and store them in binary. Then you have a number base 100 instead of base 10. (you can also use base 10000). The trick is to use div/rem to unpack when you have to display numbers. All operations are performed on binary instead of on BCD numbers, much faster... but you need div. (You could go around with a table too..)
 

Online T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 21686
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: SPI bit banging using the Z80 cpu
« Reply #31 on: September 13, 2015, 07:35:43 am »
It might be interesting to implement a trivial set of digit-based calculations that implement grade-school longhand mathematical algorithms.  Everything but division should be easy.

Actually, not having a hardware multiply means division will be almost exactly as easy as anything else!  I would vaguely guess a complete operation (mul/div) should take under 100 microseconds, maybe 50 microseconds.  For 12 digits at once.

CORDIC algorithms will need many repetitions of this (you'd want to check how many), which will of course go much slower, but I should imagine it's quite possible to go much faster than the traditional handheld calculator.

There have been demos on the ZX Spectrum (Z80 core) which perform real time 3D rotation, scaling and drawing for modest figures (usually geometric shapes not larger than a dodecahedron).  As far as I know, these were done in custom floating point, highly stripped down (since when you're drawing on a low resolution graphical display, you don't need many extra bits), and performed on the order of 10kFLOPS.

Numerically speaking, a few kB of RAM and ROM is a tremendous bounty for the kinds of things a calculator does; the limitation is mainly on time spent writing the program, and the buttons for input and display output, as far as enhancing it further.  You could easily recreate one of the famous HP classics, or a TI-89 or whatever (after all...), it's just a matter of following through and implementing it.

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

Offline grumpydoc

  • Super Contributor
  • ***
  • Posts: 2905
  • Country: gb
Re: SPI bit banging using the Z80 cpu
« Reply #32 on: September 13, 2015, 08:52:46 am »
Quote
Actually, not having a hardware multiply means division will be almost exactly as easy as anything else!  I would vaguely guess a complete operation (mul/div) should take under 100 microseconds, maybe 50 microseconds.  For 12 digits at once.

Are you thinking 12x12 packed BCD multiply?

If so that might be a tall order in 100us on a Z80 - as it will  will be less than 100 instructions on a 4MHz part . It might be doable on a 20MHz Z80.

Div will be harder.

Single precision floating point (i.e. 32bits) is actually  likely to be faster
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: SPI bit banging using the Z80 cpu
« Reply #33 on: September 13, 2015, 09:53:49 am »
Quote
not having a hardware multiply means division will be almost exactly as easy as anything else!
IIRC, the grade-school division algorithm involves "guessing" how many times the divisor will divide the upper digits of the dividend.  Since the computer doesn't guess, it will have to loop up to 9x to find each quotient digit.  That's not "awful" but I WOULD call it "harder than everything else."

For a modern microcontroller (say, the AVR), I'm not sure why you should care about BCD.  Even a modest chip has much more RAM than (say) an 8052, so you might as well work with a digit-per-byte.  (How much RAM does typical calculator actually use?  Most calculators only have one or two "numbers" worth of user-accessible memory ("memory" value, current "result", current input.)
 

Offline grumpydoc

  • Super Contributor
  • ***
  • Posts: 2905
  • Country: gb
Re: SPI bit banging using the Z80 cpu
« Reply #34 on: September 13, 2015, 10:33:30 am »
Quote
not having a hardware multiply means division will be almost exactly as easy as anything else!
IIRC, the grade-school division algorithm involves "guessing" how many times the divisor will divide the upper digits of the dividend.  Since the computer doesn't guess, it will have to loop up to 9x to find each quotient digit.  That's not "awful" but I WOULD call it "harder than everything else."
It's easier to do repeated subtraction - not for the whole division but for the partial sums that you get as you go along. You need to do the same number of iterations, of course, but subtraction is easier and faster than multiplication and you need one at the end anyway.

It is probably faster to do a BCD->binary conversion first and the a binary division and conversion back to BCD. With a binary division each step will either go or it won't so you just need one subract per step.
Quote
For a modern microcontroller (say, the AVR), I'm not sure why you should care about BCD.  Even a modest chip has much more RAM than (say) an 8052, so you might as well work with a digit-per-byte.  (How much RAM does typical calculator actually use?  Most calculators only have one or two "numbers" worth of user-accessible memory ("memory" value, current "result", current input.)
Nod, can't think of anywhere I'd use BCD; I suppose the odd bank might use it for financial calculations.

Edit: Actually I wouldn't be surprised if quite a lot of bank back office systems use BCD. The banks aren't overly fond of floating point as it introduces too many problems with rounding. That said they probably aren't doing it on Z80s :)
« Last Edit: September 13, 2015, 12:00:15 pm by grumpydoc »
 

Offline commieTopic starter

  • Frequent Contributor
  • **
  • Posts: 278
  • Country: gb
Re: SPI bit banging using the Z80 cpu
« Reply #35 on: September 13, 2015, 12:22:09 pm »
Hi all,

I just want to iterate some points, think of how a calculator works at a very simple level, you have keyboard(input), processor and display(output). You can't use your super byte efficient floats because going from keyboard to processor requires the use of string conversion and going from processor to display requires string conversion again, this causes string conversion errors ,on your register, every time you use strings for i/o.

My AVR compiler supports 64bit doubles but again whilst it gives 15 digits of precision, it will loose accuracy on i/o conversions.So, the super byte efficient floats offered within most compilers, that we all use, are not so good for calculator design. To solve this problem, we need a data type which avoids using strings all together and that's why BCD is used exclusively in calculator design. The problem is, our compilers do not support BCD data types, probably because they are very much byte inefficient. But, as westfw has pointed out, AVR's have tons of ram abundance, so there is nothing lacking there.

It might be interesting to implement a trivial set of digit-based calculations that implement grade-school longhand mathematical algorithms.  Everything but division should be easy.

Yep, I started playing around with my AVR compiler last night, basically primary school math and byte arrays.I'm going to try and build 16 digit bcd registers coupled with integer exponents, should be fun. ^-^

ALE500, I appreciate your input, I apologize as I was just trying to be competitive.

Here's an interesting link to a retro calculator: http://www.smbaker.com/nixie-tube-calculator-powered-by-a-raspberry-pi

Cheers all
commie
« Last Edit: September 13, 2015, 04:01:00 pm by commie »
 

Offline ale500

  • Frequent Contributor
  • **
  • Posts: 415
Re: SPI bit banging using the Z80 cpu
« Reply #36 on: September 14, 2015, 05:19:18 am »
Earlier Hewlett-Packard calculators (starting with the HP-35) used totally custom processors. These processors were able to do about 30 kOps/s. But the operations were done on 56 bit registers (14 BCD digits) and did BCD arithmetic. On the hpmuseum.org site, there is a working HP-45 simulator. You can check the algorithms used there. The Ti-8x (except the 89) used very similar algorithms but differently implemented due to the processor nature.

You can use python and Decimal to get nice results... You can also check the WP-34 sources (it uses lib Decimal developed by IBM).
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf