Author Topic: how does the z80 LDIR instruction work?  (Read 22213 times)

0 Members and 2 Guests are viewing this topic.

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1668
  • Karma: 133
    • View Profile
ive pulled a little clear screen function out of one of my books and it works just fine but i dont quite understand how ldir does it's job.

Code: [Select]
// ninos first z80 assembler mess around

// some screen constants
screen_addr: equ 16384
attr_addr: equ screen_addr+6144


// program placement in ram
org 24768


// main loop
MainLoop:
call ClearScreen
jp MainLoop


// clear screen subroutine
ClearScreen:
push af
push bc
push hl
ld hl,screen_addr
ld de,screen_addr+1
ld bc,6143
ld (hl),0
ldir
pop hl
pop bc
pop af
ret

acording to the book ldir will move hl 6143 times so does that mean that ldir is linked with bc or does it simply get its value from bc because bc was the last register loaded with a value.
Challenge Trophies Won:

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17412
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: how does the z80 LDIR instruction work?
« Reply #1 on: June 06, 2008 »
Shit, you're taking me back a long time here Nino :D

Hehe, apologies if this is wrong, because the last time I used Z80 was when I was about 13 years old, here's what your code is doing..

By the way LDIR is short for load, increment and repeat.

Code: [Select]
push af : preserve these three registers
push bc
push hl

ld hl,screen_addr : point hl at the start of the screen
ld de,screen_addr+1 : put loacation +1 into register pair de
ld bc,6143 : bc holds the amount of times for ldir to repeat
ld (hl),0 : moves 0 into hl
ldir
pop hl : restore the three registers
pop bc
pop af

I think that a by product of ldir will make de=hl and therefore clear the screen that way.

But like I said, I have slept since I used Z80 last ;)
I dont think I'm far out though.... Need a Speccy to try it out on!
Shockwave ^ Codigos
Challenge Trophies Won:

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1668
  • Karma: 133
    • View Profile
Re: how does the z80 LDIR instruction work?
« Reply #2 on: June 06, 2008 »
that makes a lot of sense shockwave cheers!

so if i am right ldir would take registers as so.
a source pointer a dest pointer and a counter.

cool but i wonder how fast it is ill try out some test's.

btw if you wish to build some of this stuff go here.
http://www.worldofspectrum.org/utilities.html

and pick an assembler from down the list i am using z80/.sna assembler and it seems to be doing what i want at this time.
« Last Edit: June 06, 2008 by ninogenio »
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: how does the z80 LDIR instruction work?
« Reply #3 on: June 06, 2008 »
I found only one page so far with instructions for the z80 and that page only named the instructions it didnt give away any details of what operation they did / its arguments / clock cycles etc, thats a real shame given how widely available similar info for the 6502 is. I would like to give the z80 an honest go myself but I think I will hold off until I have some more free time. But at the moment it is tempting.

Challenge Trophies Won:

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17412
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: how does the z80 LDIR instruction work?
« Reply #4 on: June 06, 2008 »
If you do some I will too, maybe we can start a Z80 revival here :)
« Last Edit: June 06, 2008 by Shockwave »
Shockwave ^ Codigos
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: how does the z80 LDIR instruction work?
« Reply #5 on: June 06, 2008 »
I think I will I have chosen the spectalutor + Z80 (sna) assembler Just reading through the manuals now.

Challenge Trophies Won:

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17412
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: how does the z80 LDIR instruction work?
« Reply #6 on: June 06, 2008 »
lol I hadnt even got as far as downloading an emulator yet :)
Shockwave ^ Codigos
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: how does the z80 LDIR instruction work?
« Reply #7 on: June 06, 2008 »
Best of luck

This page is the best opcode reference I have found so far it gives a description of operation counts clock cycles tells you what flags may be affected and tells you how many bytes each requires. Everything you need to know
http://www.ftp83plus.net/Tutorials/z80inset_fullA.htm

This is more compact and has all the above except description of operation, better for looking at if you already know what each opcode do
http://www.shiar.org/product/z80.txt

Challenge Trophies Won:

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1668
  • Karma: 133
    • View Profile
Re: how does the z80 LDIR instruction work?
« Reply #8 on: June 06, 2008 »
very cool links rain! k+,

and as for the ldir instruction i found a detailed diagram on it's actions in my book it increases hl and de as well as simultaniously decreasing bc so it is tied to those registers. somehow though i suspect this is slower than some other methods.
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: how does the z80 LDIR instruction work?
« Reply #9 on: June 07, 2008 »
There's no special ordering, the LDIR instruction works with all the current values of the registers.
It loads the data from the memory at (hl) and stores it at (de).  It does this bc times.
Effectively it does
Code: [Select]
loop:
ld temp,(hl)
ld (de),temp
inc hl
inc de
dec bc
jr nz loop
It does this in a rather respectable 16 cycles per byte moved.

Now, the code you posted does a trick.  The Z80 doesn't have a block clear instruction, only a block move instruction.  What's happening here is it's block moving an overlapping memory area - normally you don't want this - but in this case it does something like

hl = screen address
de = screen address + 1
ld (hl),0  - clear the first byte of screen memory
ld bc,size of screen
ldir - copy the blank byte at screen address (hl) to screen address+1 (de) and repeat

As ldir executes it keeps moving that blank byte one space further on, and then copying it to the next location.
This might seem wasteful - re-reading the 0 as many times as writing it, but at only 16 cycles, it's faster than doing a loop which just stores zeroes.

Jim
« Last Edit: June 07, 2008 by Jim »
Challenge Trophies Won:

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1668
  • Karma: 133
    • View Profile
Re: how does the z80 LDIR instruction work?
« Reply #10 on: June 07, 2008 »
cool cheers jim,

on the list that rain linked too it says the clock cycles for ldir are 21/16 and in my book it says that ldir takes up 21 so does that mean it can take either 21 clock cycles or 16 clock cycles?
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: how does the z80 LDIR instruction work?
« Reply #11 on: June 07, 2008 »
When there are two speeds it usually means something like 16 clock cycles would be its normal operation speed but if it crosses a page boundary then it may take 21 clocks.

Challenge Trophies Won:

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1668
  • Karma: 133
    • View Profile
Re: how does the z80 LDIR instruction work?
« Reply #12 on: June 07, 2008 »
ah right cheers rain!
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: how does the z80 LDIR instruction work?
« Reply #13 on: June 08, 2008 »
That's not right.  If you see this it means that it takes 21 cycles if it loops and 16 cycles if it doesn't.  For branches (jr cc) it's the same - 5 extra cycles if the branch is taken.  (call cc is 7 extra).

Taking in to account these extra 5 cycles it might appear that this is a rubbish way to clear memory - but then consider this 'simpler' example:
Code: [Select]
ld a,0
ld hl,screensize
ld de,screen_ptr
ld bc,65535
loop:
ld (de),a        7
inc de           6
add hl,bc       11
jr nz loop       12
Wow!  That's 36 cycles!
(You have to use add hl,bc because dec hl doesn't set any condition flags.)

The Z80 doesn't have any pages, it has a flat 64Kb address space.  On the Spectrum 48K this is split into 3 main areas, 16Kb ROM, 16Kb screen, variables, and program data, 2x16Kb of general purpose memory.
It's the 2nd 16Kb that is interesting.  The memory bandwidth for that RAM bank is shared between the CPU and the ULA (the display chip).  Depending which bit of the screen is being updated by the ULA can mean you stall reading for up to 6 extra cycles.  That might make the LDIR clear a bit worse because it is doing 6Kb of reads as well as 6Kb of writes, at an average of about 3 extra cycles per move, but that's still only 24.
Check out the 'Contended Memory' section here
http://www.worldofspectrum.org/faq/reference/48kreference.htm

By the way, Spectaculator is shareware and cost £16 to register.  ZX SPIN is free, and it has a built-in assembler - you might want to try that!

Jim

« Last Edit: June 08, 2008 by Jim »
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: how does the z80 LDIR instruction work?
« Reply #14 on: June 08, 2008 »
so its 21 if a branch is required and 16 if execution falls through?
on a side note, how does the cpu address 128k?

that ZX SPIN sounds a lot more useful

Challenge Trophies Won:

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17412
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: how does the z80 LDIR instruction work?
« Reply #15 on: June 08, 2008 »
This would appear to have the answers you want Rain,

http://www.worldofspectrum.org/faq/reference/128kreference.htm
Shockwave ^ Codigos
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: how does the z80 LDIR instruction work?
« Reply #16 on: June 08, 2008 »
Yup, Rain, that's absolutely right - 16 to copy the byte and change the register values (flags too), 5 to loop back.  Effectively the CPU 'forgets' to increment the pc register after doing an ldi instruction.  In 128K mode, 16Kb pages can be swapped in and out.  eg. There are 2 16Kb ROMs on these machines, and the 16Kb containing the screen can be swapped, allowing real double buffering.  Don't think anyone really used that though!  Shockwave's link has all the details.  WoS is the gold standard for this kind of information :)

Jim
Challenge Trophies Won:

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1668
  • Karma: 133
    • View Profile
Re: how does the z80 LDIR instruction work?
« Reply #17 on: June 08, 2008 »
cool stuff guys there is a load to digest here!

just wondering what methode was most common for displaying gfx on the speccy, ive looked at the example that comes with the z80/.sna asembler and the guy seems to draw directly to the screen a scan line at a time and during updates to the position of the gfx he clears and redraws the gfx a scanline at a time so in effect he never does a full screen clear this way is quick but is prone to tearing, is this the way most folks do it?

i wonder how good the 128 would be at double buffering, it would definitly be worth a go!
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: how does the z80 LDIR instruction work?
« Reply #18 on: June 13, 2008 »
Since there's only one screen, most programs just draw to the screen and damn the tearing.  As the years went on though, people got cleverer and synced the drawing just behind the ULA so no tearing.  Hard to do though, and most people just stuck with it.  If you look at some of the games that had rainbow fx - AgentX II, Zub, Uridium, etc, people were drawing a few bytes in front of the ULA, so they could change the 8x8 colour squares every scanline and get 8 colours per square!

I only ever saw one demo of page flipping on a 128Kb, and it was a flickery mess.  I don't recall anyone using it.

Jim
Challenge Trophies Won:

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1668
  • Karma: 133
    • View Profile
Re: how does the z80 LDIR instruction work?
« Reply #19 on: June 13, 2008 »
yeah i read on the wiki that 8 colors per attribute square was possible and i really would like to have a go at that but for now ive stuck with the norm the only draw back is that you have to keep note of the sprites last position to erase it as a full screen clear per frame on the zx isnt really feasible.

i found a web site a while back and cant remeber the name of the site but it had some 128k demos ive attached my favourite, and im sure this must do double buffering.

but i cant understand how this sort of rendering is possible on the spectrum, do you guy's have any idea?
« Last Edit: June 13, 2008 by ninogenio »
Challenge Trophies Won: