M68K Complete Documentation

Addressing Modes

Direct
Gets the content in the register directly. (the SP register is an alias of the a7)
d0, a0, sp
Dn
Data register
An
Address register
Indirect
Gets the value contained in memory with address being the content of the address register specified. Specifiying an offset by writing a number before the (), the addressing mode becomes indirect with displacement and the final address to read the memory will be (address + offset).
(a0), 4(sp)
(An)
Indirect
Indirect Post/Pre increment
Gets the value contained in memory with address being the content of the address register specified. If it's the post increment, the address register will be incremented after reading the memory. If it's the pre increment, the address register will be incremented before reading the memory. The amount of increment is specified by the size of the instruction. In the documentation, wherever there is (An), this addressing mode is valid too
(a0)+, -(sp)
(An)
Post increment
(An)
Post increment
Immediate
Represents a numerical value, it can be a number or a label. When the program is assembled, the labels will be converted to the address of the label. Immediate values can be represented in many bases. (replace <num> with the actual number). Note, a string will be represented as a list of bytes.
#1000, #$FF, #@14, #%10010, #'a', #'hey', #label
Im
Immediate
#<num>
Decimal
#$<num>
Hexadecimal
#@<num>
Octal
#%<num>
Binary
#'<char/string>
Text
Effective address
Represents the address of the memory where the data is stored. It can be a label or a number. When the program is assembled, the labels will be converted to the address of the label.
$1000, some_label, 140, %101010, @22, 'e'
ea
Effective address
<ea>
Effective address
Base displacement indirect
Gets the value contained in memory with address being the sum of (address + offset + base), where the first register (address) will be the base address, the second register (base) and offset being the number before the ().
In the documentation, wherever there is (An), this addressing mode is valid too
4(a0, d2), (sp, a0)
(An)
Base displacement indirect

Condition Codes

When performing operations, the CPU will set condition codes in the status register after the instruction is executed.
For example the tst, cmp instructions will set the condition codes that represent the result of the comparison of the operands.
The following are all the condition codes available:
hi
Unsigned higher
ls
Unsigned lower or same
cc
Carry clear
cs
Carry set
ne
Not equal
eq
Equal
vc
Overflow clear
vs
Overflow set
pl
Plus
mi
Minus
ge
Greater or equal
lt
Less than
gt
Greater than
le
Less than or equal
hs
Unsigned higher or same
lo
Unsigned lower
The instructions that use the condition codes are: bcc dbcc scc

Condition codes flags

The condition codes X, N, Z, V, C are the individual flags that can be set in the status register.

X is the extend flag, it is set when the result of an operation is too large to fit in the destination register.
N is the negative flag, it is set when the result of an operation is negative.
Z is the zero flag, it is set when the result of an operation is zero.
V is the overflow flag, in arithmetical operations, it is set if it caused the result to overflow.
C is the carry flag, when an operation causes a carry, like an addition or a shift, it is set to the value of the carry.
hi
!c && !z
ls
c || z
cc
!c
cs
c
ne
!z
eq
z
vc
!v
vs
v
pl
!n
mi
n
ge
(n && v) || (!n && !v)
lt
(n && !v) || (!n && v)
gt
(n && v && !z) || (!n && !v && !z)
le
z || (n && !v) || (!n && v)
hs
!c
lo
c

Shift Directions

The shift logical, shift arithmetical and rotate, instructions use the directions to specify in which direction the bits are shifted.
l
Left
r
Right
Those instructions are: lsl lsr rol ror asl asr

Trap tasks

The M68K has one system call: trap #15. The task number goes in D0.B, its arguments in the other registers, and the answer comes back in the registers the task names. The interface is EASy68K's, so a program written for that simulator runs here unchanged as far as its I/O goes.

Text and graphics share one image, as they do in EASy68K's output window: what a program prints is drawn on the screen at the text cursor and appended to the terminal transcript, which is what testcases assert on. Click the screen panel to give the program the keyboard; the ring around it says the editor's own shortcuts are off while it has focus.

Text I/O tasks 0 to 20

Printing and reading. Everything printed is appended to the terminal transcript and drawn on the screen at the text cursor, because EASy68K has one output window where text and graphics share the image; the transcript is what testcases assert on. Typed input is echoed to both.

0 Display string with CR, LF

in A1 = string address, D1.W = length

Displays up to D1.W characters of the string at (A1), stopping at a NULL, then a new line. See task 13 for the NULL terminated form.

1 Display string

in A1 = string address, D1.W = length

Displays up to D1.W characters of the string at (A1) without a new line. See task 14 for the NULL terminated form.

2 Read string

in A1 = buffer address
out The NULL terminated string at (A1), D1.W = its length

Reads a line of input. With a screen keyboard the line is typed on the screen and ends with Enter; otherwise the editor asks for it, and a testcase answers it from its scripted input.

3 Display signed number

in D1.L = number

Displays D1.L in decimal, in the smallest field it fits. See tasks 15 and 20.

4 Read number

out D1.L = number

Reads a line and parses it as a decimal number.

5 Read character

out D1.B = ASCII code

Reads one character. With a screen keyboard it is taken as soon as it is typed, without waiting for Enter; check task 7 first to poll instead of waiting.

6 Display character

in D1.B = ASCII code

Displays one character.

9 Terminate

Ends the program.

11 Set or get the text cursor, or clear the screen

in D1.W = $FF00 to clear, $00FF to get, otherwise column in the high byte and row in the low byte
out For $00FF, D1.W = column in the high byte, row in the low byte

The text cursor is where printed text lands, in character cells counted from the top left. Clearing with $FF00 clears text and graphics together, since they share one image, and homes the cursor. Positions outside the screen are clamped to it.

13 Display NULL terminated string with CR, LF

in A1 = string address

Displays the NULL terminated string at (A1), then a new line.

14 Display NULL terminated string

in A1 = string address

Displays the NULL terminated string at (A1) without a new line.

15 Display unsigned number in a base

in D1.L = number, D2.B = base (2 to 36)

Displays D1.L as an unsigned number in the base in D2.B.

17 Display string and number

in A1 = string address, D1.L = number

Task 14 then task 3: the NULL terminated string, then the signed number.

18 Display string and read number

in A1 = string address
out D1.L = number

Task 14 then task 4: the NULL terminated string as a prompt, then a number.

20 Display signed number in a field

in D1.L = number, D2.B = field width

Task 3 right justified in a field D2.B columns wide. A number too long for the field is displayed in full.

Graphics tasks 33 to 96

Drawing on the screen. The origin is the top left, coordinates are signed pixels, so a shape may start off the left or the top, and whatever falls outside the screen is clipped. Colors are $00BBGGRR longs, the same encoding EASy68K uses, so its color equates are unchanged. Rectangles and ellipses exclude their right and bottom edges, as they do in EASy68K, which draws them through the Windows GDI.

Colors

A color is a long written $00BBGGRR: blue in bits 23-16, green in bits 15-8 and red in bits 7-0. These are EASy68K's own equates, and a program that defines them by name needs no change.

$00000000 black
$00000080 maroon
$00008000 green
$00008080 olive
$00800000 navy
$00800080 purple
$00808000 teal
$00808080 gray
$000000FF red
$0000FF00 lime
$0000FFFF yellow
$00FF0000 blue
$00FF00FF fuchsia
$00FFFF00 aqua
$00C0C0C0 ltgray
$00FFFFFF white

33 Set or get the screen size

in D1.L = width in the high word and height in the low word, or 0 to get, 1 for windowed, 2 for full screen
out For D1.L = 0, D1.L = width in the high word, height in the low word

Resizes the screen and clears it. The minimum is EASy68K’s 640 by 480, which is also the size a program starts with. The windowed and full screen requests are accepted and ignored, since the screen is a panel in the editor.

80 Set pen color

in D1.L = color as $00BBGGRR

The color lines, outlines, pixels and text are drawn in.

81 Set fill color

in D1.L = color as $00BBGGRR

The color the insides of rectangles and ellipses and a flood fill are drawn in.

82 Draw pixel

in D1.W = X, D2.W = Y

One pixel in the pen color. The pen width does not apply and the drawing point does not move.

83 Get pixel color

in D1.W = X, D2.W = Y
out D0.L = color as $00BBGGRR

Reads the pixel of the image being drawn on, which with double buffering is the off screen one. Outside the screen it answers with the background color.

84 Draw line

in D1.W = X1, D2.W = Y1, D3.W = X2, D4.W = Y2

A line in the pen color, leaving the drawing point at X2, Y2.

85 Draw line to

in D1.W = X, D2.W = Y

A line in the pen color from the drawing point to X, Y, which becomes the new drawing point: a polyline is one task per point.

86 Move to

in D1.W = X, D2.W = Y

Moves the drawing point without drawing.

87 Draw rectangle

in D1.W = left X, D2.W = upper Y, D3.W = right X, D4.W = lower Y

Filled with the fill color and outlined with the pen. The right and bottom edges are excluded, so a rectangle whose edges meet draws nothing.

88 Draw ellipse

in D1.W = left X, D2.W = upper Y, D3.W = right X, D4.W = lower Y

The ellipse inscribed in that rectangle, filled with the fill color and outlined with the pen. A square bounding rectangle draws a circle.

89 Flood fill

in D1.W = X, D2.W = Y

Spreads the fill color from X, Y over every neighbouring pixel of the color that was there, four ways.

90 Draw unfilled rectangle

in D1.W = left X, D2.W = upper Y, D3.W = right X, D4.W = lower Y

The outline of task 87 in the pen color, with nothing inside.

91 Draw unfilled ellipse

in D1.W = left X, D2.W = upper Y, D3.W = right X, D4.W = lower Y

The outline of task 88 in the pen color, with nothing inside.

92 Set drawing mode

in D1.B = 2, 4, 16 or 17

Mode 4 draws normally and is the default; mode 2 moves the drawing point without changing any pixel; mode 16 turns double buffering off and mode 17 turns it on, so drawing goes to an off screen image until task 94 shows it.

note

EASy68K’s bitwise modes (0, 1, 3 and 5 to 15) stop the program with an error naming the mode. Double buffering covers the sprite erasing use of the XOR mode.

93 Set pen width

in D1.B = width in pixels

The width of lines and of the outlines of rectangles and ellipses. A single pixel (task 82) ignores it.

94 Repaint the screen

Shows the off screen image drawn under mode 17. With double buffering off it does nothing but ask for a repaint.

95 Draw text at a pixel position

in A1 = NULL terminated string, D1.W = X, D2.W = Y

Draws the string in the pen color with its top left corner at X, Y, over whatever is already there, so a label can sit on a drawing. Control characters are ignored. Text printed with the text tasks lands at the text cursor instead (task 11).

96 Get the drawing point

out D1.W = X, D2.W = Y

Where the next line-to would start.

Keyboard and mouse tasks 7 to 61

Polled input from the focused screen. Key codes are EASy68K’s, which every environment in this editor uses. There are no input interrupts: a program asks for the state it wants when it wants it (tasks 60 and 62 are therefore not supported).

Key codes

  • A letter key is the ASCII code of its capital, so A is $41 and Z is $5A. Shift, Alt and Ctrl do not change it.

  • A top row digit is its ASCII code, so 0 is $30 and 9 is $39.

  • The function keys are contiguous from F1, so F1 is $70 and F12 is $7B.

  • The keypad digits with Num Lock on are contiguous from $60.

$08 Backspace
$09 Tab
$0D Enter
$10 Shift
$11 Ctrl
$12 Alt
$14 Caps Lock
$1B Esc
$20 Space
$21 Page Up
$22 Page Down
$23 End
$24 Home
$25 Left arrow
$26 Up arrow
$27 Right arrow
$28 Down arrow
$2D Insert
$2E Delete
$BA Semicolon
$BB Equals
$BC Comma
$BD Minus
$BE Period
$BF Slash
$C0 Backquote
$DB Open bracket
$DC Backslash
$DD Close bracket
$DE Quote

7 Check for keyboard input

out D1.B = 1 when a character is waiting, 0 otherwise

Polls without consuming anything: the character it reports is the one task 5 or task 2 reads next. A testcase reports its remaining scripted input the same way.

19 Get key state

in D1.L = four key codes, or 0 for the last keys
out D1.L = four $FF/$00 bytes, or the last key up in the high word and the last key down in the low word

Reads whether up to four keys are held right now, one byte of the answer per key code in the same order; with D1.L = 0 it answers with the last key released and the last key pressed instead. A key held down is reported at least once however briefly it was tapped, so a polling loop never misses one.

24 Enable or disable the simulator shortcut keys

in D1.L = 0 to enable, 1 to disable

Accepted and ignored: the screen panel already hands every key it takes to the program, so there are no simulator shortcuts to give up.

61 Read the mouse

in D1.B = 0 for the current state, 1 for the last button release, 2 for the last button press
out D0.B = Ctrl, Alt, Shift, Double, Middle, Right, Left from bit 6 down; D1.L = Y in the high word, X in the low word

The pointer position is in screen pixels with the same origin drawing uses, whatever the panel’s zoom. The release and press states persist until the next one, so a program that polls slowly still sees every click; the double bit is only ever set on a press.

Program time tasks 8 to 23

Waiting and reading the clock. A delay suspends the program without blocking the editor, so Stop still answers and the screen still repaints while it runs. Testcases run on a virtual clock, where a delay completes at once and the clock starts at zero.

8 Get time

out D1.L = hundredths of a second

The time the program has been running, in hundredths of a second.

note

EASy68K counts from midnight; here the clock starts at zero when the run starts, and a testcase’s virtual clock does too. Programs measure elapsed time by subtracting two reads, which is unchanged.

23 Delay

in D1.L = hundredths of a second

Lets D1.L hundredths of a second of program time pass. The editor stays responsive throughout, and the screen is repainted, so this is how an animation paces itself.

note

A testcase runs on a virtual clock: the delay completes immediately and advances that clock instead of waiting.

Tasks that are not supported

These stop the program with an error naming the task, rather than doing something the program did not ask for. Everything they configure is either hardware this editor does not have or a decision the editor makes for itself.

10 print to the printer — the editor has no printer
12 keyboard echo — typed input is always echoed, the way a terminal does it
16 display properties — the editor’s input prompt is not a program setting
21 font properties — the screen draws text in one fixed cell font
22 read a character from the text screen — the screen holds pixels, not a grid of characters
25 scroll a text rectangle — the screen holds pixels, not a grid of characters
30 clear the cycle counter — no cycle counting is emulated
31 read the cycle counter — no cycle counting is emulated
32 hardware and simulator control — there is no hardware window and no automatic IRQ
60 enable the mouse IRQ — mouse input is polled with task 61, not delivered as an interrupt
62 enable the keyboard IRQ — keyboard input is polled with tasks 7 and 19, not delivered as an interrupt

Differences from EASy68K

  • Everything printed also reaches the terminal transcript, which EASy68K does not have. It is what keeps testcases and the non-graphical view working.
  • The screen draws text in one fixed 8 by 16 cell font, so task 21 (font properties) is not supported and the text screen cannot be read back (task 22) or scrolled (task 25).
  • Task 92's bitwise drawing modes (0, 1, 3 and 5 to 15) stop the program with an error naming the mode. Double buffering, modes 17 and 94, covers the sprite erasing the XOR mode is usually used for.
  • Task 8 counts from the start of the run rather than from midnight, and task 23 completes immediately during a testcase, which runs on a virtual clock.
  • Rectangles and ellipses exclude their right and bottom edges. That is what EASy68K does too, because it draws through the Windows GDI, but it surprises people often enough to be worth saying twice.

Directives

dc
(b, w, l)

Defines constants, following the directive there can be a list of constants separated by commas, the size of each constant depends on the selected size. If no size is selected, the size is determined by the value of the constant. If the constant is a string, it will be stored as a sequence of bytes, if it is a number, it will be stored as a sequence of words

dc.b 'Hello world!', 4, %10, $F, @8, 'a', some_label
ds
(b, w, l)

Defines a space in memory of N elements, the size of each element depends on the specified size, the content of the space is undefined

ds.l 100
dcb
(b, w, l)

Defines a space in memory of N elements, the size of each element depends on the specified size, the content of the space is initialized to the second operand

dcb.b 50, 1
org

Sets the current position in memory for the following instructions

org $1000
equ

Defines a constant that will be replaced by the value when the program is assembled

name equ 10

Assembler Features

Immediate and absolute arithmetics
Indirect and absolute values allow expressions to be used, it will be calculated at assemble time.
#label+2, #$F*10, #450-%1010, #@5834/4, #($FF+%1010)*3

Instructions

add

(b, w, l) {w}
Op 1
Dn/An/(An)/Im/ea/(An, Xn)
Op 2
Dn/(An)/An/ea/(An, Xn)

Adds the value of the first operand to second operand. If the second operand is an address register, the ADDA instruction is used instead.

add.l (a4, d3), d1

adda

(l, w) {w}
Op 1
Dn/An/(An)/Im/ea/(An, Xn)
Op 2
An

Adds the value of the first operand to second operand. It does not change the SR. When using word size, the first operand is sign extended to long and the second is read and written as a long.

adda.l d0, a0

addi

(b, w, l) {w}
Op 1
Im
Op 2
Dn/(An)/ea/(An, Xn)

Adds the immediate value to the second operand

addi.w #4, d1

addq

(b, w, l) {w}
Op 1
Im
Op 2
Dn/(An)/An/ea/(An, Xn)

Adds the value of the first operand to second operand. The first operand value must be between 1 and 8. If the destination is a address register, it is always treated as a long, and the condition codes are not affected.

addq.w #4, d1

and

(b, w, l) {w}
Op 1
Dn/(An)/Im/ea/(An, Xn)
Op 2
Dn/(An)/ea/(An, Xn)

Performs a logical AND between the first and second operand, stores the result in the second operand

and.l d0, d1

andi

(b, w, l) {w}
Op 1
Im
Op 2
Dn/(An)/ea/(An, Xn)

Performs a logical AND between the first immediate value and second operand, stores the result in the second operand

andi.l #$FF, (a0)

asd

(b, w, l) {w}
Op 1
Dn/(An)/Im/ea/(An, Xn)
Op 2
Dn/(An)/ea/(An, Xn)

Shifts the bits of the destination operand to the {direction}. Two forms: (1) as<d> Dx/Im, Dn shifts Dn by the count in Dx or immediate (1–8), any size. New bits are filled with the sign bit. Defaults to word. Note: ASL sets the overflow flag if the MSB changes during the shift, while ASR always clears it. (2) as<d> (An) shifts a memory word by 1, no size suffix allowed.

`as<d> d0, d3` or `as<d> (a0)` Where d is either (l)eft or (r)ight

bcc

Op 1
ea

Branches to the specified address if {condition code}

`b<cc> label` Where cc is one of the condition codes

bchg

Op 1
Dn/(An)/Im/ea/(An, Xn)
Op 2
Dn/(An)/ea/(An, Xn)

Inverts the bit of the second operand at the position of the value of the first operand

bchg #%101, d3

bclr

Op 1
Dn/(An)/Im/ea/(An, Xn)
Op 2
Dn/(An)/ea/(An, Xn)

Clears the bit of the second operand at the position of the value of the first operand

bclr d2, d7

bra

Op 1
ea

Branches to the specified address unconditionally

bra $2000

bset

Op 1
Dn/(An)/Im/ea/(An, Xn)
Op 2
Dn/(An)/ea/(An, Xn)

Sets to 1 the bit of the second operand at the position of the value of the first operand

bset #1, d1

bsr

Op 1
ea

Branches to the specified address and stores the return address in the stack

bsr label

btst

Op 1
Dn/(An)/Im/ea/(An, Xn)
Op 2
Dn/(An)/ea/(An, Xn)

Tests the bit of the second operand at the position of the value of the first operand, it changes the Z (zero) flag, the destination operand is not modified

btst #4, d0

clr

(b, w, l) {w}
Op 1
Dn/(An)/ea/(An, Xn)

Sets to 0 all the bits of the destination operand, how many bits are set to 0 depends on the specified size, defaults to long

clr.b d0

cmp

(b, w, l) {w}
Op 1
Dn/An/(An)/Im/ea/(An, Xn)
Op 2
Dn/An

Compares the second operand with the first operand, it sets the flags accordingly which will be used by the branching instructions. Works by subtracting the first operand from the second operand and setting the flags. If the second operand is an address register, the CMPA instruction is used instead.

cmp.l -(sp), d0

cmpa

(l, w) {w}
Op 1
Dn/An/(An)/Im/ea/(An, Xn)
Op 2
An

Compares the second operand with the first operand, it sets the flags accordingly which will be used by the branching instructions. When using word size, the first operand is sign extended to long and the second is read and written as a long.

cmpa.l $1000, a0

cmpi

(b, w, l) {w}
Op 1
Im
Op 2
Dn/(An)/An/ea/(An, Xn)

Compares the second operand with the first operand, it sets the flags accordingly which will be used by the branching instructions.

cmpi.w #10, d3

cmpm

(b, w, l) {w}
Op 1
(An)
Op 2
(An)

Compares two memory regions, only valid operand is the post increment, it sets the flags accordingly which will be used by the branchin instructions.

cmpm.b (a0)+, (a1)+

dbcc

Op 1
Dn
Op 2
ea

Decrements the first operand by 1 and branches to the specified address if {condition code} is false and the first operand is not -1. dbra is the same as dbf (will decrement untill it reaches -1). It reads the operand as a word, so it can run at maximum 64k times

`db<cc> d0, label` Where cc is one of the condition codes

dbra

Op 1
Dn
Op 2
ea

Decrements the first operand by 1 and branches to the specified address if the first operand is not -1. dbcc is the same as dbf (will decrement untill it reaches -1)

dbra d0, label

divs

Op 1
Dn/(An)/Im/ea/(An, Xn)
Op 2
Dn

Divides (signed) the value of the second operand by the value of the first operand (op2 / op1). The quotient is stored in the first 16 bits of the destination register and the remainder is stored in the last 16 bits of the destination register. The first operand is read as a word, the second as a long

divs #2, d1

divu

Op 1
Dn/(An)/Im/ea/(An, Xn)
Op 2
Dn

Divides (unsigned) the value of the second operand by the value of the first operand (op2 / op1). The quotient is stored in the first 16 bits of the destination register and the remainder is stored in the last 16 bits of the destination register. The first operand is read as a word, the second as a long

divu #4, d1

eor

(b, w, l) {w}
Op 1
Dn
Op 2
Dn/(An)/ea/(An, Xn)

Performs a logical XOR between the first and second operand, stores the result in the second operand

eor.l d0, d1

eori

(b, w, l) {w}
Op 1
Im
Op 2
Dn/(An)/ea/(An, Xn)

Performs a logical XOR between the first immediate value and second operand, stores the result in the second operand

eori.l #1, (sp)+

exg

Op 1
Dn/An
Op 2
Dn/An

Exchanges the values of the two operands, only works in 32 bits

exg d0, a1

ext

(l, w) {w}
Op 1
Dn

Extends the sign of the operand, depending on the specified size. If the part to extend is negative, it will be filled with 1s, otherwise it will be filled with 0s. Defaults to word

ext.w d0

jmp

Op 1
(An)/ea

Jumps to the specified address unconditionally

jmp (a0)

jsr

Op 1
(An)/ea

Jumps to the specified address, like the "lea" instruction, when resolving the address, it does not read the memory, so "jsr 4(a0)" will jump to the value of "a0 + 4", the address is loaded and stores the return address in the stack

jsr (sp)

lea

Op 1
(An)/ea
Op 2
An

Loads the address of the first operand into the second operand, when using indirect addressing, the value is not read, only the address is loaded. For example "lea 4(a0), a0" will load a0 + 4 in a1

lea (a0), a1
Op 1
An
Op 2
Im

Pushes to the stack the long content of the address register, sets the address register to the current stack pointer and then decrements the stack pointer by the specified amount

link a0, #-16

lsd

(b, w, l) {w}
Op 1
Dn/(An)/Im/ea/(An, Xn)
Op 2
Dn/(An)/ea/(An, Xn)

Shifts the bits of the destination operand to the {direction}. Two forms: (1) ls<d> Dx/Im, Dn shifts Dn by the count in Dx or immediate (1–8), any size. New bits are filled with 0s. Defaults to word. (2) ls<d> (An) shifts a memory word by 1, no size suffix allowed.

`ls<d> #3, d7` or `ls<d> (a0)` Where d is either (l)eft or (r)ight

move

(b, w, l) {w}
Op 1
Dn/An/(An)/Im/ea/(An, Xn)
Op 2
Dn/(An)/An/ea/(An, Xn)

Moves the value from the first operand to second operand. If the second operand is an address register, the MOVEA instruction is used instead.

move.b #10, d0

movea

(l, w) {w}
Op 1
Dn/An/(An)/Im/ea/(An, Xn)
Op 2
An

Moves the value from the first operand to second operand. If the size is word, it is sign extended to long. It does not change the SR. When using word size, the first operand is sign extended to long and the second is written as a long.

movea.l d0, a0

movem

(l, w) {w}
Op 1
Dn/(An)/An/ea/(An, Xn)
Op 2
Dn/(An)/An/ea/(An, Xn)

Move many, useful when you want to save a bunch of registers, for example to save their value when branching to a function it moves a list of registers to memory, or memory to a list of registers. The first operand is the list of registers, the second operand is the memory region. If you define the registers as the first operand, then it will save the registers to memory, if the first operand is the memory, then it will load the registers from memory. You can write the list of registers by separating them with a "/", and the range between registers by using a dash. ex: a3-a5/d0-d2 will select d0, d1, d2, a3, a4, a5. The order of the register will be converted to first data, then address registers, from 0 to 7. When using the pre-decrement operand, the order of the registers will be reversed, going from a7 to a0, and d7 to d0.

movem.l d0-d2, (a0)

moveq

Op 1
Im
Op 2
Dn

Moves the value from the first operand to second operand. The first operand is read as a byte so only values between -127 and 127.

moveq #10, d0

muls

Op 1
Dn/(An)/Im/ea/(An, Xn)
Op 2
Dn

Multiplies the value of the first operand by the second operand. The result is stored in the second operand. The first operand is read as a word, the second as a long

muls d0, d1

mulu

Op 1
Dn/(An)/Im/ea/(An, Xn)
Op 2
Dn

Multiplies (unsigned) the value of the first operand by the second operand. The result is stored in the second operand. The first operand is read as a word, the second as a long

mulu d5, d2

neg

(b, w, l) {w}
Op 1
Dn/(An)/ea

Flips the sign of the operand, depending on the specified size, defaults to word

neg.l d0

nop

This instruction is a no-operation, it does not do anything.

nop

not

(b, w, l) {w}
Op 1
Dn/(An)/ea/(An, Xn)

Inverts the bits of the operand depending on the specified size

not.b d0

or

(b, w, l) {w}
Op 1
Dn/(An)/Im/ea/(An, Xn)
Op 2
Dn/(An)/ea/(An, Xn)

Performs a logical OR between the first and second operand, stores the result in the second operand

or.l #$FF, d1

ori

(b, w, l) {w}
Op 1
Im
Op 2
Dn/(An)/ea/(An, Xn)

Performs a logical OR between the first immediate value and second operand, stores the result in the second operand

ori.l #%1100, (a0)

pea

Op 1
(An)/ea

Same as lea, but it pushes the address to the stack

pea (a0)

rod

(b, w, l) {w}
Op 1
Dn/(An)/Im/ea/(An, Xn)
Op 2
Dn/(An)/ea/(An, Xn)

Rotates the bits of the destination operand to the {direction}. Two forms: (1) ro<d> Dx/Im, Dn rotates Dn by the count in Dx or immediate (1–8), any size. Defaults to word. (2) ro<d> (An) rotates a memory word by 1, no size suffix allowed.

`ro<d> d2, d5` or `ro<d> (a0)` Where d is either (l)eft or (r)ight

rts

Returns from a subroutine, pops the return address from the stack and jumps to it

rts

scc

Op 1
Dn/(An)/ea/(An, Xn)

Sets the first byte of the destination operand to $FF (-1) if flags {condition code} is true, otherwise it sets it to 0

`s<cc> d0` Where cc is one of the condition codes

sub

(b, w, l) {w}
Op 1
Dn/An/(An)/Im/ea/(An, Xn)
Op 2
Dn/(An)/An/ea/(An, Xn)

Subtracts the value of the first operand from second operand and stores in the second. If the second operand is an address register, the SUBA instruction is used instead.

sub.w $1000, d1

suba

(l, w) {w}
Op 1
Dn/An/(An)/Im/ea/(An, Xn)
Op 2
An

Subtracts the value of the first operand from second operand and stores in the second. It does not change the SR. When using word size, the first operand is sign extended to long and the second is read and written as a long.

suba.w #$FF, a1

subi

(b, w, l) {w}
Op 1
Im
Op 2
Dn/(An)/ea/(An, Xn)

Subtracts the immediate value to the second operand

subi #1, d3

subq

(b, w, l) {w}
Op 1
Im
Op 2
Dn/(An)/An/ea/(An, Xn)

Subtracts the value of the first operand from second operand and stores in the second. The first operand value must be between 1 and 8. If the destination is a address register, it is always treated as a long, and the condition codes are not affected.

subq.b #1, d3

swap

Op 1
Dn

Swaps the two word of the register, you can see the register as [a,b] after the swap it will be [b,a]

swap d0

trap

Op 1
Im

Executes a trap, the value of the operand is used as the trap number, only #15 is supported. The register d0 holds the task number. The full table, with the registers each task takes and answers with, is on the trap tasks page.

TaskDescription
0Print string pointed by a1 with length read in d1.w, null terminated with max of 255, then prints a new line.
1Print string pointed by a1 with length read in d1.w.
2Read string from keyboard, writes the string at address of a1 and overrides the value of d1 with the length of the string.
3Print signed number at d1.
4Read number, writes to d1.
5Read character, writes to d1.
6Print character at d1.
7Check for keyboard input, writes 1 or 0 to d1.b.
8Get the time in hundredths of a second since the run started, writes to d1.
9Terminate.
11Set or get the text cursor, or clear the screen with d1.w = $FF00.
13Prints null terminated string pointed by a1 then prints new line, errors if string is longer than 16kb, to prevent infinite loops.
14Prints null terminated string pointed by a1, errors if string is longer than 16kb, to prevent infinite loops.
15Prints unsigned number at d1 in base (from 2 to 36) specified in d2.b
17Prints the null terminated string at a1, then the signed number in d1.
18Prints the null terminated string at a1, then reads a number into d1.
19Reads the state of up to four keys given in d1.l, or the last keys pressed and released with d1.l = 0.
20Print the signed number in d1 right justified in a field d2.b columns wide.
23Delay for the number of hundredths of a second in d1.
24Enable or disable the simulator shortcut keys; accepted and ignored.
33Set or get the screen size, or set the window mode.
61Read the mouse: flags in d0, y:x in d1.
80-96Graphics: colors, pixels, lines, rectangles, ellipses, flood fill, drawing modes, double buffering, text and the pen position.
trap #15

tst

(b, w, l) {w}
Op 1
Dn/(An)/An/ea/(An, Xn)

Compares the operand with 0

tst.b (a0)

unlk

Op 1
An

Sets the SP to the address register, then Pops a long value from the stack and stores the result in the address register

unlk a0