More CP/M Assembler Programming - CP/M

This is a discussion on More CP/M Assembler Programming - CP/M ; Greetings! Here's the first program I got to work in CP/M using Assembler Language just a few days ago. It's written for a Z-80 processor which is the processor that my CP/M+ system uses (it's a Commodore 128). It simply ...

+ Reply to Thread
Results 1 to 6 of 6

Thread: More CP/M Assembler Programming

  1. More CP/M Assembler Programming


    Greetings!

    Here's the first program I got to work in CP/M using Assembler Language just a few days ago. It's written for a Z-80 processor which is the processor that my CP/M+ system uses (it's a Commodore 128). It simply displays 'Hello, World!' on the system console.

    Does anyone have any pointers or corrections on how I could have written this in a more efficient manner?

    ORG 0100H
    BDOS EQU 05H ;Call 5 to run BDOS Functions
    LD C,9 ;Load C with 'Prnt String' rotine
    LD DE,Msg ;point DE reg pair to Msg string
    CALL BDOS ;Calling BDOS prints string to con
    LD C,0 ;Load C with 'Terminate' routine
    CALL BDOS ;Return to CP/M OS
    Msg: DB 0DH,0AH,'Hello, World!',0DH,0AH,'$'
    END

    Hopefully this formatting turns out... I wrote this message using RTF in Courier so that it would line up but I don't know if it will line up correctly in your newsreaders. I could use some pointers on that as well..

    Nate



  2. Re: More CP/M Assembler Programming

    "Nate Brazil" wrote:

    Here's the first program I got to work in CP/M using Assembler Language just a few days ago. It's written for a Z-80 processor which is the processor that my CP/M+ system uses (it's a Commodore 128). It simply displays 'Hello, World!' on the system console

    Does anyone have any pointers or corrections on how I could have written this in a more efficient manner?

    ORG 0100H
    BDOS EQU 05H ;Call 5 to run BDOS Function
    LD C,9 ;Load C with 'Prnt String' rotine
    LD DE,Msg ;point DE reg pair to Msg string
    CALL BDOS ;Calling BDOS prints string to con
    LD C,0 ;Load C with 'Terminate' routine
    CALL BDOS ;Return to CP/M OS
    Msg: DB 0DH,0AH,'Hello, World!',0DH,0AH,'$'
    END

    That's the simplest way to do it, using an absolute non-macro 8080 assembler like ASM. (Note that there is not one single extended Z-80 opcode in your program. ASM and SID will handle it without any problem.) My criticism is that it is too much compressed. When you will have source code files one hundred pages long, you will want to do what people writing long documents (like novels) do: use paragraphs, chapters, etc. (Macros are very useful in that they allow to compress repetitive code. For example, you could define a PRINT macro at the beginning of your program, and simply write: PRINT 'Hello, World!' in your program. This is explained in Chapter 11 of "The Amstrad CP/M Plus".)

    ; HELLO.ASM (I always put the name of the file INSIDE the file.)
    ; ---------
    ;
    ; Pseudo-ops (read below)
    ;
    ORG 0100H ; Standard CP/M COMmand file
    ;
    ; Equates (the more the better)
    ;
    lf EQU 0AH
    cr EQU 0DH
    BDOS EQU 05H ;Call 5 to run BDOS Function (No! Define the address of the entry point of BDOS...)
    ;
    ; Code area
    ;
    LD C,9 ;Load C with 'Prnt String' rotine
    LD DE,Msg ;point DE reg pair to Msg string
    CALL BDOS ;Calling BDOS prints string to con
    ;
    LD C,0 ;Load C with 'Terminate' routine
    CALL BDOS ;Return to CP/M OS
    ;
    ; Data area
    ;
    Msg: DB cr,lf,'Hello, World!',cr,lf,'$'
    ;
    ;Pseudo-op (Personally, I put "-----" lines before and after pseudo-ops, since they are not part of the program, but are directives to the assembler.)
    ;
    END

    This was the classical way. This classicism is coming from... punched cards, where each statement was punched on one cardboard card. Also, many assemblers, back then, were rigidly using the columns position of the text to decide: this is a pseudo-op, this is a label, this is a mnemonic, this is an operand, or this is a comment. With the free-format assemblers available under CP/M, you can rewrite the code area this way:

    LD C,9! LD DE,Msg! CALL BDOS
    ;
    LD C,0! CALL BDOS

    Note how much it compress, vertically, the code. Note also that assembly language places the parameters in the opposite way of much high-level programming language. In this case, most commonly-used compilers would use something like: BDOS (Print_String, Msg) and BDOS (System_Reset). In fact, it is possible to define a macro that will look like very much like a procedure call from a high-level PL, so your program would be... 2 lines long!

    Hopefully this formatting turns out... I wrote this message using RTF in Courier so that it would line up but I don't know if it will line up correctly in your newsreaders. I could use some pointers on that as well..

    I am also interested in how to display correctly ASCII files (with HT) under Windows and Google, since (for years) all my listings have been displayed atrociously by Micro**** programs. (Since I access the Internet from a cybercafe, I cannot modify what is available as "standard". Since the computer is locked, I cannot even add a font to get rid of those awful proportional characters!)

    To finish, your example was too much simple. Once you have tested all the system calls of CP/M Plus, the interesting thing becomes HOW to achieve a result (the algorithm). For the time being, get as much book as possible (I know that there are several books with titles like "(introduction to) CP/M assembly language". Personally, I started with "8080/Z-80 Assembly Language" by Alan Miller, who develops, step by step, a very rudimentary "debugger". What is interesting is not the result program, but the experience that you get by expanding, chapter after chapter, the program (not forgetting to debug it at each step!), study them (it took me one month just to follow all the steps in Alan Miller's book.), then come back.)

    Also, it is always better to use the best available tools. SID is so much superior to DDT that it is simply stupÓd to continue to use DDT. Get the manual, follow the sample debugging session until you know by hearth all the SID commands. Sooner or later, you will need a debugger, to debug your assembly language programs. Seeing the inside of an assembly language (the settings of the flags) as it is running is also VERY educative.

    (Charles Falconer mentioned the SLR assemblers. They arrived at the end of CP/M. Their only advantage is that, coming at the end, standards had been established (The main problem of the Z-80 chip was that, at the beginning, there was no standard for the mnemonics. In fact, 4 variations of extended Intel mnemonics were widely used. That's why you will see so many programs using (for example) TDL mnemonics in the CP/M Software Library (available on the Internet) or in old microcomputer magazines (like DDJ).), so they concentrated on speed. The Z-80 version is about 6 times faster than Micro****'s M80. However, for the sort of very simple programs you are likely to deal with during the coming months, any assembler as simple as ASM will do, even on a floppy disk, even with a Z-80 at 4-MHz.)

    Yours Sincerely,
    "French Luser"



  3. Re: More CP/M Assembler Programming

    Hi Nate
    When making comments try to not make redundent statements
    and use equates more. as an example,

    ; BDOS Calls to C register *********
    09 EQU PRTSTR ; Print String
    00 EQU TERM ; Terminate Program
    ; ******************

    Then in code
    LD C,PRTSTR ; Setup to print string

    Avoid such statements as "load C with". This is clear from the
    assembly
    code that that is being done. It is more important to comment why you
    are doing it then a reduntant statement of what you are doing.
    Commenting is probably the hardest part of coding. While some state
    there should be a comment on every line, sometimes, common operations
    don't require as many comments. An example might be:

    ..................
    ; Print my "HELLO WORLD" to the consol
    ; Setup and do BIOS CALL
    LD DE,Msg
    LD C,PRTSTR
    CALL BDOS
    ; Print done
    ..................

    The above is actually quite sufficient in commenting. Choice of names
    for equates can improve the readability of the code without added
    comments.
    Do avoid redundent statements as comments. They are only clutter with
    little added to the understanding of the code. Comments like:

    LD C,PRTSTR ; Setup Print String for later BDOS call

    It would be informative for code that might not be obvious( of course
    a BDOS call is commonly used in CP/M and is more obvious ). It
    might still be useful if the actual call to BDOS was not clearly inline
    with the register assignment.
    Most often, WHY is a better question to answer in a comment then
    WHAT. ( Don't forget that WHEN and WERE may also be needed in
    a comment )
    Take Care
    Dwight


    Nate Brazil wrote:
    > Greetings!
    >
    > Here's the first program I got to work in CP/M using Assembler Language just a few days ago. It's written for a Z-80 processor which is the processor that my CP/M+ system uses (it's a Commodore 128). It simply displays 'Hello, World!' on the system console.
    >
    > Does anyone have any pointers or corrections on how I could have written this in a more efficient manner?
    >
    > ORG 0100H
    > BDOS EQU 05H ;Call 5 to run BDOS Functions
    > LD C,9 ;Load C with 'Prnt String' rotine
    > LD DE,Msg ;point DE reg pair to Msg string
    > CALL BDOS ;Calling BDOS prints string to con
    > LD C,0 ;Load C with 'Terminate' routine
    > CALL BDOS ;Return to CP/M OS
    > Msg: DB 0DH,0AH,'Hello, World!',0DH,0AH,'$'
    > END
    >
    > Hopefully this formatting turns out... I wrote this message using RTF in Courier so that it would line up but I don't know if it will line up correctly in your newsreaders. I could use some pointers on that as well..
    >
    > Nate
    >
    >



  4. Re: More CP/M Assembler Programming

    On Sun, 16 Apr 2006 21:15:24 -0400
    "Nate Brazil" wrote:

    > Does anyone have any pointers or corrections on how I could have
    > written this in a more efficient manner?
    >
    > ORG 0100H
    > BDOS EQU 05H ;Call 5 to run BDOS Functions


    You might develop some procedures to organize your programs, such as
    grouping your equates (EQU) before your code declarations. It makes
    programs a little more readable.

    > LD C,9 ;Load C with 'Prnt String' rotine
    > LD DE,Msg ;point DE reg pair to Msg string
    > CALL BDOS ;Calling BDOS prints string to con


    This is correct, and a standard way of printing a string through the
    BDos.

    > LD C,0 ;Load C with 'Terminate' routine
    > CALL BDOS ;Return to CP/M OS


    While the above sequence is correct, you might consider replacing the
    "CALL" with a "JP" to reinforce the fact that the program is intended to
    terminate here and not return from the CALL (which in this case would
    attempt to execute the message as if it were code). Alternate methods
    of terminating the program (with a warm boot) are:

    JP 0 ; Jump to the Bios Warm Boot vector (3 bytes)

    or:

    RST 0 ; Execute a Restart 0 which 'calls' location 0 which
    jumps to the Bios (or RSX) warm boot where the Stack pointer is reset
    anyway. (1 byte)

    A little 'white space' (a blank line or two) to separate data elements
    from code elements might be a good thing here to improve readability.

    > Msg: DB 0DH,0AH,'Hello, World!',0DH,0AH,'$'
    > END


    Rather than using Hex and decimal numbers in your programs, you might
    consider using the following EQUates along with the one you already
    have:

    ; BDos Functions used here
    PRTLIN EQU 9
    EXITV EQU 0
    ; Control Characters used in this program
    CR EQU 0DH
    LF EQU 0AH

    Good Luck, and welcome to Assembly Programming

    Hal

  5. Re: More CP/M Assembler Programming


    "Hal" wrote in message
    news:20060418145232.0d24a7ca.halbower@verizon.net. ..
    > On Sun, 16 Apr 2006 21:15:24 -0400
    > "Nate Brazil" wrote:
    >
    >> Does anyone have any pointers or corrections on how I could have
    >> written this in a more efficient manner?
    >>
    >> ORG 0100H
    >> BDOS EQU 05H ;Call 5 to run BDOS Functions

    >
    > You might develop some procedures to organize your programs, such as
    > grouping your equates (EQU) before your code declarations. It makes
    > programs a little more readable.
    >
    >> LD C,9 ;Load C with 'Prnt String' rotine
    >> LD DE,Msg ;point DE reg pair to Msg string
    >> CALL BDOS ;Calling BDOS prints string to con

    >
    > This is correct, and a standard way of printing a string through the
    > BDos.
    >
    >> LD C,0 ;Load C with 'Terminate' routine
    >> CALL BDOS ;Return to CP/M OS

    >
    > While the above sequence is correct, you might consider replacing the
    > "CALL" with a "JP" to reinforce the fact that the program is intended to
    > terminate here and not return from the CALL (which in this case would
    > attempt to execute the message as if it were code). Alternate methods
    > of terminating the program (with a warm boot) are:
    >
    > JP 0 ; Jump to the Bios Warm Boot vector (3 bytes)
    >
    > or:
    >
    > RST 0 ; Execute a Restart 0 which 'calls' location 0 which
    > jumps to the Bios (or RSX) warm boot where the Stack pointer is reset
    > anyway. (1 byte)
    >
    > A little 'white space' (a blank line or two) to separate data elements
    > from code elements might be a good thing here to improve readability.
    >
    >> Msg: DB 0DH,0AH,'Hello, World!',0DH,0AH,'$'
    >> END

    >
    > Rather than using Hex and decimal numbers in your programs, you might
    > consider using the following EQUates along with the one you already
    > have:
    >
    > ; BDos Functions used here
    > PRTLIN EQU 9
    > EXITV EQU 0
    > ; Control Characters used in this program
    > CR EQU 0DH
    > LF EQU 0AH
    >
    > Good Luck, and welcome to Assembly Programming
    >
    > Hal


    Thanks everyone for the advice! I'm certainly glad I asked. I've received
    several good tips from you all!

    Nate



  6. Re: More CP/M Assembler Programming


    wrote in message
    news:1145378969.145536.113360@t31g2000cwb.googlegr oups.com...
    > Hi Nate
    > When making comments try to not make redundent statements
    > and use equates more. as an example,
    >


    [...snip...]

    Good advice Dwight. Thanks.



+ Reply to Thread