add basic mfd0816 site
This commit is contained in:
parent
9f29c3b52c
commit
ecf8227b53
26
build.mb
26
build.mb
|
@ -9,13 +9,18 @@ end
|
|||
|
||||
sector targets
|
||||
section static
|
||||
list str c_rules 'sites'
|
||||
list str c_rules 'sites', 'symlinks'
|
||||
end
|
||||
end
|
||||
|
||||
sector c_rules
|
||||
section sites
|
||||
list str input 'index', 'projects/fpc-sitegen', 'projects/sad', 'projects/mariebuild'
|
||||
list str input
|
||||
'index',
|
||||
'projects/fpc-sitegen',
|
||||
'projects/sad',
|
||||
'projects/mariebuild',
|
||||
'projects/mfd0816/index'
|
||||
str input_format 'data/$(%element%).sad'
|
||||
str output_format '$(%element%).html'
|
||||
|
||||
|
@ -36,6 +41,23 @@ sed -i ''s/\\\$\\\$TIME\\\$\\\$/''"\$TIME/g" $(%output%)
|
|||
sed -i ''s@\\\$\\\$BRANCH\\\$\\\$@''"\$BRANCH@g" $(%output%)
|
||||
sed -i ''s@\\\$\\\$SOURCE\\\$\\\$@$(%input%)@g'' $(%output%)
|
||||
sed -i ''s/\\\$\\\$COMMIT\\\$\\\$/''"\$COMMIT_SHORT/g" $(%output%)
|
||||
'
|
||||
end
|
||||
|
||||
section symlinks
|
||||
list str input
|
||||
'projects/mfd0816/VERSION1_DESIGN',
|
||||
'projects/mfd0816/VERSION1_INSTRUCTIONS'
|
||||
str input_format 'data/$(%element%)'
|
||||
str output_format '$(%element%)'
|
||||
|
||||
str exec '#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
mkdir -p \$(dirname $(%output%))
|
||||
|
||||
rm $(%output%)
|
||||
ln --symbolic $(%input%) $(%output%)
|
||||
'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -31,6 +31,12 @@ template this also looks like shit :)
|
|||
* [demo] epoqe - <a href="https://www.pouet.net/prod.php?which=94085">Caturday Night Fever</a> (music)<br>
|
||||
* [demo] epoqe - <a href="https://www.pouet.net/prod.php?which=93178">Eden Disorder</a> (code support, music)<br>
|
||||
|
||||
{$end-section}
|
||||
{$begin-section} other
|
||||
{$sub-head} other
|
||||
|
||||
* <a href="/projects/mfd0816/index.html">mfd0816</a> <a class="git-link" href="https://github.com/FelixEcker/mfd0816">[github]</a><br>
|
||||
<div class="description">   A fantasy CPU based on the intel 8088 </div>
|
||||
{$end-section}
|
||||
{$begin-section} c
|
||||
{$sub-head} c
|
||||
|
|
568
data/projects/mfd0816/VERSION1_DESIGN
Normal file
568
data/projects/mfd0816/VERSION1_DESIGN
Normal file
|
@ -0,0 +1,568 @@
|
|||
MFD-0816 TECHNICAL SPECIFACTION & OVERVIEW
|
||||
November 2024
|
||||
|
||||
CONTENTS
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
1..... INTRODUCTION & OVERVIEW
|
||||
1.1... PINS
|
||||
2..... REGISTERS
|
||||
2.1... GENERAL PURPOSE REGISTERS
|
||||
2.2... SPECIALIZED REGISTERS
|
||||
2.2.1. THE STACK
|
||||
2.2.2. FLAGS
|
||||
3..... ADDRESSING & THE I/O BUS
|
||||
3.1... I/O BUS INSTRUCTIONS
|
||||
4..... INSTRUCTION SET OVERVIEW
|
||||
4.1... INSTRUCTION ENCODING
|
||||
4.1.1. REGISTER IDENTIFICATION
|
||||
5..... ADDRESSING MODES
|
||||
6..... INTERRUPTS
|
||||
6.1... HARDWARE INTERRUPTS
|
||||
6.2... SOFTWARE INTERRUPTS
|
||||
7..... RESET
|
||||
...... LICENSE
|
||||
|
||||
1. INTRODUCTION & OVERVIEW
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
The MFD-0816 is a 16-bit fantasy CPU and based on the intel 8088.
|
||||
|
||||
► 16-bit address bus
|
||||
► 16-bit word
|
||||
► 8-bit I/O bus
|
||||
► 4x 16-bit general purpose register
|
||||
|
||||
1.1. PINS
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
┌───────┬────────┬────────────────────────────────────────────────┐
|
||||
│ NAME │ PINS │ DESCRIPTION │
|
||||
├───────┼────────┼────────────────────────────────────────────────┤
|
||||
│ CLK │ 00 │ Clock pin. When high the CPU executes one step │
|
||||
├───────┼────────┼────────────────────────────────────────────────┤
|
||||
│ AIO │ 01..16 │ 16-bit Memory IO Bus │
|
||||
├───────┼────────┼────────────────────────────────────────────────┤
|
||||
│ GIO │ 17..24 │ 8-bit IO Bus │
|
||||
├───────┼────────┼────────────────────────────────────────────────┤
|
||||
│ IRQ │ 25 │ Interrupt Request │
|
||||
├───────┼────────┼────────────────────────────────────────────────┤
|
||||
│ IRA │ 26 │ Interrupt Acknowledge │
|
||||
├───────┼────────┼────────────────────────────────────────────────┤
|
||||
│ RESET │ 27 │ Reset │
|
||||
├───────┼────────┼────────────────────────────────────────────────┤
|
||||
│ AMS │ 28 │ Memory IO Bus Mode Select │
|
||||
├───────┼────────┼────────────────────────────────────────────────┤
|
||||
│ GMS │ 29 │ 8-bit IO Bus Mode Select │
|
||||
└───────┴────────┴────────────────────────────────────────────────┘
|
||||
|
||||
2. REGISTERS
|
||||
2.1. GENERAL PURPOSE REGISTERS
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
The MFD-0816 has 4 16-bit general purpose registers with the following names:
|
||||
|
||||
► ACL (AH & AL)
|
||||
► BCL (BH & BL)
|
||||
► CCL (CH & CL)
|
||||
► DCL (DH & DL)
|
||||
|
||||
Each general purpose register of the MFD-0816 is usable as either a complete
|
||||
WORD or as its high and low bytes.
|
||||
|
||||
┌─────────┐
|
||||
│ ACL │
|
||||
├────┬────┤
|
||||
│ AH │ AL │
|
||||
└────┴────┘
|
||||
|
||||
The above illustration shows the register "ACL", which can be used as a
|
||||
complete word with this name, alternatively its high byte can be accessed
|
||||
with the "AH" name and the low byte using "AL".
|
||||
|
||||
2.2. SPECIALIZED REGISTERS
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
The MFD-0816 has the following specialized registers:
|
||||
|
||||
► SP (Stack Pointer)
|
||||
► IP (Instruction Pointer)
|
||||
► AR (Accumulator)
|
||||
► FL (Flags)
|
||||
► IID (Interrupt ID)
|
||||
|
||||
All of these registers have a size of one word.
|
||||
|
||||
The Stack Pointer register holds the current address of the top of the stack.
|
||||
|
||||
The Instruction Pointer register holds the address of the
|
||||
current instruction.
|
||||
|
||||
The Accumulator register holds the result of the last arithmetic operation
|
||||
|
||||
The Flags register holds an assortment of different bit flags, elaborated
|
||||
upon in chapter 2.2.2. Bits can only be set by their respective clear and set
|
||||
instructions.
|
||||
|
||||
The IID register hold the value of the last interrupt. It can only be set
|
||||
via an interrupt.
|
||||
|
||||
2.2.1. THE STACK
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
The stack is a memory structure where the first element "pushed" on to it will
|
||||
be the last element to leave it. In the case of the MFD-0816, one
|
||||
stack-element is a word.
|
||||
|
||||
In the case of this CPU, the stack grows "downwards" (the address of the top
|
||||
of the stack gets smaller the larger it gets). This address is held in the
|
||||
SP register. In case the value of SP is equal to 0 and another element is
|
||||
"pushed" onto the stack it will cause a CPU exception to be thrown.
|
||||
|
||||
The starting location of the stack is not fixed and must be set when
|
||||
initializing the CPU. This is simply done by loading the SP register with the
|
||||
address where the stack should start. Note that this address must always be a
|
||||
multiple of two.
|
||||
|
||||
2.2.2. FLAGS
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
┌──────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
|
||||
│ BIT │ 0F │ 0E │ 0D │ 0C │ 0B │ 0A │ 09 │ 08 │ 07 │ 06 │ 05 │ 04 │ 03 │
|
||||
├──────┼────┼────┼────┼────┼────┼────┼────┼────┼────┼────┼────┼────┼────┤
|
||||
│ NAME │ OF │ CF │ ZF │ NF │ IE │ RT │ RS │ RS │ RS │ RS │ RS │ RS │ RS │
|
||||
└──────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
|
||||
┌──────┬────┬────┬────┐
|
||||
│ BIT │ 02 │ 01 │ 00 │
|
||||
├──────┼────┼────┼────┤
|
||||
│ NAME │ RS │ RS │ RS │
|
||||
└──────┴────┴────┴────┘
|
||||
|
||||
► OF (Overflow Flag) Set if the last arithmetic operation overflowed.
|
||||
► CF (Carry Flag) Set to indicate that an arithmetic carry
|
||||
has been generated.
|
||||
► ZF (Zero Flag) Set to indicate that the last arithmetic operation
|
||||
resulted in a value equal to 0 in the
|
||||
accumulator register.
|
||||
► NF (Negative Flag) Set if the result of the last arithmetic operation has
|
||||
its highest (left most) bit set.
|
||||
► IE (Interrupt Enable) If set, interrupts are enabled and will be handled.
|
||||
► RT (Reset) If set, the processor is in the reset process.
|
||||
► RS (Reserved) Bits marked with this name are reserved for
|
||||
future use.
|
||||
|
||||
3. ADDRESSING & THE I/O BUS
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
The MFD-0816 provides a regular address & data bus mainly used for
|
||||
loading of instructions and memory. The address bus and its corresponding
|
||||
data bus are both 16-bits wide. The high-byte of the received data may be
|
||||
ignored by the CPU if not needed.
|
||||
|
||||
Write Operation:
|
||||
|
||||
T1 ╷ T2 ╷
|
||||
CLK ┌──────────────────┐ ┌────────────────────┐
|
||||
──┘ └────────────────────┘ └─
|
||||
|
||||
AMS ┌────────────────────┐
|
||||
┘ └───────────────────────────────────────────
|
||||
🮣───────────────────🮢 🮣────────────────────🮢
|
||||
AIO ─🮤 ADDRESS OUT 🮥────────────────────🮤 DATA OUT 🮥─
|
||||
🮡───────────────────🮠 🮡────────────────────🮠
|
||||
|
||||
Read Operation:
|
||||
|
||||
T1 ╷ T2 ╷
|
||||
CLK ┌──────────────────┐ ┌────────────────────┐
|
||||
──┘ └──────────────────┘ └─
|
||||
|
||||
AMS ┌────────────────────────────────────────────────────────────┐
|
||||
┘ └─
|
||||
🮣───────────────────🮢 🮣────────────────────🮢
|
||||
AIO ─🮤 ADDRESS OUT 🮥──────────────────🮤 DATA IN 🮥─
|
||||
🮡───────────────────🮠 🮡────────────────────🮠
|
||||
|
||||
► If AMS is high during T1, the operation is a write opeartion. If AMS is
|
||||
also hgih during T2, it is a read operation.
|
||||
► During T1 the 16-bit address is set.
|
||||
► (Write Operation) During T2 the word to be written is set in case of
|
||||
a write operation.
|
||||
► (Write Operation) During T2 the requested data must be set by the peer.
|
||||
|
||||
|
||||
An 8-bit I/O bus is also provided for interacting with external hardware
|
||||
without requiring memory-mapping.
|
||||
|
||||
Write Operation:
|
||||
|
||||
T1 ╷ T2 ╷ T3 ╷ T4 ╷
|
||||
CLK ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐
|
||||
─┘ └──────┘ └──────┘ └──────┘ └─
|
||||
|
||||
GMS ┌─────────────────────┐
|
||||
┘ └─────────────────────────────
|
||||
🮣────────────────────🮢 🮣────────────────────🮢
|
||||
GIO ─🮤 ADDRESS OUT 🮥──────🮤 DATA OUT 🮥─
|
||||
🮡────────────────────🮠 🮡────────────────────🮠
|
||||
|
||||
Read Operation:
|
||||
|
||||
T1 ╷ T2 ╷ T3 ╷ T4 ╷
|
||||
CLK ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐
|
||||
─┘ └──────┘ └──────┘ └──────┘ └─
|
||||
|
||||
GMS
|
||||
────────────────────────────────────────────────────
|
||||
🮣────────────────────🮢 🮣────────────────────🮢
|
||||
GIO ─🮤 ADDRESS OUT 🮥──────🮤 DATA IN 🮥─
|
||||
🮡────────────────────🮠 🮡────────────────────🮠
|
||||
|
||||
► If GMS is high only during T1, the operation is a write opeartion.
|
||||
If it is also high during T2, it is a read operation.
|
||||
► During T1 the high-byte of the 16-bit address is set.
|
||||
► During T2 the low-byte of the 16-bit address is set.
|
||||
► (Write Operation) During T3 the high-byte of the word is set.
|
||||
► (Write Operation) During T4 the low-byte of the word is set.
|
||||
► (Read Operation) During T3 the high-byte of the word
|
||||
must be set by the peer.
|
||||
► (Read Operation) During T4 the low-byte of the word
|
||||
must be set by the peer.
|
||||
|
||||
3.1. I/O BUS INSTRUCTIONS
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Four instructions for operation on the I/O BUS are provided:
|
||||
|
||||
► OUT - Write data to the bus
|
||||
► IN - Read data from the bus
|
||||
► BOT - Write a block of data to the bus
|
||||
► BIN - Read a block of data from the bus
|
||||
|
||||
4. INSTRUCTION SET OVERVIEW
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
┌──────┬──────────────────────────────────┬────────────┐
|
||||
│ NAME │ MEANING │ OPCODE(S) │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ ADC │ Add with carry │ 0x00 │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ ADD │ Add │ 0x01 │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ AND │ Logical AND │ 0x02 │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ BIN │ Read block of data from I/O │ 0x03 │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ BOT │ Write block of data to I/O │ 0x04 │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ CALL │ Call subroutine │ 0x05 │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ CLf │ Clear flag │ 0x2b..0x3a │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ CMP │ Compare operands │ 0x07 │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ DEC │ Decrement by 1 │ 0x08 │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ DIV │ Unsigned divide │ 0x09 │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ IDIV │ Signed divide │ 0x0a │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ IMUL │ Signed multiply │ 0x0b │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ IN │ Read data from I/O │ 0x0c │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ INC │ Increment by 1 │ 0x0d │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ INT │ Trigger interrupt │ 0x0e │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ IRET │ Return from interrupt │ 0x0f │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ Jcc │ Jump (if condition) │ 0x10..0x1a │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ LD │ Load word to register │ 0x1b │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ MOV │ Mov value between registers │ 0x1c │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ MUL │ Unsigned multiply │ 0x1d │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ NEG │ Negate │ 0x1e │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ NOP │ No operation │ 0x1f │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ NOT │ Negate the operand (logical NOT) │ 0x20 │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ OR │ Logical OR │ 0x21 │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ OUT │ Write data to I/O │ 0x22 │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ POP │ Pop data from stack │ 0x23 │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ PUSH │ Push data onto stack │ 0x24 │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ RET │ Return from subroutine │ 0x25 │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ ROL │ Rotate left │ 0x26 │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ ROR │ Roate right │ 0x27 │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ SL │ Shift left │ 0x28 │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ SR │ Shift right │ 0x29 │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ ST │ Store word from register │ 0x2a │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ STf │ Set flag │ 0x3b..0x4a │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ SUB │ Subtraction │ 0x4b │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ TEST │ Logical compare (AND) │ 0x4c │
|
||||
├──────┼──────────────────────────────────┼────────────┤
|
||||
│ XOR │ Exclusive OR │ 0x4d │
|
||||
└──────┴──────────────────────────────────┴────────────┘
|
||||
|
||||
4.1 INSTRUCTION ENCODING
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
┌────────┬────────┬───────────────────────────────────────────┐
|
||||
│ WORD │ BITS │ USAGE │
|
||||
├────────┼────────┼───────────────────────────────────────────┤
|
||||
│ 00 │ 0F..08 │ Identification of the instruction │
|
||||
├────────┼────────┼───────────────────────────────────────────┤
|
||||
│ 00 │ 07..04 │ Operand 1 addressing mode │
|
||||
├────────┼────────┼───────────────────────────────────────────┤
|
||||
│ 00 │ 03..00 │ Operand 2 addressing mode │
|
||||
└────────┴────────┴───────────────────────────────────────────┘
|
||||
|
||||
The addressing modes are encoded as follows:
|
||||
|
||||
┌────────┬────────────────────────────┐
|
||||
│ VALUE │ MODE │
|
||||
├────────┼────────────────────────────┤
|
||||
│ 0000 │ Immediate │
|
||||
├────────┼────────────────────────────┤
|
||||
│ 0001 │ Direct │
|
||||
├────────┼────────────────────────────┤
|
||||
│ 0010 │ Indirect │
|
||||
├────────┼────────────────────────────┤
|
||||
│ 0101 │ Relative Direct │
|
||||
├────────┼────────────────────────────┤
|
||||
│ 0110 │ Relative Indirect │
|
||||
├────────┼────────────────────────────┤
|
||||
│ 1000 │ Register Immediate │
|
||||
├────────┼────────────────────────────┤
|
||||
│ 1001 │ Register Direct │
|
||||
├────────┼────────────────────────────┤
|
||||
│ 1010 │ Register Indirect │
|
||||
├────────┼────────────────────────────┤
|
||||
│ 1101 │ Register Relative Direct │
|
||||
├────────┼────────────────────────────┤
|
||||
│ 1110 │ Register Relative Indirect │
|
||||
└────────┴────────────────────────────┘
|
||||
|
||||
The highest bit (bit 03) is reffered to as the register bit. If high,
|
||||
the operand's immediate value identifies a register.
|
||||
|
||||
The second highest bit (bit 02) is the relative bit. If high,
|
||||
the operands value is relative to the value of the IP register.
|
||||
|
||||
The second lowest bit (bit 01) is the indirect bit. If high,
|
||||
the value behind the operand is another address which must be read from.
|
||||
|
||||
The lowest bit (bit 00) is the direct bit. If high,
|
||||
the operand is an address pointing towards the actual value to be worked
|
||||
with.
|
||||
|
||||
Bits 00 and 01 should not be set at the same time. Should the CPU encounter
|
||||
this, an exception will be raised.
|
||||
|
||||
Bit 02 has no effect if neither Bit 01 or Bit 00 are high.
|
||||
|
||||
4.1.1. REGISTER IDENTIFICATION
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
In case the register bit is set for a specific operand, the immediate value
|
||||
is only one byte long. The register is encoded as follows:
|
||||
|
||||
┌─────┬───────┐
|
||||
│ REG │ VALUE │
|
||||
├─────┼───────┤
|
||||
│ AL │ 0x00 │
|
||||
├─────┼───────┤
|
||||
│ AH │ 0x01 │
|
||||
├─────┼───────┤
|
||||
│ ACL │ 0x02 │
|
||||
├─────┼───────┤
|
||||
│ BL │ 0x03 │
|
||||
├─────┼───────┤
|
||||
│ BH │ 0x04 │
|
||||
├─────┼───────┤
|
||||
│ BCL │ 0x05 │
|
||||
├─────┼───────┤
|
||||
│ CL │ 0x06 │
|
||||
├─────┼───────┤
|
||||
│ CH │ 0x07 │
|
||||
├─────┼───────┤
|
||||
│ CCL │ 0x08 │
|
||||
├─────┼───────┤
|
||||
│ DL │ 0x09 │
|
||||
├─────┼───────┤
|
||||
│ DH │ 0x0a │
|
||||
├─────┼───────┤
|
||||
│ DCL │ 0x0b │
|
||||
├─────┼───────┤
|
||||
│ SP │ 0x0c │
|
||||
├─────┼───────┤
|
||||
│ IP │ 0x0d │
|
||||
├─────┼───────┤
|
||||
│ AR │ 0x0e │
|
||||
├─────┼───────┤
|
||||
│ FL │ 0x0f │
|
||||
├─────┼───────┤
|
||||
│ IID │ 0x10 │
|
||||
└─────┴───────┘
|
||||
|
||||
5. ADDRESSING MODES
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Addressing modes define how instructions access operands. There are three
|
||||
primary modes: Immediate, Direct, and Indirect.
|
||||
|
||||
In Immediate Addressing, the operand is either a literal value or a
|
||||
register value. For example, in the instruction "MOV #64, AL", the immediate
|
||||
value 64 is assigned directly to the register AL, making AL equal to 64.
|
||||
|
||||
┌─────────────┬─────────┐
|
||||
│ INSTRUCTION │ OPERAND │
|
||||
└─────────────┴─────────┘
|
||||
IMMEDIATE ADDRESSING
|
||||
|
||||
In Direct Addressing, the operand specifies an address where the actual
|
||||
value is stored. The instruction accesses the value directly from
|
||||
this address.
|
||||
|
||||
┌─────────────┬───────────────────┐ ┌───────┐
|
||||
│ INSTRUCTION │ OPERAND (ADDRESS) ├────────►│ VALUE │
|
||||
└─────────────┴───────────────────┘ └───────┘
|
||||
DIRECT ADDRESSING
|
||||
|
||||
Indirect Addressing also uses an address as the operand, but instead of
|
||||
pointing directly to the value, the address points to another address
|
||||
where the final value is stored. This requires an extra level of indirection.
|
||||
|
||||
┌─────────────┬───────────────────┐ ┌────────────────────────────┐
|
||||
│ INSTRUCTION │ OPERAND (ADDRESS) ├────────►│ POINTER TO VALUE (ADDRESS) ├─┐
|
||||
└─────────────┴───────────────────┘ ├────────────────────────────┤ │
|
||||
INDIRECT ADDRESSING │ VALUE │◄┘
|
||||
└────────────────────────────┘
|
||||
|
||||
Direct and Indirect modes typically use absolute addresses. However, they can
|
||||
also operate in Relative Addressing mode, where the address is calculated
|
||||
relative to the current value of the Instruction Pointer (IP) register.
|
||||
|
||||
► To reference a memory location before the current IP value,
|
||||
the highest bit of the address must be set, indicating a negative offset.
|
||||
|
||||
6. INTERRUPTS
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Interrupts can be triggered by the INT instruction or the INT-Pin being pulled
|
||||
high.
|
||||
|
||||
Both types of interrupts share this behaviour after acquiring the interrupt
|
||||
id.
|
||||
|
||||
1. Save the value of the IP register to the top of the stack
|
||||
2. Load the value from the interrupt vector into the IP register.
|
||||
The interrupt vector is located at address 0xfffc
|
||||
3. Clear the IE flag
|
||||
4. Continue execution
|
||||
|
||||
After handling of an interrupt is done, the IRET instruction must be invoked.
|
||||
This does the following:
|
||||
|
||||
1. Set the IE flag
|
||||
2. Load the value from the top of the stack into the IP register
|
||||
3. continue execution
|
||||
|
||||
6.1. HARDWARE INTERRUPTS
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Hardware interrupts consist of two sequences: The Interrupt request and the
|
||||
Interrupt Acknowledge sequence.
|
||||
|
||||
Interrupt request:
|
||||
|
||||
T1 ╷
|
||||
CLK ┐ ┌──────┐ ┌
|
||||
└──────┘ └──────┘
|
||||
|
||||
IRQ ┌──────┐
|
||||
───────┘ └───────
|
||||
|
||||
The CPU checks if the IRQ line is high at the ench of each clock cycle. So if
|
||||
IRQ is high at the end of T1, an interrupt was requested. After this sequence,
|
||||
the Acknowledge sequence is entered.
|
||||
|
||||
Interrupt acknowledge:
|
||||
|
||||
T1 ╷ T2 ╷
|
||||
CLK ┐ ┌─────────┐ ┌─────────┐
|
||||
└─────────┘ └─────────┘ └─
|
||||
|
||||
IRA ┌─────────────────────────────┐
|
||||
──────────┘ └─
|
||||
|
||||
🮣──────────🮢
|
||||
GIO ─────────────────────────────🮤 DATA IN 🮥─
|
||||
🮡──────────🮠
|
||||
|
||||
As soon as the CPU is ready, it will set the IRA line high for two clock
|
||||
pulses. During the first pulse, nothing else happens. During the second pulse
|
||||
the CPU reads a byte of whatever data currently is on the I/O Bus. This data
|
||||
is used as the interrupt id and written to the IID register.
|
||||
|
||||
After both sequences are completed, the CPU continues with the shared
|
||||
behaviour specified in chapter 6.
|
||||
|
||||
6.1. SOFTWARE INTERRUPTS
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Software interrupts are a lot simpler. They are triggered by an INT
|
||||
instruction.
|
||||
|
||||
When an INT instruction is encountered, the CPU first sets the IID register
|
||||
to the value of the first operand of the instruction.
|
||||
|
||||
After this is completed, the CPU continues with the shared
|
||||
behaviour specified in chapter 6.
|
||||
|
||||
7. RESET
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
The CPU can be reset to start execution from the reset vector. The reset
|
||||
vector is located at address 0xfffe.
|
||||
|
||||
T1 ╷ T2 ╷ T3 ╷
|
||||
CLK ┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
|
||||
└─────────┘ └─────────┘ └─────────┘ └
|
||||
|
||||
RESET ┌─────────┐
|
||||
──────────┘ └────────────────────────────────────────
|
||||
|
||||
In order to execute a reset, the RESET pin must be high at the end of a
|
||||
clock pulse. If reset is high for longer than this, it will continually reset
|
||||
the processor.
|
||||
|
||||
After a reset has been triggered, the RT flag is set and the next few cycles
|
||||
are used to read the value of the reset vector into the IP register.
|
||||
Afterwards, the RT flag is cleared and the processor resumes execution.
|
||||
|
||||
Note that resetting does not clear any registers or memories except for the
|
||||
FL register. Interrupts also have no effect whilst resetting, regardless of
|
||||
the state of the IE flag.
|
||||
|
||||
LICENSE
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
MFD0816 DESIGN by Marie Eckert is licensed under CC BY-SA 4.0,
|
||||
see <https://creativecommons.org/licenses/by-sa/4.0/>
|
756
data/projects/mfd0816/VERSION1_INSTRUCTIONS
Normal file
756
data/projects/mfd0816/VERSION1_INSTRUCTIONS
Normal file
|
@ -0,0 +1,756 @@
|
|||
MFD-0816 INSTRUCTION SET REFERENCE
|
||||
November 2024
|
||||
|
||||
CONTENTS
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
1.... INSTRUCTION LISTING
|
||||
2.... INSTRUCTION SPECIFICATIONS
|
||||
..... LICENSE
|
||||
|
||||
1. INSTRUCTION LISTING
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
0x00..0x0f
|
||||
‾‾‾‾‾‾‾‾‾‾
|
||||
┌──────┬─────────────┬─────────────────────────┐
|
||||
│ CODE │ NAME(S) │ DESCRIPTION │
|
||||
├──────┼─────────────┼─────────────────────────┤
|
||||
│ 0x00 │ ADC │ Add with carry │
|
||||
│ 0x01 │ ADD │ Add │
|
||||
│ 0x02 │ AND │ Logical AND │
|
||||
│ 0x03 │ BIN │ Read block from I/O Bus │
|
||||
│ 0x04 │ BOT │ Write block to I/O Bus │
|
||||
│ 0x05 │ CALL │ Call subroutine │
|
||||
│ 0x06 │ │ Reserved │
|
||||
│ 0x07 │ CMP │ Compare operands │
|
||||
│ 0x08 │ DEC │ Decrement by 1 │
|
||||
│ 0x09 │ DIV │ Unsigned divide │
|
||||
│ 0x0a │ IDIV │ Signed divide │
|
||||
│ 0x0b │ IMUL │ Signed multiply │
|
||||
│ 0x0c │ IN │ Read byte from I/O Bus │
|
||||
│ 0x0d │ INC │ Increment by 1 │
|
||||
│ 0x0e │ INT │ Trigger interrupt │
|
||||
│ 0x0f │ IRET │ Return from interrupt │
|
||||
└──────┴─────────────┴─────────────────────────┘
|
||||
|
||||
Jcc - Jump (if condition is met)
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
┌──────┬─────────────┬─────────────────────────┐
|
||||
│ CODE │ NAME(S) │ DESCRIPTION │
|
||||
├──────┼─────────────┼─────────────────────────┤
|
||||
│ 0x10 │ JMP │ Jump │
|
||||
│ 0x11 │ JZ/JE │ Jump if ZF=1 │
|
||||
│ 0x12 │ JG │ Jump if ZF=0 and NF=OF │
|
||||
│ 0x13 │ JGE │ Jump if NF=OF │
|
||||
│ 0x14 │ JL │ Jump if NF<>OF │
|
||||
│ 0x15 │ JLE │ Jump if ZF=1 or NF<>OF │
|
||||
│ 0x16 │ JC │ Jump if CF=1 │
|
||||
│ 0x17 │ JS │ Jump if NF=1 │
|
||||
│ 0x18 │ JNZ/JNE │ Jump if ZF=0 │
|
||||
│ 0x19 │ JNC │ Jump if CF=0 │
|
||||
│ 0x1a │ JNS │ Jump if NF=0 │
|
||||
└──────┴─────────────┴─────────────────────────┘
|
||||
|
||||
0x1b..0x2a
|
||||
‾‾‾‾‾‾‾‾‾‾
|
||||
┌──────┬─────────────┬─────────────────────────┐
|
||||
│ CODE │ NAME(S) │ DESCRIPTION │
|
||||
├──────┼─────────────┼─────────────────────────┤
|
||||
│ 0x1b │ LD │ Load word into register │
|
||||
│ 0x1c │ MOV │ Move between registers │
|
||||
│ 0x1d │ MUL │ Unsigned multiply │
|
||||
│ 0x1e │ NEG │ Negate │
|
||||
│ 0x1f │ NOP │ No operation │
|
||||
│ 0x20 │ NOT │ Negate operand (logical)│
|
||||
│ 0x21 │ OR │ Logical OR │
|
||||
│ 0x22 │ OUT │ Write byte to I/O Bus │
|
||||
│ 0x23 │ POP │ Pop word from stack │
|
||||
│ 0x24 │ PUSH │ Push word to stack │
|
||||
│ 0x25 │ RET │ Return from subroutine │
|
||||
│ 0x26 │ ROL │ Rotate left │
|
||||
│ 0x27 │ ROR │ Rotate right │
|
||||
│ 0x28 │ SL │ Shift left │
|
||||
│ 0x29 │ SR │ Shift right │
|
||||
│ 0x2a │ ST │ Store register to memory│
|
||||
└──────┴─────────────┴─────────────────────────┘
|
||||
|
||||
CLf - Clear flag
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
┌──────┬─────────────┬─────────────────────────┐
|
||||
│ CODE │ NAME(S) │ DESCRIPTION │
|
||||
├──────┼─────────────┼─────────────────────────┤
|
||||
│ 0x2b │ CLO │ Clear OF in FL Register │
|
||||
│ 0x2c │ CLC │ Clear CF in FL Register │
|
||||
│ 0x2d │ CLZ │ Clear ZF in FL Register │
|
||||
│ 0x2e │ CLN │ Clear NF in FL Register │
|
||||
│ 0x2f │ CLI │ Clear IE in FL Register │
|
||||
│ 0x30 │ CL? │ Reserved │
|
||||
│ 0x31 │ CL? │ Reserved │
|
||||
│ 0x32 │ CL? │ Reserved │
|
||||
│ 0x33 │ CL? │ Reserved │
|
||||
│ 0x34 │ CL? │ Reserved │
|
||||
│ 0x35 │ CL? │ Reserved │
|
||||
│ 0x36 │ CL? │ Reserved │
|
||||
│ 0x37 │ CL? │ Reserved │
|
||||
│ 0x38 │ CL? │ Reserved │
|
||||
│ 0x39 │ CL? │ Reserved │
|
||||
│ 0x3a │ CL? │ Reserved │
|
||||
└──────┴─────────────┴─────────────────────────┘
|
||||
|
||||
STf - Set flag
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
┌──────┬─────────────┬─────────────────────────┐
|
||||
│ CODE │ NAME(S) │ DESCRIPTION │
|
||||
├──────┼─────────────┼─────────────────────────┤
|
||||
│ 0x3b │ STO │ Set OF in FL Register │
|
||||
│ 0x3c │ STC │ Set CF in FL Register │
|
||||
│ 0x3d │ STZ │ Set ZF in FL Register │
|
||||
│ 0x3e │ STN │ Set NF in FL Register │
|
||||
│ 0x3f │ STI │ Set IE in FL Register │
|
||||
│ 0x40 │ ST? │ Reserved │
|
||||
│ 0x41 │ ST? │ Reserved │
|
||||
│ 0x42 │ ST? │ Reserved │
|
||||
│ 0x43 │ ST? │ Reserved │
|
||||
│ 0x44 │ ST? │ Reserved │
|
||||
│ 0x45 │ ST? │ Reserved │
|
||||
│ 0x46 │ ST? │ Reserved │
|
||||
│ 0x47 │ ST? │ Reserved │
|
||||
│ 0x48 │ ST? │ Reserved │
|
||||
│ 0x49 │ ST? │ Reserved │
|
||||
│ 0x4a │ ST? │ Reserved │
|
||||
└──────┴─────────────┴─────────────────────────┘
|
||||
|
||||
0x4b..0x4d
|
||||
‾‾‾‾‾‾‾‾‾‾
|
||||
┌──────┬─────────────┬─────────────────────────┐
|
||||
│ CODE │ NAME(S) │ DESCRIPTION │
|
||||
├──────┼─────────────┼─────────────────────────┤
|
||||
│ 0x4b │ SUB │ Subtraction │
|
||||
│ 0x4c │ TEST │ Logical compare (AND) │
|
||||
│ 0x4d │ XOR │ Exclusive OR │
|
||||
└──────┴─────────────┴─────────────────────────┘
|
||||
|
||||
2. INSTRUCTION SPECIFICATIONS
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
0x00 ADC <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Adds the value of ACL with the first operand and the carry flag and stores
|
||||
the result in ACL. SF is modified to indicate if the result is
|
||||
signed (SF = 1) or unsigned (SF = 0). Sets CF on carry for unsigned math,
|
||||
OF on overflow for signed math and NF flag to indicate the sign of the
|
||||
signed result. Sets ZF if the result is 0 (ACL = 0 && CF = 0 && OF = 0).
|
||||
|
||||
The first operand can be immediate, register immediate, direct,
|
||||
register direct, indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
ACL := ACL + Operand1 + CF;
|
||||
|
||||
0x01 ADD <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Adds the value of ACL with the first operand and stores the result in ACL.
|
||||
Sets the NF flag to indicate the sign of the signed result.
|
||||
Sets CF on carry for unsigned math, OF on overflow for signed math and the
|
||||
NF flag to indicate the sign of the signed result. Sets ZF if the result
|
||||
is 0 (ACL = 0 && CF = 0 && OF = 0).
|
||||
|
||||
The first operand can be immediate, register immediate, direct,
|
||||
register direct, indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
ACL := ACL + Operand1;
|
||||
|
||||
Carry and Overflow example:
|
||||
|
||||
0111b + 0001b = 0_1000b ; Signed int overflow, OF = 1 CF = 0
|
||||
0111b + 1001b = 1_0000b ; Unsigned int overflow, OF = 0 CF = 1
|
||||
0001b + 0001b = 0010b ; No overflow/carry, OF = 0 CF = 0
|
||||
|
||||
0x02 AND <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Executes a logical AND with the current value of ACL and the first operand.
|
||||
The result is then stored in ACL. Sets ZF if the result is 0, clears OF and
|
||||
CF.
|
||||
|
||||
Operation:
|
||||
|
||||
ACL := ACL & Operand1;
|
||||
|
||||
0x03 BIN <r/imm/m> <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Reads n units of data from the I/O Bus starting at the address indicated by
|
||||
Operand 1 and stores it to the destination indicated by Operand 2.
|
||||
The number of units read is indicated by the value of AL.
|
||||
|
||||
Both operand can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
for i := 1 to ACL do
|
||||
io_read(Operand1 + i - 1, Operand2);
|
||||
end
|
||||
|
||||
0x04 BOT <r/imm/m> <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Writes n units of data to the I/O Bus starting at the address indicated by
|
||||
Operand 1 and stores it to the destination indicated by Operand 2.
|
||||
The number of units written is indicated by the value of AL.
|
||||
|
||||
Both operand can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
for i := 1 to ACL do
|
||||
io_write(Operand1 + i - 1, Operand2);
|
||||
end
|
||||
|
||||
0x05 CALL <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Pushes the current value of IP to the stack and jumps to the address located
|
||||
by Operand 1.
|
||||
|
||||
Operand 1 can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
push(IP);
|
||||
IP := Operand1;
|
||||
|
||||
0x07 CMP <r/imm/m> <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Subtracts Operand 1 from Operand 2 and sets the OF, CF and NF flags in the
|
||||
same way as SUB. Discards the actual subtraction result.
|
||||
|
||||
Both operands can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
tmp := Operand1 - Operand2;
|
||||
SUBSetFlags;
|
||||
|
||||
0x08 DEC <r>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Decrements the register given in Operand 1 by one.
|
||||
|
||||
Operation:
|
||||
|
||||
register := register - 1;
|
||||
|
||||
0x09 DIV <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Divides the value of ACL by Operand 1 as an unsigned value and stores the
|
||||
result in ACL.
|
||||
|
||||
Operand 1 can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
ACL := ACL / Operand1;
|
||||
|
||||
0x0a IDIV <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Divides the value of ACL by Operand 1 as a signed value and stores the
|
||||
result in ACL.
|
||||
|
||||
Operand 1 can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
ACL := ACL / Operand1;
|
||||
|
||||
0x0b IMUL <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Multiplies the value of ACL by Operand 1 as a signed value and stores the
|
||||
result in ACL. CF and OF are set if the most signficant bit,
|
||||
including the sign bit, are carried over into AH. If the result fits into
|
||||
AL, CF and OF are cleared.
|
||||
|
||||
Operand 1 can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
ACL := ACL * Operand 1;
|
||||
|
||||
if ACL = AL then
|
||||
CF := 0;
|
||||
OF := 0;
|
||||
else
|
||||
CF := 1;
|
||||
OF := 0;
|
||||
end
|
||||
|
||||
0x0c IN <r/imm/m> <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Reads in one unit of data from the I/O bus at the address indicated by
|
||||
Operand 1 and writes the result to the address indicated by Operand 2.
|
||||
|
||||
Both operands can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
io_read(Operand1, Operand2);
|
||||
|
||||
0x0d INC <r>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Increments the target register indicated by Operand 1 by one.
|
||||
|
||||
Operation:
|
||||
|
||||
register := register + 1;
|
||||
|
||||
0x0e INT <imm>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Triggers an interrupt with the id indicated by Operand1 if the IE flag is
|
||||
set. If IE is clear, this instruction does nothing.
|
||||
|
||||
Operation:
|
||||
|
||||
if not IE then exit;
|
||||
|
||||
Interrupt(Operand1);
|
||||
|
||||
0x0f IRET
|
||||
‾‾‾‾‾‾‾‾‾
|
||||
Returns from an interrupt and sets IE. IID is also set to 0.
|
||||
This instruction should only be executed from within an interrupt handler.
|
||||
|
||||
Operation:
|
||||
|
||||
IE := 1;
|
||||
IID := 0;
|
||||
pop(IP);
|
||||
|
||||
0x10 JMP <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Jumps to the address indicated by Operand 1.
|
||||
|
||||
Operand 1 can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
IP := Operand1;
|
||||
|
||||
0x11 JZ/JE <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Jumps to the address indicated by Operand 1 if ZF is set.
|
||||
|
||||
Operand 1 can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
if ZF = 1 then
|
||||
IP := Operand1;
|
||||
end
|
||||
|
||||
0x12 JG <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Jumps to the address indicated by Operand 1 if ZF is not set and NF is the
|
||||
same as OF.
|
||||
|
||||
Operand 1 can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
if ZF = 0 and (NF = OF) then
|
||||
IP := Operand1;
|
||||
end
|
||||
|
||||
0x13 JGE <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Jumps to the address indicated by Operand 1 if NF is the same as OF.
|
||||
|
||||
Operand 1 can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
if NF = OF then
|
||||
IP := Operand1;
|
||||
end
|
||||
|
||||
0x14 JL <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Jumps to the address indicated by Operand 1 if NF is not the same as OF.
|
||||
|
||||
Operand 1 can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
if NF <> OF then
|
||||
IP := Operand1;
|
||||
end
|
||||
|
||||
0x15 JLE <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Jumps to the address indicated by Operand 1 if ZF is set or NF is not the
|
||||
same as OF.
|
||||
|
||||
Operand 1 can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
if ZF = 1 or (NF <> OF) then
|
||||
IP := Operand1;
|
||||
end;
|
||||
|
||||
0x16 JC <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Jumps to the address indicated by Operand 1 if CF is set.
|
||||
|
||||
Operand 1 can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
if CF = 1 then
|
||||
IP := Operand1;
|
||||
end
|
||||
|
||||
0x17 JS <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Jumps to the address indicated by Operand 1 if NF is set.
|
||||
|
||||
Operand 1 can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
if NF = 1 then
|
||||
IP := Operand1;
|
||||
end
|
||||
|
||||
0x18 JNZ/JNE <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Jumps to the address indicated by Operand 1 if ZF is not set.
|
||||
|
||||
Operand 1 can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
if ZF = 0 then
|
||||
IP := Operand1;
|
||||
end;
|
||||
|
||||
0x19 JNC <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Jumps to the address indicated by Operand 1 if CF is not set.
|
||||
|
||||
Operand 1 can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
if CF = 0 then
|
||||
IP := Operand1;
|
||||
end;
|
||||
|
||||
0x1a JNS <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Jumps to the address indicated by Operand 1 if NF is not set.
|
||||
|
||||
Operand 1 can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
if NF = 0 then
|
||||
IP := Operand1;
|
||||
end;
|
||||
|
||||
0x1b LD <r> <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Loads the value indicated by Operand 2 into the register indicated by
|
||||
Operand 1.
|
||||
|
||||
Operand 2 can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
register := Operand2;
|
||||
|
||||
0x1c MOV <r/imm> <r>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Sets the register indicated by Operand 2 to the value indicated by
|
||||
Operand 1.
|
||||
|
||||
Operand 1 can be immediate or register immediate.
|
||||
|
||||
0x1d MUL <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Multiplies (unsigned) the value of ACL by Operand 1 and stores the result in
|
||||
ACL. If the result fits into ACL, CF and OF are cleared otherwise both get
|
||||
set.
|
||||
|
||||
Operand 2 can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
0x1e NEG <r/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
|
||||
Negates (Two's Complement) the value of Operand 1 and stores the result
|
||||
in Operand 1.
|
||||
|
||||
Operand 1 can be register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
Operand1 := 0 - Operand1;
|
||||
|
||||
0x1f NOP
|
||||
‾‾‾‾‾‾‾‾
|
||||
|
||||
Does nothing.
|
||||
|
||||
0x20 NOT <r/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Negates (One's Complement) the value of Operand 1 and stores the result in
|
||||
Operand 1.
|
||||
|
||||
Operand 1 can be direct, register direct, indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
Operand1 := 0 - Operand1;
|
||||
|
||||
0x21 OR <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Performs a logical OR with the value of ACL and Operand 1 and stores the
|
||||
result in ACL.
|
||||
|
||||
Operand 1 can be direct, register direct, indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
ACL := ACL or Operand1;
|
||||
|
||||
0x22 OUT <r/imm/m> <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Writes in one unit of data to the I/O bus to the address indicated by
|
||||
Operand 2 from the address indicated by Operand 1.
|
||||
|
||||
Both operands can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
io_write(Operand2, Operand1);
|
||||
|
||||
0x23 POP <r/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Pops the top value from the stack and writes it to the location indicated by
|
||||
Operand 1. Increments SP by 2.
|
||||
|
||||
Operand 1 can be register immediate, direct, register direct, indirect
|
||||
or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
Operand1 := *SP;
|
||||
SP := SP + 2;
|
||||
|
||||
0x24 PUSH <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Pushes the value indicated by Operand 1 to the top of the stack. Decrements
|
||||
SP by 2.
|
||||
|
||||
Operand 1 can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
SP := SP - 2;
|
||||
*SP := Operand1;
|
||||
|
||||
0x25 RET
|
||||
‾‾‾‾‾‾‾‾
|
||||
Returns from a subroutine.
|
||||
|
||||
Operation:
|
||||
|
||||
pop(IP);
|
||||
|
||||
0x26 ROL <r/m> <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Rotates the value indicated by Operand 1 left by the amount of times
|
||||
indicated by Operand 2 and stores the result in Operand 1.
|
||||
|
||||
Operand 1 can be register immediate, direct, register direct, indirect or
|
||||
register indirect.
|
||||
|
||||
Operand 2 can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
tmp := Operand1 shl Operand2;
|
||||
Operand1 := tmp or (tmp shr 16 and 0xff)
|
||||
|
||||
0x27 ROR <r/m> <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Rotates the value indicated by Operand 1 right by the amount of times
|
||||
indicated by Operand 2 and stores the result in Operand 1.
|
||||
|
||||
Operand 1 can be register immediate, direct, register direct, indirect or
|
||||
register indirect.
|
||||
|
||||
Operand 2 can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
tmp := (Operand1 shl 8) shr Operand2;
|
||||
Operand1 := (Operand1 shr Operand2) or ((tmp and 0xff) shl 8)
|
||||
|
||||
0x28 SL <r/m> <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Shifts the value indicated by Operand 1 left by the amount indicated by
|
||||
Operand 2 and stores the result in Operand 1.
|
||||
|
||||
Operand 1 can be register immediate, direct, register direct, indirect or
|
||||
register indirect.
|
||||
|
||||
Operand 2 can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
Operand1 := Operand1 shl Operand2;
|
||||
|
||||
0x29 SR <r/m> <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Shifts the value indicated by Operand 1 right by the amount indicated by
|
||||
Operand 2 and stores the result in Operand 1.
|
||||
|
||||
Operand 1 can be register immediate, direct, register direct, indirect or
|
||||
register indirect.
|
||||
|
||||
Operand 2 can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
Operand1 := Operand1 shr Operand2;
|
||||
|
||||
0x2a ST <r/imm/m> <m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Stores the value indicated by Operand 1 to the place in memory indicated by
|
||||
Operand 2.
|
||||
|
||||
Operand 1 can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operand 2 can be direct, register direct, indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
Operand2 := Operand1;
|
||||
|
||||
0x2b CLO
|
||||
‾‾‾‾‾‾‾‾
|
||||
Clears the overflow flag.
|
||||
|
||||
0x2c CLC
|
||||
‾‾‾‾‾‾‾‾
|
||||
Clears the carry flag.
|
||||
|
||||
0x2d CLZ
|
||||
‾‾‾‾‾‾‾‾
|
||||
Clears the zero flag.
|
||||
|
||||
0x2e CLN
|
||||
‾‾‾‾‾‾‾‾
|
||||
Clears the negative flag.
|
||||
|
||||
0x2f CLI
|
||||
‾‾‾‾‾‾‾‾
|
||||
Clears the interrupt enable flag.
|
||||
|
||||
0x30..0x3a CL?
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
This range of instructions is currently invalid.
|
||||
|
||||
0x3b STO
|
||||
‾‾‾‾‾‾‾‾
|
||||
Sets the overflow flag.
|
||||
|
||||
0x3c STC
|
||||
‾‾‾‾‾‾‾‾
|
||||
Sets the carry flag.
|
||||
|
||||
0x3d STZ
|
||||
‾‾‾‾‾‾‾‾
|
||||
Sets the zero flag.
|
||||
|
||||
0x3e STN
|
||||
‾‾‾‾‾‾‾‾
|
||||
Sets the negative flag.
|
||||
|
||||
0x3f STI
|
||||
‾‾‾‾‾‾‾‾
|
||||
Sets the interrupt enable flag.
|
||||
|
||||
0x40..0x4a ST?
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
This range of instructions is currently invalid.
|
||||
|
||||
0x4b SUB <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Subtracts the value indacted by Operand 1 from the value of ACL and stores
|
||||
the result in ACL.
|
||||
Sets CF on carry for unsigned math, OF on overflow for signed math and the
|
||||
NF flag to indicate the sign of the signed result. Sets ZF if the result
|
||||
is 0 (ACL = 0 && CF = 0 && OF = 0).
|
||||
|
||||
Operand 1 can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
0x4c TEST <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Executes a logical AND with the value indicated by Operand 1 and the value
|
||||
indicated by Operand 2. The result of the AND is discarded. Sets ZF if the
|
||||
result is 0, clears OF and CF.
|
||||
|
||||
Operand 1 can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
ANDSetFlags(ACL & Operand1);
|
||||
|
||||
0x4d XOR <r/imm/m>
|
||||
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
Executes a XOR operation on the value of ACL with the value indicated by
|
||||
Operand 1. Stores the result in ACL.
|
||||
|
||||
Operand 1 can be immediate, register immediate, direct, register direct,
|
||||
indirect or register indirect.
|
||||
|
||||
Operation:
|
||||
|
||||
ACL := ACL ^ Operand1;
|
||||
|
||||
LICENSE
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
MFD0816 INSTRUCTIONS by Marie Eckert is licensed under CC BY-SA 4.0,
|
||||
see <https://creativecommons.org/licenses/by-sa/4.0/>
|
21
data/projects/mfd0816/index.sad
Normal file
21
data/projects/mfd0816/index.sad
Normal file
|
@ -0,0 +1,21 @@
|
|||
{$start}
|
||||
{$title} mfd0816
|
||||
|
||||
{$begin-section} about
|
||||
{$head} about
|
||||
|
||||
The MFD-0816 is a 16-bit fantasy CPU and based on the intel 8088.
|
||||
|
||||
|
||||
* 16-bit address bus <br>
|
||||
* 16-bit word <br>
|
||||
* 8-bit I/O bus <br>
|
||||
* 4x 16-bit general purpose register <br>
|
||||
|
||||
{$begin-section} links
|
||||
{$sub-head} links
|
||||
* <a href="/projects/mfd0816/VERSION1_DESIGN">[Version 1] Design</a><br>
|
||||
* <a href="/projects/mfd0816_VERSION1_INSTRUCTIONS">[Version 1] Instruction Set Reference </a><br>
|
||||
* <a href="https://github.com/FelixEcker/mfd0816">GitHub</a><br>
|
||||
{$end-section}
|
||||
{$end-section}
|
Loading…
Reference in a new issue