LDIR¶
- The Legendary LDIR
- Load And Increment with Style
- Description
- Performs
ldi
untilBC
= 0, effectively copyingBC
bytes of data fromHL
toDE
, whereHL
andDE
point to the start of their respective blocks.ldi ret po jr -5
- Uses
- Copying lots of data
- Sprite routines
- Copying graphical data from some buffer to the actual screen
- Filling lots of space with one (or more) bytes
- Results
Register/Flag 16-bit (non-ADL) 24-bit (ADL) S
flagNot affected Z
flagNot affected H
flagReset P/V
flagSet if BC
≠ 0 after the operation; else resetN
flagReset C
flagNot affected - Allowed Instructions
Instruction Opcode CC (ADL/non-ADL) CC (.S) CC (.L) ldir $ED, $B0 2F + (1R + 1W + 1)* BC
3F + (1R + 1W + 1)* BC
3F + (1R + 1W + 1)* BC
- Notes
- Interrupts can be triggered while this instruction is in progress (unless they are disabled using
DI
, of course). - Assuming you are copying hard-coded data and BC is NOT already set to the desired number of bytes, it is only faster to use hard-coded
LDI
s instead ofld bc,BytesToCopy \ ldir
if you are copying two bytes. Copying three bytes, the cycle times and size of the code are exactly the same (6 bytes, 6F+3R+3W+3). - If you want to copy a few more bytes than whatever number is in
BC
, it is both smaller and significantly faster to useINC BC
several times beforeLDIR
than a fewLDI
s after it. (INC BC
is one byte and only 1F (plus the extra 1R + 1W + 1 fromLDIR
) whereasLDI
is two bytes and 2F+1R+1W+1. So you just save one byte and 1F.)
- Interrupts can be triggered while this instruction is in progress (unless they are disabled using
- Examples
Filling a block of memory with a single byte
ld hl,StartOfData ld de,StartOfData+1 ld bc,SizeOfData-1 ld (hl),ByteToCopy ldir
Copy graphical data from vBuf2 to vBuf1
ld hl,vBuf2 ld de,vBuf1 ld bc,320*240 ldir
Set up a hard-coded 8bpp palette
ld hl,Palette_Start ld de,mpLcdPalette ld bc,Palette_End-Palette_Start ldir
A simple 8bpp rectangle drawing routine (credit: MateoConLechuga)
; INPUTS ; BC Width ; DE X-position ; H Height ; L Y-position ; (FillRect_Color) Color FillRect: ld a,h ; Store the height in A to be used as a loop counter ld h,160 mlt hl add hl,hl ; HL now contains the Y position multiplied by 320 add hl,de ; Add in the X position... ld de,vBuf1 add hl,de ; And the LCD memory location... ; Now HL is pointing to the first pixel of the rectangle dec bc ; Get the rectangle width minus 1 in BC (more on that later) FillRect_Loop: FillRect_Color = $+1 ld (hl),0 ; This is self-modifying code push hl pop de inc de ; Now DE = HL + 1 push bc ; Save BC for later ldir ; Copy BC (width-1) bytes from HL (first pixel of this row of the rectangle) to DE (next pixel) ; Now one row of the rectangle is done pop bc ; Grab BC again ld de,320 add hl,de ; Advanced HL one pixel down... sbc hl,bc ; And return to the left edge of the rectangle dec a ; Decrement our loop counter... jr nz,FillRect_Loop ; And repeat if we haven't finished ret
- See Also
- CPIR, LD, LDD, LDDR, LDI