During the making of my first big demo, CRTC3, available assemblers on CPC were too slow and too limited for my needs: The source code consisted in 250’000 words (out of comments), 35’000 labels and 60’000 expressions. I needed a damn fast assembler with cartridge management, memory bank management and integrated crunched code and data sections, so i had to write a new assembler.
It was not my first attempt to write such a tool: 18 years ago, i had already written a small assembler. It was so limited, i couldn’t use it for CRTC3, but i’ve kept some aspects of its design, particularly the fact that the process of assembling was mono-pass.
RASM uses efficient algorithmic patterns, such as merkel trees, caches, and grouped memory allocation. Thanks to its linear conception, performances in real conditions are really high, it’s particularly fast, even with huge projects. Nowadays RASM is used on big projects such as:
Rasm is licenced under MIT licence. This documentation is maintained by Stephane Sikora, please send any feedback to https://github.com/sikorama/rasm-doc
RASM is meant to be convenient to use. It selects automatically the correct file format (plan binary, snaphost or cartridge file)) depending on the selected ROMs, give a consistent name to generated files, looks for files in relatives path, allows multiple origin (ORG) directives, but will detect overlapping code blocks, and so on...
RASM preprocessor not only performs some checks (valid characters, strings), it also converts some operators into their C equivalent (for example XOR, AND,OR,MOD which are used by Maxam), so you can indiferently use AND or & in your expressions. And last, but not least, it is possible to use conditional expressions in order to change the way your program is assembled (like with C preprocessor), and you can even define macros and data structures!
Usage:
Without any option,
produces rasmoutput.bin file.
These options are used for changing the name of the files produced by RASM:
Symbols such as label’s addresses, constants, can be exported in a .sym file, using different formats. For example, it can be useful for debugging a program with Winape.
Example:
The symbol file looks like this:
With -sp option:
With -sw, symbols are exported in Winape format:
It is possible to disable symbol export for portion of codes with NOEXPORT directive.
Including source code or binary file can be achieved with INCBIN and READ directives. By default, included files are searched in the local folder, paths are relative, but it is possible to specify one ore more folder where to look for files. It is also possible to define or import symbols:
If a filename for binary output is set (-ob option), it will be added to the dependances list, in first position.
- unsigned 16 bit computation, with wrong rounding
- comparisons are done with equal (=) sign
- Operator priorities are simplified (see charts)
- 32 bits integer calculations with wrong rounding
- DEFB,DEFW,DEFI or DEFR directives with more than one parameter use the address of the first byte, when using $
- MACRO directive must be used after the name of the macro, and not before (see 5.3.3)
- Macro parameters are not protected by {}
- 32 bits integer calculations with wrong rounding
- macro parameters are not protected by
- MACRO directive must be used after the name of the macro
- labels beginning by a dot are ignored
- DEFB,DEFW,DEFI or DEFR directives with more than one parameter use the address of the first byte, when using $
These options are useful in rare occasions, it can sometime help for tracking bugs:
Additional options are useful for some architectures only. Export options specific to the Amstrad CPC (Snapshot and cartridge generation) are documented in paragraph 7.4.3. Also remember -help option, which will display a complete list of all available command line arguments.
RASM is meant to be easy to use, it offers some flexibility, concerning the syntax. For example:
Simply keep in mind you cannot use a reserved word (directive, register, Z80 instruction) as a label.
In this part,we’ll see general syntax of a z80 assembly file, as it can be commonly found in other assemblers. In the next parts, we’ll see some specific aspects of RASM.
Rasm uses semicolons to start a comment: Any character after a semicolon (until then end of the line) will be ignored. It also works possible to use C syntax, single line comments starting with a double slash (//), and multi lines comments delimited by /* and */.
Labels are used for naming a specific memory address.
We’ll see special labels later in this document: Some labels can be defined as locals to a Loop or macro (see local and proximity labels, 5.4.1). Also any label beginning with BRK or @BRK will generate a BREAKPOINT. (see section 7.4.2).
The complete Z80 instruction set is supported, including undocumented ones. See Appendix B for the full opcode list.
IX and IY registers can be addressed as two 8 bit registers. For example, IX lower part can be addressed indifferently with LX, IXL or XL, and higher part with HX, IXH or XH:
Also, complex instructions with IX and IY are written with this syntax:
Rasm allows some shortcuts. These are not real instrctions, but a convenient way to write shorter assembly code.
PUSH BC,DE,HL | → | PUSH BC : PUSH DE : PUSH HL |
POP HL,DE,BC | → | POP HL : POP DE : POP BC |
nop 4 | → | nop : nop : nop : nop |
LD BC,BC | → | LD B,B : LD C,C |
LD BC,DE | → | LD B,D : LD C,E |
LD BC,HL | → | LD B,H : LD C,L |
LD DE,BC | → | LD D,B : LD E,C |
LD DE,DE | → | LD D,D : LD E,E |
LD DE,HL | → | LD D,H : LD E,L |
LD HL,BC | → | LD H,B : LD L,C |
LD HL,DE | → | LD H,D : LD L,E |
LD HL,HL | → | LD H,H : LD L,L |
LD HL,(IX+n) | → | LD H,(IX+n+1) : LD L,(IX+n) |
LD HL,(IY+n) | → | LD H,(IY+n+1) : LD L,(IY+n) |
LD DE,(IX+n) | → | LD D,(IX+n+1) : LD E,(IX+n) |
LD DE,(IY+n) | → | LD D,(IY+n+1) : LD E,(IY+n) |
LD BC,(IX+n) | → | LD B,(IX+n+1) : LD C,(IX+n) |
LD BC,(IY+n) | → | LD B,(IY+n+1) : LD C,(IY+n) |
LD (IX+n),HL | → | LD (IX+n+1),H : LD (IX+n),L |
LD (IY+n),HL | → | LD (IY+n+1),H : LD (IY+n),L |
LD (IX+n),DE | → | LD (IX+n+1),D : LD (IX+n),E |
LD (IY+n),DE | → | LD (IY+n+1),D : LD (IY+n),E |
LD (IX+n),BC | → | LD (IX+n+1),B : LD (IX+n),C |
LD (IY+n),BC | → | LD (IY+n+1),B : LD (IY+n),C |
EXA | → | EX AF,AF’ |
ORG is used for locating assembled code to a specific address. This directive can be used multiple times in the same memory space, but assembled memory blocks may not overlap. In that case, RASM will produce an error message.
Still, if you need to generate two or more pieces of code targeted for the same address, but physically stored in a different place, you can use the second parameter. For example, in order to generate code targeted for address #8000, but stored in #1000:
On Amstrad CPC, you also can write tagetted to the same address, by defining a new memory space, using BANK directive. (See section 7.3.6)
If the current memory address is not a multiple of the ’boundary’ parameter, it will be increased in order to meet the alignment constraint. The gap between the current memory address and the aligned one is filled by zeroes, except if the second parameter is specified. For example:
By default, the upper address for locating code is set to 65535, but for some reason, you may need to reduce this value. However if you want to protect a memory area zone, take a look at the PROTECT directive below.
This directive protects a memory area, delimited by the two parameters, from writing. It data is written in the area while assembling, an error will be raised. It applies to current memory space and can be used many times, as long as the areas don’t overlap.
This directive handle one or more parameters and output bytes regarding of those parameters. The value may be a literal value, a formula (the result will be rounded), or a string where each char will output a byte. Following code will producte ’Roudoudou’ string. (’u’ char corresponds to ASCII code #75) Example:
With character strings, it’s possible to use control characters, with \, just like in C syntax: \n\t\r See CHARSET directive for altering the way strings are interpreted.
This directive handles one or more parameters and output words (two bytes). Values may be literals, formula, single char, but char strings are not allowed!
Example:
This directive handles one or more parameters and output four bytes integers. Values may be literal value, formula, single char, but not a string!
DEFR (or DR) directive handles one or more parameters and output AMSTRAD firmware compatible real numbers (5 bytes)
Example:
This directive is used for repeating the same byte many times. If no output value is set, then zeroes will be written. If repetition value is zero then nothing will be output. You can declare more than one repetition sequences with only DEFS.
Examples:
defs 5,8,4,1 | ; #08,#08,#08,#08,#08,#01,#01,#01,#01 |
defs 5,8,4 | ; #08,#08,#08,#08,#08,#00,#00,#00,#00 |
defs 5 | ; #00,#00,#00,#00,#00 |
Almost same directive as DEFB, except the very last char will have its 7th bit set to 1. Both lines will output the same byte sequence:
This directive allows to redefine quoted char values to be changed. There are 4 ways to use this directive:
For example, you can set a simple char redefinition:
Or redefine consecutives chars in a range:
You can also redefine non consecutives chars:
The symbols ($) refers to the current byte address. For example:
is equivalent to:
With AS80 compatibility mode it would produce the same output as:
However, when used with ORG directive, $ refers to the physical address, not the logical one:
EQU is a common way in assemblers to define constants in a convenient way. RASM also introduces variables, which value can be changed during the assembling process. There is no limit in the number of variables or alias that can be defined.
EQU directive allows to define aliases by associating a symbol with a value: any occurrence of the symbol will be replaced by the value. An alias cannot be changed once it has been changed, it’s a constant value. There is an infinite recursivity check done for each alias declaration.
Example:
An alias it cannot be changed, once it has been defined. However, it is possible to use variables with RASM, with the following syntax:
You can define as many variables as you want. Some examples:
Rasm accepts these values in expressions:
All internal calculation are done with double precision floating point accumulator. A correct rounding is done in the end for integer needs. If the evaluation leads to a computation error, the result will be null.
Beware of the & char, it is reserved for AND operator.
Between quotes, all standard ASCII characters are allowed. Quoted strings may contains escaped chars: \t \n \r \f \v \b \0 . Escaped characters are ignored when used with PRINT directive.
Rasm is using a simplified calculation engine with multiple priorities (like C language). Here is the list of supported operations:
* | multiply | ∕ | divide |
+ | addition | - | subtraction |
or XOR | logical Exclusive OR | %% or MOD | Modulo |
& AND | Logical AND | | OR | Logical OR |
&& | Boolean AND | || | Boolean OR |
<< | Left shift (multiply by 2n) | >> | Right shift (divide by 2n) |
hi() | get upper 8 bits of a word | lo() | get lower 8 bits of a words |
sin() | sinus | cos() | cosinus |
asin() | arg sinus | acos() | arc-cosinus |
atan() | arc-tangente | ||
int() | float to integer conversion | frac() | keeps fractional part of a float |
floor() | rounds to the lower integer | ceil() | ronds to the higher integer |
abs() | absolute value | rnd() | Random number between 0 and n - 1 |
ln() | neperian logarithm | log10() | base 10 logarithm |
exp() | exponent | sqrt() | square root |
== | equals (= in Maxam mode) | ! = ou <> | not equal |
<= | lesser or equal | >= | greater or equal |
< | lesser | > | greater |
Lower is the prevalence, higher is the execution priority.
Operators | Rasm Prevalence | Maxam Prevalence |
( ) | 0 | 0 |
! | 1 | 464 |
* ∕ % | 2 | 464 |
+ - | 3 | 464 |
<< >> | 4 | 464 |
< <= == => > ! = | 5 | 664 |
& AND | 6 | 464 |
| OR | 7 | 464 |
XOR | 8 | 464 |
&& | 9 | 6128 |
|| | 10 | 6128 |
RASM preprocessor recognizes many directives.
When a directive has parameters, it must be separated by at least one space char:
Wrong syntax: ASSERT(4*myvar)
Correct syntax: ASSERT (4*myvar)
Write text, variables or the result of evaluation of an expression during assembly.
By default, numerical values are formatted as floating point values, but you may use prefixes to change this behaviour:
This directive is similar to PRINT, but it will also trigger an error and STOP assembling.
Stop assembling an do not generate any file.
NOEXPORT directive disables symbol export. By default, it applies to all symbols (labels,variables,constants), but it is possible to specify a subset of symbols. Symbol export can be re enabled (fully or partially) with ENOEXPORT.
It is possible to use conditional directives with RASM, in a way similar to C preprocessor: it is possible to change the assembled code, depending on some conditions. There is a basic rule when writing such expressions: all variables used in it must be declared prior to the expression.
Stop assembling if the condition test fails. In that case, and if some text is specified, it will be printed on the console. Example:
As with C preprocessor, this directive can be used for enabling some portions of code, depending on a condition. Example:
Both directives test variable or label existence.
Removes a variable definition. Any IFDEF condition with this variable will be evaluated as false. If the variable doesn’t exist, this directive won’t do anything.
Both directives test variable or label usage, BEFORE the test.
SWITCH/CASE syntax mimics the C syntax. A SWITCH block is terminated by ENDSWITCH directive,and each of its ’CASE’ block with a ’BREAK’. With RASM, you can use the same value in different cases, allowing to write more complex cases. For example, this code will be produce ’BCE’ string:
This directive repeats a block of instructions. You may fix a number of repetition or use conditional mode with UNTIL. It is also possible to close such a block with ENDREP or ENDREPEAT, for Vasm compatibility.
Non Conditional Repeat In the case of a non conditional loop, it is possible to specify a variable which contains the iteraction counter. There’s no need to declare this variable (here cnt) prior to the REPEAT block. It will automatically be created.
By default, the loop counter starts from 1 and is increased by 1 at every loop. These values can be changed, respectively with counter_start and counter_step optional parameters. These values can be integer, but also floating values.
These values can either be integer, but also floating values.
Another way to specify textttcounter_start and counter_step consists in using REPEAT_COUNTER. All REPEAT blocks declared after REPEAT_COUNTER will use these values. Without parameters, the counter will start at 1, and increment will be set to 1.
You can get the internal loop counter anytime with internal variable REPEAT_COUNTER.
Repeat a block as long as the condition is evaluated as true. You may use the internal variable WHILE_COUNTER variable to get the loop counter.
This code will loop 10 times with the following output:
A macro is a way to extend the language, by defining a block of instructions, delimited by MACRO and MEND (or ENDM) directives, that can later be inserted in your code. Macros can take parameters, so you can make conditional assembling with it: a macro is barely a copy/paste with arguments replacement. Arguments inside the macro are referenced using curly brackets. Here is an example of a long distance indexing, working for any 16 bit register (except B or C):
Macro calls with static or dynamic args Arguments sent to a macro can also be formulas.
Separating Low an Hi bytes of a 16bit register Inside a Macro, it is possible to use LOW or HI for using the lower or the higher part of a 16 bit register. For example, ld A,R1.low is identical to ld A,C if R1=BC. A macro for adding two 16 bits register can be written like this:
Inside a loop (REPEAT/WHILE/UNTIL) or inside a macro, you can define local labels the same way as Winape assembler does, by prefixing labels with ’@’. You cannot use these labels outside of the loop or macro.
You can use label value with a directive (ORG for example) only if the label was previously declared. Usage of local label in a loop:
Proximity labels are prefixed with a dot, and are associated with the previous label. They can be used ’locally’ directly with their ’short’ names, and anymwhere with their full name:
MODULE is a way to declare a section in your code. It is similar to namespace in C, and allows to prefix globals and proximity labels with a name. It can be useful in order to avoid conflict between portions of code using similar labels, for example when including external code. Closing a Module section can be done by declaring a new module, or using MODULE OFF In order to prefix a label inside a module, underscore symbol is used : module_label. For example:
As Z80 processor is able to manage structured data thanks to its IX and IY registers, RASM introduces STRUCT directive, which is used for defining a structure, in a similar way to C syntax
When {STRUCT} directive is used with 2 parameters, RASM will create a structure in memory, based on the prototype. In the example below, it will instantiate a metast1 structure type, called mymeta.
Example of retrieving fields absolute address using the structure previously declared:
Example of accessing a field with an offset, by using the prototype name:
Recommended usage to get the size of a structure is to use {SIZEOF} prefix. It alsoworks for a substructure or a field.
Like Vasm, you also can get the structure size using its prototype name but it is not recommended.
It’s possible to instantiate an array of structs, using this syntax:
Compared to ds 10*SIZEOF(mystruct), data is initialized with default values as defined in structure declaration, and not filled with a zero value. Also it is possible to access to a specific instance, using an index, like a regular array.
TICKER directive computes the duration of an instruction block (delimited by TICKER START and TICKER STOP), and stores the result in a variable. It can be used for counting cycles for CPC architecture (by using TICKER STOP), or for ZX architectures (by using TICKER STOPZX) On CPC, the duration is expressed as ”number of NOPs”, which is approximately equivalent to micro seconds (see Annexe C). This directive is very convenient when writing video effects, such as rasters, where colors have to be changed periodically, every 64 micro seconds (the duration of a video line):
For example with this code, cnt variable will be equal to 8
It can be used this way, to obtain a loop duration of 64us:
Read a textfile in place of the directive. The root of the relative path is the location of the file containing the include directive. An absolute path discard the relative path. There is no recursivity limit, so be aware of what you are doing.
Read a binary file. Binary data will go straight to memory space. Additional parameters are an offset, a size, and an option for disabling overwrite check. The extended offset is only here for compaitibily with Winape, so you can ignore it.
Example:
If you want for example to import a 32K file into 2 16Kb banks (see 7.3.6)
You can use INCBIN inside a REPEAT block, for importing a series of files. For example if you want to import files myfile1, myfile2, ... myfile10:
If REVERT keyword is used, the file will be inserted backwards.
REMAP VTILES and ITILES variants are used for importing sprites.
All WAV formats -single channel or multi channel- are supported . Voices will be merged in latter case. The sampling frequency is not taken into account. To import a WAV file, you must specify one of the 4 formats among SMP, SM2, SM4 and DMA:
Open a crunched section in LZ48,LZ49, LZ4, ZX7, LZAPU, LZSA, LZX0, or Exomizer. A LZ section is closed with LZCLOSE.
LZSA takes an optional parameter, for controlling how strong data will be crunched, and how fast it will uncompress. For example, for LZSA1, with minmatch=5, it will uncrunch quickly For LZSA2, with minmatch=2, it will crunch strongly. For more information, check the documentation by Emmanuel Marty, who created LZSA cruncher.
LZX0 is a new recent addition to RASM, and offers a good compression ratio, and uncrunches really quickly. LZX0b is a variant for decrunching backwards.
Generated code is crunched once it is assembled. The code following such a block is then relocated (labels, ...).
You cannot call a label located after a crunched zone from the crunched zone because RASM cannot determine where it will be located after crunching. This will trigger an error.
Code or data of a crunched zone cannot exceed 64K. Also, you cannot imbricate crunched sections.
Example:
Read a binary file, crunch it in LZ48, LZ49, LZ4, Exomizer, LZSA or ZX7 on the fly.
This directive sums all bytes between start_address and end_address in the current bank and store the result at the address where the directive is located.
Same as XORMEM, but computes a XOR operation instead of a sum. It can be used for computing a checksum, for example:
Using {BANK} prefix before a label (example: {BANK}mylabel ) will return the BANK number where the label is located, instead of its absolute address. For example:
Use PAGE prefix before a label (example: {PAGE}mylabel ) to get a value that can be used to program the Gate Array for accessing the bank where the label is located. For example with a label located into BANK 5, #7FC5 will be returned. If you are using BANKSET directive to select 4 banks in a 64K set, then the gate array value is composed by the set number and the 2 most significant bits of the label address. Example:
You can use {PAGESET} prefix before a label (example: {PAGESET}mylabel) to program the Gate array for selecting the BANKSET where the label is located. For example, for a label stored in BANK #5, #7FC2 will be returned.
This directive adds an AMSDOS header to the binary file generated by RASM. This directive has no effect on SAVE directive, which has its own option for adding AMSDOS header.
Records a binary file of the given size, starting from the specified address, from current memory space. All SAVE directives are executed at the end of the assemblig process: there is no way to save intermediate assembling states.
When recording a file on a floppy image (DSK), its name will be automatically converted according to the AMSDOS format: lower cases will be replaced by upper cases, and it will be truncated. If the DSK file doesn’t exist, il will be automatically created. If it already exists, and if the binary file produced by rasm already exists on the disk, it WON’T be updated, except if -eo option is used.
With TAPE format, a CDT filt will be produced.
Examples:
Combined with RUN:
RASM also allows to generate cartridge (.crt) and snapshot (.sna) files. These files can be used by some emulators such as Wanape and Ace.
Without parameter, this directive is optional, as by default, when a BANK directive is used, a cardridge file is generated. However, it is recommended to explicitly use this directive to indicate that a cardridge will be generated. If EXTENDED parameter is added, then an extended cartridge (.xpr) will be generated. It can be used in cunjunction with -xpr option, for generating additional file for each 512KB slot.
This directive forces Rasm to generate a snapshot instead of a cartridge. The entry point must be specified (0 is not valid).
By default, the snapshot is targeted for a CPC 6128 with CRTC 0. You can use SETCRTC and SETCPC directives to select an other configuration. Audio channels are disabled, ROMS are disabled and interrupt mode is set to 1.
Select CPC model when recording a v3 snapshot:
0: | CPC 464 |
1: | CPC 664 |
2: | CPC 6128 |
4: | 464 Plus |
5: | 6128 Plus |
6: | GX-4000 |
Select CRTC model when writing a v3 snapshot file. Value for CRTC model ranges from 0 to 4. CRTC 3 corresponds to CPC Plus and GX-4000, other values to classic CPCs.
With first syntax (taking two parameters), these registers can be set:
With the 3 other syntaxes, SETSNA takes an additional parameter, in order to specify the index of the register
Generates a CDT file. Like BUILDSNA directive, it’s possible to declare an entry point with RUN
Selects a ROM bank (while exporting a cartridge) or a RAM slot (for snapshots) for storing code or data. For a cartridge, values range from 0 to 31. In snapshot mode the values range from 0 to 35 (64K base memory + 512K extended memory). Used without parameter, BANK directive opens a new memory workspace.
By default, when using BANK, a cartridge will be generated, except if BUILDSNA directive was used previously.
By default, snapshot v3 are exported. There is a compatibility option for selecting snapshot version 2, some emulators or hardware board do not support snapshot v3 yet. Just add arg ’v2’ to SNAPSHOT directive or add -v2 option to the command line while invocating RASM.
This option is only used to set then entry point of a snapshot file. It is ignored if a cartridge is exported. The gate array can be configured with additional parameters
BANKSET directive select a set of 4 pages in a row. With snapshot v3, there are 9 memory sets, indexed from 0 to 8.
You may use BANK and BANKSET in a source but you cannot select the same memory space. A check will trigger an error if you try to.
Using this directive enables snapshot output (like BUILDSNA does).
Add a breakpoint (this won’t be assembled) to the current address or to the address of the parameter. Breakpoints may be exported to a text file or into snapshots (Winape and ACE compatible) with -sb option.
Another way to set a breakpoint is to prefix a label with BRK or @BRK.
Use this in an expression, in order to get one of the 4 bit component of a 16 bit color as used in the ASIC
Returns a 16 bit value where the 4-bit value of the color component (R,G,B) is set
This directive is used for disabling code generation for a portion of code.
This directive is only supported for Winape compatibility. Prefer usage of BANK or BANKSET directives.
These directives are ignored. Usage for Maxam/Winape compatibility only.
RASM also features a few options and directives specific for ZX architecture.
Use this directive for generating a file in HOBETA format.
Use this directive to enable ZX SNA file generation (Snapshot) With ZX SNA, you must specify a second parameter to RUN directive, in order to provide the value of Stack Pointer (SP)
-sx option can be used for exporting symbols for ZX emulators, where the selected bank is output. (<bank>:<address>)
There is no installation procedure for RASM, as it consists in a single executable file. As C source code is provided with RASM, it can be recompiled. Here are the commands for some platforms and compilers - mainly calling scripts or Makefiles All these scripts use UPX, a compression tool for executable binaries, available here: https://upx.github.io
Dos/Windows 32 (Watcom) For DosBox, you need to set RAM to at least 64Mb
There are 3 steps t follow for integrating RASM into your own C/C++ application:
As a first example, we’ll use RasmAssemble function, which returns an error code (0 if everything went fine, or -1 if an error happened), and also assembled byte code, in an array of unsigned chars. RasmAssembleInfos is similar, but it also returns additional data, such as a list of errors and the value of all symbols.
In order to copile rasm and our example (embed.cpp):
When executed, it produces this:
If you already have a syntax color file, just add the following lines to the file .vim/syntax/z80.vim Or you may download the whole file here
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | |
0 | nop | ld bc,** | ld (bc),a | inc bc | inc b | dec b | ld b,* | rlca | ex af,af’ | add hl,bc | ld a,(bc) | dec bc | inc c | dec c | ld c,* | rrca |
1 | djnz * | ld de,** | ld (de),a | inc de | inc d | dec d | ld d,* | rla | jr * | add hl,de | ld a,(de) | dec de | inc e | dec e | ld e,* | rra |
2 | jr nz,* | ld hl,** | ld (**),hl | inc hl | inc h | dec h | ld h,* | daa | jr z,* | add hl,hl | ld hl,(**) | dec hl | inc l | dec l | ld l,* | cpl |
3 | jr nc,* | ld sp,** | ld (**),a | inc sp | inc (hl) | dec (hl) | ld (hl),* | scf | jr c,* | add hl,sp | ld a,(**) | dec sp | inc a | dec a | ld a,* | ccf |
4 | ld b,b | ld b,c | ld b,d | ld b,e | ld b,h | ld b,l | ld b,(hl) | ld b,a | ld c,b | ld c,c | ld c,d | ld c,e | ld c,h | ld c,l | ld c,(hl) | ld c,a |
5 | ld d,b | ld d,c | ld d,d | ld d,e | ld d,h | ld d,l | ld d,(hl) | ld d,a | ld e,b | ld e,c | ld e,d | ld e,e | ld e,h | ld e,l | ld e,(hl) | ld e,a |
6 | ld h,b | ld h,c | ld h,d | ld h,e | ld h,h | ld h,l | ld h,(hl) | ld h,a | ld l,b | ld l,c | ld l,d | ld l,e | ld l,h | ld l,l | ld l,(hl) | ld l,a |
7 | ld (hl),b | ld (hl),c | ld (hl),d | ld (hl),e | ld (hl),h | ld (hl),l | halt | ld (hl),a | ld a,b | ld a,c | ld a,d | ld a,e | ld a,h | ld a,l | ld a,(hl) | ld a,a |
8 | add a,b | add a,c | add a,d | add a,e | add a,h | add a,l | add a,(hl) | add a,a | adc a,b | adc a,c | adc a,d | adc a,e | adc a,h | adc a,l | adc a,(hl) | adc a,a |
9 | sub b | sub c | sub d | sub e | sub h | sub l | sub (hl) | sub a | sbc a,b | sbc a,c | sbc a,d | sbc a,e | sbc a,h | sbc a,l | sbc a,(hl) | sbc a,a |
A | and b | and c | and d | and e | and h | and l | and (hl) | and a | xor b | xor c | xor d | xor e | xor h | xor l | xor (hl) | xor a |
B | or b | or c | or d | or e | or h | or l | or (hl) | or a | cp b | cp c | cp d | cp e | cp h | cp l | cp (hl) | cp a |
C | ret nz | pop bc | jp nz,** | jp ** | call nz,** | push bc | add a,* | rst #00 | ret z | ret | jp z,** | call z,** | call ** | adc a,* | rst #08 |
|
D | ret nc | pop de | jp nc,** | out (*),a | call nc,** | push de | sub * | rst #10 | ret c | exx | jp c,** | in a,(*) | call c,** | sbc a,* | rst #18 |
|
E | ret po | pop hl | jp po,** | ex (sp),hl | call po,** | push hl | and * | rst #20 | ret pe | jp (hl) | jp pe,** | ex de,hl | call pe,** | xor * | rst #28 |
|
F | ret p | pop af | jp p,** | di | call p,** | push af | or * | rst #30 | ret m | ld sp,hl | jp m,** | ei | call m,** | cp * | rst #38 |
|
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | |
4 | in b,(c) | out (c),b | sbc hl,bc | ld (**),bc | neg | retn | im 0 | ld i,a | in c,(c) | out (c),c | adc hl,bc | ld bc,(**) | neg | reti | im 0/1 | ld r,a |
5 | in d,(c) | out (c),d | sbc hl,de | ld (**),de | neg | retn | im 1 | ld a,i | in e,(c) | out (c),e | adc hl,de | ld de,(**) | neg | retn | im 2 | ld a,r |
6 | in h,(c) | out (c),h | sbc hl,hl | ld (**),hl | neg | retn | im 0 | rrd | in l,(c) | out (c),l | adc hl,hl | ld hl,(**) | neg | retn | im 0/1 | rld |
7 | in (c) | out (c),0 | sbc hl,sp | ld (**),sp | neg | retn | im 1 |
| in a,(c) | out (c),a | adc hl,sp | ld sp,(**) | neg | retn | im 2 |
|
A | ldi | cpi | ini | outi |
|
|
|
| ldd | cpd | ind | outd |
|
|
|
|
B | ldir | cpir | inir | otir |
|
|
|
| lddr | cpdr | indr | otdr |
|
|
|
|
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | |
0 | rlc b | rlc c | rlc d | rlc e | rlc h | rlc l | rlc (hl) | rlc a | rrc b | rrc c | rrc d | rrc e | rrc h | rrc l | rrc (hl) | rrc a |
1 | rl b | rl c | rl d | rl e | rl h | rl l | rl (hl) | rl a | rr b | rr c | rr d | rr e | rr h | rr l | rr (hl) | rr a |
2 | sla b | sla c | sla d | sla e | sla h | sla l | sla (hl) | sla a | sra b | sra c | sra d | sra e | sra h | sra l | sra (hl) | sra a |
3 | sll b | sll c | sll d | sll e | sll h | sll l | sll (hl) | sll a | srl b | srl c | srl d | srl e | srl h | srl l | srl (hl) | srl a |
4 | bit 0,b | bit 0,c | bit 0,d | bit 0,e | bit 0,h | bit 0,l | bit 0,(hl) | bit 0,a | bit 1,b | bit 1,c | bit 1,d | bit 1,e | bit 1,h | bit 1,l | bit 1,(hl) | bit 1,a |
5 | bit 2,b | bit 2,c | bit 2,d | bit 2,e | bit 2,h | bit 2,l | bit 2,(hl) | bit 2,a | bit 3,b | bit 3,c | bit 3,d | bit 3,e | bit 3,h | bit 3,l | bit 3,(hl) | bit 3,a |
6 | bit 4,b | bit 4,c | bit 4,d | bit 4,e | bit 4,h | bit 4,l | bit 4,(hl) | bit 4,a | bit 5,b | bit 5,c | bit 5,d | bit 5,e | bit 5,h | bit 5,l | bit 5,(hl) | bit 5,a |
7 | bit 6,b | bit 6,c | bit 6,d | bit 6,e | bit 6,h | bit 6,l | bit 6,(hl) | bit 6,a | bit 7,b | bit 7,c | bit 7,d | bit 7,e | bit 7,h | bit 7,l | bit 7,(hl) | bit 7,a |
8 | res 0,b | res 0,c | res 0,d | res 0,e | res 0,h | res 0,l | res 0,(hl) | res 0,a | res 1,b | res 1,c | res 1,d | res 1,e | res 1,h | res 1,l | res 1,(hl) | res 1,a |
9 | res 2,b | res 2,c | res 2,d | res 2,e | res 2,h | res 2,l | res 2,(hl) | res 2,a | res 3,b | res 3,c | res 3,d | res 3,e | res 3,h | res 3,l | res 3,(hl) | res 3,a |
A | res 4,b | res 4,c | res 4,d | res 4,e | res 4,h | res 4,l | res 4,(hl) | res 4,a | res 5,b | res 5,c | res 5,d | res 5,e | res 5,h | res 5,l | res 5,(hl) | res 5,a |
B | res 6,b | res 6,c | res 6,d | res 6,e | res 6,h | res 6,l | res 6,(hl) | res 6,a | res 7,b | res 7,c | res 7,d | res 7,e | res 7,h | res 7,l | res 7,(hl) | res 7,a |
C | set 0,b | set 0,c | set 0,d | set 0,e | set 0,h | set 0,l | set 0,(hl) | set 0,a | set 1,b | set 1,c | set 1,d | set 1,e | set 1,h | set 1,l | set 1,(hl) | set 1,a |
D | set 2,b | set 2,c | set 2,d | set 2,e | set 2,h | set 2,l | set 2,(hl) | set 2,a | set 3,b | set 3,c | set 3,d | set 3,e | set 3,h | set 3,l | set 3,(hl) | set 3,a |
E | set 4,b | set 4,c | set 4,d | set 4,e | set 4,h | set 4,l | set 4,(hl) | set 4,a | set 5,b | set 5,c | set 5,d | set 5,e | set 5,h | set 5,l | set 5,(hl) | set 5,a |
F | set 6,b | set 6,c | set 6,d | set 6,e | set 6,h | set 6,l | set 6,(hl) | set 6,a | set 7,b | set 7,c | set 7,d | set 7,e | set 7,h | set 7,l | set 7,(hl) | set 7,a |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | |
0 |
|
|
|
|
|
|
|
|
| add ix,bc |
|
|
|
|
|
|
1 |
|
|
|
|
|
|
|
|
| add ix,de |
|
|
|
|
|
|
2 |
| ld ix,** | ld (**),ix | inc ix | inc ixh | dec ixh | ld ixh,* |
|
| add ix,ix | ld ix,(**) | dec ix | inc ixl | dec ixl | ld ixl,* |
|
3 |
|
|
|
| inc (ix+*) | dec (ix+*) | ld (ix+*),* |
|
| add ix,sp |
|
|
|
|
|
|
4 |
|
|
|
| ld b,ixh | ld b,ixl | ld b, (ix+*) |
|
|
|
|
| ld c,ixh | ld c,ixl | ld c, (ix+*) |
|
5 |
|
|
|
| ld d,ixh | ld d,ixl | ld d, (ix+*) |
|
|
|
|
| ld e,ixh | ld e,ixl | ld e, (ix+*) |
|
6 | ld ixh,b | ld ixh,c | ld ixh,d | ld ixh,e | ld ixh,ixh | ld ixh,ixl | ld h, (ix+*) | ld ixh,a | ld ixl,b | ld ixl,c | ld ixl,d | ld ixl,e | ld ixl,ixh | ld ixl,ixl | ld l, (ix+*) | ld ixl,a |
7 | ld (ix+*),b | ld (ix+*),c | ld (ix+*),d | ld (ix+*),e | ld (ix+*),h | ld (ix+*),l |
| ld (ix+*),a |
|
|
|
| ld a,ixh | ld a,ixl | ld a, (ix+*) |
|
8 |
|
|
|
| add a,ixh | add a,ixl | add a, (ix+*) |
|
|
|
|
| adc a,ixh | adc a,ixl | adc a, (ix+*) |
|
9 |
|
|
|
| sub ixh | sub ixl | sub (ix+*) |
|
|
|
|
| sbc a,ixh | sbc a,ixl | sbc a, (ix+*) |
|
A |
|
|
|
| and ixh | and ixl | and (ix+*) |
|
|
|
|
| xor ixh | xor ixl | xor (ix+*) |
|
B |
|
|
|
| or ixh | or ixl | or (ix+*) |
|
|
|
|
| cp ixh | cp ixl | cp (ix+*) |
|
C |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
D |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
E |
| pop ix |
| ex (sp),ix |
| push ix |
|
|
| jp (ix) |
|
|
|
|
|
|
F |
|
|
|
|
|
|
|
|
| ld sp,ix |
|
|
|
|
|
|
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | |
0 | rlc (ix+*),b | rlc (ix+*),c | rlc (ix+*),d | rlc (ix+*),e | rlc (ix+*),h | rlc (ix+*),l | rlc (ix+*) | rlc (ix+*),a | rrc (ix+*),b | rrc (ix+*),c | rrc (ix+*),d | rrc (ix+*),e | rrc (ix+*),h | rrc (ix+*),l | rrc (ix+*) | rrc (ix+*),a |
1 | rl (ix+*),b | rl (ix+*),c | rl (ix+*),d | rl (ix+*),e | rl (ix+*),h | rl (ix+*),l | rl (ix+*) | rl (ix+*),a | rr (ix+*),b | rr (ix+*),c | rr (ix+*),d | rr (ix+*),e | rr (ix+*),h | rr (ix+*),l | rr (ix+*) | rr (ix+*),a |
2 | sla (ix+*),b | sla (ix+*),c | sla (ix+*),d | sla (ix+*),e | sla (ix+*),h | sla (ix+*),l | sla (ix+*) | sla (ix+*),a | sra (ix+*),b | sra (ix+*),c | sra (ix+*),d | sra (ix+*),e | sra (ix+*),h | sra (ix+*),l | sra (ix+*) | sra (ix+*),a |
3 | sll (ix+*),b | sll (ix+*),c | sll (ix+*),d | sll (ix+*),e | sll (ix+*),h | sll (ix+*),l | sll (ix+*) | sll (ix+*),a | srl (ix+*),b | srl (ix+*),c | srl (ix+*),d | srl (ix+*),e | srl (ix+*),h | srl (ix+*),l | srl (ix+*) | srl (ix+*),a |
4 | bit 0, (ix+*) | bit 0, (ix+*) | bit 0, (ix+*) | bit 0, (ix+*) | bit 0, (ix+*) | bit 0, (ix+*) | bit 0, (ix+*) | bit 0, (ix+*) | bit 1, (ix+*) | bit 1, (ix+*) | bit 1, (ix+*) | bit 1, (ix+*) | bit 1, (ix+*) | bit 1, (ix+*) | bit 1, (ix+*) | bit 1, (ix+*) |
5 | bit 2, (ix+*) | bit 2, (ix+*) | bit 2, (ix+*) | bit 2, (ix+*) | bit 2, (ix+*) | bit 2, (ix+*) | bit 2, (ix+*) | bit 2, (ix+*) | bit 3, (ix+*) | bit 3, (ix+*) | bit 3, (ix+*) | bit 3, (ix+*) | bit 3, (ix+*) | bit 3, (ix+*) | bit 3, (ix+*) | bit 3, (ix+*) |
6 | bit 4, (ix+*) | bit 4, (ix+*) | bit 4, (ix+*) | bit 4, (ix+*) | bit 4, (ix+*) | bit 4, (ix+*) | bit 4, (ix+*) | bit 4, (ix+*) | bit 5, (ix+*) | bit 5, (ix+*) | bit 5, (ix+*) | bit 5, (ix+*) | bit 5, (ix+*) | bit 5, (ix+*) | bit 5, (ix+*) | bit 5, (ix+*) |
7 | bit 6, (ix+*) | bit 6, (ix+*) | bit 6, (ix+*) | bit 6, (ix+*) | bit 6, (ix+*) | bit 6, (ix+*) | bit 6, (ix+*) | bit 6, (ix+*) | bit 7, (ix+*) | bit 7, (ix+*) | bit 7, (ix+*) | bit 7, (ix+*) | bit 7, (ix+*) | bit 7, (ix+*) | bit 7, (ix+*) | bit 7, (ix+*) |
8 | res 0, (ix+*),b | res 0, (ix+*),c | res 0, (ix+*),d | res 0, (ix+*),e | res 0, (ix+*),h | res 0, (ix+*),l | res 0, (ix+*) | res 0, (ix+*),a | res 1, (ix+*),b | res 1, (ix+*),c | res 1, (ix+*),d | res 1, (ix+*),e | res 1, (ix+*),h | res 1, (ix+*),l | res 1, (ix+*) | res 1, (ix+*),a |
9 | res 2, (ix+*),b | res 2, (ix+*),c | res 2, (ix+*),d | res 2, (ix+*),e | res 2, (ix+*),h | res 2, (ix+*),l | res 2, (ix+*) | res 2, (ix+*),a | res 3, (ix+*),b | res 3, (ix+*),c | res 3, (ix+*),d | res 3, (ix+*),e | res 3, (ix+*),h | res 3, (ix+*),l | res 3, (ix+*) | res 3, (ix+*),a |
A | res 4, (ix+*),b | res 4, (ix+*),c | res 4, (ix+*),d | res 4, (ix+*),e | res 4, (ix+*),h | res 4, (ix+*),l | res 4, (ix+*) | res 4, (ix+*),a | res 5, (ix+*),b | res 5, (ix+*),c | res 5, (ix+*),d | res 5, (ix+*),e | res 5, (ix+*),h | res 5, (ix+*),l | res 5, (ix+*) | res 5, (ix+*),a |
B | res 6, (ix+*),b | res 6, (ix+*),c | res 6, (ix+*),d | res 6, (ix+*),e | res 6, (ix+*),h | res 6, (ix+*),l | res 6, (ix+*) | res 6, (ix+*),a | res 7, (ix+*),b | res 7, (ix+*),c | res 7, (ix+*),d | res 7, (ix+*),e | res 7, (ix+*),h | res 7, (ix+*),l | res 7, (ix+*) | res 7, (ix+*),a |
C | set 0, (ix+*),b | set 0, (ix+*),c | set 0, (ix+*),d | set 0, (ix+*),e | set 0, (ix+*),h | set 0, (ix+*),l | set 0, (ix+*) | set 0, (ix+*),a | set 1, (ix+*),b | set 1, (ix+*),c | set 1, (ix+*),d | set 1, (ix+*),e | set 1, (ix+*),h | set 1, (ix+*),l | set 1, (ix+*) | set 1, (ix+*),a |
D | set 2, (ix+*),b | set 2, (ix+*),c | set 2, (ix+*),d | set 2, (ix+*),e | set 2, (ix+*),h | set 2, (ix+*),l | set 2, (ix+*) | set 2, (ix+*),a | set 3, (ix+*),b | set 3, (ix+*),c | set 3, (ix+*),d | set 3, (ix+*),e | set 3, (ix+*),h | set 3, (ix+*),l | set 3, (ix+*) | set 3, (ix+*),a |
E | set 4, (ix+*),b | set 4, (ix+*),c | set 4, (ix+*),d | set 4, (ix+*),e | set 4, (ix+*),h | set 4, (ix+*),l | set 4, (ix+*) | set 4, (ix+*),a | set 5, (ix+*),b | set 5, (ix+*),c | set 5, (ix+*),d | set 5, (ix+*),e | set 5, (ix+*),h | set 5, (ix+*),l | set 5, (ix+*) | set 5, (ix+*),a |
F | set 6, (ix+*),b | set 6, (ix+*),c | set 6, (ix+*),d | set 6, (ix+*),e | set 6, (ix+*),h | set 6, (ix+*),l | set 6, (ix+*) | set 6, (ix+*),a | set 7, (ix+*),b | set 7, (ix+*),c | set 7, (ix+*),d | set 7, (ix+*),e | set 7, (ix+*),h | set 7, (ix+*),l | set 7, (ix+*) | set 7, (ix+*),a |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | |
0 |
|
|
|
|
|
|
|
|
| add iy,bc |
|
|
|
|
|
|
1 |
|
|
|
|
|
|
|
|
| add iy,de |
|
|
|
|
|
|
2 |
| ld iy,** | ld (**),iy | inc iy | inc iyh | dec iyh | ld iyh,* |
|
| add iy,iy | ld iy,(**) | dec iy | inc iyl | dec iyl | ld iyl,* |
|
3 |
|
|
|
| inc (iy+*) | dec (iy+*) | ld (iy+*),* |
|
| add iy,sp |
|
|
|
|
|
|
4 |
|
|
|
| ld b,iyh | ld b,iyl | ld b, (iy+*) |
|
|
|
|
| ld c,iyh | ld c,iyl | ld c, (iy+*) |
|
5 |
|
|
|
| ld d,iyh | ld d,iyl | ld d, (iy+*) |
|
|
|
|
| ld e,iyh | ld e,iyl | ld e, (iy+*) |
|
6 | ld iyh,b | ld iyh,c | ld iyh,d | ld iyh,e | ld iyh,iyh | ld iyh,iyl | ld h, (iy+*) | ld iyh,a | ld iyl,b | ld iyl,c | ld iyl,d | ld iyl,e | ld iyl,iyh | ld iyl,iyl | ld l, (iy+*) | ld iyl,a |
7 | ld (iy+*),b | ld (iy+*),c | ld (iy+*),d | ld (iy+*),e | ld (iy+*),h | ld (iy+*),l |
| ld (iy+*),a |
|
|
|
| ld a,iyh | ld a,iyl | ld a, (iy+*) |
|
8 |
|
|
|
| add a,iyh | add a,iyl | add a, (iy+*) |
|
|
|
|
| adc a,iyh | adc a,iyl | adc a, (iy+*) |
|
9 |
|
|
|
| sub iyh | sub iyl | sub (iy+*) |
|
|
|
|
| sbc a,iyh | sbc a,iyl | sbc a, (iy+*) |
|
A |
|
|
|
| and iyh | and iyl | and (iy+*) |
|
|
|
|
| xor iyh | xor iyl | xor (iy+*) |
|
B |
|
|
|
| or iyh | or iyl | or (iy+*) |
|
|
|
|
| cp iyh | cp iyl | cp (iy+*) |
|
C |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
D |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
E |
| pop iy |
| ex (sp),iy |
| push iy |
|
|
| jp (iy) |
|
|
|
|
|
|
F |
|
|
|
|
|
|
|
|
| ld sp,iy |
|
|
|
|
|
|
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | |
0 | rlc (iy+*),b | rlc (iy+*),c | rlc (iy+*),d | rlc (iy+*),e | rlc (iy+*),h | rlc (iy+*),l | rlc (iy+*) | rlc (iy+*),a | rrc (iy+*),b | rrc (iy+*),c | rrc (iy+*),d | rrc (iy+*),e | rrc (iy+*),h | rrc (iy+*),l | rrc (iy+*) | rrc (iy+*),a |
1 | rl (iy+*),b | rl (iy+*),c | rl (iy+*),d | rl (iy+*),e | rl (iy+*),h | rl (iy+*),l | rl (iy+*) | rl (iy+*),a | rr (iy+*),b | rr (iy+*),c | rr (iy+*),d | rr (iy+*),e | rr (iy+*),h | rr (iy+*),l | rr (iy+*) | rr (iy+*),a |
2 | sla (iy+*),b | sla (iy+*),c | sla (iy+*),d | sla (iy+*),e | sla (iy+*),h | sla (iy+*),l | sla (iy+*) | sla (iy+*),a | sra (iy+*),b | sra (iy+*),c | sra (iy+*),d | sra (iy+*),e | sra (iy+*),h | sra (iy+*),l | sra (iy+*) | sra (iy+*),a |
3 | sll (iy+*),b | sll (iy+*),c | sll (iy+*),d | sll (iy+*),e | sll (iy+*),h | sll (iy+*),l | sll (iy+*) | sll (iy+*),a | srl (iy+*),b | srl (iy+*),c | srl (iy+*),d | srl (iy+*),e | srl (iy+*),h | srl (iy+*),l | srl (iy+*) | srl (iy+*),a |
4 | bit 0, (iy+*) | bit 0, (iy+*) | bit 0, (iy+*) | bit 0, (iy+*) | bit 0, (iy+*) | bit 0, (iy+*) | bit 0, (iy+*) | bit 0, (iy+*) | bit 1, (iy+*) | bit 1, (iy+*) | bit 1, (iy+*) | bit 1, (iy+*) | bit 1, (iy+*) | bit 1, (iy+*) | bit 1, (iy+*) | bit 1, (iy+*) |
5 | bit 2, (iy+*) | bit 2, (iy+*) | bit 2, (iy+*) | bit 2, (iy+*) | bit 2, (iy+*) | bit 2, (iy+*) | bit 2, (iy+*) | bit 2, (iy+*) | bit 3, (iy+*) | bit 3, (iy+*) | bit 3, (iy+*) | bit 3, (iy+*) | bit 3, (iy+*) | bit 3, (iy+*) | bit 3, (iy+*) | bit 3, (iy+*) |
6 | bit 4, (iy+*) | bit 4, (iy+*) | bit 4, (iy+*) | bit 4, (iy+*) | bit 4, (iy+*) | bit 4, (iy+*) | bit 4, (iy+*) | bit 4, (iy+*) | bit 5, (iy+*) | bit 5, (iy+*) | bit 5, (iy+*) | bit 5, (iy+*) | bit 5, (iy+*) | bit 5, (iy+*) | bit 5, (iy+*) | bit 5, (iy+*) |
7 | bit 6, (iy+*) | bit 6, (iy+*) | bit 6, (iy+*) | bit 6, (iy+*) | bit 6, (iy+*) | bit 6, (iy+*) | bit 6, (iy+*) | bit 6, (iy+*) | bit 7, (iy+*) | bit 7, (iy+*) | bit 7, (iy+*) | bit 7, (iy+*) | bit 7, (iy+*) | bit 7, (iy+*) | bit 7, (iy+*) | bit 7, (iy+*) |
8 | res 0, (iy+*),b | res 0, (iy+*),c | res 0, (iy+*),d | res 0, (iy+*),e | res 0, (iy+*),h | res 0, (iy+*),l | res 0, (iy+*) | res 0, (iy+*),a | res 1, (iy+*),b | res 1, (iy+*),c | res 1, (iy+*),d | res 1, (iy+*),e | res 1, (iy+*),h | res 1, (iy+*),l | res 1, (iy+*) | res 1, (iy+*),a |
9 | res 2, (iy+*),b | res 2, (iy+*),c | res 2, (iy+*),d | res 2, (iy+*),e | res 2, (iy+*),h | res 2, (iy+*),l | res 2, (iy+*) | res 2, (iy+*),a | res 3, (iy+*),b | res 3, (iy+*),c | res 3, (iy+*),d | res 3, (iy+*),e | res 3, (iy+*),h | res 3, (iy+*),l | res 3, (iy+*) | res 3, (iy+*),a |
A | res 4, (iy+*),b | res 4, (iy+*),c | res 4, (iy+*),d | res 4, (iy+*),e | res 4, (iy+*),h | res 4, (iy+*),l | res 4, (iy+*) | res 4, (iy+*),a | res 5, (iy+*),b | res 5, (iy+*),c | res 5, (iy+*),d | res 5, (iy+*),e | res 5, (iy+*),h | res 5, (iy+*),l | res 5, (iy+*) | res 5, (iy+*),a |
B | res 6, (iy+*),b | res 6, (iy+*),c | res 6, (iy+*),d | res 6, (iy+*),e | res 6, (iy+*),h | res 6, (iy+*),l | res 6, (iy+*) | res 6, (iy+*),a | res 7, (iy+*),b | res 7, (iy+*),c | res 7, (iy+*),d | res 7, (iy+*),e | res 7, (iy+*),h | res 7, (iy+*),l | res 7, (iy+*) | res 7, (iy+*),a |
C | set 0, (iy+*),b | set 0, (iy+*),c | set 0, (iy+*),d | set 0, (iy+*),e | set 0, (iy+*),h | set 0, (iy+*),l | set 0, (iy+*) | set 0, (iy+*),a | set 1, (iy+*),b | set 1, (iy+*),c | set 1, (iy+*),d | set 1, (iy+*),e | set 1, (iy+*),h | set 1, (iy+*),l | set 1, (iy+*) | set 1, (iy+*),a |
D | set 2, (iy+*),b | set 2, (iy+*),c | set 2, (iy+*),d | set 2, (iy+*),e | set 2, (iy+*),h | set 2, (iy+*),l | set 2, (iy+*) | set 2, (iy+*),a | set 3, (iy+*),b | set 3, (iy+*),c | set 3, (iy+*),d | set 3, (iy+*),e | set 3, (iy+*),h | set 3, (iy+*),l | set 3, (iy+*) | set 3, (iy+*),a |
E | set 4, (iy+*),b | set 4, (iy+*),c | set 4, (iy+*),d | set 4, (iy+*),e | set 4, (iy+*),h | set 4, (iy+*),l | set 4, (iy+*) | set 4, (iy+*),a | set 5, (iy+*),b | set 5, (iy+*),c | set 5, (iy+*),d | set 5, (iy+*),e | set 5, (iy+*),h | set 5, (iy+*),l | set 5, (iy+*) | set 5, (iy+*),a |
F | set 6, (iy+*),b | set 6, (iy+*),c | set 6, (iy+*),d | set 6, (iy+*),e | set 6, (iy+*),h | set 6, (iy+*),l | set 6, (iy+*) | set 6, (iy+*),a | set 7, (iy+*),b | set 7, (iy+*),c | set 7, (iy+*),d | set 7, (iy+*),e | set 7, (iy+*),h | set 7, (iy+*),l | set 7, (iy+*) | set 7, (iy+*),a |
This table shows the duration of all z80 opcodes, expressed in number of equivalent NOPs. This is valid for CPC only. For example, ADD A,(HL) has the same duration as 2 NOPs.
Instruction using IY register have exactly the same duration as IX instructions, they are omitted in the table.
Opcode | Duration |
ADC r,r | 1 |
ADC A,(HL) | 2 |
ADC A,n | 2 |
ADC HL,rr | 4 |
ADC HL,SP | 4 |
ADC A,IXH | 2 |
ADC A,IXL | 2 |
ADC A,(IX+d) | 5 |
ADD r,r | 1 |
ADD A,(HL) | 2 |
ADD A,d | 2 |
ADD HL,dd | 3 |
ADD IX,rr | 4 |
ADD IX,IX | 4 |
ADD IX,SP | 4 |
ADD A,IXH | 2 |
ADD A,IXL | 2 |
ADD A,(IX+d) | 5 |
AND r | 1 |
AND d | 2 |
AND (HL) | 2 |
AND IXH | 2 |
AND IXL | 2 |
AND (IX+d) | 5 |
BIT r | 2 |
BIT (HL) | 3 |
BIT b,(IX+d) | 6 |
BIT b,(IX+d),r | 6 |
CALL dd | 5 |
CALL cond,dd | 5 / 3 |
CCF | 1 |
CP r | 1 |
CP d | 2 |
CP (HL) | 2 |
CP IXH | 2 |
Opcode | Duration |
CP IXL | 2 |
CP (IX+d) | 3 |
CPD | 4 |
CPDR | 6 / 4 |
CPI | 4 |
CPIR | 6 / 4 |
CPL | 1 |
DAA | 1 |
DEC r | 1 |
DEC rr | 2 |
DEC (HL) | 3 |
DEC IX | 3 |
DEC IXH | 2 |
DEC IXL | 2 |
DEC (IX+d) | 6 |
DI | 1 |
DJNZ d | 4 / 3 |
EI | 1 |
EX AF,AF’ | 1 |
EX DE,HL | 1 |
EX (SP),HL | 6 |
EX (SP),IX | 7 |
EXX | 1 |
HALT | 1 |
IM 0 | 2 |
IM 1 | 2 |
IM 2 | 2 |
IN A,(d) | 3 |
IN r,(C) | 4 |
INC r | 1 |
INC rr | 2 |
INC (HL) | 3 |
INC IX | 3 |
INC IXH | 2 |
INC IXL | 2 |
Opcode | Duration |
INC (IX+d) | 6 |
IND | 5 |
INI | 5 |
INIR | 6 / 5 |
INDR | 6 / 5 |
JP dd | 3 |
JP cond,dd | 3 |
JP (HL) | 1 |
JP (IX) | 2 |
JR d | 3 |
JR C,d | 3 / 2 |
JR NC,d | 3 / 2 |
JR NZ,d | 3 / 2 |
JR Z,d | 3 / 2 |
LD r,r | 1 |
LD r,d | 2 |
LD A,(rr) | 2 |
LD r,(HL) | 2 |
LD (rr),A | 2 |
LD SP,HL | 2 |
LD r,IXH | 2 |
LD r,IXL | 2 |
LD SP,IX | 3 |
LD rr,dd | 3 |
LD (HL),d | 3 |
LD A,R | 3 |
LD R,A | 3 |
LD A,I | 3 |
LD I,A | 3 |
LD IXH,d | 3 |
LD IXL,d | 3 |
LD A,(dd) | 4 |
LD (dd),A | 4 |
LD IX,dd | 4 |
LD HL,(dd) | 5 |
Opcode | Duration |
LD BC,(dd) | 6 |
LD DE,(dd) | 6 |
LD (dd),HL | 5 |
LD r,(IX+d) | 5 |
LD (dd),rr | 6 |
LD IX,(dd) | 6 |
LD (dd),IX | 6 |
LD (IX+d),r | 5 |
LD (IX+d),d | 6 |
LD (dd),SP | 6 |
LD SP,(dd) | 6 |
LDD | 5 |
LDI | 5 |
LDDR | 6 / 5 |
LDIR | 6 / 5 |
NEG | 2 |
NOP | 1 |
OR r | 1 |
OR d | 2 |
OR (HL) | 2 |
OR IXH | 2 |
OR IXL | 2 |
OR (IX+d) | 5 |
OUT (d),A | 3 |
OUT (C),r | 4 |
OUT (C),0 | 4 |
OUTD | 5 |
OUTI | 5 |
OTDR | 6 / 5 |
OTIR | 6 / 5 |
POP rr | 3 |
POP IX | 4 |
PUSH rr | 4 |
PUSH IX | 5 |
RES b,r | 2 |
RES b, (HL) | 4 |
RES b,(IX+d) | 7 |
RES b,(IX+d),r | 7 |
Opcode | Duration |
RET | 3 |
RET cond | 4 / 2 |
RETN | 4 |
RETI | 4 |
RL r | 2 |
RL (HL) | 4 |
RL (IX+d) | 7 |
RL (IX+d),r | 7 |
RLC r | 2 |
RLC (HL) | 4 |
RLC (IX+d) | 7 |
RLC (IX+d),r | 7 |
RLCA | 1 |
RLA | 1 |
RLD | 5 |
RR r | 2 |
RR (HL) | 4 |
RR (IX+d) | 7 |
RR (IX+d),r | 7 |
RRA | 1 |
RRC r | 2 |
RRC (HL) | 4 |
RRC (IX+d) | 7 |
RRC (IX+d),r | 7 |
RRD | 5 |
RRCA | 1 |
RST d | 4 |
SBC A,r | 1 |
SBC A,d | 2 |
SBC A,IXH | 2 |
SBC A,IXL | 2 |
SBC A,(HL) | 2 |
SBC A,(IX+d) | 5 |
SBC HL,rr | 4 |
SBC HL,SP | 4 |
Opcode | Duration |
SCF | 1 |
SET b,r | 2 |
SET b, (HL) | 4 |
SET b,(IX+d) | 7 |
SET b,(IX+d),r | 7 |
SLA r | 2 |
SLA (HL) | 4 |
SLA (IX+d) | 7 |
SLA (IX+d),r | 7 |
SLL r | 2 |
SLL (HL) | 4 |
SLL (IX+d) | 7 |
SLL (IX+d),r | 7 |
SRA r | 2 |
SRA (HL) | 4 |
SRA (IX+d) | 7 |
SRA (IX+d),r | 7 |
SRL r | 2 |
SRL (HL) | 4 |
SRL (IX+d) | 7 |
SRL (IX+d),r | 7 |
SUB r | 1 |
SUB d | 2 |
SUB (HL) | 2 |
SUB IXH | 2 |
SUB IXL | 2 |
SUB (IX+d) | 5 |
XOR r | 1 |
XOR d | 2 |
XOR (HL) | 2 |
XOR IXH | 2 |
XOR IXL | 2 |
XOR (IX+d) | 5 |