02200000000801 1 2 9[...............................................................]0 68000 ASSEMBLY LANGUAGE COURSE PART II by Mark van den Boer Welcome to part II of this course. In part I, some fundamentals of the 68000 were shown. In this part, I will show you which addressing modes the 68000 uses. First an example of addressing modes which the 6502 and 6809 use: lda #10 * immediate addressing lda $10 * zero-page (6502) or direct-page addressing (6809) inx * inherent (6502) inca * inherent (6809) Now, what does a line of code in 68000 assembler look like?  LABEL OPCODE OPER1,OPER2 COMMENT  The meanings of these fields are: label: A name given to this line of code. Some assemblers require a : to follow the label-name. This field is optional. opcode: This field specifies the operation you wish to perform. It is the only field that isn't optional. Depending on the opcode the 68000 expects 0, 1 or 2 operands. oper1: The first operand to appear with the opcode. The appearance of this field depends on the specified opcode. oper2: The second operand to appear with the opcode. The appearance of this field depends (surprise, surprise) on the specified opcode. comment: Another optional field which is used for commenting all tricks people put in their programs. Most assemblers require a * as the first character of the comment field. The comment field is optional. Now what does an addressing mode do? An addressing mode specifies on which data the opcode (instruction) must operate. The 68000 has a total of 14 addressing modes, all of which now will explained. As examples in all addressing modes I will use the MOVE instruction. MOVE can have the .b, .w and .l suffixes as mentioned in part I of the course. The MOVE instruction moves the data specified by oper1 to the place specified by oper2. For example: MOVE.B $1,$2 performs exactly the same operation as the following 6502 and 6809 code: LDA $1 STA $2.  The addressing modes: 1. Inherent addressing  In this addressing mode there are no operands since they are already supplied by the opcode. E.g.: RESET * reset all peripherals RESET is an 68000 instruction which is used to reset all the peripherals. 2. DATA REGISTER DIRECT ADDRESSING  Assembler syntax: Dn (n can range from 0 to 7) In this addressing mode a data register contains the operand. E.g.: Instruction Before After MOVE.B D1,D0 d0=ffffffff d0=ffffff67 d1=01234567 d1=01234567 MOVE.W D1,D0 d0=ffffffff d0=ffff4567   d1=01234567 d1=01234567 MOVE.L D1,D0 d0=ffffffff d0=01234567 d1=01234567 d1=01234567 As you might have noticed, an instruction with .b as a suffix only changes the lowest 8 bits of the destination, and instructions with .w as a suffix only change the lowest 16 bits of the destination. Instructions with .l as a suffix change all 32 bits of the destination. 3. ADDRESS REGISTER DIRECT ADDRESSING  Assembler syntax: An (n can range from 0 to 7) In this addressing mode an address register contains the operand. Byte operators (those with .b suffix) are not allowed in this addressing mode. When using the address register as a destination and it is a word operation (suffix is .w), the word is sign- extended into a longword. This means that during a wordtransfer into a data register the upper 16 bits are filled with the value of the most-significant bit (this is bit 15) of the word. An example below will show you how it's done. E.g.: Instruction Before After MOVE.W A1,D0 d0=ffffffff d0=ffff4567 a1=01234567 a1=01234567 MOVE.W D0,A1 d0=01234567 d0=01234567 a1=ffffffff a1=00004567 <- extend!! MOVE.W D0,A1 d0=0000ffff d0=0000ffff a1=00000000 a1=ffffffff <- extend!! MOVE.L A1,D0 d0=ffffffff d0=01234567 a1=01234567 a1=01234567 4. ADDRESS REGISTER INDIRECT ADDRESSING  Assembler syntax: (An) (n between 0 and 7) In this addressing mode, the address register contains the address of the operand. In assembler this is being denotated by putting parentheses around an address registers name, e.g. (a0). The contents of a0 points to the address where the data has to be fetched from. When using word (.w) or longword (.l) addressing it is absolutely necessary that the address register contains an even number (I will explain the reason for this in a forthcoming article). E.g.: Instruction Before After MOVE.L (A1),D0 d0=ffffffff d0=01234567 a1=00001000 a1=00001000 address $1000 contains 01234567 MOVE.L D0,(A1) d0=76543210 d0=76543210 a1=00001000 a1=00001000 address $1000 now contains 76543210 5. ADDRESS REGISTER INDIRECT ADDRESSING WITH POST-INCREMENT  Assembler syntax: (An)+ (n between 0 and 7) This addressing mode resembles the address register indirect addressing mode. The only difference is that after having fetched or stored the data, the address register is incremented. The increment depends on the suffix used in the opcode. If the suffix is .b then the address register will be incremented by one. If the suffix is .w then the address register will be incremented by two (one word is two bytes). If the suffix is .l then the address register will be incremented by four (one longword is four bytes). In assembler this addressing mode is denotated by putting the address register within parentheses followed by a + sign. For example: (a7)+ E.g.: Instruction Before After MOVE.L (A1)+,D0 d0=ffffffff d0=01234567 a1=00001000 a1=00001004 address $1000 contains 01234567 MOVE.W (A1)+,D0 d0=ffffffff d0=ffff0123 a1=00001000 a1=00001002 address $1000 contains 01234567 MOVE.B (A1)+,D0 d0=ffffffff d0=ffffff01 a1=00001000 a1=00001001 address $1000 contains 01234567 MOVE.L D0,(A1)+ d0=76543210 d0=76543210 a1=00001000 a1=00001004 address $1000 now contains 76543210 6. ADDRESS REGISTER INDIRECT ADDRESSING WITH PRE-DECREMENT  Assembler syntax: -(An) (n between 0 and 7) This addressing mode resembles the address register indirect addressing mode. The only difference is that after before fetching or storing the data, the address register is decre mented. The decrement depends on the suffix used in the opcode. If the suffix is .b then the address register will be decremented by one. If the suffix is .w then the address register will be decremented by two (one word is two bytes). If the suffix is .l then the address register will be decremented by four (one longword is four bytes). In assembler this addressing mode is denotated by putting the address register within parentheses preceded by a - sign. For example: -(a7) E.g.: Instruction Before After MOVE.L -(A1),D0 d0=ffffffff d0=01234567 a1=00001004 a1=00001000 address $1000 contains 01234567 MOVE.W -(A1),D0 d0=ffffffff d0=ffff4567 a1=00001004 a1=00001002 address $1000 contains 01234567 MOVE.B -(A1),D0 d0=ffffffff d0=ffffff67 a1=00001004 a1=00001003 address $1000 contains 01234567 MOVE.L D0,-(A1) d0=76543210 d0=76543210 a1=00001004 a1=00001000 address $1000 now contains 76543210 7. ADDRESS REGISTER INDIRECT ADDRESSING WITH DISPLACEMENT Assembler syntax: w(An) (w stands for word displacement) This addressing is also rather similar to address register indirect addressing. The only difference lies in the fact that before fetching or moving the data a 16-bit signed displacement is added to the contents of the address register (the address register itself does not change). In assembler this addressing mode is denotated by enclosing the address register name in parentheses preceded by a 16-bit constant. For example: 8(a6) denotes the memory location whose address is the contents of a6 plus 8. This addressing method comes in very handy when passing parameters to subroutines. By the way, did you ever wonder why the ATARI ST has a resolution of 640 by 400 pixels? Here's one reason: 640*400=256000 bits=32000 bytes. Since 32000 bytes can be addressed using 16 bits, the address register indirect with displacement is an easy way to address the screen. E.g.: Instruction Before After MOVE.L 8(A1),D0 d0=ffffffff d0=01234567 a1=00001000 a1=00001000 address $1008 contains 01234567 MOVE.L D0,-6(A1) d0=76543210 d0=76543210 a1=00001006 a1=00001006 address $1000 now contains 76543210  8. ADDRESS REGISTER INDIRECT ADDRESSING WITH INDEX Assembler syntax: b(An,Rn.w) or b(An,Rn.l) ( b stands for byte, w and l for word and longword and R for register). This addressing mode makes it possible to add a variable index (contained in an address or data register) to an address register and also an eight bit signed displacement. The variable index may be either word or longword. Both the index and displacement are sign extended before they are added to the address register. E.g.: Instruction Before After MOVE.L 8(A1,A0.L),D0 d0=ffffffff d0=01234567 a1=00001000 a1=00001000 a0=00078000 a0=00078000 address $79008 contains 01234567 MOVE.L 8(A1,A0.W),D0 d0=ffffffff d0=01234567 a1=00001000 a1=00001000 a0=00078000 a0=00078000 *** a0.w=8000 -> sign-extend gives ffff8000 *** address $ffff8008 contains 01234567 MOVE.W 8(A1,D0.L),D0 d0=0001fffe d0=00010123 a1=00001000 a1=00001000 *** 00001000 (contents of a1) 0001fffe (contents of d0.l) 00000008 (sign-extended byte displacement) --------- 00021006 address $21006 contains 01234567 MOVE.L 8(A1,D0.W),D0 d0=0001fffe d0=01234567 a1=00001000 a1=00001000 *** 00001000 (contents of a1) fffffffe (sign-extended contents of d0.w) 00000008 (sign-extended byte displacement) --------- 00001006 address $1006 contains 01234567 9. ABSOLUTE SHORT ADDRESSING  Assembler syntax: x (x is a 16 bit constant) With absolute short addressing it is only possible to specify a 16 bit constant. At execution time the 68000 sign extends the word into a long address, meaning that only addresses 0 to 7fff and ffff8000 to ffffffff can be addressed using this form. This addressing mode can be compared with zero-page addressing on the 6502 and direct-page addressing on the 6809.Like on the 6502 and 6809 this mode is faster than any other mode. This addressing mode can be compared with zero-page addressing on the 6502 and direct-page addressing on the 6809. By the way, on the Atari ST, the lower 32 K of memory can only be accessed in supervisor-mode (the S-bit in SR is set, see part I). E.g.: Instruction Before After MOVE.L $1234,D0 d0=ffffffff d0=01234567 address 1234 contains 01234567 ( the $ sign is used to denote a hex digit) MOVE.L $8000,D0 d0=ffffffff d0=76543210 address $ffff8000 contains 76543210  10. ABSOLUTE LONG ADDRESSING Assembler syntax: l (l is 32 bit constant) With this addressing mode a long address is supplied. It is very similar to absolute short addressing. E.g.: Instruction Before After MOVE.L $12345678,D0 d0=ffffffff d0=01234567 address $00345678 contains 01234567 Note that since the address bus is only 24 bits wide the upper byte of the address is ignored by the 68000. 11. PROGRAM COUNTER WITH DISPLACEMENT Assembler syntax: x(PC) (x is a 16 bit constant) This addressing mode is in fact the same as address register indirect with displacement. The only difference is that the address register is replaced with the PC (the PC is in fact also an address register). E.g.: Instruction Before After MOVE.L 8(PC),D0 d0=ffffffff d0=01234567 pc=00001000 pc=00001000 address $1008 contains 01234567 12. PROGRAM COUNTER WITH INDEX Assembler syntax: b(PC,Rn.L) or b(PC,Rn.w) (b is 8 bits) This mode is in fact the same address register indirect addressing with index. E.g.: Instruction Before After MOVE.L 8(PC,A0.L),D0 d0=ffffffff d0=01234567 pc=00001000 pc=00001000 a0=00078000 a0=00078000 address $79008 contains 01234567 MOVE.L 8(PC,A0.W),D0 d0=ffffffff d0=01234567 pc=00001000 pc=00001000 a0=00078000 a0=00078000 *** a0.w=8000 -> sign-extend gives ffff8000 *** address $ffff8008 contains 01234567 MOVE.W 8(PC,D0.L),D0 d0=0001fffe d0=00010123 pc=00001000 pc=00001000 *** 00001000 (contents of pc) 0001fffe (contents of d0.l) 00000008 (sign-extended byte displacement) --------- 00021006 address $21006 contains 01234567 MOVE.L 8(PC,D0.W),D0 d0=0001fffe d0=01234567 pc=00001000 pc=00001000 *** 00001000 (contents of pc) fffffffe (sign-extended contents of d0.w) 00000008 (sign-extended byte displacement) --------- 00001006 address $1006 contains 01234567 13. IMMEDIATE ADDRESSING  Assembler syntax: #x (x is byte, word or longword) The data for the operation is the value x. Programmers of the 6502 and 6809 will recognize this addressing mode. For example (6502 and 6809) LDA #$21. E.g.: Instruction Before After MOVE.L #$A03B4C11,D0 d0=00000000 d0=a03b4c11 14. STATUS REGISTER ADDRESSING Assembler syntax: SR or CCR This mode is used to control the contents of this register. See part I of this course for the individual meanings of the bits contained in this register. Changes to the SR can only be made when in user-mode. Changes to the CCR can be made in any mode. E.g.: Instruction Before After MOVE.W SR,D0 d0=87654321 d0=87652700 sr=2700 sr=2700 MOVE.W #$0500,SR sr=2700 sr=0500 Notice that the 68000 was in supervisor mode before executing the instruction but after completion it is in user mode!! This operation isn't possible the other way around. To conclude this part, I will give you a summary of the addressing modes of the 68000. SYNTAX NAME ----------------------------------- Dn | Data register direct An | Address register direct (An) | Address register indirect (An)+ | Address register indirect with post-increment -(An) | Address register indirect with pre-decrement w(An) | Address register with displacement b(An,Rn) | Address register with index w | Absolute short l | Absolute long w(PC) | PC with displacement b(PC,Rn) | PC with index #x | Immediate SR or CCR | Status register b is a byte constant w is a word constant l is a long constant x any of b, l or w n is a register number ranging from 0 to 7 R is a register specifier, either A or D If you have any comments on these courses, please let me know! Originally published in ST NEWS Volume 2 Issue 1.