CALM Assembler CALM
What is CALM ?
CALM is the abbreviation for Common Assembly Language for
Microprocessors. CALM is not a new programming language, but another
consistent, processor independant notation of assembly instructions.
Nowadays each manufacturer defines a specific assembly language for
his microprocessor. Also the used terminology depends very much on the
microprocessor. What is still missing today is a consistent notation
for those instructions which are 100% identical.
CALM takes advantage of the fact, that many instructions - even on
different microprocessors - execute the same operation. Isn't it
obvious in these cases to choose the same notation, independantly of
the processor?
What defines CALM ?
CALM defines a consistent and processor independant syntax for
instructions and pseudo-instructions. Past experience and tests on
over 20 microprocessors have shown that nearly all instructions of a
microprocessor could be expressed by the instructions and the
notation, which have been defined by CALM.
But CALM defines also a consistent assembly terminology. Also a
concept is presented, which shows, how an instruction is assembled.
The user understands why an instruction in CALM has the given
notation. In addition a consistent notation is defined for operation
codes, addressing modes, address and data specifiers, condition codes
and much more.
CALM proposes a unique notation of the instructions for all
(micro)processors. CALM fulfills this goal in about 95% of the
instructions for a microprocessor. The remaining 5% represent
processor specific singularities, which could not be covered by a
common assembly language. But in many cases it is favorable, that just
these singularities are also distinguished by a different notation.
What are the advantages for the user ?
A common notation of the instructions and especially of the
addressing modes gives an objective view of the features of a
microprocessor. Therefore objective comparisons between
microprocessors are also possible.
For the first time programmers of different microprocessors can
communicate together. Up until now they failed because of the
different notation.
The changes of processors are also much easier, since the notation
of the instructions does not change. Only the general architecture and
some singularities of the new processor must be learned.
CALM is not only appropriate for microprocessors, but also for
mini- processors, mainframes and microprogrammed units. CALM is
extensible and for that not only limited to 8, 16 and 32 bit
processors.
And what are the disadvantages ?
CALM defines only the software part of a processor. If one needs
any hardware information (execution time, instruction code, pin
configuration, electrical characteristics, information for the
implemented functions like timers, DMA-units, etc.), then the
documentation of the manufacturer is necessary. Hence the user must
occasionally know both notations of the instructions: the one of CALM
and the one of the manufacturer.
Examples
The following page compares the notation of the instructions in
CALM to one of the manufacturers for the microprocessors 8080, iAPX86
and 68000.
CALM Assembler CALM
; i8080: multiplication: RESULT.16 = MUL1.8 * MUL2.8
; modifies: A, B, D, E, H, L, F
MULT: MULT:
MOVE MUL1,A LDA MUL1
MOVE A,E MOV E,A
MOVE #0,D MVI D,0
MOVE MUL2,A LDA MUL2
MOVE #0,HL LXI H,0
MOVE #8,B MVI B,8
LOOP$: LOOP:
ADD HL,HL DAD H
RLC A RAL
JUMP,CC NEXT$ JNC NEXT
ADD DE,HL DAD D
NEXT$: NEXT:
DEC B DCR B
JUMP,NE LOOP$ JNZ LOOP$
MOVE HL,RESULT SHLD RESULT
RET RET
; iAPX86: translates an EBCDIC character string to ASCII-codes
; ( ends); assume: ES = DS, [DS] is equivalent to {DS}*16
; modifies AL, BX, CX, DI, SI, F
EBCDIC_ASCII: EBCDIC_ASCII: PROC NEAR
MOVE.16 #CONV_TAB,BX MOV BX,OFFSET CONV_TAB
MOVE.16 #EBCDIC_CODES,SI MOV SI,OFFSET EBCDIC_CODES
MOVE.16 #ASCII_CODES,DI MOV DI,OFFSET ASCII_CODES
MOVE.16 [DS]+ASCII_LENGTH,CX MOV CX,SIZE ASCII_LENGTH
AUTOINC CLD
LOOP$: LOOP:
MOVE.8 [DS]+{SI!},AL LODS EBCDIC_CODES
MOVE.8 [DS]+{BX}+{AL},AL XLAT CONV_TAB
MOVE.8 AL,[ES]+{DI!} STOS ASCII_CODES
COMP.8 #16'D,AL CMP AL,0DH
LOOP,NE LOOP$ LOOPNE LOOP
RET.16 RET ; EQ: CR found
; 68000: division: D4 = D5D4 / D3, remainder in D5, CS if error
DIV64: DIV64 ; modifies: D3, D4, D5, F
TEST.32 D3 TST.L D3
JUMP,ZS R8^DIV_ZERO$ BEQ.S ZERO
PUSH.32 D0 MOVE.L D0,-(A7)
MOVE.32 #32-1,D0 MOVEQ #32-1,D0
DIV_LOOP$: LOOP
SETX ORI #$10,CCR
RLX.32 D4 ROLX.L D4
RLX.32 D5 ROLX.L D5
JUMP,CS R8^DIV_OVER$ BCS.S OVER
SUB.32 D3,D5 SUB.L D3,D5
JUMP,HS R8^DIV_OK$ BCC.S OK
ADD.32 D3,D5 ADD.L D3,D5
TCLR.32 D4:#0 BCLR #0,D4
DIV_OK$: OK
DJ.16,NMO D0,DIV_LOOP$ DBRA D0,LOOP
POP.32 D0 MOVE.L (A7)+,D0
CLRC ANDI #$FE,CCR
RET RTS
DIV_OVER$: OVER
POP.32 D0 MOVE.L (A7)+,D0
DIV_ZERO$: ZERO
SETC ORI #$1,CCR
RET RTS
CALM ASSEMBLER - product description (PC/MS-DOS, Atari ST, Smaky)
The CALM assembler consists of several programs and files:
The assembly programs
ASCALM: The real assembler. It works like all other traditional
assemblers. The only difference: The programs must be written in the
producer independent assembly language CALM. Advantage: This assembly
language does not differ from one processor to another. With the
corresponding modules, the assembler generates machine code without
linker for nearly all microprocessors (see list). Assembler
features: labels (32 significant characters), local labels, expression
with 32 bit precision, conditional assembly (.IF/.ELSE/.ENDIF),
conditional listing (.LIST/.ENDLIST), inserting of files of any size
(.INS), actual system time and date can be accessed by constants,
inserting error messages (language selectable) directly in the source
file, cross reference generator, macros, and much more. Macro
features: up to eight parameters and a data specifier may be specified
in a macro call. The length of a parameter is only limited by the
input line length. Parameters may be predefined. In a macro call, one
can distinguish if any passed parameters have been predefined or have
been defined at the macro call. Macros may call other macros (allowed
nested level: 10). In addition, the passed parameters can be analyzed
by built-in functions (compare, copy, test characters, etc.). With
these functions, powerful macros may be written (i.e. translate the
instructions from the producer notation to the CALM notation). Machine
code output format: MUFOM (refer to MUFBIN).
MUFBIN: Converts the object files from the MUFOM format to the
formats: binary (.BIN/.COM), hex, Intel hex (.HEX), Motorola S format
(.FRS), PC/MS-DOS (.EXE) and Atari ST (.TOS/.TTP/.PRG).
Debugger: Debugger for 8086 (DBGCALM, PC/MS-DOS) or 68000 (DEBUG68,
Atari ST/Smaky 100). With disassembler (CALM notation).
The utility programs
CALMMENU presents a simple menu.
FORMCALM formats a CALM assembly source file.
LSTTOASM transforms a listing to a source file.
PFED a program editor (with macros!).
PROCSET changes in *.PRO modules the default value.
SPACETAB replaces the spaces by tabulators in any source file.
TABSPACE replaces the tabulators by spaces in any source file.
TESTLIST verifies a listing file.
The files for a processor
*.DOK CALM reference card for the processor *, i.e., Z80.DOK.
*.PRO the module for the processor *, i.e., Z80.PRO.
B*.TXT description of the processor module, i.e. BZ80.TXT.
C*.TXT instruction comparison (producer notation -> CALM
notation).
D*.EXE disassembler CALM for the processor *, i.e. DZ80.EXE.
I*.TXT list of machine codes with the CALM notation
(disassembling).
ST*.ASM list of instructions in the CALM notation (sorted
alphabetically).
S_*.ASM program examples (or E*.ASM or *.ASM).
T*.ASM test file (list of instructions).
xxx_CALM translator (producer notation -> CALM)
CALM_xxx translator (CALM -> producer notation)
Note: for some processors, not all files above are available.
Remarks related to the CALM assembler
Object code without linker
The CALM assembler generates object files without a linker in the
so-called MUFOM format. This allows the user to directly obtain an
executable program after the transformation of the MUFOM format to the
binary format.
This is sufficient in many cases. The combination assembler-linker,
which generates relocatable object modules and links them, very often
needs much more time than an assembler, which assembles each time the
whole source and directly generates the machine code. However, some
efficient hardware is required for this (like hard disks and emulated
disks in memory).
The type of programming depends on the requirements. The programs
for simple 8 bit microprocessors (like 6502, 6800, 8080, Z80) and
single-chip microcomputers are relatively small. Furthermore, these
processors are based on operating systems which load and start the
user program always at the same address.
The requirements for more efficient microprocessors (like 6809,
iAPX86, 68000, NS32000) and operating systems are higher: the programs
must be loaded and executed at any memory address and the programs
must be separated in program, data and stack segments. Both
requirements can be satisfied without problems, as these processors
have the needed addressing modes (relative addressing, indirect
addressing with any offset value, etc.).
The programmer can choose the desired addressing mode in the CALM
assembler. If he wants to generate position independant programs
(which can be loaded and executed at any address without relocation),
then he should only use relative addressing. He can access the data
and stack segments only with the indirect addressing. The reward for
these limitations: the generated objects can be loaded and executed at
any memory address without complicated and time-consuming relocation.
One has also to bear in mind that the programming field has
changed. Nobody today addresses more than one MByte of memory space
for the program and the data with absolute addressing.
Therefore this programming concept requires a certain discipline
from the programmer as he can no longer use all addressing modes. When
the programmer does not have this discipline, an assembler with a
linker is necessary.
Object code in the MUFOM format
The CALM assembler generates an object in the so-called MUFOM
format. This format has some advantages when compared to the formats
.HEX (Intel) and S format (Motorola): In addition to the
characteristics of the two "standard" formats like checksum, data
addresses, start address, ASCII codes, alterable by an editor, etc.,
the following information is given: version of the assembler and the
processor description, indications of the processor architecture, and
the character strings of the pseudo-instructions .TITLE and .CHAP
appear also in this format. All this information is uncoded (ASCII
codes) and therefore can be read by the operation system command TYPE.
In addition, the MUFOM format is also usable for linkable objects.
The MUFOM format is processor independant. Actually, the CALM
assembler uses only the MUFOM commands for non-linkable objects.
Processor documentation
The delivered CALM documentation is normally not enough to
understand a processor in all its details. This is particularly true
for microprocessors and single-chip microcomputers with built-in
functions like RAM, DMA and I/O. Hence, the corresponding
documentation of the producer for the concerned processor is at least
necessary. Therefore, the CALM documentation also contains comparison
lists, for example producer notation to CALM notation.
CALM reference cards
CALM reference card
On a CALM reference card, all the instructions of a microprocessor
are clearly arranged in the producer independent assembler notation
CALM. The benefit of this card is to give an overview.
Utility of a CALM reference card
CALM reference cards are primarily useful in daily programming
work: Which addressing modes are allowed with AND? Which flags are
modified with COMP? etc.
But even if you have no interest for the CALM assembler, a CALM
reference card may be useful to you: For example, if:
- you want to better understand your own microprocessor with a
different notation
- you want to obtain a producer independent description of all
instructions of a microprocessor
- you want to compare microprocessors and want to be independant
of producer informations
- you look for a new, better microprocessor
- you need to rate the performance of a microprocessor
- you would like to indicate if a microprocessor has a specific
instruction/operation code/addressing mode/data type
- you want to get to know CALM first
Structure of a CALM reference card
All CALM reference cards are arranged in the same way. On the one
side, this gives an homogeneous appearance and, on the other side,
direct comparisons are possible.
In addition, the operation codes of the producer are given with the
CALM operation codes.
Extent of supply of a CALM reference card documentation
CALM reference card documentation consists of:
- CALM reference card
- comparison producer notation -> CALM notation of the
instructions
- an example (in CALM and producer notation)
- alphabetically sorted list of all operation codes (CALM
notation)
- alphabetically sorted list of all instruction codes with the
correspondent instructions in the CALM notation
Example of a CALM reference card
The CALM reference card of the microprocessor 8080/5 is presented
in the following pages.
8080/8085 - 1
8080/8085
CALM REFERENCE CARD
8080/8085 Description
Programming Model
15 8 7 0
-----------------------------------------------------------------
A [ accumulator | N . Z . x . H . 0 . P . v . C ] F
-----------------------------------------------------------------
B [ | ] C
-----------------------------------------------------------------
D [ | ] E
-----------------------------------------------------------------
H [ | ] L
-----------------------------------------------------------------
15 0
-----------------------------------------------------------------
[ stack pointer ] SP
-----------------------------------------------------------------
[ program counter ] PC
-----------------------------------------------------------------
General
Address: 16 bit
Data: 8 bit (8085: data multiplexed with addresses A0-A7)
Abbreviations used
v 16'0, 16'8, 16'10, 16'18, 16'20, 16'28, 16'30, 16'38
r8 A B C D E H L
s8 B C D E H L
r16 BC DE HL SP
i8 {BC} {DE} {HL}
VAL8 8-bit value
VAL16 16-bit value
cc EQ NE CS CC MI PL PO PE
Modifications versus CALM Standard
8 Bit: All transfers are 8 bits wide, except those determined by
register names (1 letter = 8 bit, 2 letters = 16 bits).
Flag v Unspecified 8085 flag: 2's complement overflow (in arithmetic
8-bit and 16-bit operations). 8080: flag is always 1. (U8085)
Flag x Unspecified 8085 flag: sign(op1)*sign(op2) + sign(op1)*sign
(result)(U8085) + sign(op2)*sign(result). For COMP and SUB,
invert sign(op2). 8080: flag is always 0.
Remarks
- flag equalities: EQ=ZS, NE=ZC, CS=LO, CC=HS, MI=NS, PL=NC.
- Reset: IOFF
JUMP 16'0
- Interrupt: IOFF
CALL v
Additional interrupt addresses for 8085: 16'2C, 16'34, 16'3C. (8085)
- NMI: IOFF (8085)
CALL 16'24
- CALM - Intel register names: equal except: F=PSW and 16 bit names.
- CALM - Intel flag names: N=S, Z=Z, H=AC, P=P, C=C.
8080/8085 - 2
Transfer instructions
MOVE #VAL8 |,A []
VAL16 |
r8 |
i8 |
$VAL8 |
A,| VAL16
| r8
| i8
| $n
(MVI LDA MOV LDAX IN STA MOV STAX OUT)
MOVE #VAL8 |,s8 []
s8 |
{HL} |
s8,{HL}
(MVI MOV MOV)
MOVE #VAL16,r16 []
VAL16,HL
HL,VAL16
HL,SP
(LXI LHLD SHLD SPHL)
MOVE HL,{DE} [] (U8085)
{DE},HL
#{HL}+VAL8,DE
#{SP}+VAL8,DE
(SHLX LHLX LDHI LDSI)
PUSH | r16 [], r16 without SP
POP | AF [], [all] if POP AF
(PUSH POP)
SETC [C=1]
(STC)
EX DE,HL []
{SP},HL
(XCHG XTHL)
Arithmetic instructions
ADD | #VAL8 |,A [N,Z,H,P,C]
ADDC | r8 | [N,Z,H,P,C]
SUB | {HL} | [N,Z,H,P,C]
SUBC | [N,Z,H,P,C]
COMP | [N,Z,H,P,C]
(ADI ADD ACI ADC SUI SUB SBI SBB CPI CMP)
ADD r16,HL [C]
(DAD)
SUB BC,HL [N,Z,x,H,P,v,C] (U8085)
(DSUB)
INC | r8 [N,Z,H,P]
DEC | {HL} [N,Z,H,P]
(INR DCR)
INC | r16 []
DEC |
(INX DCX)
8080/8085 - 3
Logical instructions
AND | #VAL8 |,A [N,Z,H,P,C=0]
OR | r8 | [N,Z,H,P,C=0]
XOR | {HL} | [N,Z,H,P,C=0]
(ANA ANI ORA ORI XRA XRI)
NOT A []
NOTC [C]
(CMA CMC)
Shift instructions
RR | A [C = A:#0]
RRC | [C = A:#0]
RL | [C = A:#7]
RLC | [C = A:#7]
(RRC RAR RLC RAL)
ASR HL [C = L:#0] (U8085)
RLC DE [v,C = D:#7] (U8085)
(ARHL RDEL)
Program flow instructions
JUMP,cc | VAL16 []
JUMP |
CALL,cc |
CALL |
JUMP {HL} []
JUMP,XC | VAL16 [] (U8085)
JUMP,XS |
(J- JMP C- CALL PCHL JNX5 JX5)
RST v []
RST,VS 16'40 [] (U8085)
(RST RSTV) one byte call (restart)
RET,cc []
RET []
WAIT []
NOP []
ION []
IOFF []
(R- RET HLT NOP EI DI)
Special instructions
DAA A [N,Z,H,P,C]
(DAA) Decimal Adjust A, only valid after ADD and ADDC
RIM | A [] (8085)
SIM | RIM: read interrupt mask
(RIM SIM) SIM: set interrupt mask
RETEM [all] return from emulation mode (V20)
(RETEM) POP.16 IP; POP.16 CS; POP.16 SF;
MD bit write disable
TRAPNATIVE #VAL8 [MD=1] trap to native mode (8086)(V20)
(CALLN) PUSH.16 SF; PUSH.16 CS; PUSH.16 IP; SET MD;
return with RETI.32
Notes
(8085) only available in 8085.
(U8085) unspecified 8085 flag or operation code.
(V20) only available in V20, V30, V40, and V50 (8080 emulation
mode). (c) Patrick Faeh, June 1985.