Class: Cpu

Inherits:
Object
  • Object
show all
Defined in:
lib/cpu.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(rom) ⇒ Cpu

Returns a new instance of Cpu.



6
7
8
9
10
11
12
# File 'lib/cpu.rb', line 6

def initialize(rom)	
	@ram = [0]*100000
	@ppu = Ppu.new
	#@oam = Oam.new
	prg_start_index = map_rom(rom)
	@cpu = {:Y=>0,:X=>0,:A=>0,:S=>255,:P=>0,:compteur=>prg_start_index,:compteur_new=>prg_start_index}
end

Instance Attribute Details

#cpuObject

Returns the value of attribute cpu.



3
4
5
# File 'lib/cpu.rb', line 3

def cpu
  @cpu
end

#ppuObject

Returns the value of attribute ppu.



4
5
6
# File 'lib/cpu.rb', line 4

def ppu
  @ppu
end

#ramObject

Returns the value of attribute ram.



2
3
4
# File 'lib/cpu.rb', line 2

def ram
  @ram
end

Instance Method Details

#adc(zone, arg1, arg2) ⇒ Object



327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
# File 'lib/cpu.rb', line 327

def adc(zone,arg1,arg2)
	opcode = zone.to_s(16).upcase
	accumulator_temp = @cpu[:A]
	@cpu[:P].bit?(0) == 1 ? valeur_carry = 1 : valeur_carry = 0
	@cpu[:A] = @cpu[:A].int8_plus case opcode
		when "69" then arg1.int8_plus(valeur_carry)
		when "65" then read(arg1).int8_plus(valeur_carry)
		when "75" then read(arg1+@cpu[:X]).int8_plus(valeur_carry)
		when "6D" then read(arg1+(arg2*256)).int8_plus(valeur_carry)
		when "7D" then read(arg1+(arg2*256)+@cpu[:X]).int8_plus(valeur_carry)
		when "79" then read(arg1+(arg2*256)+@cpu[:Y]).int8_plus(valeur_carry)
		when "61" then read(read(arg1+@cpu[:X]) + (read(arg1+@cpu[:X]+1)*256)).int8_plus(valeur_carry)
		when "71" then read(read(arg1)+(read(arg1+1)*256)+@cpu[:Y]).int8_plus(valeur_carry)
	end
	@cpu[:P] = @cpu[:P].clear_bit(0) #clear the carry
	set_overflow(accumulator_temp)
	sign_zero_clear_or_set(@cpu[:A])
end

#and(zone, arg1, arg2) ⇒ Object



155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/cpu.rb', line 155

def and(zone,arg1,arg2)
	opcode = zone.to_s(16).upcase
	@cpu[:A] = @cpu[:A] & case opcode
		when "29" then arg1
		when "25" then read(arg1)
		when "35" then read(arg1+@cpu[:X])
		when "2D" then read(arg1+(arg2*256))
		when "3D" then read(arg1+(arg2*256)+@cpu[:X])
		when "39" then read(arg1+(arg2*256)+@cpu[:Y])
		when "21" then read(read(arg1+@cpu[:X]) + read(arg1+@cpu[:X]+1)*256)
		when "31" then read(read(arg1)+(read(arg1+1)*256)+@cpu[:Y])
	end
	sign_zero_set(@cpu[:A])
end

#asl(zone, arg1, arg2) ⇒ Object



68
69
70
71
72
73
74
75
76
77
# File 'lib/cpu.rb', line 68

def asl(zone,arg1,arg2)
	opcode = zone.to_s(16).upcase
	sign_zero_set_switch case zone
		when 0x0A then @cpu[:A] << 1
		when 0x06 then write(arg1,read(arg1) << 1)
		when 0x16 then write(arg1+@cpu[:X], read(arg1+@cpu[:X]) << 1)
		when 0x0E then write(arg1+(arg2*256),read(arg1+(arg2*256)) << 1)
		when 0x1E then write(arg1+(arg2*256)+@cpu[:X],read(arg1+(arg2*256)+@cpu[:X]) << 1)
	end
end

#bcc(zone, arg1, arg2) ⇒ Object



530
531
532
533
534
# File 'lib/cpu.rb', line 530

def bcc(zone,arg1,arg2)
	if @cpu[:P].bit?(0) == 0
		@cpu[:compteur_new] = @cpu[:compteur_new]+signed(arg1)
	end
end

#bcs(zone, arg1, arg2) ⇒ Object



536
537
538
539
540
# File 'lib/cpu.rb', line 536

def bcs(zone,arg1,arg2)
	if @cpu[:P].bit?(0) == 1
		@cpu[:compteur_new] = @cpu[:compteur_new]+signed(arg1)
	end
end

#beq(zone, arg1, arg2) ⇒ Object



572
573
574
575
576
# File 'lib/cpu.rb', line 572

def beq(zone,arg1,arg2)
	if @cpu[:P].bit?(1) == 1
		@cpu[:compteur_new] = @cpu[:compteur_new]+signed(arg1)
	end
end

#bit(zone, arg1, arg2) ⇒ Object



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/cpu.rb', line 232

def bit(zone,arg1,arg2)
	opcode = zone.to_s(16).upcase
	case opcode
	when "24"
		valeur = read(arg1)
		if valeur.bit?(7) == 0
			@cpu[:P] = @cpu[:P].clear_bit(7) #clear
		else
			@cpu[:P] = @cpu[:P].set_bit(7)	 #set
		end
		if valeur.bit?(6) == 0
			@cpu[:P] = @cpu[:P].clear_bit(6) #clear
		else
			@cpu[:P] = @cpu[:P].set_bit(6)	 #set
		end
		if valeur & @cpu[:A] == 0
			@cpu[:P] = @cpu[:P].set_bit(1)	 #set
		else
			@cpu[:P] = @cpu[:P].clear_bit(1) #clear
		end
	when "2C"
		valeur = read(arg1+(arg2*256))	
		if valeur.bit?(7) == 0
			@cpu[:P] = @cpu[:P].clear_bit(7) #clear
		else
			@cpu[:P] = @cpu[:P].set_bit(7)	 #set
		end
		if valeur.bit?(6) == 0
			@cpu[:P] = @cpu[:P].clear_bit(6) #clear
		else
			@cpu[:P] = @cpu[:P].set_bit(6)	 #set
		end
		if valeur & @cpu[:A] == 0
			@cpu[:P] = @cpu[:P].set_bit(1) 	 #set
		else
			@cpu[:P] = @cpu[:P].clear_bit(1) #clear
		end
	end
end

#bmi(zone, arg1, arg2) ⇒ Object



560
561
562
563
564
# File 'lib/cpu.rb', line 560

def bmi(zone,arg1,arg2)
	if @cpu[:P].bit?(7) == 1
		@cpu[:compteur_new] = @cpu[:compteur_new]+signed(arg1)
	end
end

#bne(zone, arg1, arg2) ⇒ Object



566
567
568
569
570
# File 'lib/cpu.rb', line 566

def bne(zone,arg1,arg2)
	if @cpu[:P].bit?(1) == 0
		@cpu[:compteur_new] = @cpu[:compteur_new]+signed(arg1)
	end
end

#bpl(zone, arg1, arg2) ⇒ Object



554
555
556
557
558
# File 'lib/cpu.rb', line 554

def bpl(zone,arg1,arg2)
	if @cpu[:P].bit?(7) == 0
		@cpu[:compteur_new] = @cpu[:compteur_new]+signed(arg1)
	end
end

#brk(x, y, z) ⇒ Object



302
303
304
305
306
307
308
309
310
311
312
313
314
# File 'lib/cpu.rb', line 302

def brk(x,y,z)
#Interruption push d'abord l'octet de poids fort ensuite octet de pds faible ensuite le status
	bytefort = @cpu[:compteur_new] >> 8
	bytefaible = @cpu[:compteur_new] & 0x00FF
	@ram[@cpu[:S]+0x100] = bytefort # octet de poids fort
	@cpu[:S] -= 1 #decrementation pour la prochaine valeur
	@ram[@cpu[:S]+0x100] = bytefaible #octet de poids faible
	@cpu[:S] -= 1
	@ram[@cpu[:S]+0x100] = @cpu[:P] #status
	@cpu[:S] -= 1
	@cpu[:compteur_new] = read(0xFFFE)+(read(0xFFFF)*256)
	@cpu[:P] = @cpu[:P].set_bit(4)
end

#bvc(zone, arg1, arg2) ⇒ Object



542
543
544
545
546
# File 'lib/cpu.rb', line 542

def bvc(zone,arg1,arg2)
	if @cpu[:P].bit?(6) == 0
		@cpu[:compteur_new] = @cpu[:compteur_new]+signed(arg1)
	end
end

#bvs(zone, arg1, arg2) ⇒ Object



548
549
550
551
552
# File 'lib/cpu.rb', line 548

def bvs(zone,arg1,arg2)
	if @cpu[:P].bit?(6) == 1
		@cpu[:compteur_new] = @cpu[:compteur_new]+signed(arg1)
	end
end

#clc(x, y, z) ⇒ Object



201
202
203
# File 'lib/cpu.rb', line 201

def clc(x,y,z)
	@cpu[:P] = @cpu[:P].clear_bit(0)
end

#cld(x, y, z) ⇒ Object



221
222
223
# File 'lib/cpu.rb', line 221

def cld(x,y,z)
	@cpu[:P] = @cpu[:P].clear_bit(3)
end

#cli(x, y, z) ⇒ Object



209
210
211
# File 'lib/cpu.rb', line 209

def cli(x,y,z)
	@cpu[:P] = @cpu[:P].clear_bit(2)
end

#clv(x, y, z) ⇒ Object



217
218
219
# File 'lib/cpu.rb', line 217

def clv(x,y,z)
	@cpu[:P] = @cpu[:P].clear_bit(6)
end

#cmp(zone, arg1, arg2) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/cpu.rb', line 54

def cmp(zone,arg1,arg2)
	opcode = zone.to_s(16).upcase
	sign_zero_carry @cpu[:A].int8_minus signed case opcode
		when "C9" then arg1
		when "C5" then read(arg1)
		when "D5" then read(arg1+@cpu[:X])
		when "CD" then read(arg1+(arg2*256))
		when "DD" then read(arg1+(arg2*256)+@cpu[:X])
		when "D9" then read(arg1+(arg2*256)+@cpu[:Y])
		when "C1" then read(read(arg1+@cpu[:X]) + (read(arg1+@cpu[:X]+1)*256))
		when "D1" then read(read(arg1)+(read(arg1+1)*256)+@cpu[:Y])
	end
end

#cpx(zone, arg1, arg2) ⇒ Object



135
136
137
138
139
140
141
142
# File 'lib/cpu.rb', line 135

def cpx(zone,arg1,arg2)
	opcode = zone.to_s(16).upcase
	sign_zero_carry @cpu[:X].int8_minus signed case opcode
		when "E0" then arg1
		when "E4" then read(arg1)
		when "EC" then read(arg1+(arg2*256))
	end	
end

#cpy(zone, arg1, arg2) ⇒ Object



144
145
146
147
148
149
150
151
152
# File 'lib/cpu.rb', line 144

def cpy(zone,arg1,arg2)
	opcode = zone.to_s(16).upcase
	sign_zero_carry @cpu[:Y].int8_minus signed case opcode
		when "C0" then arg1
		when "C4" then read(arg1)
		when "CC" then read(arg1+(arg2*256))
	end	

end

#dec(zone, arg1, arg2) ⇒ Object



365
366
367
368
369
370
371
372
373
# File 'lib/cpu.rb', line 365

def dec(zone,arg1,arg2)
	opcode = zone.to_s(16).upcase
	sign_zero_clear_or_set case opcode
		when "C6" then write(arg1,read(arg1).int8_minus(1))
		when "D6" then write(arg1+@cpu[:X],read(arg1+@cpu[:X]).int8_minus(1))
		when "CE" then write(arg1+(arg2*256),read(arg1+(arg2*256)).int8_minus(1))
		when "DE" then write(arg1+(arg2*256)+@cpu[:X],read(arg1+(arg2*256)+@cpu[:X]).int8_minus(1))
	end
end

#dex(x, y, z) ⇒ Object



471
472
473
474
# File 'lib/cpu.rb', line 471

def dex(x,y,z)
	@cpu[:X] = @cpu[:X].int8_minus(1)
	sign_zero_clear_or_set(@cpu[:X])
end

#dey(x, y, z) ⇒ Object



491
492
493
494
# File 'lib/cpu.rb', line 491

def dey(x,y,z)
	@cpu[:Y] = @cpu[:Y].int8_minus(1)
	sign_zero_clear_or_set(@cpu[:Y])
end

#eor(zone, arg1, arg2) ⇒ Object



170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/cpu.rb', line 170

def eor(zone,arg1,arg2)
	opcode = zone.to_s(16).upcase
	@cpu[:A] = @cpu[:A] ^ case opcode
		when "49" then arg1
		when "45" then read(arg1)
		when "55" then read(arg1+@cpu[:X])
		when "4D" then read(arg1+(arg2*256))
		when "5D" then read(arg1+(arg2*256)+@cpu[:X])
		when "59" then read(arg1+(arg2*256)+@cpu[:Y])
		when "41" then read(read(arg1+@cpu[:X]) + read(arg1+@cpu[:X]+1)*256)
		when "51" then read(read(arg1)+(read(arg1+1)*256)+@cpu[:Y])
	end
	sign_zero_set(@cpu[:A])
end

#inc(zone, arg1, arg2) ⇒ Object



375
376
377
378
379
380
381
382
383
# File 'lib/cpu.rb', line 375

def inc(zone,arg1,arg2)
	opcode = zone.to_s(16).upcase
	sign_zero_clear_or_set case opcode
		when "E6" then write(arg1,read(arg1).int8_plus(1))
		when "F6" then write(arg1+@cpu[:X],read(arg1+@cpu[:X]).int8_plus(1))
		when "EE" then write(arg1+(arg2*256),read(arg1+(arg2*256)).int8_plus(1))
		when "FE" then write(arg1+(arg2*256)+@cpu[:X],read(arg1+(arg2*256)+@cpu[:X]).int8_plus(1))
	end
end

#inx(x, y, z) ⇒ Object



476
477
478
479
# File 'lib/cpu.rb', line 476

def inx(x,y,z)
	@cpu[:X] = @cpu[:X].int8_plus(1)
	sign_zero_clear_or_set(@cpu[:X])
end

#iny(x, y, z) ⇒ Object



496
497
498
499
# File 'lib/cpu.rb', line 496

def iny(x,y,z)
	@cpu[:Y] = @cpu[:Y].int8_plus(1)
	sign_zero_clear_or_set(@cpu[:Y])
end

#jmp(zone, arg1, arg2) ⇒ Object



319
320
321
322
323
324
325
# File 'lib/cpu.rb', line 319

def jmp(zone,arg1,arg2)
	opcode = zone.to_s(16).upcase
	@cpu[:compteur_new] = case opcode
		when "4C" then arg1+(arg2*256)
		when "6C" then read(arg1+(arg2*256))+(read(arg1+(arg2*256)+1)*256)
	end
end

#jsr(zone, arg1, arg2) ⇒ Object

Rappel : dans 0xC0E1 , C0 est l’octet de poids fort et E1 celui de poids faible



275
276
277
278
279
280
281
282
283
284
# File 'lib/cpu.rb', line 275

def jsr(zone,arg1,arg2)
	adresse = @cpu[:compteur_new] -1
	bytefort = adresse >> 8 #byte fort
	bytefaible = adresse & 0x00FF #byte faible
	@ram[@cpu[:S]+0x100] = bytefort # adresse actuelle
	@cpu[:S] -= 1 #decrementation pour la prochaine valeur
	@ram[@cpu[:S]+0x100] = bytefaible
	@cpu[:S] -= 1
	@cpu[:compteur_new] = arg1+(arg2*256)
end

#lda(zone, arg1, arg2) ⇒ Object



385
386
387
388
389
390
391
392
393
394
395
396
397
398
# File 'lib/cpu.rb', line 385

def lda(zone,arg1,arg2)
	opcode = zone.to_s(16).upcase
	@cpu[:A] = case opcode
		when "A9" then arg1
		when "A5" then read(arg1)
		when "B5" then read(arg1+@cpu[:X])
		when "AD" then read(arg1+(arg2*256))
		when "BD" then read(arg1+(arg2*256)+@cpu[:X])
		when "B9" then read(arg1+(arg2*256)+@cpu[:Y])
		when "A1" then read(read(arg1+@cpu[:X]) + (read(arg1+@cpu[:X]+1)*256))
		when "B1" then read(read(arg1)+(read(arg1+1)*256)+@cpu[:Y])
	end
	sign_zero_set(@cpu[:A])
end

#ldx(zone, arg1, arg2) ⇒ Object



400
401
402
403
404
405
406
407
408
409
410
# File 'lib/cpu.rb', line 400

def ldx(zone,arg1,arg2)
	opcode = zone.to_s(16).upcase
	@cpu[:X] = case opcode
		when "A2" then arg1
		when "A6" then read(arg1)
		when "B6" then read(arg1+@cpu[:Y])
		when "AE" then read(arg1+(arg2*256))
		when "BE" then read(arg1+(arg2*256)+@cpu[:Y])
	end
	sign_zero_set(@cpu[:X])
end

#ldy(zone, arg1, arg2) ⇒ Object



412
413
414
415
416
417
418
419
420
421
422
# File 'lib/cpu.rb', line 412

def ldy(zone,arg1,arg2)
	opcode = zone.to_s(16).upcase
	@cpu[:Y] = case opcode
		when "A0" then arg1
		when "A4" then read(arg1)
		when "B4" then read(arg1+@cpu[:X])
		when "AC" then read(arg1+(arg2*256))
		when "BC" then read(arg1+(arg2*256)+@cpu[:X])
	end
	sign_zero_set(@cpu[:Y])
end

#lsr(zone, arg1, arg2) ⇒ Object



121
122
123
124
125
126
127
128
129
130
# File 'lib/cpu.rb', line 121

def lsr(zone,arg1,arg2)
	opcode = zone.to_s(16).upcase
	sign_zero_set_switch case opcode
		when "4A" then @cpu[:A] = @cpu[:A] >> 1
		when "46" then write(arg1,read(arg1) >> 1)
		when "56" then write(arg1+@cpu[:X], read(arg1+@cpu[:X]) >> 1)
		when "4E" then write(arg1+(arg2*256),read(arg1+(arg2*256)) >> 1)
		when "5E" then write(arg1+(arg2*256)+@cpu[:X], read(arg1+(arg2*256)+@cpu[:X]) >> 1)
	end
end

#map_rom(rom) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/cpu.rb', line 14

def map_rom(rom)
	header = rom.shift(16)
	if header[4] == 1
		prg_start_index = 0xC000 #Index de mappage de la PRG (- de 16Ko de PRG)
	else
		prg_start_index = 0x8000 #Index de mappage de la PRG (+ de 16Ko de PRG)
	end
	if header[6].bit?(2) == 1
		trainer = rom.shift(512)
		@ram[0x7000,trainer.length] = trainer # Mapping du trainer dans la RAM
	end
	prg_rom = rom.shift(header[4]*16384)
	chr_rom = rom.shift(header[5]*8192)
	@ppu.ppu[0,chr_rom.length] = chr_rom
	@ram[prg_start_index,prg_rom.length] = prg_rom # Mapping de la PRG dans la RAM
	return prg_start_index
end

#nmi_interruptObject



33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/cpu.rb', line 33

def nmi_interrupt()
	bytefort = @cpu[:compteur_new] >> 8
	bytefaible = @cpu[:compteur_new] & 0x00FF
	@ram[@cpu[:S]+0x100] = bytefort # octet de poids fort
	@cpu[:S] -= 1 #decrementation pour la prochaine valeur
	@ram[@cpu[:S]+0x100] = bytefaible #octet de poids faible
	@cpu[:S] -= 1
	@ram[@cpu[:S]+0x100] = @cpu[:P] #status
	@cpu[:S] -= 1
	@cpu[:compteur_new] = read(0xFFFA)+(read(0xFFFB)*256)
	@cpu[:P] = @cpu[:P].set_bit(2)
end

#nop(x, y, z) ⇒ Object



229
230
# File 'lib/cpu.rb', line 229

def nop(x,y,z)
end

#ora(zone, arg1, arg2) ⇒ Object



186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/cpu.rb', line 186

def ora(zone,arg1,arg2)
	@cpu[:A] |= case zone
		when 0x09 then arg1
		when 0x05 then read(arg1)
		when 0x15 then read(arg1+@cpu[:X])
		when 0x0D then read(arg1+(arg2*256))
		when 0x1D then read(arg1+(arg2*256)+@cpu[:X])
		when 0x19 then read(arg1+(arg2*256)+@cpu[:Y])
		when 0x01 then read(read(arg1+@cpu[:X]) + read(arg1+@cpu[:X]+1)*256)
		when 0x11 then read(read(arg1)+(read(arg1+1)*256)+@cpu[:Y])
	end
	sign_zero_set(@cpu[:A])
end

#pha(x, y, z) ⇒ Object



509
510
511
512
# File 'lib/cpu.rb', line 509

def pha(x,y,z)
	@ram[@cpu[:S]+0x100] = @cpu[:A]
	@cpu[:S] -= 1
end

#php(x, y, z) ⇒ Object



316
317
# File 'lib/cpu.rb', line 316

def php(x,y,z)
end

#pla(x, y, z) ⇒ Object



514
515
516
517
# File 'lib/cpu.rb', line 514

def pla(x,y,z)
	@cpu[:A] = @ram[@cpu[:S]+1+0x100]	#dernier elem
	@cpu[:S] += 1
end

#plp(x, y, z) ⇒ Object



524
525
526
527
528
# File 'lib/cpu.rb', line 524

def plp(x,y,z)
	@cpu[:A] = @ram[@cpu[:S]+1+0x100]
	@cpu[:S] += 1	

end

#read(adresse) ⇒ Object



645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
# File 'lib/cpu.rb', line 645

def read(adresse)

	case adresse
		when 0x2007
			@ppu.registers[0x2000].bit?(2) ==1 ? @pointeur_2006+=32 : @pointeur_2006+=1

	
		when 0x2004
			@ppu.registers[0x2003] =  @ppu.registers[0x2003].int8_plus(1)
	end

	if Registers.include?(adresse)
		return @ppu.registers[adresse]
	else
		return @ram[adresse]
	end
end

#reset_romObject



48
49
50
51
# File 'lib/cpu.rb', line 48

def reset_rom()
	reset_address = @ram[0xFFFC]+(@ram[0xFFFD]*256)
	@cpu[:compteur] = @cpu[:compteur_new] = reset_address
end

#rol(zone, arg1, arg2) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
# File 'lib/cpu.rb', line 79

def rol(zone,arg1,arg2)
	opcode = zone.to_s(16).upcase
	sign_zero_set case opcode
		when "2A" then @cpu[:A] = rotate_left(@cpu[:A])
		when "26" then write(arg1,rotate_left(read(arg1)))
		when "36" then write(arg1+@cpu[:X], rotate_left(read(arg1+@cpu[:X])))
		when "2E" then write(arg1+(arg2*256), rotate_left(read(arg1+(arg2*256))))
		when "3E" then write(arg1+(arg2*256)+@cpu[:X], rotate_left(read(arg1+(arg2*256)+@cpu[:X])))
	end

end

#ror(zone, arg1, arg2) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
# File 'lib/cpu.rb', line 91

def ror(zone,arg1,arg2)
	opcode = zone.to_s(16).upcase
	sign_zero_set case opcode
		when "6A" then @cpu[:A] = rotate_right(@cpu[:A])
		when "66" then write(arg1,rotate_right(read(arg1)))
		when "76" then write(arg1+@cpu[:X], rotate_right(read(arg1+@cpu[:X])))
		when "6E" then write(arg1+(arg2*256), rotate_right(read(arg1+(arg2*256))))
		when "7E" then write(arg1+(arg2*256)+@cpu[:X], rotate_right(read(arg1+(arg2*256)+@cpu[:X])))
	end

end

#rotate_left(byte) ⇒ Object



103
104
105
106
107
108
109
# File 'lib/cpu.rb', line 103

def rotate_left(byte)
	byte.bit?(7) == 1 ? @cpu[:P] = @cpu[:P].set_bit(0) : @cpu[:P] = @cpu[:P].clear_bit(0)
	@cpu[:P].bit?(0) == 1 ? byte = ((byte << 1)&0xFF)| 1 : byte = ((byte << 1)&0xFF)| 0
	@cpu[:P] = @cpu[:P].clear_bit(0) if byte.bit?(7) == 0 #clear carry
	@cpu[:P] = @cpu[:P].set_bit(0) if byte.bit?(7) == 1 #set carry
	return byte
end

#rotate_right(byte) ⇒ Object



111
112
113
114
115
116
117
# File 'lib/cpu.rb', line 111

def rotate_right(byte)
	byte.bit?(0) == 1 ? @cpu[:P] = @cpu[:P].set_bit(0) : @cpu[:P] = @cpu[:P].clear_bit(0)
	@cpu[:P].bit?(0) ==1 ? byte = (byte >> 1)| 128 : byte = (byte >> 1)| 0
	@cpu[:P] = @cpu[:P].clear_bit(0) if byte.bit?(0) == 0 #clear carry
	@cpu[:P] = @cpu[:P].set_bit(0) if byte.bit?(0)==1 #set carry
	return byte
end

#rti(zone, arg1, arg2) ⇒ Object



293
294
295
296
297
298
299
300
# File 'lib/cpu.rb', line 293

def rti(zone,arg1,arg2)
	bytefort = @ram[@cpu[:S]+3+0x100]
	bytefaible = @ram[@cpu[:S]+2+0x100]
	status = @ram[@cpu[:S]+1+0x100]
	@cpu[:compteur_new] = bytefaible+(bytefort*256)
	@cpu[:P] = status #récup du status
	@cpu[:S]+=3 # pour ecraser l'adresse précédente sur 3x8bits
end

#rts(zone, arg1, arg2) ⇒ Object



286
287
288
289
290
291
# File 'lib/cpu.rb', line 286

def rts(zone,arg1,arg2)
	bytefaible = @ram[@cpu[:S]+1+0x100]
	bytefort = @ram[@cpu[:S]+2+0x100]
	@cpu[:compteur_new] = bytefaible+(bytefort*256) +1
	@cpu[:S]+=2 # pour ecraser l'adresse précédente sur 2x8bits
end

#sbc(zone, arg1, arg2) ⇒ Object



346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
# File 'lib/cpu.rb', line 346

def sbc(zone,arg1,arg2)
	opcode = zone.to_s(16).upcase
	accumulator_temp = @cpu[:A]
	@cpu[:P].bit?(0) == 1 ? valeur_carry = 1 : valeur_carry = 0
	@cpu[:A] = @cpu[:A].int8_minus case opcode
		when "E9" then arg1.int8_minus(valeur_carry)
		when "E5" then read(arg1).int8_minus(valeur_carry)
		when "F5" then read(arg1+@cpu[:X]).int8_minus(valeur_carry)
		when "ED" then read(arg1+(arg2*256)).int8_minus(valeur_carry)
		when "FD" then read(arg1+(arg2*256)+@cpu[:X]).int8_minus(valeur_carry)
		when "F9" then read(arg1+(arg2*256)+@cpu[:Y]).int8_minus(valeur_carry)
		when "E1" then read(read(arg1+@cpu[:X]) + (read(arg1+@cpu[:X]+1)*256)).int8_minus(valeur_carry)
		when "F1" then read(read(arg1)+(read(arg1+1)*256)+@cpu[:Y]).int8_minus(valeur_carry)
	end
	@cpu[:P] = @cpu[:P].set_bit(0) #set the carry
	set_overflow(accumulator_temp)
	sign_zero_clear_or_set(@cpu[:A])
end

#sec(x, y, z) ⇒ Object



205
206
207
# File 'lib/cpu.rb', line 205

def sec(x,y,z)
	@cpu[:P] = @cpu[:P].set_bit(0)
end

#sed(x, y, z) ⇒ Object



225
226
227
# File 'lib/cpu.rb', line 225

def sed(x,y,z)
	@cpu[:P] = @cpu[:P].set_bit(3)
end

#sei(x, y, z) ⇒ Object



213
214
215
# File 'lib/cpu.rb', line 213

def sei(x,y,z)
	@cpu[:P] = @cpu[:P].set_bit(2)
end

#set_overflow(byte) ⇒ Object



579
580
581
582
583
# File 'lib/cpu.rb', line 579

def set_overflow(byte)
	if @cpu[:A].bit?(6) != byte.bit?(6)
		@cpu[:P] = @cpu[:P].set_bit(6)
	end
end

#sign_zero_carry(byte) ⇒ Object



586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
# File 'lib/cpu.rb', line 586

def sign_zero_carry(byte)
	if byte & 0x80 == 0
		@cpu[:P] = @cpu[:P].set_bit(0)
		@cpu[:P] = @cpu[:P].clear_bit(7)
		@cpu[:P] = @cpu[:P].clear_bit(1)
	elsif byte == 0
		@cpu[:P] = @cpu[:P].set_bit(0)
		@cpu[:P] = @cpu[:P].clear_bit(7)
		@cpu[:P] = @cpu[:P].set_bit(1)
	elsif byte & 0x80 != 0
		@cpu[:P] = @cpu[:P].clear_bit(0)
		@cpu[:P] = @cpu[:P].set_bit(7)
		@cpu[:P] = @cpu[:P].clear_bit(1)
	end
end

#sign_zero_clear_or_set(byte) ⇒ Object

Clears or sets flag



602
603
604
605
606
607
608
609
610
611
612
613
614
# File 'lib/cpu.rb', line 602

def sign_zero_clear_or_set(byte) #Clears or sets flag 
	if byte==0
		@cpu[:P] = @cpu[:P].set_bit(1)
	else
		@cpu[:P] = @cpu[:P].clear_bit(1)
	end

	if byte & 0x80 == 0
		@cpu[:P] = @cpu[:P].clear_bit(7)
	else
		@cpu[:P] = @cpu[:P].set_bit(7)
	end
end

#sign_zero_set(byte) ⇒ Object

Only sets flag ( in case of load or store instruction )



616
617
618
619
620
621
622
623
624
625
626
# File 'lib/cpu.rb', line 616

def sign_zero_set(byte) #Only sets flag ( in case of load or store instruction )
	if byte==0
		@cpu[:P] = @cpu[:P].set_bit(1)
	else 
		@cpu[:P] = @cpu[:P].clear_bit(1)
	end

	if byte & 0x80 != 0
		@cpu[:P] = @cpu[:P].set_bit(7)
	end
end

#sign_zero_set_switch(byte) ⇒ Object

S_z_set, mais avec le petit bonus “Carry” pour les opcodes de switch !



628
629
630
631
632
633
634
635
636
637
# File 'lib/cpu.rb', line 628

def sign_zero_set_switch(byte) # S_z_set, mais avec le petit bonus "Carry" pour les opcodes de switch !
	if byte==0
		@cpu[:P] = @cpu[:P].set_bit(1)
	end
	if byte & 0x80 != 0
		@cpu[:P] = @cpu[:P].set_bit(7)
		@cpu[:P] = @cpu[:P].set_bit(0) #set carry
	end
	@cpu[:P] = @cpu[:P].clear_bit(0) if byte & 0x80 == 0 #clear carry
end

#sta(zone, arg1, arg2) ⇒ Object



425
426
427
428
429
430
431
432
433
434
435
436
437
# File 'lib/cpu.rb', line 425

def sta(zone,arg1,arg2)
	opcode = zone.to_s(16).upcase
	case opcode
		when "85" then write(arg1,@cpu[:A])
		when "95" then write(arg1+@cpu[:X],@cpu[:A])
		when "8D" then write(arg1+(arg2*256),@cpu[:A])
		when "9D" then write(arg1+(arg2*256)+@cpu[:X], @cpu[:A])
		when "99" then write(arg1+(arg2*256)+@cpu[:Y], @cpu[:A])
		when "81" then write(read(read(arg1+@cpu[:X]) + (read(arg1+@cpu[:X]+1)*256)),@cpu[:A])
		when "91" then write(read(read(arg1)+(read(arg1+1)*256)+@cpu[:Y]), @cpu[:A])
	end
	sign_zero_set(@cpu[:A])
end

#stx(zone, arg1, arg2) ⇒ Object



439
440
441
442
443
444
445
446
447
# File 'lib/cpu.rb', line 439

def stx(zone,arg1,arg2)
	opcode = zone.to_s(16).upcase
	case opcode
		when "86" then write(arg1, @cpu[:X])
		when "96" then write(arg1+@cpu[:Y], @cpu[:X])
		when "8E" then write(arg1+(arg2*256),@cpu[:X])
	end
	sign_zero_set(@cpu[:X])
end

#sty(zone, arg1, arg2) ⇒ Object



449
450
451
452
453
454
455
456
457
# File 'lib/cpu.rb', line 449

def sty(zone,arg1,arg2)
	opcode = zone.to_s(16).upcase
	case opcode
		when "84" then write(arg1, @cpu[:Y])
		when "94" then write(arg1+@cpu[:X], @cpu[:Y])
		when "8C" then write(arg1+(arg2*256),@cpu[:Y])
	end
	sign_zero_set(@cpu[:Y])
end

#tax(x, y, z) ⇒ Object



461
462
463
464
# File 'lib/cpu.rb', line 461

def tax(x,y,z)
	@cpu[:X] = @cpu[:A]
	sign_zero_set(@cpu[:X])
end

#tay(x, y, z) ⇒ Object



481
482
483
484
# File 'lib/cpu.rb', line 481

def tay(x,y,z)
	@cpu[:Y] = @cpu[:A]
	sign_zero_set(@cpu[:Y])
end

#tsx(x, y, z) ⇒ Object



505
506
507
# File 'lib/cpu.rb', line 505

def tsx(x,y,z)
	@cpu[:X] = @cpu[:S]
end

#txa(x, y, z) ⇒ Object



466
467
468
469
# File 'lib/cpu.rb', line 466

def txa(x,y,z)
	@cpu[:A] = @cpu[:X]
	sign_zero_set(@cpu[:A])
end

#txs(x, y, z) ⇒ Object



501
502
503
# File 'lib/cpu.rb', line 501

def txs(x,y,z)
	@cpu[:S] = @cpu[:X]
end

#tya(x, y, z) ⇒ Object



486
487
488
489
# File 'lib/cpu.rb', line 486

def tya(x,y,z)
	@cpu[:A] = @cpu[:Y]
	sign_zero_set(@cpu[:A])
end

#write(adresse, value) ⇒ Object



665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
# File 'lib/cpu.rb', line 665

def write(adresse,value)

	case adresse 
		when 0x2007
			print value
			@ppu.ppu[@pointeur_2006] = value
		
			@ppu.registers[0x2000].bit?(2) ==1 ? @pointeur_2006+=32 : @pointeur_2006+=1
	
		when 0x2006
			if @pointeur_2006==nil
				@pointeur_2006 = value
			elsif @pointeur_2006 <= 0xFF
				@pointeur_2006 = value + (@pointeur_2006 *256) ###CA VIENDRAIT DE Là 
			elsif @pointeur_2006 > 0xFF
				@pointeur_2006 = value
			end
			until @pointeur_2006.between?(0,0x3FFF)
				@pointeur_2006 -= 0x4000
			end


		when 0x2004
			@OAM[@ppu.registers[0x2003]] = value
			@ppu.registers[0x2003] = @ppu.registers[0x2003].int8_plus(1)

		when 0x4014
			@OAM = @ram[value*0x100..(value*0x100)+0xFF]
	end

	if Registers.include?(adresse)
		@ppu.registers[adresse] = value
		return @ppu.registers[adresse]
	else
		@ram[adresse] = value
		return @ram[adresse]
	end

end