@@ -24,317 +24,32 @@ public class Chip8 {
2424 private static Cpu cpu ;
2525 private static Display display ;
2626 private static Keyboard keyboard ;
27+ private static ProcesingUnit pu ;
2728 private static Sprite sprites ;
2829
2930 public static void main (String [] args ) throws InterruptedException {
3031
3132 cpu = new Cpu ();
3233 display = new Display ();
3334 keyboard = new Keyboard ();
35+ pu = new ProcesingUnit (cpu , keyboard , display );
3436 sprites = new Sprite ();
3537
38+
3639 init ();
3740 loadRom ();
3841 //cpu.dumpMemory();
3942 prepareGUI ();
43+
4044 boolean end = false ;
4145
46+
4247 while (!end ) {
43- int opcode = (int ) ((((cpu .memory [cpu .pc ] & 0xFF ) << 8 ) + (cpu .memory [cpu .pc +1 ] & 0xFF )) & 0xFFFF );
44- short nnn = (short ) (opcode & 0xFFF );
45- short kk = (short ) (opcode & 0xFF );
46- short n = (short ) (opcode & 0xF );
47- short x = (short ) (opcode >> 8 & 0xF );
48- short y = (short ) (opcode >> 4 & 0xF );
49- short msb = (short ) (opcode >> 12 & 0xF );
50- /*
51- System.out.println("opcode: " + String.format("0x%04X",opcode));
52- System.out.println("nnn: " + String.format("%03X",nnn));
53- System.out.println("kk: " + String.format("%02X",kk));
54- System.out.println("n: " + String.format("%01X",n));
55- System.out.println("x: " + String.format("%01X",x));
56- System.out.println("y: " + String.format("%01X",y));
57- System.out.println("msb: " + String.format("%01X",msb));
58- */
59-
60-
61- switch (msb ) {
62- case 0 :
63- if (n ==0x0 )
64- if (opcode ==0x00E0 ) {
65- for (int i = 0 ; i < cpu .screen .length ; i ++){
66- cpu .screen [i ] = 0x0 ; //CLS
67- }
68-
69- } else if (opcode ==0X00EE ) {
70- cpu .pc = cpu .sp --;
71- //cpu.sp = (short) (cpu.sp - 0x01);
72- }
73- break ;
74-
75- case 1 : cpu .pc = (short ) (nnn & 0x0FFF ); break ;
76-
77- case 2 :
78- if (cpu .sp < 16 ) {
79- cpu .stack [++cpu .sp ] = cpu .pc ;
80- }
81- cpu .pc = nnn ;
82- break ;
83-
84- case 3 :
85- if (cpu .v [x ] == kk ) {
86- cpu .pc += 0x0002 ;
87- }
88- break ;
89-
90- case 4 :
91- if (cpu .v [x ] != kk ) {
92- cpu .pc += 0x0002 ;
93- }
94- break ;
95-
96- case 5 :
97- if (cpu .v [x ] == cpu .v [y ]) {
98- cpu .pc += 0x0002 ;
99- }
100- break ;
101-
102- case 6 :
103- cpu .v [x ] = (short ) (kk & 0xFF );
104- break ;
105-
106- case 7 : cpu .v [x ] = (short ) ((cpu .v [x ] + kk ) & 0xFF ); break ;
107-
108- case 8 :
109- switch (n ) {
110- case 0 : cpu .v [x ] = cpu .v [y ]; break ;
111-
112- case 1 : cpu .v [x ] = (short ) (cpu .v [x ] | cpu .v [y ]); cpu .pc = nnn ; break ;
113-
114- case 2 : cpu .v [x ] = (short ) (cpu .v [x ] & cpu .v [y ]); break ;
115-
116- case 3 : cpu .v [x ] = (short ) (cpu .v [x ] ^ cpu .v [y ]); break ;
117-
118- case 4 :
119- int sum = cpu .v [x ] + cpu .v [y ];
120-
121- if (sum > 0xFF ) cpu .v [0xF ] = 1 ;
122- else cpu .v [0xF ] = 0 ;
123-
124- cpu .v [x ] = (short ) (sum & 0xFF );
125-
126- /*cpu.v[0xF] = (short) ((cpu.v[x] > cpu.v[x] + cpu.v[y]) ? 1 : 0); // Carry
127- cpu.v[x] += cpu.v[y];*/
128- break ;
129-
130- case 5 :
131-
132- if (cpu .v [x ] > cpu .v [y ]) cpu .v [0xF ] = 1 ;
133- else cpu .v [0xF ] = 0 ;
134-
135- short sub = (short )((cpu .v [x ] - cpu .v [y ]) & 0xFF );
136- cpu .v [x ] = sub ;
137-
138- /*
139- cpu.v[0xF] = (short) ((cpu.v[x] > cpu.v[y]) ? 1 : 0); // Carry
140- cpu.v[x] -= cpu.v[y];
141- */
142- break ;
143-
144- case 6 :
145- cpu .v [0xF ] = (short ) (cpu .v [x ] & 0x1 ); // Carry
146- cpu .v [x ] >>>= 1 ;
147- break ;
148-
149- case 7 :
150- if (cpu .v [y ] > cpu .v [x ]) cpu .v [0xF ] = 1 ;
151- else cpu .v [0xF ] = 0 ;
152-
153- cpu .v [x ] = (short ) (cpu .v [y ] - cpu .v [x ]);
154-
155- /*
156- cpu.v[0xF] = (short) ((cpu.v[y] > cpu.v[x]) ? 1 : 0); // Carry
157- cpu.v[x] = (short) (cpu.v[y] - cpu.v[x]);
158- */
159- break ;
160-
161- case 0xE :
162-
163- byte b = (byte )(cpu .v [x ] >>> 7 & 0x1 );
164- cpu .v [0xF ] = b ;
165- cpu .v [x ] = (short )((cpu .v [x ] << 1 ) & 0xFF );
166-
167- /*
168- cpu.v[0xF] = (short) (((cpu.v[x] & 0x80) != 0) ? 1 : 0);
169- cpu.v[x] <<= 1;
170- */
171- break ;
172- }
173- break ;
174-
175- case 9 :
176- if (cpu .v [x ] != cpu .v [y ]) {
177- cpu .pc += 0x0002 ;
178- //cpu.pc = (short) (cpu.pc + 2 & 0xFFF);
179- }
180- break ;
181-
182- case 0xA : cpu .i = nnn ; break ;
183-
184- case 0xB : cpu .pc = (short ) ((cpu .v [0 ] + nnn & 0XFFF )); break ;
185-
186- case 0xC :
187- cpu .v [x ] = (short ) (cpu .rnd .nextInt (256 ) & kk ); break ; //Random value
188-
189- case 0xD :
190- //DRW
191- /*
192- byte readBytes = 0;
193- byte vf = (byte)0x0;
194- while (readBytes < n){
195- byte currentByte = (byte) cpu.memory[cpu.i + readBytes];
196- for (int i=0; i<=7; i++) {
197- int px = cpu.v[x] & 0xFF;
198- int py = cpu.v[y] & 0xFF;
199- int pos = (64* (py + px) & 0xFF);
200- boolean previousPixel = false;
201- if (cpu.screen[pos] == 1) previousPixel = true;
202- boolean newPixel = previousPixel ^ isBitSet(currentByte, 7-i);
203- short valPixel = 0;
204- if (newPixel == true) valPixel = 1;
205- cpu.screen[pos] = valPixel;
206-
207- if(previousPixel == true && newPixel == false) {
208- vf = (byte)0x01;
209- }
210- }
211-
212- cpu.v[0xF] = vf;
213- readBytes++;
214- }
215- */
216- //Flag a true?
217-
218- //System.out.println ("DRW x:" + String.format("%01X",x) + " y:" + String.format("%01X",y) + " n:" + String.format("%01X",n));
219-
220- cpu .v [15 ] = 0 ;
221- for (int j =0 ; j <n ; j ++) {
222- short sprite = cpu .memory [cpu .i + j ];
223- //System.out.println("sprite: " + Integer.toBinaryString(cpu.memory[cpu.i + j]));
224- for (int i =0 ; i <8 ; i ++) {
225- int px = (cpu .v [x ] + i ) & 63 ;
226- int py = (cpu .v [y ] + j ) & 31 ;
227- int pos = ((64 * py + px ) & 0xFFFF );
228-
229- boolean isActive = ((sprite & (1 << (7 -i ))) != 0 );
230-
231- //System.out.print(sprite & (1 << (7-i)));
232- //System.out.print(" - isActive: "+isActive);
233- //System.out.println(" - cpu.screen[pos]" + cpu.screen[pos]);
234-
235-
236- if (isActive & (cpu .screen [pos ] == 1 )) cpu .v [15 ] = 1 ;
237- cpu .screen [pos ] ^= (short ) (isActive ? 1 : 0 );
238- }
239- }
240-
241- display .drawFlag = true ;
242-
243- break ;
244-
245- case 0xE :
246-
247- switch (kk ) {
248- case 0x9E :
249- if (cpu .v [x ] == keyboard .getCurrentKey ()) {
250- cpu .pc +=0x0002 ;
251- }
252- break ;
253-
254- case 0xA1 :
255- if (cpu .v [x ] != keyboard .getCurrentKey ()) {
256- cpu .pc +=0x0002 ;
257- }
258- break ;
259- }
260- break ;
261-
262- case 0xF :
263- switch (kk ) {
264-
265- case 0x07 : cpu .v [x ] = (short ) (cpu .dt & 0xFF ); break ;
266-
267- case 0x0A :
268-
269- int currentKey = keyboard .getCurrentKey ();
270- while (currentKey == 0 ) {
271- try {
272- Thread .sleep (300 );
273- } catch (InterruptedException e ) {
274- e .printStackTrace ();
275- }
276- currentKey = keyboard .getCurrentKey ();
277- }
278- cpu .v [x ] = (short ) currentKey ;
279-
280- break ;
281-
282- case 0x15 : cpu .dt = cpu .v [x ]; break ;
283-
284- case 0x18 : cpu .st = cpu .v [x ]; break ;
285-
286- case 0x1E : cpu .i += cpu .v [x ]; break ;
287-
288- case 0x29 : cpu .i = (short ) (0x65 + cpu .v [x ] * 5 ); break ; //Draw Sprites
289-
290- case 0x33 :
291- cpu .memory [cpu .i + 2 ] = (short ) (cpu .v [x ] % 10 );
292- cpu .memory [cpu .i + 1 ] = (short ) (cpu .v [x ] / 10 /* % 10*/ );
293- cpu .memory [cpu .i ] = (short ) (cpu .v [x ] / 100 );
294- break ;
295-
296- case 0x55 :
297- for (int reg =0 ; reg <=x ; reg ++) {
298- cpu .memory [cpu .i + reg ] = cpu .v [reg ];
299- }
300- break ;
301-
302- case 0x65 :
303- for (int reg =0 ; reg <=x ; reg ++) {
304- cpu .v [reg ] = cpu .memory [cpu .i + reg ];
305- }
306- break ;
307- }
308- //break;
309- }
310-
311-
312-
313-
314- //Display
315- if (display .drawFlag = true ) {
316- display .paint (display .getGraphics (), cpu .screen );
317- //display.paintFullScreen(cpu.screen);
318- }
319- display .drawFlag = false ;
320-
321-
322- //Increment program counter
48+ pu .run ();
32349 //end = true;
324- cpu .pc +=0x2 ;
325- if (cpu .pc >= 4096 ) cpu .pc = 0x200 ;
326-
327- //1000 / 60
328- Thread .sleep (1000 / 60 );
329- if (cpu .dt > 0 ) --cpu .dt ;
330- if (cpu .st > 0 ){
331- if (cpu .st == 1 )// Toolkit.getDefaultToolkit().beep();
332- --cpu .st ;
333- }
334-
335- //cpu.screen[0] = cpu.screen[63] = cpu.screen[1984] = cpu.screen[2047] = 1;
336- //display.paint(display.getGraphics(), cpu.screen);
33750 }
51+
52+
33853
33954 }
34055
@@ -353,7 +68,7 @@ private static void init() {
35368
35469 }
35570
356- //Hardcoded load pong.rom in memory
71+
35772 private static void loadRom () {
35873
35974 File file = new File ("roms/PONG" );
@@ -387,11 +102,8 @@ private static void prepareGUI(){
387102 f .pack ();
388103 f .setResizable (false );
389104 f .setVisible (true );
105+ f .addKeyListener (keyboard );
106+
107+ }
390108
391- }
392-
393- private static Boolean isBitSet (byte b , int bit )
394- {
395- return (b & (1 << bit )) != 0 ;
396- }
397109}
0 commit comments