diff --git a/notes/cowgod-chip8-techref.html b/notes/cowgod-chip8-techref.html new file mode 100644 index 0000000..d9a8286 --- /dev/null +++ b/notes/cowgod-chip8-techref.html @@ -0,0 +1,1200 @@ + + + Cowgod's Chip-8 Technical Reference + + +
+ Cowgod's
+ Chip-8
+ Technical Reference v1.0
+
+
+ + 0.0 - Table of Contents          
+
+
+ + 0.0 - Table of Contents
+       0.1 - Using This Document
+
+ 1.0 - About Chip-8
+
+ 2.0 - Chip-8 Specifications
+       2.1 - Memory
+             Diagram - Memory Map
+       2.2 - Registers
+       2.3 - Keyboard
+             Diagram - Keyboard Layout
+       2.4 - Display
+             Diagram - Display Coordinates
+             Listing - The Chip-8 Hexadecimal Font
+       2.5 - Timers & Sound
+
+ 3.0 - Chip-8 Instructions
+       3.1 - Standard Chip-8 Instructions
+             00E0 - CLS
+             00EE - RET
+             0nnn - SYS addr
+             1nnn - JP addr
+             2nnn - CALL addr
+             3xkk - SE Vx, byte
+             4xkk - SNE Vx, byte
+             5xy0 - SE Vx, Vy
+             6xkk - LD Vx, byte
+             7xkk - ADD Vx, byte
+             8xy0 - LD Vx, Vy
+             8xy1 - OR Vx, Vy
+             8xy2 - AND Vx, Vy
+             8xy3 - XOR Vx, Vy
+             8xy4 - ADD Vx, Vy
+             8xy5 - SUB Vx, Vy
+             8xy6 - SHR Vx {, Vy}
+             8xy7 - SUBN Vx, Vy
+             8xyE - SHL Vx {, Vy}
+             9xy0 - SNE Vx, Vy
+             Annn - LD I, addr
+             Bnnn - JP V0, addr
+             Cxkk - RND Vx, byte
+             Dxyn - DRW Vx, Vy, nibble
+             Ex9E - SKP Vx
+             ExA1 - SKNP Vx
+             Fx07 - LD Vx, DT
+             Fx0A - LD Vx, K
+             Fx15 - LD DT, Vx
+             Fx18 - LD ST, Vx
+             Fx1E - ADD I, Vx
+             Fx29 - LD F, Vx
+             Fx33 - LD B, Vx
+             Fx55 - LD [I], Vx
+             Fx65 - LD Vx, [I]
+       3.2 - Super Chip-48 Instructions
+             00Cn - SCD nibble
+             00FB - SCR
+             00FC - SCL
+             00FD - EXIT
+             00FE - LOW
+             00FF - HIGH
+             Dxy0 - DRW Vx, Vy, 0
+             Fx30 - LD HF, Vx
+             Fx75 - LD R, Vx
+             Fx85 - LD Vx, R
+ +
+ 4.0 - Interpreters
+ +
+ 5.0 - Credits
+ +
+
+
+ + + 0.1 - Using This Document           + [TOC]
+
+ + While creating this document, I took every effort to try to make it easy to read, as + well as easy to find what you're looking for.
+
+ In most cases, where a hexadecimal value is given, it is followed by the equivalent + decimal value in parenthesis. For example, "0x200 (512)."
+
+ In most cases, when a word or letter is italicized, it is referring to a variable + value, for example, if I write "Vx," the x reffers to a 4-bit + value.
+
+ The most important thing to remember as you read this document is that every [TOC] + link will take you back to the Table Of Contents. Also, links that you have not yet visited + will appear in blue, while links you have used will be + gray.
+
+
+
+ + + 1.0 - About Chip-8           + [TOC]
+
+ + Whenever I mention to someone that I'm writing a Chip-8 interpreter, the response + is always the same: "What's a Chip-8?"
+
+ Chip-8 is a simple, interpreted, programming language which was first used on some + do-it-yourself computer systems in the late 1970s and early 1980s. The COSMAC VIP, + DREAM 6800, and ETI 660 computers are a few examples. These computers typically + were designed to use a television as a display, had between 1 and 4K of RAM, and + used a 16-key hexadecimal keypad for input. The interpreter took up only + 512 bytes of memory, and programs, which were entered into the computer in + hexadecimal, were even smaller.
+
+ In the early 1990s, the Chip-8 language was revived by a man named Andreas + Gustafsson. He created a Chip-8 interpreter for the HP48 graphing calculator, + called Chip-48. The HP48 was lacking a way to easily make fast games at the time, + and Chip-8 was the answer. Chip-48 later begat Super Chip-48, a modification of + Chip-48 which allowed higher resolution graphics, as well as other graphical + enhancements.
+
+ Chip-48 inspired a whole new crop of Chip-8 interpreters for various platforms, + including MS-DOS, Windows 3.1, Amiga, HP48, MSX, Adam, and ColecoVision. I became + involved with Chip-8 after stumbling upon Paul Robson's interpreter on the + World Wide Web. Shortly after that, I began writing my own Chip-8 interpreter.
+
+ This document is a compilation of all the different sources of information I used + while programming my interpreter.
+
+
+
+ + + 2.0 - Chip-8 Specifications           + [TOC]
+
+ + This section describes the Chip-8 memory, registers, display, keyboard, and timers.
+
+
+
+ + + 2.1 - Memory           + [TOC]
+
+ + The Chip-8 language is capable of accessing up to 4KB (4,096 bytes) of RAM, from + location 0x000 (0) to 0xFFF (4095). The first 512 bytes, from 0x000 to 0x1FF, are + where the original interpreter was located, and should not be used by programs.
+
+ Most Chip-8 programs start at location 0x200 (512), but some begin at 0x600 (1536). + Programs beginning at 0x600 are intended for the ETI 660 computer.
+
+ Memory Map:
+ +---------------+= 0xFFF (4095) End of Chip-8 RAM
+ |               |
+ |               |
+ |               |
+ |               |
+ |               |
+ | 0x200 to 0xFFF|
+ |     Chip-8    |
+ | Program / Data|
+ |     Space     |
+ |               |
+ |               |
+ |               |
+ +- - - - - - - -+= 0x600 (1536) Start of ETI 660 Chip-8 programs
+ |               |
+ |               |
+ |               |
+ +---------------+= 0x200 (512) Start of most Chip-8 programs
+ | 0x000 to 0x1FF|
+ | Reserved for  |
+ |  interpreter  |
+ +---------------+= 0x000 (0) Start of Chip-8 RAM
+ + +
+
+
+ + + 2.2 - Registers           + [TOC]
+
+ + Chip-8 has 16 general purpose 8-bit registers, usually referred to as + Vx, where x is a hexadecimal digit (0 through F). There is also + a 16-bit register called I. This register is generally used to store + memory addresses, so only the lowest (rightmost) 12 bits are usually used.
+
+ The VF register should not be used by any program, as it is used as a flag by + some instructions. See section 3.0, Instructions + for details.
+
+ Chip-8 also has two special purpose 8-bit registers, for the delay and sound timers. + When these registers are non-zero, they are automatically decremented at a rate + of 60Hz. See the section 2.5, Timers & Sound, for more + information on these.
+
+ There are also some "pseudo-registers" which are not accessable from Chip-8 + programs. The program counter (PC) should be 16-bit, and is used to store the + currently executing address. The stack pointer (SP) can be 8-bit, it is used to + point to the topmost level of the stack.
+
+ The stack is an array of 16 16-bit values, used to store the address that + the interpreter shoud return to when finished with a subroutine. Chip-8 allows + for up to 16 levels of nested subroutines.
+
+
+
+ + + 2.3 - Keyboard           + [TOC]
+
+ + The computers which originally used the Chip-8 Language had a 16-key hexadecimal + keypad with the following layout:
+
+ + + + + +
123C
456D
789E
A0BF
+
+ This layout must be mapped into various other configurations to fit the keyboards + of today's platforms.
+
+
+
+ + + 2.4 - Display           + [TOC]
+
+ + The original implementation of the Chip-8 language used a 64x32-pixel monochrome display + with this format:
+
+ + +
+ + + +
(0,0)(63,0)
(0,31)(63,31)
+
+
+ Some other interpreters, most notably the one on the ETI 660, also had 64x48 and + 64x64 modes. To my knowledge, no current interpreter supports these modes. More + recently, Super Chip-48, an interpreter for the HP48 calculator, added a + 128x64-pixel mode. This mode is now supported by most of the interpreters on other + platforms.
+
+ Chip-8 draws graphics on screen through the use of sprites. A sprite is a group + of bytes which are a binary representation of the desired picture. Chip-8 sprites + may be up to 15 bytes, for a possible sprite size of 8x15.
+
+ Programs may also refer to a group of sprites representing the hexadecimal + digits 0 through F. These sprites are 5 bytes long, or 8x5 pixels. The data + should be stored in the interpreter area of Chip-8 memory (0x000 to 0x1FF). + Below is a listing of each character's bytes, in binary and hexadecimal:
+
+   + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
"0"BinaryHex
+ ****
+ *  *
+ *  *
+ *  *
+ ****
+
+ 11110000
+ 10010000
+ 10010000
+ 10010000
+ 11110000
+
+ 0xF0
+ 0x90
+ 0x90
+ 0x90
+ 0xF0
+
+
+ + + + + + + +
"1"BinaryHex
+   * 
+  ** 
+   * 
+   * 
+  ***
+
+ 00100000
+ 01100000
+ 00100000
+ 00100000
+ 01110000
+
+ 0x20
+ 0x60
+ 0x20
+ 0x20
+ 0x70
+
+
+ + + + + + + +
"2"BinaryHex
+ ****
+    *
+ ****
+ *   
+ ****
+
+ 11110000
+ 00010000
+ 11110000
+ 10000000
+ 11110000
+
+ 0xF0
+ 0x10
+ 0xF0
+ 0x80
+ 0xF0
+
+
+ + + + + + + +
"3"BinaryHex
+ ****
+    *
+ ****
+    *
+ ****
+
+ 11110000
+ 00010000
+ 11110000
+ 00010000
+ 11110000
+
+ 0xF0
+ 0x10
+ 0xF0
+ 0x10
+ 0xF0
+
+
+ + + + + + + +
"4"BinaryHex
+ *  *
+ *  *
+ ****
+    *
+    *
+
+ 10010000
+ 10010000
+ 11110000
+ 00010000
+ 00010000
+
+ 0x90
+ 0x90
+ 0xF0
+ 0x10
+ 0x10
+
+
+ + + + + + + +
"5"BinaryHex
+ ****
+ *   
+ ****
+    *
+ ****
+
+ 11110000
+ 10000000
+ 11110000
+ 00010000
+ 11110000
+
+ 0xF0
+ 0x80
+ 0xF0
+ 0x10
+ 0xF0
+
+
+ + + + + + + +
"6"BinaryHex
+ ****
+ *   
+ ****
+ *  *
+ ****
+
+ 11110000
+ 10000000
+ 11110000
+ 10010000
+ 11110000
+
+ 0xF0
+ 0x80
+ 0xF0
+ 0x90
+ 0xF0
+
+
+ + + + + + + +
"7"BinaryHex
+ ****
+    *
+   * 
+  *  
+  *  
+
+ 11110000
+ 00010000
+ 00100000
+ 01000000
+ 01000000
+
+ 0xF0
+ 0x10
+ 0x20
+ 0x40
+ 0x40
+
+
+ + + + + + + +
"8"BinaryHex
+ ****
+ *  *
+ ****
+ *  *
+ ****
+
+ 11110000
+ 10010000
+ 11110000
+ 10010000
+ 11110000
+
+ 0xF0
+ 0x90
+ 0xF0
+ 0x90
+ 0xF0
+
+
+ + + + + + + +
"9"BinaryHex
+ ****
+ *  *
+ ****
+    *
+ ****
+
+ 11110000
+ 10010000
+ 11110000
+ 00010000
+ 11110000
+
+ 0xF0
+ 0x90
+ 0xF0
+ 0x10
+ 0xF0
+
+
+ + + + + + + +
"A"BinaryHex
+ ****
+ *  *
+ ****
+ *  *
+ *  *
+
+ 11110000
+ 10010000
+ 11110000
+ 10010000
+ 10010000
+
+ 0xF0
+ 0x90
+ 0xF0
+ 0x90
+ 0x90
+
+
+ + + + + + + +
"B"BinaryHex
+ *** 
+ *  *
+ *** 
+ *  *
+ *** 
+
+ 11100000
+ 10010000
+ 11100000
+ 10010000
+ 11100000
+
+ 0xE0
+ 0x90
+ 0xE0
+ 0x90
+ 0xE0
+
+
+ + + + + + + +
"C"BinaryHex
+ ****
+ *   
+ *   
+ *   
+ ****
+
+ 11110000
+ 10000000
+ 10000000
+ 10000000
+ 11110000
+
+ 0xF0
+ 0x80
+ 0x80
+ 0x80
+ 0xF0
+
+
+ + + + + + + +
"D"BinaryHex
+ *** 
+ *  *
+ *  *
+ *  *
+ *** 
+
+ 11100000
+ 10010000
+ 10010000
+ 10010000
+ 11100000
+
+ 0xE0
+ 0x90
+ 0x90
+ 0x90
+ 0xE0
+
+
+ + + + + + + +
"E"BinaryHex
+ ****
+ *   
+ ****
+ *   
+ ****
+
+ 11110000
+ 10000000
+ 11110000
+ 10000000
+ 11110000
+
+ 0xF0
+ 0x80
+ 0xF0
+ 0x80
+ 0xF0
+
+
+ + + + + + + +
"F"BinaryHex
+ ****
+ *   
+ ****
+ *   
+ *   
+
+ 11110000
+ 10000000
+ 11110000
+ 10000000
+ 10000000
+
+ 0xF0
+ 0x80
+ 0xF0
+ 0x80
+ 0x80
+
+
+
+
+
+ + 2.5 - Timers & Sound           + [TOC]
+
+ + Chip-8 provides 2 timers, a delay timer and a sound timer.
+
+ The delay timer is active whenever the delay timer register (DT) is non-zero. + This timer does nothing more than subtract 1 from the value of DT at a rate + of 60Hz. When DT reaches 0, it deactivates.
+
+ The sound timer is active whenever the sound timer register (ST) is non-zero. + This timer also decrements at a rate of 60Hz, however, as long as ST's value is + greater than zero, the Chip-8 buzzer will sound. When ST reaches zero, the sound + timer deactivates.
+
+ The sound produced by the Chip-8 interpreter has only one tone. The frequency + of this tone is decided by the author of the interpreter.
+
+
+
+ + + 3.0 - Chip-8 Instructions           + [TOC]
+
+ + The original implementation of the Chip-8 language includes 36 different + instructions, including math, graphics, and flow control functions.
+
+ Super Chip-48 added an additional 10 instructions, for a total of 46.
+
+ All instructions are 2 bytes long and are stored most-significant-byte first. + In memory, the first byte of each instruction should be located at an even + addresses. If a program includes sprite data, it should be padded so any + instructions following it will be properly situated in RAM.
+
+ This document does not yet contain descriptions of the Super Chip-48 instructions. + They are, however, listed below.
+
+ In these listings, the following variables are used:
+
+ nnn or addr - A 12-bit value, the lowest 12 bits of the instruction
+ n or nibble - A 4-bit value, the lowest 4 bits of the instruction
+ x - A 4-bit value, the lower 4 bits of the high byte of the instruction
+ y - A 4-bit value, the upper 4 bits of the low byte of the instruction
+ kk or byte - An 8-bit value, the lowest 8 bits of the instruction
+
+
+
+ + 3.1 - Standard Chip-8 Instructions           + [TOC]
+
+ + 0nnn - SYS addr
+ Jump to a machine code routine at nnn.
+
+ This instruction is only used on the old computers on which Chip-8 was + originally implemented. It is ignored by modern interpreters.
+
+
+ + 00E0 - CLS
+ Clear the display.
+
+
+ + 00EE - RET
+ Return from a subroutine.
+
+ The interpreter sets the program counter to the address at the top of the + stack, then subtracts 1 from the stack pointer.
+
+
+ + 1nnn - JP addr
+ Jump to location nnn.
+
+ The interpreter sets the program counter to nnn.
+
+
+ + 2nnn - CALL addr
+ Call subroutine at nnn.
+
+ The interpreter increments the stack pointer, then puts the current PC on + the top of the stack. The PC is then set to nnn.
+
+
+ + 3xkk - SE Vx, byte
+ Skip next instruction if Vx = kk.
+
+ The interpreter compares register Vx to kk, and if they are + equal, increments the program counter by 2.
+
+
+ + 4xkk - SNE Vx, byte
+ Skip next instruction if Vx != kk.
+
+ The interpreter compares register Vx to kk, and if they are + not equal, increments the program counter by 2.
+
+
+ + 5xy0 - SE Vx, Vy
+ Skip next instruction if Vx = Vy.
+
+ The interpreter compares register Vx to register Vy, and if + they are equal, increments the program counter by 2.
+
+
+ + 6xkk - LD Vx, byte
+ Set Vx = kk.
+
+ The interpreter puts the value kk into register Vx.
+
+
+ + 7xkk - ADD Vx, byte
+ Set Vx = Vx + kk.
+
+ Adds the value kk to the value of register Vx, then stores the result in Vx. +
+
+ + 8xy0 - LD Vx, Vy
+ Set Vx = Vy.
+
+ Stores the value of register Vy in register Vx.
+
+
+ + 8xy1 - OR Vx, Vy
+ Set Vx = Vx OR Vy.
+
+ Performs a bitwise OR on the values of Vx and Vy, then stores the result in Vx. A + bitwise OR compares the corrseponding bits from two values, and if either bit + is 1, then the same bit in the result is also 1. Otherwise, it is 0.
+
+
+ + 8xy2 - AND Vx, Vy
+ Set Vx = Vx AND Vy.
+
+ Performs a bitwise AND on the values of Vx and Vy, then stores the result in Vx. A + bitwise AND compares the corrseponding bits from two values, and if both bits + are 1, then the same bit in the result is also 1. Otherwise, it is 0.
+
+
+ + 8xy3 - XOR Vx, Vy
+ Set Vx = Vx XOR Vy.
+
+ Performs a bitwise exclusive OR on the values of Vx and Vy, then stores the + result in Vx. An exclusive OR compares the corrseponding bits from two values, + and if the bits are not both the same, then the corresponding bit in the result + is set to 1. Otherwise, it is 0.
+
+
+ + 8xy4 - ADD Vx, Vy
+ Set Vx = Vx + Vy, set VF = carry.
+
+ The values of Vx and Vy are added together. If the result is greater than 8 bits + (i.e., > 255,) VF is set to 1, otherwise 0. Only the lowest 8 bits of the result + are kept, and stored in Vx.
+
+
+ + 8xy5 - SUB Vx, Vy
+ Set Vx = Vx - Vy, set VF = NOT borrow.
+
+ If Vx > Vy, then VF is set to 1, otherwise 0. Then Vy is subtracted from Vx, + and the results stored in Vx.
+
+
+ + 8xy6 - SHR Vx {, Vy}
+ Set Vx = Vx SHR 1.
+
+ If the least-significant bit of Vx is 1, then VF is set to 1, otherwise 0. Then + Vx is divided by 2.
+
+
+ + 8xy7 - SUBN Vx, Vy
+ Set Vx = Vy - Vx, set VF = NOT borrow.
+
+ If Vy > Vx, then VF is set to 1, otherwise 0. Then Vx is subtracted from Vy, + and the results stored in Vx.
+
+
+ + 8xyE - SHL Vx {, Vy}
+ Set Vx = Vx SHL 1.
+
+ If the most-significant bit of Vx is 1, then VF is set to 1, otherwise to 0. Then + Vx is multiplied by 2.
+
+
+ + 9xy0 - SNE Vx, Vy
+ Skip next instruction if Vx != Vy.
+
+ The values of Vx and Vy are compared, and if they are not equal, the program + counter is increased by 2.
+
+
+ + Annn - LD I, addr
+ Set I = nnn.
+
+ The value of register I is set to nnn.
+
+
+ + Bnnn - JP V0, addr
+ Jump to location nnn + V0.
+
+ The program counter is set to nnn plus the value of V0.
+
+
+ + Cxkk - RND Vx, byte
+ Set Vx = random byte AND kk.
+
+ The interpreter generates a random number from 0 to 255, which is then ANDed + with the value kk. The results are stored in Vx. See instruction 8xy2 + for more information on AND.
+
+
+ + Dxyn - DRW Vx, Vy, nibble
+ Display n-byte sprite starting at memory location I at (Vx, Vy), set VF = collision.
+
+ The interpreter reads n bytes from memory, starting at the address stored in + I. These bytes are then displayed as sprites on screen at coordinates (Vx, Vy). + Sprites are XORed onto the existing screen. If this causes any pixels to be + erased, VF is set to 1, otherwise it is set to 0. If the sprite is positioned + so part of it is outside the coordinates of the display, it wraps around to + the opposite side of the screen. See instruction 8xy3 for + more information on XOR, and section 2.4, Display, for + more information on the Chip-8 screen and sprites.
+
+
+ + Ex9E - SKP Vx
+ Skip next instruction if key with the value of Vx is pressed.
+
+ Checks the keyboard, and if the key corresponding to the value of Vx is currently + in the down position, PC is increased by 2.
+
+
+ + ExA1 - SKNP Vx
+ Skip next instruction if key with the value of Vx is not pressed.
+
+ Checks the keyboard, and if the key corresponding to the value of Vx is currently + in the up position, PC is increased by 2.
+
+
+ + Fx07 - LD Vx, DT
+ Set Vx = delay timer value.
+
+ The value of DT is placed into Vx.
+
+
+ + Fx0A - LD Vx, K
+ Wait for a key press, store the value of the key in Vx.
+
+ All execution stops until a key is pressed, then the value of that key + is stored in Vx.
+
+
+ + Fx15 - LD DT, Vx
+ Set delay timer = Vx.
+
+ DT is set equal to the value of Vx.
+
+
+ + Fx18 - LD ST, Vx
+ Set sound timer = Vx.
+
+ ST is set equal to the value of Vx.
+
+
+ + Fx1E - ADD I, Vx
+ Set I = I + Vx.
+
+ The values of I and Vx are added, and the results are stored in I.
+
+
+ + Fx29 - LD F, Vx
+ Set I = location of sprite for digit Vx.
+
+ The value of I is set to the location for the hexadecimal sprite corresponding to + the value of Vx. See section 2.4, Display, for more information + on the Chip-8 hexadecimal font.
+
+
+ + Fx33 - LD B, Vx
+ Store BCD representation of Vx in memory locations I, I+1, and I+2.
+
+ The interpreter takes the decimal value of Vx, and places the hundreds + digit in memory at location in I, the tens digit at location I+1, and the + ones digit at location I+2.
+
+
+ + Fx55 - LD [I], Vx
+ Store registers V0 through Vx in memory starting at location I.
+
+ The interpreter copies the values of registers V0 through Vx into memory, + starting at the address in I.
+
+
+ + Fx65 - LD Vx, [I]
+ Read registers V0 through Vx from memory starting at location I.
+
+ The interpreter reads values from memory starting at location I into registers + V0 through Vx.
+
+
+ +
+ + 3.2 - Super Chip-48 Instructions           + [TOC]
+
+ + 00Cn - SCD nibble
+ 00FB - SCR
+ 00FC - SCL
+ 00FD - EXIT
+ 00FE - LOW
+ 00FF - HIGH
+ Dxy0 - DRW Vx, Vy, 0
+ Fx30 - LD HF, Vx
+ Fx75 - LD R, Vx
+ Fx85 - LD Vx, R
+
+
+
+ +
+ + 4.0 - Interpreters           + [TOC]
+
+ + Below is a list of every Chip-8 interpreter I could find on the World Wide Web:
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TitleVersionAuthorPlatform(s)
Chip-482.20Anrdreas GustafssonHP48
Chip81.1Paul RobsonDOS
Chip-8 Emulator2.0.0David WinterDOS
CowChip0.1Thomas P. GreeneWindows 3.1
DREAM MON1.1Paul HayterAmiga
Super Chip-481.1Based on Chip-48, modified by Erik BryntseHP48
Vision-81.0Marcel de KogelDOS, Adam, MSX, ColecoVision
+
+
+
+ + + 5.0 - Credits           + [TOC]
+
+ + This document was compiled by Thomas P. Greene.
+
+ Sources include:
+ +
+
+
+
+ August 30, 1997 06:00:00 + + \ No newline at end of file diff --git a/programs/test.ch8 b/programs/test.ch8 index feda8b1..0bdc1c1 100644 Binary files a/programs/test.ch8 and b/programs/test.ch8 differ diff --git a/src/chip8.rs b/src/chip8.rs index 2247365..099fbdf 100644 --- a/src/chip8.rs +++ b/src/chip8.rs @@ -9,8 +9,18 @@ pub const MAX_MEM_SIZE: usize = 4096; pub const MAX_PRG_SIZE: usize = 3584; // Instruction constants -const INSTR_NOOP: u16 = 0x0000; -const INSTR_EXIT: u16 = 0x00FD; +const INSTR_NOOP: u16 = 0x0000; +const INSTR_EXIT: u16 = 0x00FD; +const INSTR_CLS: u16 = 0x00E0; +const INSTR_RET: u16 = 0x00EE; + +// Commonn Instruction Masks +const INSTR_MASK_SYS: u16 = 0x0000; +const INSTR_MASK_JP: u16 = 0x1000; +const INSTR_MASK_CALL: u16 = 0x2000; + +const ADDR_MASK: u16 = 0x0FFF; + #[derive(Debug)] struct EmulationState { @@ -73,7 +83,7 @@ fn exec_program(state: &mut EmulationState) { let mut head_byte: u8; let mut tail_byte: u8; - let mut instruction_tuple: (u8, u8); + let mut instruction: u16; for _i in PRGRM_START+usize::from(state.program_counter)..MAX_MEM_SIZE { // Grab the first byte of instruction @@ -84,20 +94,47 @@ fn exec_program(state: &mut EmulationState) { tail_byte = state.memory[PRGRM_START + usize::from(state.program_counter)]; state.program_counter += 1; - instruction_tuple = (head_byte, tail_byte); + instruction = util::u8_tuple_to_u16((head_byte, tail_byte)); + println!("0x{:02X?}{:02X?}", head_byte, tail_byte); - if util::u8_tuple_to_u16(instruction_tuple) == INSTR_EXIT { + if instruction == INSTR_EXIT { println!("Read exit instruction, stopping emulation"); return; } - if util::u8_tuple_to_u16(instruction_tuple) == INSTR_NOOP { + if instruction == INSTR_NOOP { println!("Read no-op instruction, stopping emulation"); return; } + + parse_instruction(state, instruction); + } +} + +fn parse_instruction(state: &mut EmulationState, instr: u16) { + + if (instr == INSTR_CLS) { + println!("Clear screen"); } - + if (instr == INSTR_RET) { + println!("Return"); + } + + if ((instr & INSTR_MASK_SYS) > 0) { + let addr: u16 = (instr & ADDR_MASK); + println!("Got SYS instruction {:04X?} with address {:04X?}", instr, addr); + } + + if ((instr & INSTR_MASK_JP) > 0) { + let addr: u16 = (instr & ADDR_MASK); + println!("Got JP instruction {:04X?} with address {:04X?}", instr, addr); + } + + if ((instr & INSTR_MASK_CALL) > 0) { + let addr: u16 = (instr & ADDR_MASK); + println!("Got CALL instruction {:04X?} with address {:04X?}", instr, addr); + } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index f01706c..94a15fe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,8 +11,6 @@ fn main() { // Collect our execution args let args: Vec = env::args().collect(); - // let mut inject_mode: bool = false; - // let mut patch_file_path: &String = &"".to_string(); // Grab our filepath from our options if &args.len() < &2 @@ -22,11 +20,12 @@ fn main() exit(0); } - let file_path: &String = &args[1]; + // Read last argument as path of chip8 executable + let file_path: &String = &args[args.len()-1]; if path::Path::new(file_path).exists() { - println!("File exists, reading '{}'...", file_path); + println!("'{}' exists, reading...", file_path); let contents: Result, std::io::Error> = fs::read(file_path); @@ -49,9 +48,9 @@ fn main() println!("Read {} bytes of program data", file_data.len()); chip8::start_emulation(program); - } - } else + } + else { println!("[Error] File '{}' does not exist", file_path); exit(-1);