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 price 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.