• Please review our updated Terms and Rules here

CP/M 2.2 ASM File Format

Mike_Z

Veteran Member
Joined
Dec 1, 2013
Messages
1,713
Location
Near Milwaukee Wisconsin
I may have asked this question before, but have forgotten and can't find it on the forum. Can I make a test file on a newer computer and use it as a *.asm in CP/M. Here is what I did, which by the way didn't work. I wrote some CP/M code in Windows XP notepad as a text file. Named it TEST.ASM. Then copied it to my 8 inch disk using 22disk. I tried to access this file with ED.COM but it would not append anything into the file buffer. Can this be done? What is the file format for a *.asm file? Thanks Mike
 
ASM files are just pure text. Windows uses a different encoding for text than the usual ASCII of CP/M. If you save the file in one of the Unicode variants, it will not be readable by any CP/M program I know of.

What size does dir show according to CP/M? Can you TYPE the ASM file? If it isn't an encoding issue, then it might be that the file wasn't transferred correctly.
 
Size is zero. Type doesn't do any thing, probably because there is nothing there. I'll try again with some different encoding with notepad. Let you know. Mike Thanks
 
I do it all the time. Note that CP/M text editors and programs need a hex "1A" (Ctrl-Z; decimal 26 code) to the end of the file. A lot of DOS software honored that terminator, but very few Windows programs. The simplest way to get that Ctrl-Z at the end of a file is to use the DOS COPY command with the /A option. E.g. COPY /A X Y which will copy the contents of file X to file Y and append an EOF marker.
 
Well.... I have not had time to test any of this yet. My computer suffered a failure. I've been working on a EEPROM programmer and to test the newly programmed chips, I use my 32K (16x2K) memory board. But..... my failing eye sight caused my to miss that I plugged in a RAM chip backwards. The 7805 regulator failed and became a resistor. Fortunately, the amount of chips on the board drew enough current to keep the +5 VCC low enough so as to not cause any of the memory chips to fail, yet I did lose one hex inverter 7404. So.... this evening I'm going to paint a little white dots over the little chip markers so I can easily see that each chip is correctly in place. Getting old is tough on humans and computers. I'll try the file stuff tomorrow after Church. Thanks Mike
 
Hi Mike,
I have written assembler code in both an XP and Vista environment and the moved it over to a CP/M environment several times. The newly created Notepad file shows up as a Text Document in the folder it is created in. What I do is complete the entry of the assembler code, SAVE-ing as I go along. When completed I have a text Document file as an original.
Next, I double click the file to bring up the display and then I click on FILE and then SAVE AS...

Then, step 1, in the - File Name - field at the bottom, I append .asm to the filename.
Step 2, in the - Save as type - field, I click the down arrow and select All Files.
Step 3, at that point, click the save button.

You can click out of the Notepad display at this time and you should see two file labelled TEST. One as Text Document and one as ASM File.
Try this and see if it works. If you are using the rename, you are probably ending up with a file named TEST.asm but still showing it as a Text Document.

If you are doing all of this correctly to begin with, then check that the format of the 22disk DTOC command is correct.

Hope this helps,
Phillip
 
Notepad, IMOHO, is a pretty poor editor for program files, including ASM files.

If you're doing your editing on Windows, try "joe" -- "Joe's Own Editor" for Windows. It also exists in a DOS mode version as well as in Linux/BSD. It's basically a clone of WordStar non-document mode, so if you know WS, you'll be immediately at home. The benefit is that you can use the same editing command over all platforms.

Also, remember that the inocation for ASM is different from other utilities. "ASM PROG.AAA" will assemble the file A:pROG.ASM, put the object in A:pROG.HEX and make a program listing in A:pROG.PRN. In other words, the name suffix in the command line is not an extension, but rather specifies the drives for the .ASM .HEX and .PRN files that are created.
 
Chuck, what is 'IMOHO'?

Phil, tried your method and it works. So does Chuck's DOS Copy method. I also tried using an old copy of SMART that I have. It has a word processor that runs in DOS. And this works also. The SMART text file saves a 1A at the end. I tried to use ED.COM to write a program in and I seem to get turned around and confused. So I want to try and write my first CP/M program with one of these methods. Transfer it to my 8" disk and assemble it with the CP/M.

I have my full complement of memory back. I think that maybe one of the memory chips is flaky. I spent some time looking for a memory test program on the internet, but didn't find what I wanted. Thought about writing something, but would rather just down load something. Does anyone know where I could look?

Thanks for the help Mike
 
Hey Mike,
Memory test programs for CP/M can be found in the Walnut Creek CD subfolders. Search for that. If you can't readily find that, then search for any of the CP/M SIG or CP/M UG repositories. Gaby's website may lead you to these or other resources that will help.

Phillip
 
Thanks Phil. A while back I downloaded that Walnut Creek CD ROM, but I had forgotten I had it. I found a few memory test programs on it. I will try one of them in the next week or so. Thanks for the help. Mike
 
I have started to program a little with CP/M and have some basic questions. I started out with a header that records some information about the file. I have always done this and have no trouble with this part. It's just a bunch of comments.

The next part that I have a question is, I usually set some constants next. Here I use the EQU directive. The question is do I have to set the ORG prior to these constants or DW's etc. Where would be the best spot for ORG.

While practicing, I wrote a dozen or so lines in SMART and copied it over to my 8 inch drive. CP/M opened it and I could assemble it. I did have one error. I don't understand (yet) why. In my list of EQU's I have the following line

Code:
MT      EQU      FFH

This generates a 'U' error.

U0000 MT EQU FFH

Did I use an invalid label? Thanks Mike
 
Thanks Larry. I suppose that applies to all hex numbers that start with a letter. This is a little new to me. I am used to programming in OCTAL.

Mike
 
A good practice is to begin all hex numbers with a 0. So, instead of writing 1H, write 01H. After all, if you'd have had a symbol defined previously named "FFH", you would have not gotten an error and would be in even more hot water than having a simple syntax error.

"IMOHO" is net-speak for "in my own humble opinion", just as "YMMV" is "your mileage may vary"
 
Thanks Larry. I suppose that applies to all hex numbers that start with a letter. This is a little new to me. I am used to programming in OCTAL.

Mike

Even in octal it helps to prepend a 0 to all octal integers to make clear they are not decimal. Lots of assemblers and compilers make number base assumptions based on syntax. Obviously for integers equal to or less than 7 this is a moot point since 7 octal = 7 decimal = 7 hexidecimal. In old manuals you used to see people doing things like 234.d or 234.o. But over time things kind of standardized on a defacto standard of 234 for decimal, 0234 for octal, 0x234 for hex or sometimes in IBM world H as the last character like 234H. For come reason 0D0AH sticks in my head. ;-) Of course this is more than idle chatter since more than one insidious bug has occurred because a buffer was allocated in one number base when the programmer intended another.

And then of course the Heath aficionados count in "split octal, 002.034"to make the byte boundary distinct in a sixteen bit word, but then the kind of people who would stay up all night soldering an H8 are getting few and far between. I for one miss them.

You can buy a t-shirt that reads: "There are only 10 kinds of people in the world. Those who understand binary and those who don't."

There's an old joke about Christmas being the same day as Halloween because decimal 25 = octal 31 (Dec. 25 = Oct. 31) but that would take up a whole 'nother thread. ;-)

All of this foolishness because some computers only had two fingers to count on, while some had eight, and others 16. When your head stops hurting about that last line consider that the Mayans counted in base 20 because they didn't wear shoes much. ;-)

K. I've caused enough chaos and confusion here for one day. Back to Runescape!
 
Well, so much of net-speak mnemonics. I haven't learned any of those. I'll prefix a zero to my hex numbers.

Another quick question, If I wanted to reference an address of a routine in PROM can I use EQU to define a two byte number? For example can I do this?
Code:
PRINT   EQU   08000H

CALL PRINT

I have a PRINT routine I like to use at 200 000 O (split Octal) which is 08000H

Thanks Mike
 
Yup, on an x80 architecture, it should work fine. In x86, some assemblers demand that the symbol be defined as a location in the absolute segment, but that's neither here nor there on a Z80.
 
Million questions not just 20. Do I have to define all the ASCII characters or does CP/M know them already? If I load the accumulator with some character and then compare it with a specific one, how do I do that? Like this? Whats the format for the compare immdediate command for an ASCII character?

Code:
LDA    TEMP
CPI     "A"       ;ASCII character A

Thanks Mike
 
I think the answer is yes I have to define the ASCII characters. BUT..... I'm having a problem doing so. Here is what happens

Code:
A   EQU   041H
B   EQU   042H
I    EQU   049H

Then after assembly I get error codes like this

Code:
S   A   EQU   041H
S   B   EQU   042H
0049 = I   EQU   049H

This implies that the ASCII character I worked byt the A & B failed. But I thought I did them all the same?

Mike
 
You're confusing literal (constant) values with symbolic values.

A in ASM is predefined as the value 7
B = 0
C = 1
D = 2
E = 3
H = 4
L = 5
M = 6
SP = 6
PSW = 6

because they're operands in an instruction. If you need a character literal, just code it directly as previously mentioned.

ASM is very simple-minded. You can use numbers (or your own EQU symbols) instead of the predefined registers. For example,

Code:
 0100           	ORG	100H
                
 0100 F5        	PUSH	6
 0101 C5        	PUSH	0
 0102 F5        	PUSH	7
                
 0103           	END

The first instruction assembles to a "PUSH PSW", the second, to "PUSH B" and the third to "PUSH PSW" again (in the 8080 PUSH instruction, the low-order bit of the register value is masked out).



You can code symbolic literals, but be careful. For example,

GREET EQU 'HI'

and then you code:

DW GREET

you'll have "i" in the first location and "H" in the second, which is probably not what you wanted.

Page 6 in the CP/M ASM manual talks all about constants. Obviously, all 8-bit operations take a single-character 8-bit operand; but 2-character operands can be used for the LXI instructions. So
Code:
        LXI      B,"HI"
would result in loading B with 048H and C with 049H.

Note that a DB pseudo operation can define a whole string of characters--and can include several operands.

Code:
        DB      'A stitch in time saves nine.',0

results in the string of characters (A stitch in time saves nine.) followed by a zero byte stored in memory.

If you have to represent a single quote as a character string, just use two--ASM will take tht to mean that you literally mean a single quote. So

Code:
        CPI     ''''

is perfectly legitimate.
 
Last edited:
Back
Top