рднрд╛рд╖рд╛ рдЬрд╛рдУред рд╣рдо CHIP-8 рдПрдореБрд▓реЗрдЯрд░ рд▓рд┐рдЦрддреЗ рд╣реИрдВ

рдЧреЛ рдиреЗ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдЕрдкрдиреЗ рдЬреАрд╡рди рдХрд╛ рдкрд╣рд▓рд╛ рд╡рд░реНрд╖ рдордирд╛рдпрд╛ рд╣реИред рджреБрднрд╛рд╖рд┐рдпрд╛ рд╕реАрдПрдЪрдЖрдИрдкреА -8 рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЪрд╛рд▓реАрд╕ рдХреЗ рдиреАрдЪреЗ рдорд╛рд░рд╛ред

рдпрд╣ рдкреЛрд╕реНрдЯ рдирдИ рднрд╛рд╖рд╛рдУрдВ рдФрд░ рдкреБрд░рд╛рдиреЗ рд╣рд╛рд░реНрдбрд╡реЗрдпрд░ рдХреЗ рдкреНрд░рд╢рдВрд╕рдХреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдкрд┐рдд рд╣реИ - рдЗрд╕рдореЗрдВ рд╣рдо рдЧреЛ рдореЗрдВ 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
      
      





рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рд╕реНрд░реЛрдд рдХреЛрдб рдХреЛ рд╕рдордЭрдирд╛ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдореБрдЭреЗ рдпрд╛рдж рд╣реИ рдХрд┐:



рдмреЗрд╢рдХ, рднрд╛рд╖рд╛ рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рд╣реИрдВ, рдФрд░ рд╡реЗ рд╕рднреА рдЕрд╕рд╛рдорд╛рдиреНрдп рд▓рдЧрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╕рдЦреНрддреА рд╕реЗ рдиреНрдпрд╛рдп рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рднрд╛рд╖рд╛ рдмрд╕ рдЕрд▓рдЧ рд╣реИред



рдЗрд╕рд▓рд┐рдП, 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 рдХреЛрд░ рдХреЛ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдХрд░рдирд╛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛрдЧрд╛ред

рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рджрд┐рд▓рдЪрд╕реНрдк рд╣реЛрдЧрд╛!



All Articles