Listings 0056, 0057. Improve README
This commit is contained in:
parent
85a8172923
commit
51dae3128b
100
README.org
100
README.org
@ -1,8 +1,96 @@
|
||||
#+OPTIONS: toc:nil
|
||||
|
||||
* 8086 CPU Emulator
|
||||
Following along with [[https://www.computerenhance.com/p/table-of-contents][Performance Aware by Computer Enhance]]
|
||||
* License
|
||||
This project is licensed under the terms of the MIT license. For more
|
||||
information, see the included LICENSE file. However, some of this is related to
|
||||
a paid course so maybe pay for the course if you want to use these files?
|
||||
* 8086 CPU Simulator
|
||||
|
||||
A complete 8086 processor emulator written in Odin, featuring instruction decoding, execution, and cycle-accurate simulation. Implements a comprehensive subset of the Intel 8086 instruction set with proper flag handling, memory management, and register operations.
|
||||
|
||||
** Features
|
||||
|
||||
- *Complete 8086 instruction decoding* - Supports MOV, arithmetic, jumps, loops, stack operations, and more
|
||||
- *Cycle-accurate execution* - Proper CPU state management with registers and flags
|
||||
- *Memory simulation* - 1MB addressable memory space with effective address calculation
|
||||
- *Comprehensive testing* - 21 assembly test programs with automated validation
|
||||
- *Reference validation* - Compares execution results against reference CPU states
|
||||
|
||||
** Architecture
|
||||
|
||||
The simulator is organized into several focused modules:
|
||||
|
||||
- =sim8086.odin= - Main entry point and program orchestration
|
||||
- =types.odin= - Core data structures (CPU state, instructions, operands)
|
||||
- =instructions.odin= - Complete 8086 instruction set definitions
|
||||
- =decoding.odin= - Binary instruction decoding and parsing
|
||||
- =execution.odin= - CPU execution engine with flag calculations
|
||||
- =printing.odin= - Assembly output formatting
|
||||
- =testing.odin= - Reference state parsing and validation
|
||||
|
||||
** Building and Running
|
||||
|
||||
#+BEGIN_SRC bash
|
||||
# Build the simulator
|
||||
make
|
||||
|
||||
# Decode and print assembly
|
||||
./sim8086 program.bin instructions
|
||||
|
||||
# Execute with register dump
|
||||
./sim8086 program.bin registers
|
||||
|
||||
# Full execution with memory dump
|
||||
./sim8086 program.bin all dump
|
||||
#+END_SRC
|
||||
|
||||
** Testing
|
||||
|
||||
Comprehensive test coverage included:
|
||||
|
||||
#+BEGIN_SRC bash
|
||||
# Run all assembly tests
|
||||
./test_asm.sh
|
||||
|
||||
# Run reference CPU validation tests
|
||||
./test_ref_cpu.sh
|
||||
#+END_SRC
|
||||
|
||||
Test files cover:
|
||||
- Basic MOV operations and addressing modes
|
||||
- Arithmetic and logical operations with proper flag setting
|
||||
- Jump and loop instructions
|
||||
- Stack operations (PUSH/POP)
|
||||
- Complex programs with multiple instruction types
|
||||
|
||||
** Technical Implementation
|
||||
|
||||
*** Instruction Decoding
|
||||
- Bit-level parsing of 8086 machine code
|
||||
- Support for all addressing modes (register, immediate, memory, direct)
|
||||
- Proper handling of prefixes and multi-byte instructions
|
||||
|
||||
*** Execution Engine
|
||||
- Register file with proper 8/16-bit access patterns
|
||||
- CPU flags (Zero, Carry, Sign, Overflow, etc.) with accurate calculations
|
||||
- Effective address computation for memory operations
|
||||
- Instruction pointer management and control flow
|
||||
|
||||
*** Memory Model
|
||||
- 1MB linear address space
|
||||
- Little-endian byte ordering
|
||||
- Memory-mapped I/O simulation
|
||||
|
||||
** Supported Instructions
|
||||
|
||||
*Data Movement:* MOV, PUSH, POP, XCHG, LEA, LDS, LES
|
||||
*Arithmetic:* ADD, SUB, MUL, DIV, INC, DEC, CMP, NEG
|
||||
*Logical:* AND, OR, XOR, NOT, TEST
|
||||
*Shifts/Rotates:* SHL, SHR, SAR, ROL, ROR, RCL, RCR
|
||||
*Control Flow:* JMP, JE, JNE, JL, JG, LOOP, CALL, RET
|
||||
*String Operations:* MOVS, CMPS, SCAS, LODS, STOS
|
||||
*System:* INT, IRET, HLT, NOP
|
||||
|
||||
Built following the [[https://www.computerenhance.com/p/table-of-contents][Performance Aware Programming]] course by Casey Muratori.
|
||||
|
||||
** License
|
||||
|
||||
This project is licensed under the MIT License - see the LICENSE file for details.
|
||||
|
||||
*Note:* Some test files are derived from the Performance Aware Programming course materials. Consider supporting the course if you find this project useful.
|
||||
|
41
asm_files/list-0056.asm
Normal file
41
asm_files/list-0056.asm
Normal file
@ -0,0 +1,41 @@
|
||||
; ========================================================================
|
||||
;
|
||||
; (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
|
||||
;
|
||||
; This software is provided 'as-is', without any express or implied
|
||||
; warranty. In no event will the authors be held liable for any damages
|
||||
; arising from the use of this software.
|
||||
;
|
||||
; Please see https://computerenhance.com for further information
|
||||
;
|
||||
; ========================================================================
|
||||
|
||||
; ========================================================================
|
||||
; LISTING 56
|
||||
; ========================================================================
|
||||
|
||||
bits 16
|
||||
|
||||
mov bx, 1000
|
||||
mov bp, 2000
|
||||
mov si, 3000
|
||||
mov di, 4000
|
||||
|
||||
mov cx, bx
|
||||
mov dx, 12
|
||||
|
||||
mov dx, [1000]
|
||||
|
||||
mov cx, [bx]
|
||||
mov cx, [bp]
|
||||
mov [si], cx
|
||||
mov [di], cx
|
||||
|
||||
mov cx, [bx + 1000]
|
||||
mov cx, [bp + 1000]
|
||||
mov [si + 1000], cx
|
||||
mov [di + 1000], cx
|
||||
|
||||
add cx, dx
|
||||
add [di + 1000], cx
|
||||
add dx, 50
|
72
asm_files/list-0056.txt
Normal file
72
asm_files/list-0056.txt
Normal file
@ -0,0 +1,72 @@
|
||||
**************
|
||||
**** 8086 ****
|
||||
**************
|
||||
|
||||
WARNING: Clocks reported by this utility are strictly from the 8086 manual.
|
||||
They will be inaccurate, both because the manual clocks are estimates, and because
|
||||
some of the entries in the manual look highly suspicious and are probably typos.
|
||||
|
||||
--- test\listing_0056_estimating_cycles execution ---
|
||||
mov bx, 1000 ; Clocks: +4 = 4 | bx:0x0->0x3e8 ip:0x0->0x3
|
||||
mov bp, 2000 ; Clocks: +4 = 8 | bp:0x0->0x7d0 ip:0x3->0x6
|
||||
mov si, 3000 ; Clocks: +4 = 12 | si:0x0->0xbb8 ip:0x6->0x9
|
||||
mov di, 4000 ; Clocks: +4 = 16 | di:0x0->0xfa0 ip:0x9->0xc
|
||||
mov cx, bx ; Clocks: +2 = 18 | cx:0x0->0x3e8 ip:0xc->0xe
|
||||
mov dx, 12 ; Clocks: +4 = 22 | dx:0x0->0xc ip:0xe->0x11
|
||||
mov dx, [+1000] ; Clocks: +14 = 36 (8 + 6ea) | dx:0xc->0x0 ip:0x11->0x15
|
||||
mov cx, [bx] ; Clocks: +13 = 49 (8 + 5ea) | cx:0x3e8->0x0 ip:0x15->0x17
|
||||
mov cx, [bp] ; Clocks: +13 = 62 (8 + 5ea) | ip:0x17->0x1a
|
||||
mov word [si], cx ; Clocks: +14 = 76 (9 + 5ea) | ip:0x1a->0x1c
|
||||
mov word [di], cx ; Clocks: +14 = 90 (9 + 5ea) | ip:0x1c->0x1e
|
||||
mov cx, [bx+1000] ; Clocks: +17 = 107 (8 + 9ea) | ip:0x1e->0x22
|
||||
mov cx, [bp+1000] ; Clocks: +17 = 124 (8 + 9ea) | ip:0x22->0x26
|
||||
mov word [si+1000], cx ; Clocks: +18 = 142 (9 + 9ea) | ip:0x26->0x2a
|
||||
mov word [di+1000], cx ; Clocks: +18 = 160 (9 + 9ea) | ip:0x2a->0x2e
|
||||
add cx, dx ; Clocks: +3 = 163 | ip:0x2e->0x30 flags:->PZ
|
||||
add word [di+1000], cx ; Clocks: +25 = 188 (16 + 9ea) | ip:0x30->0x34
|
||||
add dx, 50 ; Clocks: +4 = 192 | dx:0x0->0x32 ip:0x34->0x37 flags:PZ->
|
||||
|
||||
Final registers:
|
||||
bx: 0x03e8 (1000)
|
||||
dx: 0x0032 (50)
|
||||
bp: 0x07d0 (2000)
|
||||
si: 0x0bb8 (3000)
|
||||
di: 0x0fa0 (4000)
|
||||
ip: 0x0037 (55)
|
||||
|
||||
|
||||
**************
|
||||
**** 8088 ****
|
||||
**************
|
||||
|
||||
WARNING: Clocks reported by this utility are strictly from the 8086 manual.
|
||||
They will be inaccurate, both because the manual clocks are estimates, and because
|
||||
some of the entries in the manual look highly suspicious and are probably typos.
|
||||
|
||||
--- test\listing_0056_estimating_cycles execution ---
|
||||
mov bx, 1000 ; Clocks: +4 = 4 | bx:0x0->0x3e8 ip:0x0->0x3
|
||||
mov bp, 2000 ; Clocks: +4 = 8 | bp:0x0->0x7d0 ip:0x3->0x6
|
||||
mov si, 3000 ; Clocks: +4 = 12 | si:0x0->0xbb8 ip:0x6->0x9
|
||||
mov di, 4000 ; Clocks: +4 = 16 | di:0x0->0xfa0 ip:0x9->0xc
|
||||
mov cx, bx ; Clocks: +2 = 18 | cx:0x0->0x3e8 ip:0xc->0xe
|
||||
mov dx, 12 ; Clocks: +4 = 22 | dx:0x0->0xc ip:0xe->0x11
|
||||
mov dx, [+1000] ; Clocks: +18 = 40 (8 + 6ea + 4p) | dx:0xc->0x0 ip:0x11->0x15
|
||||
mov cx, [bx] ; Clocks: +17 = 57 (8 + 5ea + 4p) | cx:0x3e8->0x0 ip:0x15->0x17
|
||||
mov cx, [bp] ; Clocks: +17 = 74 (8 + 5ea + 4p) | ip:0x17->0x1a
|
||||
mov word [si], cx ; Clocks: +18 = 92 (9 + 5ea + 4p) | ip:0x1a->0x1c
|
||||
mov word [di], cx ; Clocks: +18 = 110 (9 + 5ea + 4p) | ip:0x1c->0x1e
|
||||
mov cx, [bx+1000] ; Clocks: +21 = 131 (8 + 9ea + 4p) | ip:0x1e->0x22
|
||||
mov cx, [bp+1000] ; Clocks: +21 = 152 (8 + 9ea + 4p) | ip:0x22->0x26
|
||||
mov word [si+1000], cx ; Clocks: +22 = 174 (9 + 9ea + 4p) | ip:0x26->0x2a
|
||||
mov word [di+1000], cx ; Clocks: +22 = 196 (9 + 9ea + 4p) | ip:0x2a->0x2e
|
||||
add cx, dx ; Clocks: +3 = 199 | ip:0x2e->0x30 flags:->PZ
|
||||
add word [di+1000], cx ; Clocks: +33 = 232 (16 + 9ea + 8p) | ip:0x30->0x34
|
||||
add dx, 50 ; Clocks: +4 = 236 | dx:0x0->0x32 ip:0x34->0x37 flags:PZ->
|
||||
|
||||
Final registers:
|
||||
bx: 0x03e8 (1000)
|
||||
dx: 0x0032 (50)
|
||||
bp: 0x07d0 (2000)
|
||||
si: 0x0bb8 (3000)
|
||||
di: 0x0fa0 (4000)
|
||||
ip: 0x0037 (55)
|
42
asm_files/list-0057.asm
Normal file
42
asm_files/list-0057.asm
Normal file
@ -0,0 +1,42 @@
|
||||
; ========================================================================
|
||||
;
|
||||
; (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
|
||||
;
|
||||
; This software is provided 'as-is', without any express or implied
|
||||
; warranty. In no event will the authors be held liable for any damages
|
||||
; arising from the use of this software.
|
||||
;
|
||||
; Please see https://computerenhance.com for further information
|
||||
;
|
||||
; ========================================================================
|
||||
|
||||
; ========================================================================
|
||||
; LISTING 57
|
||||
; ========================================================================
|
||||
|
||||
bits 16
|
||||
|
||||
mov bx, 1000
|
||||
mov bp, 2000
|
||||
mov si, 3000
|
||||
mov di, 4000
|
||||
|
||||
mov cx, [bp + di]
|
||||
mov [bx + si], cx
|
||||
|
||||
mov cx, [bp + si]
|
||||
mov [bx + di], cx
|
||||
|
||||
mov cx, [bp + di + 1000]
|
||||
mov [bx + si + 1000], cx
|
||||
|
||||
mov cx, [bp + si + 1000]
|
||||
mov [bx + di + 1000], cx
|
||||
|
||||
add dx, [bp + si + 1000]
|
||||
|
||||
add word [bp + si], 76
|
||||
|
||||
add dx, [bp + si + 1001]
|
||||
add [di + 999], dx
|
||||
add word [bp + si], 75
|
71
asm_files/list-0057.txt
Normal file
71
asm_files/list-0057.txt
Normal file
@ -0,0 +1,71 @@
|
||||
**************
|
||||
**** 8086 ****
|
||||
**************
|
||||
|
||||
WARNING: Clocks reported by this utility are strictly from the 8086 manual.
|
||||
They will be inaccurate, both because the manual clocks are estimates, and because
|
||||
some of the entries in the manual look highly suspicious and are probably typos.
|
||||
|
||||
--- test\listing_0057_challenge_cycles execution ---
|
||||
mov bx, 1000 ; Clocks: +4 = 4 | bx:0x0->0x3e8 ip:0x0->0x3
|
||||
mov bp, 2000 ; Clocks: +4 = 8 | bp:0x0->0x7d0 ip:0x3->0x6
|
||||
mov si, 3000 ; Clocks: +4 = 12 | si:0x0->0xbb8 ip:0x6->0x9
|
||||
mov di, 4000 ; Clocks: +4 = 16 | di:0x0->0xfa0 ip:0x9->0xc
|
||||
mov cx, [bp+di] ; Clocks: +15 = 31 (8 + 7ea) | ip:0xc->0xe
|
||||
mov word [bx+si], cx ; Clocks: +16 = 47 (9 + 7ea) | ip:0xe->0x10
|
||||
mov cx, [bp+si] ; Clocks: +16 = 63 (8 + 8ea) | ip:0x10->0x12
|
||||
mov word [bx+di], cx ; Clocks: +17 = 80 (9 + 8ea) | ip:0x12->0x14
|
||||
mov cx, [bp+di+1000] ; Clocks: +19 = 99 (8 + 11ea) | ip:0x14->0x18
|
||||
mov word [bx+si+1000], cx ; Clocks: +20 = 119 (9 + 11ea) | ip:0x18->0x1c
|
||||
mov cx, [bp+si+1000] ; Clocks: +20 = 139 (8 + 12ea) | ip:0x1c->0x20
|
||||
mov word [bx+di+1000], cx ; Clocks: +21 = 160 (9 + 12ea) | ip:0x20->0x24
|
||||
add dx, [bp+si+1000] ; Clocks: +21 = 181 (9 + 12ea) | ip:0x24->0x28 flags:->PZ
|
||||
add word [bp+si], 76 ; Clocks: +25 = 206 (17 + 8ea) | ip:0x28->0x2b flags:PZ->
|
||||
add dx, [bp+si+1001] ; Clocks: +25 = 231 (9 + 12ea + 4p) | ip:0x2b->0x2f flags:->PZ
|
||||
add word [di+999], dx ; Clocks: +33 = 264 (16 + 9ea + 8p) | ip:0x2f->0x33 flags:PZ->P
|
||||
add word [bp+si], 75 ; Clocks: +25 = 289 (17 + 8ea) | ip:0x33->0x36 flags:P->A
|
||||
|
||||
Final registers:
|
||||
bx: 0x03e8 (1000)
|
||||
bp: 0x07d0 (2000)
|
||||
si: 0x0bb8 (3000)
|
||||
di: 0x0fa0 (4000)
|
||||
ip: 0x0036 (54)
|
||||
flags: A
|
||||
|
||||
|
||||
|
||||
**************
|
||||
**** 8088 ****
|
||||
**************
|
||||
|
||||
WARNING: Clocks reported by this utility are strictly from the 8086 manual.
|
||||
They will be inaccurate, both because the manual clocks are estimates, and because
|
||||
some of the entries in the manual look highly suspicious and are probably typos.
|
||||
|
||||
--- test\listing_0057_challenge_cycles execution ---
|
||||
mov bx, 1000 ; Clocks: +4 = 4 | bx:0x0->0x3e8 ip:0x0->0x3
|
||||
mov bp, 2000 ; Clocks: +4 = 8 | bp:0x0->0x7d0 ip:0x3->0x6
|
||||
mov si, 3000 ; Clocks: +4 = 12 | si:0x0->0xbb8 ip:0x6->0x9
|
||||
mov di, 4000 ; Clocks: +4 = 16 | di:0x0->0xfa0 ip:0x9->0xc
|
||||
mov cx, [bp+di] ; Clocks: +19 = 35 (8 + 7ea + 4p) | ip:0xc->0xe
|
||||
mov word [bx+si], cx ; Clocks: +20 = 55 (9 + 7ea + 4p) | ip:0xe->0x10
|
||||
mov cx, [bp+si] ; Clocks: +20 = 75 (8 + 8ea + 4p) | ip:0x10->0x12
|
||||
mov word [bx+di], cx ; Clocks: +21 = 96 (9 + 8ea + 4p) | ip:0x12->0x14
|
||||
mov cx, [bp+di+1000] ; Clocks: +23 = 119 (8 + 11ea + 4p) | ip:0x14->0x18
|
||||
mov word [bx+si+1000], cx ; Clocks: +24 = 143 (9 + 11ea + 4p) | ip:0x18->0x1c
|
||||
mov cx, [bp+si+1000] ; Clocks: +24 = 167 (8 + 12ea + 4p) | ip:0x1c->0x20
|
||||
mov word [bx+di+1000], cx ; Clocks: +25 = 192 (9 + 12ea + 4p) | ip:0x20->0x24
|
||||
add dx, [bp+si+1000] ; Clocks: +25 = 217 (9 + 12ea + 4p) | ip:0x24->0x28 flags:->PZ
|
||||
add word [bp+si], 76 ; Clocks: +33 = 250 (17 + 8ea + 8p) | ip:0x28->0x2b flags:PZ->
|
||||
add dx, [bp+si+1001] ; Clocks: +25 = 275 (9 + 12ea + 4p) | ip:0x2b->0x2f flags:->PZ
|
||||
add word [di+999], dx ; Clocks: +33 = 308 (16 + 9ea + 8p) | ip:0x2f->0x33 flags:PZ->P
|
||||
add word [bp+si], 75 ; Clocks: +33 = 341 (17 + 8ea + 8p) | ip:0x33->0x36 flags:P->A
|
||||
|
||||
Final registers:
|
||||
bx: 0x03e8 (1000)
|
||||
bp: 0x07d0 (2000)
|
||||
si: 0x0bb8 (3000)
|
||||
di: 0x0fa0 (4000)
|
||||
ip: 0x0036 (54)
|
||||
flags: A
|
Loading…
x
Reference in New Issue
Block a user