Author Topic: z80 division  (Read 13437 times)

0 Members and 1 Guest are viewing this topic.

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1668
  • Karma: 133
    • View Profile
z80 division
« on: June 17, 2008 »
hi all ive been tinkering about again and i got stuck with divison. do you have to do a divide on the current screen_addr byte from left to right to get to the next pixel location ie 128 64 32 16 8 4 2 1 or is there an easyer way of moving about pixel wise in screen address space.

if divison is the only way then is srl a the only option i have or is there another way that can divide by more than 2 at a time.

cheers!
« Last Edit: June 17, 2008 by ninogenio »
Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1294
  • Karma: 466
    • View Profile
    • my stuff
Re: z80 division
« Reply #1 on: June 17, 2008 »
could you be a bit more specific about what you are trying to achieve and what specific hardware you use?
(edit: ok, looking at your other posts your hardware is obviously zx...)

seems like you are talking about "shifting" to address a single bit in a byte (so you are probably using a monochrome video-mode).
division, on the other hand, is an issue on its own.
generally you have to organize your code in such a way, that you simply know which pixel (bit) is next.

Quote
is srl a the only option or is there another way that can divide by more than 2
two srl's can divide by four ;)
« Last Edit: June 17, 2008 by hellfire »
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: z80 division
« Reply #2 on: June 17, 2008 »
You can mul or div by powers of 2 using shifts.  lsl or asl multiply by 2, lsr or asr divide by 2.  But if you want 'real' division then either:
a) don't do division.  Think of a different algorithm.
b) use repeated subtraction (11/2=11-2-2-2-2-2) 5 lots of 2 can be subtracted.  11/2=5.
c) use multiplication 11*(1/2)==(1/2).
d) you can write a specific routine to do your division.
e) you can do b or c using self writing/modifying code.
f) don't do division.

Jim
Challenge Trophies Won:

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1668
  • Karma: 133
    • View Profile
Re: z80 division
« Reply #3 on: June 17, 2008 »
thanks guys,

@jim i really think a) is the the best option on the zx and really quite acceptable most times.

im just trying to get my head around pixel pefect movement and its really hard to do especially if the graphic is two or three bytes in x and y.

do you guys know any specific algo that will take an x and a y for a graphic and move the screen ptr to the correct byte and bit shift the gfx to the correct pixel carrying over any bits too the next byte?
Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1294
  • Karma: 466
    • View Profile
    • my stuff
Re: z80 division
« Reply #4 on: June 17, 2008 »
the stupid way:
don't move by single pixels but only by multiples of 8.

the easy way:
just move by a single pixel from one frame to another so you just need a single shift per byte.

the brute-force way:
store your graphics 8 times (each moved by one pixel) and copy the coresponding version.
Challenge Trophies Won:

Offline rain_storm

  • Here comes the Rain
  • DBF Aficionado
  • ******
  • Posts: 3088
  • Karma: 182
  • Rain never hurt nobody
    • View Profile
    • org_100h
Re: z80 division
« Reply #5 on: June 17, 2008 »
Yeah that is one complicated display mode alright with the bitmap memory starting sequentially then going off down a different street. Im still trying to figure out how to store pixels to the bottom half of the screen with no success :(

I can appreciate that things were very limited in those days but they could have hired a monkey to come up with a better solution. Exactly why are there gaps in the display memory is just beyond me and I have been tippy-toe-ing around the issue hoping that things will eventually make sense.

Challenge Trophies Won:

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1668
  • Karma: 133
    • View Profile
Re: z80 division
« Reply #6 on: June 17, 2008 »
@hellfire cheers mate all input is much appreciated, i have a rough sketch of what i want to do in my head so ill keep bashing away at it.

@rain they left gaps in video memory kepping in mind that there is no gfx acceleration and speed is a of big importance so that

inc h can be used and its pretty much the fastest instruction for a vertical movement available, it makes life hard for us but its quicker than simple memory manipulation.

when moving in a y direction this function works well i got it from the z80/.sna assembler refrence.

Code: [Select]
inc_row:
inc h ; move down one row
ld a,h
and 7 ; moved over a character cell ?
ret nz ; nz = no, all done
ld a,l
add a,32 ; update character row number
ld l,a
ret c
ld a,h
sub 8 ; if no carry, need to re-adjust h
ld h,a
ret nz
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: z80 division
« Reply #7 on: June 17, 2008 »
There's no gaps as such - the pixel screen memory is 32*192 bytes - but you're right, the first 32bytes are scanline 1, the 2nd 32bytes are scanline 8!
The Spectrum manual suggests thinking about the address in base 8.  See if that helps.

Jim
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: z80 division
« Reply #8 on: June 18, 2008 »
From what I gather from this thread and I might be completely wrong it might be something like this to get the byte address of a pixel given x and y:

address = screen_address + (y and 7)*768 + ((y and 248)shl 2) + (x shr 3)

with the exception of the last part of that involving x, the results of each step must be calculated to 16 bit before doing the addition.

As for how to shift the pixels for drawing a bitmap sprite or something to the screen I can't think of anything yet.

EDIT: still not sure if that's right.
« Last Edit: June 18, 2008 by Stonemonkey »

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1668
  • Karma: 133
    • View Profile
Re: z80 division
« Reply #9 on: June 20, 2008 »
after a little mess around on the calculator, im not shure thats quite right fryer,

i dont think an algo is possible on the spectrum after looking a bit deeper, because of the weird mapping.

each screen row on the speccy is 32 bytes or 256 bits/pixels. the problem comes in on the 33 byte as this points to the 8th scanline and the 65 byte points to the 16th scanline and so on. the 257 byte however points to the second scanline. if you draw it on paper it turns into a real mess belive me :)

@jim your right if you convert y to octal and swap the least two significant bits then convert back to decimal your looking at the number bytes down you need! for example.

if i wanted to find y = 1

1 converted to octal is 001 swaped is 010 and converted to decimal is 0x64 + 1x8 + 0 = 8 row!! cool stuff.
« Last Edit: June 20, 2008 by ninogenio »
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: z80 division
« Reply #10 on: June 23, 2008 »
Quote
the 257 byte however points to the second scanline.

Ah, didn't realise that, sorry.

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: z80 division
« Reply #11 on: July 01, 2008 »
Another possibility on the ZX Spectrum is to use the ROM routines for division (rst 28h).  You can look up the details in the Incomplete Spectrum ROM Disassembly on WoS.

Jim
Challenge Trophies Won:

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1668
  • Karma: 133
    • View Profile
Re: z80 division
« Reply #12 on: July 02, 2008 »
yeah ive been looking into various rom routines,

and they can be really handy. i was actually thinking of asking how fast are they i mean using a routine such as divide from machine code will it execute much faster than calling it in basic and is it better to use tailor made routines where ever applicable for speed and rom routines for generalized stuff (and where memory becomes tight) like lots of diffrent divides in a tight loop where tailor made routines with safety checks and such chopped out just wont work.
« Last Edit: July 02, 2008 by ninogenio »
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: z80 division
« Reply #13 on: July 02, 2008 »
Any routine should execute at the same speed no matter where it's called from, what might make a difference is how the data the routine needs gets into the right place before the routine is called. I don't know but I doubt there's any fixed point routines other than for dealing with integers and floating point calculations will probably be pretty slow compared to some well written fixed point routines.

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: z80 division
« Reply #14 on: July 02, 2008 »
The ROM only does floating point - in ZXBASIC you only have floating point numbers :)  Bit like yabasic!

Jim
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: z80 division
« Reply #15 on: July 02, 2008 »
You're joking! that must've been terrible for stuff like loops and poking with address pointers/data.

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1668
  • Karma: 133
    • View Profile
Re: z80 division
« Reply #16 on: July 03, 2008 »
lol yeah fryer the zxbasic is pretty useless for anything other than calling machine code, its painfully slow.

although the one thing i find incredable usefull is the usr command as it runs the machine code and returns the bc register pair by default, so you can have say a really quick algo stored in memory and do let a=usr xxxxxx and in machine code you just drop whatever answer you like into bc before ret'ing.

with some assembler's you can also pass basic variables to the machine code routine thus creating fully fledged functions.

i havent went into that to much yet though im just messing around getting my head around everything.
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: z80 division
« Reply #17 on: July 03, 2008 »
The floating point number representation wasn't IEEE, they had some cheeky short cuts, but yup, it didn't help the speed :)

Jim
Challenge Trophies Won: