I want to do hello world in CP/M (Yes, this isn't strictly z80, but the 8080 is close enough). My code is:


Code:
WRITESTR: EQU 9h
BDOS: EQU 5h
ORG 100h
        MVI C, WRITESTR
        LXI D, HELLO
        CALL BDOS
HELLO:  DB "Hello World!$"


But my Hello.prn output is:


Code:
 0009 =         WRITESTR: EQU 9h
 0005 =         BDOS: EQU 5h
 0100           ORG 100h
 0100 0E09              MVI C, WRITESTR
 0102 110801            LXI D, HELLO
 0105 CD0500            CALL BDOS


Which means that the label isn't being assembled. Anyone know why it isn't working?

Moved by Merth to General Programming. The only thing "close enough" to z80 to be in the z80 forum is z80.
I don't see how you can assume the label isn't being assembled. The "LXI D, HELLO" hex is 110801, which is opcode 11, argument 0108 (assuming this is little-endian, or 0801 if it's big-endian). You should have "ret" or whatever the CP/M equivalent is after the call to BDOS, but other than that I see nothing wrong. Presumably whatever a .prn output is doesn't show constants/data fields?
KermMartian wrote:
I don't see how you can assume the label isn't being assembled. The "LXI D, HELLO" hex is 110801, which is opcode 11, argument 0108 (assuming this is little-endian, or 0801 if it's big-endian). You should have "ret" or whatever the CP/M equivalent is after the call to BDOS, but other than that I see nothing wrong. Presumably whatever a .prn output is doesn't show constants/data fields?


I'm saying that it isn't being assembled because that value points to nothing. What the .prn output is is the assembled output. There is nothing else in hello.hex but 0s.
Which assembler are you using?

A number of tools require that each line in a text document ends in a newline (this is the reason for the double .end in TASM source code; you only need one, but it needs to have a newline after it). Your assembler may be ignoring the final line in your program if it doesn't have a newline after it. You may also need an END statement in there.

You need to jump back to $0000 after your program has executed - stick a RST 0 after your call to BDOS.

Here's a version that works in M80 (in superior Z80 syntax):


Code:
.Z80

WRITESTR EQU 9h
BDOS     EQU 5h

ORG 100h
   LD C,WRITESTR
   LD DE,HELLO
   CALL BDOS
   RST 0

HELLO:
   DB "Hello World!$"
   
   END

Hello, I know this is a bit dated of a question, but I wanted to add a quick bit to it, just for anyone trying to learn assembler programming for CP/M systems. I'd ran into this page while doing so, and it caused a bit of confusion, so here's my take on the issue (with a few side notes as well)

Assuming that you are using the built in ASM.COM assembler that comes packaged with CP/M, it may be due to using double quotes (") for your string, with the assembler it requires you to use single quotes ('), otherwise it throws a fit. I believe that would explain why HELLO, the label, is pointing to the correct address (0108h) while the string itself isn't present in the assembled binary/hex.


Code:

WRITESTR        EQU 9h
BDOS            EQU 5h

ORG     100h
        MVI     C,WRITESTR
        LXI     D,HELLO
        CALL    BDOS
        RST     0

HELLO:  DB 'Hello World!$'

        END     100h


Then the PRN output file should be something along the lines of this, mine may not be 100% accurate as I don't have a system to check it on currently

Code:

0009 =       WRITESTR        EQU 9h
0005 =       BDOS            EQU 5h

0100         ORG     100h
0100 0E09            MVI     C,WRITESTR
0102 110901          LXI     D,HELLO
0105 CD0500          CALL    BDOS
0108 C7              RST     0

0109 45656C6CHELLO:  DB 'Hello World!$'

0116         END     100h



Here are some non-essential side notes, which may be helpful to those just starting off-
    ▪ ASM.COM will only work for 8080 syntax; it does NOT accept the z80 style syntax. the z80 is a the newer version of the 8080, therefore all binaries written for the 8080/8085 should run fine on the z80. being that the z80 has more op codes than the 8080 does, this only is guaranteed one way.
    ▪ Generally, its a good idea to add "RST 0" to the end of you code block, as without it the system will try to execute your data as code, and on the off chance that no error is found there, then it will continue falling through memory until it finds a "CALL 0", "JMP 0", or encounters an error. which is not ideal-
    ▪ Though optional with the ASM assembler, it is good practice to have an "END 100h" at the end of your program. This tells the assembler where the starting address should be, in most cases, for CP/M, you will want to start at the base of the TPA (i.e. 100h)


Please note that the most of this is verry specific to CP/M and the supplied ASM.COM assembler.
Slight necropost but I was browsing the forums and found this - thanks for stopping by and providing clarification!
It may be worth adding that CP/M 3 comes with MAC as its supplied assembler in place of CP/M 2's ASM. It's a macro assembler and does support the Z80 via the supplied Z80.LIB which defines the appropriate macros but this is a particularly cursed combination of Z80 features with Intel-esque mnemonics and syntax, e.g. LD (IX+D),NN would need to be written MVIX NN,D.

If you're going to be writing Z80 code on CP/M I still recommend Microsoft's M80 as that has a Zilog-compatible Z80 mode. Smile
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement