Need help with Z80 code

Thread Starter

AldoLinklot

Joined May 6, 2009
4
FYI! This is for a school project. I just need some guidance as my instructor seems uninterested.

I have to write some code for the Z80 that will execute two instructions then copy those instructions to 2000H then goto 2000H and execute those instructions there then return to the original program and delete the instructions that were copied to 2000H

Here is what we start with:

Rich (BB code):
ORG 1800H

ADD A,B
ADD A,C
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
HALT
I have to replace the NOP's with the new instructions.

Here is where I am:

Rich (BB code):
  ORG 1800H
  ADD A,B
  ADD A,C
  LD  A,(1800H)
  LD  (2000H),A
  LD  A,(1801H)
  LD  (2001H),A
  ORG 2000H
  ORG 180EH
  LD  A,00H
  LD  (2000H),A
  LD  (2001H),A
  HALT
My problem is after copying the opcode to 2000H and 2001H and then going there using ORG 2000H, I dont know how to make the instructions in that memory actually execute before returning to 180EH.

Can anyone give me a little insight or just slap me in the head and tuen me in the right direction if this is all wrong?

Thanks
Aldo
 

DonQ

Joined May 6, 2009
321
'and then going there using ORG 2000H"

ORG doesn't "go there". It only moves the location where the assembler is placing the code you write after the 'ORG' directive.

Look at the difference between an "assembler directive" and a "Z80 instruction". Then look at the Z80 instruction "JP" and "JR".

You also need to learn how to use labels (another assembler directive that will make your life easier, along with anyone who will ever have to use your code).

After that, you might want to look at "LDIR".
 

Thread Starter

AldoLinklot

Joined May 6, 2009
4
Ok, it appears LDIR would just be used to actually copy the instructions to 2000H if I setup DE HL and BC correctly something like this

Rich (BB code):
Start:    LD BC,02H
          ADD A,B
          ADD A,C
          LD  HL,(0003H)
          LD  DE,(2000H)
          LDIR
if thats correct, it just replaces my 4 previous LD instructions.
I still have the same problem. Changing my ORG 2000H to JP 2000H gets me to 2000H but once there, how do I make the instruction stored there(in this case 80 for ADD) actually execute.

Rich (BB code):
          ORG 1800H

Start:                     LD BC,02H
                           ADD A,B
                           ADD A,C
Setup locations:           LD  HL,(1803H)
                           LD  DE,(2000H)
                           LDIR
                           JP  2000H

Execute at 2000H:    Now that Im here, how do I make the 
                     80 stored here actually execute like 
                     an instruction.

Return to original:        JP 180EH
                           LD  A,00H
                           LD  (2000H),A
                           LD  (2001H),A
End:                       HALT
 
Last edited:

Thread Starter

AldoLinklot

Joined May 6, 2009
4
Thanks for the help DonQ Ive figured it out.

LDIR would probably be a more efficient way to setup the instructions at 2000H on but I dont have time to set it up that way.

The key is to setup HEX code for the add instructions and the JP instruction going back to the original spot

IE the memory map starting at 2000H would read something like this

80 81 C3 18 23

Once that is setup correctly, using a JP 2000H to get there will automatically run through that code first doing the two adds and then at 2002-2004 the JP back to the original area would execute.

Again, thanks for the help DonQ. Sometime we just need that little spark.
 

DonQ

Joined May 6, 2009
321
The JP instruction loads the PC (program counter) with the address of the next instruction to execute. Just doing the jump executes the instruction at that address, same as if it was the next instruction in line. Then when you're done, JP back to the original code.

(Note: you could also do this as a CALL nn, RETURN.)

Here is more what I was meaning by use labels. When you do this, you don't have to count the number of bytes of the instructions. You let the assembler do it for you.
Rich (BB code):
            ORG   1800H
START:      
            LD    BC,02H
COPYSTART:  
            ADD   A,B
            ADD   A,C
COPYEND:
            LD    DE,COPYSTART          ; COPY FROM
            LD    HL,START2             ; COPY TO
            LD    BC,COPYEND-COPYSTART  ; FOR THIS # OF BYTES
            LDIR                        ; MOVE THE CODE
            JP    START2                ; GO THERE AND EXECUTE IT
RESTART:
            LD    A,NOP ; SOME ASSEMBLERS LET YOU DO THIS
                        ; OTHERWISE, LD A,00H (Z80 NOP IS 00H)
            LD    (START2),A
            LD    DE,START2
            LD    HL,START2+1
            LD    BC,COPYEND-COPYSTART-1 ; ALREADY PUT IN ONE NOP
            LDIR
            HALT  ; HALT HERE, or whatever


            ORG   2000H
START2:     
            DS    COPYEND-COPYSTART   ; DEFINE SPACE, AN ASSEMBLER DIRECTIVE
                                      ; DEFINES AN UNITIALIZED SPACE OF THE STATED SIZE

            JP    RESTART    ; ONCE YOU JUMP, YOU WILL NO LONGER EXECUTE CODE BELOW HERE
END:
This is overkill, but supposed you wanted to add some more instructions? With this version, you just put the instructions between the CopyStart and CopyEnd labels and everything else is handled for you.

Didn't syntax check this, working from memory, but this should give you the idea.
 

Thread Starter

AldoLinklot

Joined May 6, 2009
4
I understand the use of the labels, they do make life easier.

Problem is I had to follow the format as originally posted, just replacing NOP's with other instructions.

About the jump, I was under the impression that JP address would just bring you to a address and then look for the next instruction the programmer actually entered. After your previous post I researched it a little more and realized it worked the way you said in the last post.

With that knowledge I was able to do what I needed to do.

I hesitate to post my finished code because I noticed there is another student from what appears to be the same class on this forum asking a question about the other problem, the PIC one.

I wouldnt want the same code to come in on someone elses paper and I get accused of collaboration.

But again, your second to last post pointed me in the right direction and I was able to get through from there.

Thank You
Aldo
 

tr1p1ea

Joined Jul 29, 2009
1
You could use 16-bit load/store and call, maybe something like this:

Rich (BB code):
ORG 1800H

ADD A,B
ADD A,C
LD HL,(1800H)        ; load 2 bytes starting at 1800H into HL (2 instructions)
LD (2000H),HL        ; store 2 bytes in HL to 2000H
LD A,C9H             ; opcode for RET
LD (2002H),A         ; store to 2002H after previous 2 instructions
CALL 2000H           ; call 2000H, will execute instructions and return
LD HL,0000H          ; load H and L with opcode for NOP
LD (2000H),HL        ; store to 2000H
LD A,00H             ; load A with opcode for NOP
LD (2002H),A         ; store to 2002H (clear RET)
HALT
 
Top