рдпрд╣ рдкреЛрд╕реНрдЯ рдирдИ рднрд╛рд╖рд╛рдУрдВ рдФрд░ рдкреБрд░рд╛рдиреЗ рд╣рд╛рд░реНрдбрд╡реЗрдпрд░ рдХреЗ рдкреНрд░рд╢рдВрд╕рдХреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдкрд┐рдд рд╣реИ - рдЗрд╕рдореЗрдВ рд╣рдо рдЧреЛ рдореЗрдВ CHIP-8 рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрди рдХрд╛ рдПрдХ рдПрдореБрд▓реЗрдЯрд░ рд▓рд┐рдЦреЗрдВрдЧреЗред
рд╣рдордиреЗ рдкрд╣рд▓реЗ рд╣реА рд▓рд┐рдЦрд╛ рд╣реИ рдХрд┐ рдЧреЛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рд╡рд░рдг рдХреЛ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдмрд╛рд░ рдХреИрд╕реЗ рд╕реЗрдЯ рдХрд░реЗрдВред рд╣рд╛рд▓ рд╣реА рдореЗрдВ, рдереЛрдбрд╝рд╛ рдмрджрд▓ рдЧрдпрд╛ рд╣реИ, рд╕рд┐рд╡рд╛рдп рдЗрд╕рдХреЗ рдХрд┐ рд╡рд┐рдВрдбреЛрдЬ рдХреЗ рд▓рд┐рдП рд╕рдВрд╕реНрдХрд░рдг рдЕрдзрд┐рдХ рд╕реНрдерд┐рд░ рд╣реЛ рдЧрдпрд╛ рд╣реИред
рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд╕рдм рдХреБрдЫ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо CHIP-8 рдХреЗ рдЗрдирд╕рд╛рдЗрдЯреНрд╕ рдХрд╛ рдЕрдзреНрдпрдпрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВред
рдХрд╣рд╛рдиреА
CHIP-8 рдкрд░ рдЖрдзрд╛рд░рд┐рдд рдЧреЗрдо рдХрдВрд╕реЛрд▓ рдЗрддрд┐рд╣рд╛рд╕ рдореЗрдВ рдкрд╣рд▓реА рдЖрднрд╛рд╕реА рдорд╢реАрдиреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдЙрд▓реНрд▓реЗрдЦрдиреАрдп рд╣реИрдВред
CHIP-8 рдХреЗ рдХрд╛рд░реНрдпрдХреНрд░рдореЛрдВ рдХреЛ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкреНрд░реЛрд╕реЗрд╕рд░ рдкрд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХреА рдЬрд╛рддреА рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореВрд▓ рджреБрднрд╛рд╖рд┐рдпрд╛ рдХреЗрд╡рд▓ 512 рдмрд╛рдЗрдЯреНрд╕ рд▓рд┐рдпрд╛ред
CHIP-8 рдХреА рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рдкреНрд░рднрд╛рд╡рд╢рд╛рд▓реА рд░реВрдк рд╕реЗ рд╡рд┐рдирдореНрд░ рд╣реИрдВ: рдореЗрдЧрд╛рд╣рд░реНрдЯреНрдЬрд╝ рдХреЗ рдПрдХ рдЬреЛрдбрд╝реЗ рдХреА рдЖрд╡реГрддреНрддрд┐ рдХреЗ рд╕рд╛рде рдПрдХ 8-рдмрд┐рдЯ рдкреНрд░реЛрд╕реЗрд╕рд░, 4 рдХреЗрдмреА рд░реИрдо (рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛрдб рднреА рд░реИрдо рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИ), рдПрдХ рдореЛрдиреЛрдХреНрд░реЛрдо 32x64 рдкрд┐рдХреНрд╕реЗрд▓ рд╕реНрдХреНрд░реАрди, рджреЛ рдЯрд╛рдЗрдорд░ - рдЧрд┐рдирддреА рдХреЗ рд╕рдордп рдХреЗ рд▓рд┐рдП рдПрдХ, рдзреНрд╡рдирд┐ рдЦреЗрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ ("рдЯреНрд╡реАрдЯрд░") )ред
рд╕рднреА рджреЛрд╖реЛрдВ рдХреЗ рдмрд╛рд╡рдЬреВрдж, CHIP-8 рдореЗрдВ рдЕрдВрддрд░рд┐рдХреНрд╖ рдЖрдХреНрд░рдордгрдХрд╛рд░рд┐рдпреЛрдВ, рдкреЛрдВрдЧ, рдФрд░ рдЕрдиреНрдп рдкреБрд░рд╛рдиреЗ рд╕реНрдХреВрд▓ рдХреЗ рдЦреЗрд▓реЛрдВ рдХреЛ рд▓реЙрдиреНрдЪ рдХрд░рдиреЗ рдХреА рдкрд░реНрдпрд╛рдкреНрдд рд╢рдХреНрддрд┐ рдереАред
CHIP-8 рдХреЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЕрд╕реЗрдВрдмрд▓рд░ рдореЗрдВ рд▓рд┐рдЦреЗ рдЧрдП рд╣реИрдВред рдкреВрд░реА рднрд╛рд╖рд╛ рдореЗрдВ 35 рдХрдорд╛рдВрдб рд╣реЛрддреЗ рд╣реИрдВ - рдЕрдВрдХрдЧрдгрд┐рдд, рд╕рд╢рд░реНрдд / рдмрд┐рдирд╛ рд╢рд░реНрдд рдХреВрдж, рдЗрдирдкреБрдЯ / рдЖрдЙрдЯрдкреБрдЯ (рдкреНрд░рджрд░реНрд╢рди, рдХреАрдмреЛрд░реНрдб, рдзреНрд╡рдирд┐ рдХреЗ рд╕рд╛рде рдХрд╛рдо)ред
рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреА рд╕рдВрд░рдЪрдирд╛
рд╣рдорд╛рд░реЗ рдПрдореБрд▓реЗрдЯрд░ рдореЗрдВ рдПрдХрд▓ c8emu.go рдлрд╝рд╛рдЗрд▓ рд╢рд╛рдорд┐рд▓ рд╣реЛрдЧреА ...
// "" Go package main func main() { }
... рдФрд░ рдореЗрдХрдлрд╛рдЗрд▓:
# Makefile Go include $(GOROOT)/src/Make.inc TARG=c8emu GOFILES=c8emu.go include $(GOROOT)/src/Make.cmd
рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рд╕реНрд░реЛрдд рдХреЛрдб рдХреЛ рд╕рдордЭрдирд╛ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдореБрдЭреЗ рдпрд╛рдж рд╣реИ рдХрд┐:
- рдЧреЛ рдореЗрдВ рдЕрд░реНрдзрд╡рд┐рд░рд╛рдо рд╡реИрдХрд▓реНрдкрд┐рдХ рд╣реИрдВ; рдпрджрд┐ рдХрдерди рднреА рд╡реИрдХрд▓реНрдкрд┐рдХ рд╣реИрдВ / рд╣реИрдВред рдмрд╛рдХреА рднрд╛рд╖рд╛ C / Java рдХреЗ рд╕рдорд╛рди рд╣реИред рдЧреЛ рдореЗрдВ рдЪрд░ рдХреЛ рдХрдИ рддрд░реАрдХреЛрдВ рд╕реЗ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (рд╣рд╛рдВ, рдЙрд▓реНрдЯрд╛ рдмрдирд╛рдо рд╕реА):
var i int
var i int = 0
i := 0
- рдЫреЛрд░реЛрдВ рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ рдПрдХ рдмрдпрд╛рди рд╣реИ - рдХреЗ рд▓рд┐рдП
for i:=0; i<10; i++ { .. }
for cond == true { ... }
for { }
- рдЖрдк рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдПрдХ рдСрдкрд░реЗрдЯрд░ рдореЗрдВ рдЗрд╕рдХрд╛ рдкрд░рд┐рдгрд╛рдо рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ:
if err = DoSomethin(); err != nil { fmt.Println("Error: "+err) }
- рдирд┐рдЬреА / рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рддрд░реАрдХреЗ рдФрд░ рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рдХреЗрд╡рд▓ рдорд╛рдорд▓реЗ рдореЗрдВ рднрд┐рдиреНрди рд╣реЛрддреА рд╣реИрдВ:
someMethod() //
SomeMethod() //
рдмреЗрд╢рдХ, рднрд╛рд╖рд╛ рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рд╣реИрдВ, рдФрд░ рд╡реЗ рд╕рднреА рдЕрд╕рд╛рдорд╛рдиреНрдп рд▓рдЧрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╕рдЦреНрддреА рд╕реЗ рдиреНрдпрд╛рдп рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рднрд╛рд╖рд╛ рдмрд╕ рдЕрд▓рдЧ рд╣реИред
рдЗрд╕рд▓рд┐рдП, CHIP-8 рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдПрдХ рдЙрдкрдпреБрдХреНрдд рд╡рд░реНрдЧ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ (рдЧреЛ рдореЗрдВ рдХреЛрдИ рдХрдХреНрд╖рд╛рдПрдВ рдирд╣реАрдВ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдлрд╝реАрд▓реНрдб рдФрд░ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдВрд░рдЪрдирд╛рдПрдВ рд╣реИрдВ):
type Chip8 struct { memory []byte // memory address is in range: 0x200...0xfff regs [16]byte // CHIP-8 has 16 8-bit registers ireg uint16 // I-reg was a 16-bit register for memory operations stack [16]uint16 // Stack up to 16 levels of nesting sp int // Stack pointer pc uint16 // Program counter }
рдпрд╣ рд╕рдВрд░рдЪрдирд╛ CHIP-8: рдПрдХ рдореЗрдореЛрд░реА рдмреНрд▓реЙрдХ, 16 рдЖрда-рдмрд┐рдЯ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ, рд░рдЬрд┐рд╕реНрдЯрд░-рдкреЙрдЗрдВрдЯрд░ I, 16 рдиреЗрд╕реНрдЯрд┐рдВрдЧ рд╕реНрддрд░реЛрдВ рдХреЗ рдПрдХ рд╕реНрдЯреИрдХ рдХреЗ рд╕рд╛рде-рд╕рд╛рде рдПрдХ рдХрдорд╛рдВрдб рдХрд╛рдЙрдВрдЯрд░ рдФрд░ рд╕реНрдЯреИрдХ рдкреЙрдЗрдВрдЯрд░ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреА рд╣реИред
рдПрдореБрд▓реЗрдЯрд░ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди
рд╣рдорд╛рд░реА CHIP-8 рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо
NewChip8()
рдлрд╝рдВрдХреНрд╢рди
NewChip8()
:
func NewChip8() (c *Chip8) { c = new(Chip8); // c.memory = make([]byte, 0xfff) // "" ( ) c.sp = 0 c.pc = 0x200 // CHIP-8 0x200 c.ireg = 0 // return c }
CHIP-8 рджреБрднрд╛рд╖рд┐рдпрд╛ рдореЗрдВ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛрдб рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд▓реЛрдб () рд╡рд┐рдзрд┐ рд▓рд┐рдЦрддреЗ рд╣реИрдВред рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рддрд░реАрдХреЗ рдХреЛ рд╕рдорд╛рди рд░реВрдк рд╕реЗ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:
func (c *Chip8) Load(rom []byte) (err os.Error) { if len(rom) > len(c.memory) - 0x200 { // len (- ) err = os.NewError("ROM is too large!") // - return } copy(c.memory[0x200:], rom) // 0200 err = nil return }
рдирд┐рд░реНрджреЗрд╢ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг
рдЪрд░рдг () рд╡рд┐рдзрд┐ рдЖрдкрдХреЛ рдПрдХ рдЕрд▓рдЧ CHIP-8 рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИред рд╕рднреА рдирд┐рд░реНрджреЗрд╢ 2-рдмрд╛рдЗрдЯ рд╣реИрдВред рдСрдкрдХреЛрдб рдЕрдзрд┐рдХ рдпрд╛ рдХрдо рд╕рдВрд░рдЪрд┐рдд рд╣реИрдВ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдПрдЖрд░рдПрдо рдореЗрдВ рдмрд┐рд▓реНрдХреБрд▓ рдкрд╕рдВрдж рдирд╣реАрдВ рд╣реИ ... рдореВрд▓ рд░реВрдк рд╕реЗ, рдЖрдк рдХреЛрдб рдХреЗ рдЙрдЪреНрдЪ 4 рдмрд┐рдЯреНрд╕ рджреНрд╡рд╛рд░рд╛ рдиреЗрд╡рд┐рдЧреЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
func (c *Chip8) Step() (err os.Error) { var op uint16 // if (c.pc >= uint16(len(c.memory))) { err = os.EOF return } // op = (uint16(c.memory[c.pc]) << 8) | uint16(c.memory[c.pc + 1]) switch (op & 0xf000) >> 12 { case ... /* */ default: return os.NewError("Illelal instruction") } c.pc += 2 return }
рдЕрдзрд┐рдХрд╛рдВрд╢ рдирд┐рд░реНрджреЗрд╢ рдмрд╣реБрдд рддреБрдЪреНрдЫ рд╣реИрдВ:
// JMP addr - jump to address case 0x1: c.pc = op & 0xfff return // SKEQ reg, value - skip if register equals value case 0x3: if c.regs[(op & 0x0f00) >> 8] == byte(op & 0xff) { c.pc += 2 // skip one instruction } // SKNE reg, value - skip if not equal case 0x4: if c.regs[(op & 0x0f00) >> 8] != byte(op & 0xff) { c.pc += 2 // skip one instruction } // MOV reg, value case 0x6: c.regs[(op & 0x0f00) >> 8] = byte(op & 0xff) // MVI addr - - I case 0xa: c.ireg = op & 0xfff // RAND reg, max - 0..max case 0xc: c.regs[(op & 0x0f00) >> 8] = byte(rand.Intn(int(op & 0xff)))
рдЕрдВрдХрдЧрдгрд┐рдд рдФрд░ рддрд╛рд░реНрдХрд┐рдХ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЛ рдПрдХ рд╣реА рддрд░реАрдХреЗ рд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЙрд▓ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдмрд╛рд╣рд░ рдирд┐рдХрд╛рд▓рдирд╛ рднреА рдмрд╣реБрдд рд╕рд░рд▓ рд▓рдЧрддрд╛ рд╣реИ:
// RET - ( 00EE) case 0x0: switch op & 0xff { case 0xee: c.sp-- c.pc = c.stack[c.sp] return } // CALL addr - case 0x2: c.stack[c.sp] = c.pc + 2 c.sp++ c.pc = op & 0xfff return
рдореИрдВ рдпрд╣рд╛рдВ рд╕рднреА рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдирд╣реАрдВ рдХрд░реВрдВрдЧрд╛ред рдореИрдВ рддреАрди рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд▓реЛрдЧреЛрдВ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░реВрдБрдЧрд╛ (рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рд▓рдЧрднрдЧ рдХрд┐рд╕реА рднреА рдЦреЗрд▓ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ) - рдПрдХ рдЯрд╛рдЗрдорд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдФрд░ рд╕реНрдХреНрд░реАрди рдкрд░ рдЪрд┐рддреНрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдирд╛ред
рдШрдбрд╝реА
рдЯрд╛рдЗрдорд░ 60 рд╣рд░реНрдЯреНрдЬ рдХреА рдЖрд╡реГрддреНрддрд┐ рдкрд░ рд╕рдВрдЪрд╛рд▓рд┐рдд рд╣реЛрддрд╛ рд╣реИ, рдПрдХ рд╕рдВрдЦреНрдпрд╛ (рдПрдХ рдмрд╛рдЗрдЯ) рдЗрд╕рдореЗрдВ рджрд░реНрдЬ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИ, рдФрд░ рдпрд╣ рдкреНрд░рддреНрдпреЗрдХ рдЯрд┐рдХ рдХреЗ рд╕рд╛рде 1 рд╕реЗ рдШрдЯ рдЬрд╛рдПрдЧреАред
рдЯрд╛рдЗрдорд░ рдХреЛ рд╕рдордп-рд╕рдордп рдкрд░ рдкрдврд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЗрд╕рдХреЗ рд▓реЙрдиреНрдЪ рдХреЗ рдмрд╛рдж рд╕реЗ рдХрд┐рддрдиреЗ "рдЯрд┐рдХ" рдмреАрдд рдЪреБрдХреЗ рд╣реИрдВред рд╢реВрдиреНрдп рд╕реЗ рдиреАрдЪреЗ, рдЯрд╛рдЗрдорд░ рдорд╛рди рдирд╣реАрдВ рдЬрд╛ рд╕рдХрддрд╛ред
рдпрд╣рд╛рдБ рдкрд░рд┐рдгрд╛рдо рд╣реИ:
type Timer struct { value byte // start int64 // period int64 // "" } // func NewTimer(hz int) (t *Timer) { t = new(Timer) t.period = int64(1000000000/hz) t.value = 0 return t } // func (t *Timer) Set(value byte) { t.value = value t.start = time.Nanoseconds() } // func (t *Timer) Get() byte { delta := (time.Nanoseconds() - t.start) / t.period if int64(t.value) > delta { return t.value - byte(delta) } return 0 }
рдЪрд┐рдк 8 рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рдПрдХ рдЯрд╛рдЗрдорд░ рдлрд╝реАрд▓реНрдб рдЬреЛрдбрд╝реЗрдВ рдФрд░ рдЪрд┐рдк 8 рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рддреЗ рд╕рдордп рдЗрд╕реЗ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░реЗрдВ:
type Chip8 struct { ... timer *Timer ... } func NewChip8() (c *Chip8) { ... c.timer = NewTimer(60) .. } case 0xf: switch (op & 0xff) { case 0x07: // c.regs[(op & 0x0f00) >> 8] = c.timer.Get() case 0x15: // c.timer.Set(c.regs[(op & 0x0f00) >> 8]) }
рдкреНрд░рджрд░реНрд╢рди
рд╕реНрдХреНрд░реАрди рдкрд░ рдЫрд╡рд┐ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ рдПрдХ рдирд┐рд░реНрджреЗрд╢ рд╣реИред рд╕реАрдПрдЪрдЖрдИрдкреА -8 рдореЗрдВ рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИрдВред рдПрдХ рд╣реА рдЪреМрдбрд╝рд╛рдИ рдХреЗ рд╕рднреА рд╕реНрдкреНрд░рд╛рдЗрдЯреНрд╕ - 8 рдкрд┐рдХреНрд╕реЗрд▓, рдХреЗрд╡рд▓ рдКрдВрдЪрд╛рдИ рдореЗрдВ рднрд┐рдиреНрди рд╣реЛрддреЗ рд╣реИрдВред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдЬреЛ рдПрдХ рдХреНрд░реЙрд╕ рдХреЛ рдЦреАрдВрдЪрддрд╛ рд╣реИ, рдкрд╛рдБрдЪ рдмрд╛рдЗрдЯреНрд╕ рдХреЗ рдЕрдиреБрдХреНрд░рдо рдХреА рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
0x88 ; 10001000 0x50 ; 01010000 0x20 ; 00100000 0x50 ; 01010000 0x88 ; 10001000
рдирд┐рд╖реНрдХрд░реНрд╖ рд╕реЗ рдкрд╣рд▓реЗ, рдЖрдкрдХреЛ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреА рд╢реБрд░реБрдЖрдд рдХреЗ рдкрддреЗ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рддрджрдиреБрд╕рд╛рд░ рд░рдЬрд┐рд╕реНрдЯрд░ I рдХрд╛ рдореВрд▓реНрдп рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдирд╛ред
рд╕реНрдХреНрд░реАрди рдкрд░ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдХрд┐рд╕реА рднреА рджреЛ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдореЗрдВ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рджрд░реНрдЬ рдХрд░рдиреЗ рдФрд░ рдбреНрд░реЙ рдирд┐рд░реНрджреЗрд╢ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреА рдКрдВрдЪрд╛рдИ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рдирд╛ рд╣реИ:
mvi x_sprite mov v0, 10 mov v1, 15 draw v0, v1, 5 ; 5 (10,15) x_sprite: db 0x88, 0x50, 0x20, 0x50, 0x88
рд▓реЗрдХрд┐рди рдбреНрд░рд╛ рд╕рд┐рд░реНрдл рдЖрдХрд░реНрд╖рд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдпрд╣ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдкрд┐рдХреНрд╕рд▓ рдХреЗ рд╕рд╛рде рдореМрдЬреВрджрд╛ рдкрд┐рдХреНрд╕рд▓ рдХреЗ XOR рдмрдирд╛рддрд╛ рд╣реИред рдпрд╣ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ - рдПрдХ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреЛ рдорд┐рдЯрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рдПрдХ рд╣реА рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдореЗрдВ рдмрд╛рд░-рдмрд╛рд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрджрд┐ рдХрд┐рд╕реА рднреА рдкрд┐рдХреНрд╕реЗрд▓ рдХреЛ 0 рдкрд░ рд░реАрд╕реЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рддреЛ vf рд░рдЬрд┐рд╕реНрдЯрд░ (рдЖрдорддреМрд░ рдкрд░ рдПрдХ рдзреНрд╡рдЬ рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ) рдХрд╛ рдорд╛рди рд╕реЗрдЯ рдХрд░реЗрдВред
Chip8 рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ "рд╡реАрдбрд┐рдпреЛ рдмрдлрд░" рдХреА рдПрдХ рд╕рд░рдгреА рдЬреЛрдбрд╝реЗрдВ: рд╕реНрдХреНрд░реАрди [64 * 32] рдмреВрд▓ рдФрд░ рдбреНрд░рд╛рдЗрдВрдЧ рдХреЗ рд▓рд┐рдП рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд▓рд┐рдЦреЗрдВ:
c.regs[0xf] = 0 for col:=0; col<8; col++ { for row:=0; row<int(size); row++ { px := int(x) + col py := int(y) + row bit := (c.memory[c.ireg + uint16(row)] & (1 << uint(col))) != 0 if (px < 64 && py < 32 && px >= 0 && py >= 0) { src := c.screen[py*64 + px] dst := (bit != src) // , XOR c.screen[py*64 + px] = dst if (src && !dst) { c.regs[0xf] = 1 } } } }
рдХрд┐рд╕реА рддрд░рд╣ рдкрд░рд┐рдгрд╛рдореА рдПрдореБрд▓реЗрдЯрд░ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рд╡реАрдбрд┐рдпреЛ рдмрдлрд░ рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рд╕реАрдзреЗ рдЯрд░реНрдорд┐рдирд▓ рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ред рдЗрд╕ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдореЗрд░реЗ рдЖрд╢реНрдЪрд░реНрдп рдХреЗ рд▓рд┐рдП, рдЙрд╕рдиреЗ рдХрдорд╛рдпрд╛ рдФрд░ рдЯрд┐рдХ-рдЯреИрдХ-рдЯреЛ рдЪрд▓рд╛рдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛:
рдЖрдЧреЗ рдХреНрдпрд╛ рд╣реИ?
рджрд░рдЕрд╕рд▓, рдореБрдЭреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ CHIP-8 рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо рдкрд╕рдВрдж рд╣реИред рдХреЛрдИ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд▓рд╛рдн рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдк рдЕрдкрдиреЗ рджрд┐рдорд╛рдЧ рдХреЛ рдЗрд╕ рдкрд░ рдкреНрд░рд╢рд┐рдХреНрд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдореИрдВрдиреЗ c8kit рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╢реБрд░реВ рдХреА - рдореИрдВ рдЗрд╕рдореЗрдВ рдПрдХ рдПрдореБрд▓реЗрдЯрд░, рдЕрд╕реЗрдВрдмрд▓рд░ рдФрд░ рдбрд┐рд╕реНрд╕рдореЗрдВрдмрд▓рд░ рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛ рд░рд╣рд╛ рд╣реВрдВред
рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореБрдЭреЗ рдПрд╕рдбреАрдПрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рдФрд░ рдХреАрдмреЛрд░реНрдб рдХреЛ рдкреЗрдВрдЪ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП (рдЧреЛ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдЗрд╕рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ)ред рдЧреЛ рдЪреИрдирд▓реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдореЙрдбреНрдпреВрд▓ рдФрд░ рд╕реАрдПрдЪрдЖрдИрдкреА -8 рдХреЛрд░ рдХреЛ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдХрд░рдирд╛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛрдЧрд╛ред
рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рджрд┐рд▓рдЪрд╕реНрдк рд╣реЛрдЧрд╛!