Re: A86: djnz, jr and jp


[Prev][Next][Index][Thread]

Re: A86: djnz, jr and jp




I assume you're talking about programming on the calc (or else you'd use an
assembler).  Writting code in hex without an assmbler isn't difficult, just
make sure you write it out completely and run through it to make sure you've
worked out the bugs.  If you don't, you'll have to recalculate your jumps
and other addresses again (takes a while) or worse, crash your calc.

You need to think about what the code actually looks like once it comes out
of the assembler.  The .org instruction tells the assembler to generate all
labels (for absolute jumps) starting at that address.  For example, ".org
_asm_exec_ram" means that the code will be executed from $d748.  Also, do
yourself a favor and print off z80time.txt (at ticalc.org), as it comes in
very handy . (I found the best way to print it is use MS-Word on two columns
in 9 point Courier New, with column width at 2.95" and spacing at 0.1".
Fits nicely on 3 pages that way.  I'll send the file if anyone wants.)

--
JP's (absolute) jumps are simple.  These jump to an absolute address.
Format:

JP $NN = C3 XX XX

XX XX is the address to jump to.  Remember that the z80 uses big-endian
format (least-significant-byte [LSB] first, MSB last) to store 16-bit
numbers, so the addresses are backwards.  This goes for all instructions.
To jump to $D78A

C3 8A D7

To calculate the address to jump through, count the bytes of your program up
to that address (example code...does nothing):

D748   nop
D749   ld a,4
D74B   jp $d751      ----|      this will jump to...
D74E   ld ($d801),a      |
D751   inc hl       <----|      here!
D752   add hl,de
...

--
JR's/DJNZ's are similiar to JP's, but they are relative.  Relative means
that they will jump a certain offset forwards or backwards from their
position in the code.  They are usually easier to calculate than JP's.
Format:

JR $N+2 = 18 XX
DJNZ $N+2 = 10 XX

Note that each of these instructions are 2 bytes, not 3.  This is because
they can only jump up to 127 bytes, forward or backwards.  The numbers are
signed.  So to jump backwards, set bit 7.  Also note the $N+2.  The $ symbol
stands for the instruction pointer.  They will jump whatever number is
specified, plus two.  So the range is actually 129 bytes forwards, 125
backwards.  Specifying zero bytes would jump (or move the instruction
pointer or program counter, PC) to the beginning of the next instruction.
Specifying -2 ($FE) would jump back onto itself, creating an endless loop.
Example:

label1:
  r label1     ; 18 FE

  jr label2    ; 18 04
  inc hl       \
  ld a,b        > these instructions take up 4 bytes
  neg          /
label2:
  nop

DJNZ is exactly the same as JR...

 ld b,4
loop:
 nop           \
 ld a,$fe       > 5 bytes here
 out (1),a     /
 djnz loop     ; 10 F9

If you need more help and examples, write up a program, assemble it and
check out the hex listing.  It's not too difficult after a little bit of
getting used to, and comes in handy if you plan to write self-modifying
code.

Hope this helps,

--
David Phillips <david@acz.org>
http://www.acz.org/

----- Original Message -----
From: Dave VanEe <dvanee@dowco.com>
To: <assembly-86@lists.ticalc.org>
Sent: Friday, January 08, 1999 8:30 PM
Subject: Re: A86: djnz, jr and jp


>
>>
>>well, it probably wouldn't be "quite simple" to make.  and besides, when
>>you're dealing with assembly, one bug and you lose all your code.  it's
much
>>safer to always have it on the computer so that you don't lose all your
work
>>by a missing "ret" or a messed up branch or something.
>>
>>
>
>despite all this choas and crap...I'm quite interested now to know if
>ANYONE knows how to use jp/jr/djnz when programming in hex.
>
>