From e3fbf385f8f2621155902f1616c42eb3ef95503f Mon Sep 17 00:00:00 2001 From: Sebastian Cabrera Date: Sun, 26 Jul 2020 11:20:59 -0400 Subject: [PATCH] Initial Commit --- bin/chip/Chip.class | Bin 0 -> 3757 bytes bin/chip/ChipData.class | Bin 0 -> 967 bytes bin/emu/ChipFrame.class | Bin 0 -> 1165 bytes bin/emu/ChipPanel.class | Bin 0 -> 953 bytes bin/emu/Main.class | Bin 0 -> 1036 bytes res/invaders.c8 | Bin 0 -> 1301 bytes res/pong2.c8 | Bin 0 -> 294 bytes res/tetris.c8 | Bin 0 -> 494 bytes src/chip/Chip.java | 190 ++++++++++++++++++++++++++++++++++++++++ src/chip/ChipData.java | 29 ++++++ src/emu/ChipFrame.java | 27 ++++++ src/emu/ChipPanel.java | 32 +++++++ src/emu/Main.java | 36 ++++++++ 13 files changed, 314 insertions(+) create mode 100644 bin/chip/Chip.class create mode 100644 bin/chip/ChipData.class create mode 100644 bin/emu/ChipFrame.class create mode 100644 bin/emu/ChipPanel.class create mode 100644 bin/emu/Main.class create mode 100644 res/invaders.c8 create mode 100644 res/pong2.c8 create mode 100644 res/tetris.c8 create mode 100644 src/chip/Chip.java create mode 100644 src/chip/ChipData.java create mode 100644 src/emu/ChipFrame.java create mode 100644 src/emu/ChipPanel.java create mode 100644 src/emu/Main.java diff --git a/bin/chip/Chip.class b/bin/chip/Chip.class new file mode 100644 index 0000000000000000000000000000000000000000..5acb7720b2cc555730617ac8d54f42312512a31f GIT binary patch literal 3757 zcmZu!TW}NC8UD^n@=Ef8C4;y*fG`GZ0X7%a2{srPn~RCD9gGbwq)13>TOdn9mcRz$ zxZt!+NXsQn+N2EuN~1uSA%L+np-nQ=nLP9s8}XqEMZgj2k0ffE_)=jNa2*Yv2-ZY{vA&x2BS-a6N}y;! zABZQ11(btL0-~Ew3m@`IA|zlNOa(*71T=$o#3Qkko)jn!>(Suw;Z$V67!AhLv2cE5 zJ*E#2N`2b|)No`l!Ic8en68KS>fvPYB-Q_b2XBtVBB=%eOJx;LwKm1Wx)T;G&@dMs zfs)opOm9mM9MO~ef=8mdKxu0{6pVHUlMy-239YIA2u~|+o$|Dv%A{%s1eR*Bp-6Je zG^i%GT!S4BDO;hzX>zMH6q~bE8aOX!S8JGMa%(lrHn|!NC2+~v^%~qJw^2hW<~S+) zo`za!dT}%!4DX1?QiD1pY)PhL4s1fbinr-zV+&Ws(_HImH8K>5*K{Nq z>dsVB4-RnSR)P7`xuZA|>)V!&M8kU0j_(WD+Y=$iug>d41Da$6o2jhQ)Mn({+*4oG z?Zgi3Qn6FOJ*}~YY3h;0#zv8y7nu+D*CV-)r4 zk-mPaQ4Vutjk4+`&skd{GNebjA{9>sqX+U#kHD->*_C^OiChyn`}9`w(2OwSgm%`JLO!+E^U z?6Mca+lEsN553vu#2Nft!v$O<%n{ZiQ4=LN*W$!w{6fVW1^I7j-#!%56RAi%rr}Kk zV2u15k=&OIhG_E{{8GcO)vpb{kIIzpg934jJA{27$s zXHY^PshuYfwfUaMQ4OgewfQD7|E{rYA>T!Y(2hmqHFE*V@C-)+i>Ef<y z?`;pT#OHEJ>h)P3pxozH@BkG#*-9y^lrNurt&w8;162Fmc1UKOly2}%z&~w9Eqwxy zb?{I(meAs*uR zkE6oxvJd5XYrsExdGkFy_Ye&|rHzx=R`xNrPvH3pyfA^T2^=UZeR1SN8HsQCVx(no zc{03`_5kZ7eF+38{yqT`l70oY8TZhitCFqs3gWI;~x%=+H*%*-QJzRN+xw z_G{VuV>aQjd92s6Zx)#9v$8ldC@FMH)~N-uT^{kK0oJqbHt@5;k1;%p*YO-KQvL?E zFy#%ng{>GzBPP*|&snWs@N)kWJMlN{!q>daAF+o1$(#CL=)hyVARO2$=Au)~$A00( z0kIN2ViWJlW*ihd5fFzE7Gdb3A4kP842U#hVia+44uj$nQsN5I;s#EN+ZY!2a7uiR z)8Y%95r5|0@fVDUuXs&-jZyIroE87ZIR$t{(QsOshhfEwSC!RxO<9NY%0^sJ>Tyxo zN>3yl+?IJ(8gqTMNLh&p`%};-KaR2=6na*TW8^IKV-ccKMh{k*v-D$`IZG?A=VVt1 z^8<1RExv#lIjgvXC;l< z++w6@@nMvHhcPjG`D0WIcI~Y4nz^&*XK7`T3Ss;}Q|AbgWxlk$EI*Sa7~7|XbpBg7 zvdp_8g%YX-PT(ZpGXa(L_7P84j0!OU^{oPAvP~h=5Qd+!dBg4h+x*T`H=oMG8pCg* zaghO}vN+A7out4OUMKGrXegRG{xl2Hu$>7pubPu$&qJK)d594{qdlu9adr~tCh_Av zmWB*rhD}IlUmRF7fmcmH7_$fte)ewmQ3lm*YbS6?;@KKj0>y7-u&R#TTV7|SL^CC} zI@?0)XEVlkX`;fsHt>_+d48DgB~{oV`)U4*2qMh!0P~+BHT$m3xY4e2)eT1ZeY%w4 zE%5<6@g~EOp{_gZx{uI=yVP@^TF0sF9#Q%}HIAbf6Rh6*)H==-P8#9y(+V)1=5;5z zxA6`Gq_CELjo*-#5$fM%omr^c&cMD$PS)98I3Ht)${zD%*%B6(hl*B?CB59qr&-0- zEbkuM^b{q=G;2>O+=AU)FYjjlP03Zqao$@pl@*rFxh%Lk$^!Rry{tNy1tH2f{PbG( x@6*^+%3bmvvf&{XkS@m`3_s_Yx^jLh?8*=5jW9gnAJXsGc=F(z+^pc%{{Wd~`_TXZ literal 0 HcmV?d00001 diff --git a/bin/chip/ChipData.class b/bin/chip/ChipData.class new file mode 100644 index 0000000000000000000000000000000000000000..d73727bb2e58b338ed792e50e749bb02f9f78854 GIT binary patch literal 967 zcmY+COHUI~7>3_7y-Yi8>6u=*ixg1-g{pW55hdmuy4Uw? zL>2U|_uMPDz0T8ey}9eR`U>`wZl}NR%gK7QsgPK1wS!L3Ur~t6%x)<}E8T5B358S| zF~k+J)u7|o4xTmr-b1h1_7!r~Zp&+LdA%UyKW2Q{v~duDPGbNGY1Q8e_QMAMJ#0zA zdC)!Rwfv1B?3Vfa;)U?BD9PxE{FOp7oG&K}3E1+54y;#*iU(^--~a41A})T_8&Map z>y4O+aT9IhC-h{!q2v0oMBAL{B=w#+j>*v}tp(DAjEfgS1EefPn+%tbGms|~%rIS~ z4ALAj8N()y&>CgiG19oXIzpJB9A(BNsl=229245}W6)Ef+|j~G$kF{%zRW=+7cN*I?8;Z}w_DtpeoL|Igc b7n}Ql?7z`*V@6C#nh7#6XNto|St$Gl%pAnD literal 0 HcmV?d00001 diff --git a/bin/emu/ChipFrame.class b/bin/emu/ChipFrame.class new file mode 100644 index 0000000000000000000000000000000000000000..3c20d0eebed89e519f60d17632c15ab02a3b3fe3 GIT binary patch literal 1165 zcmY*Y*-{fh6g`~;62g!`kWE~0PX;6iifB-g02&O71f%hZCTU7a zpOUo$!`x0Tx;R5im7Ai>5Y3)AtSTVI&^m3HhJ4NtiD!!x$c>gtj@k^_!?z)Cyb#L9Yq_iqQ+&|ZH zw}WAfAgSsOwNaiAG_;^KhzW+C(*$NMyCm!^|7_J|7~^PH6-{b*j47&!it(Np2G6y` z!Siveon0)g_ z&Dc~_f%r!y&uG>##d5u}DeQIbKEzb`a-Q3Ux;Mdq+%ZTkXTo!qpA$duxM?yyM*_l-OuG9b=?0+`#BhjFIzrp@D}E9_jiK#$rz#r1Vw? zFZ5X2!Msbr9Axx>gQXvoh!1b+f0FhR^a~(@9z-#KPAsAedBnicjXhe>D!uHZ7l-J> f7uvjUWVJ?Ky4qfKnkwpsVDqen3v3W7?`&ZeAdgJh7iD6JBsOObtPF=}@5y z1e2+97)0s_p+g{AvTEj&o$YnAu`1VXle8tLBJHwlSe}2hskl|E>7oCVN$OBtS~XXo zFIn>BX63G%U1-R9)v7desj`MX^s6{65N-?BaRvhd+Lr0gS&3OW@>9~#wGHqJ6 z{nV_mC~C6E&+CKOBJZ*6mN*tr-DuSyur^De#Zlzg<6vQo6<1bXEXumy2o+N-+={c) zsF?GX*R4qV&5V0j$1r;vg*8O8@66XhK7BO_1{ zB{s$%Y@d%tH+twX&d*A1=*6j{oIj74meZeL93Z|J%$73*g>gE620h literal 0 HcmV?d00001 diff --git a/bin/emu/Main.class b/bin/emu/Main.class new file mode 100644 index 0000000000000000000000000000000000000000..5684625772ec5acbd45b0e71673adf59bd39de55 GIT binary patch literal 1036 zcmZuv?M@Rx6g@**w_T{=3l3v&=G%Ql~jS>yXFi_IX)&0A5!y)dAf(!^CYs~83RACUIp%PU zD7#WtTQ6l*iT8m;uQVH*L^r=)DNFgMV@SWZB>y)N1GSZ-V`(~WCAUo!5D2#ZtLg}=>udx2Y}Nw zP6Xg4!SrJQ94W++A#V#5U8a5Bg~t`lP{j0Q^;&-n$N_WRURHO?e+rssJ1BG$H%4&l zD{k)}|0?Yt|D@UsVOh9GLUjK$y(D0m#t{tBvmPS`8I04J3FMGG#bK_;VTsO1sXG1C zAe0#HW4Xs@y~iki1V%nQD9v{8@I-1Na5PKBQzUCTfKE{fNb(9+1K0?`%@7>J8pVAm F{sFZ}zN!EK literal 0 HcmV?d00001 diff --git a/res/invaders.c8 b/res/invaders.c8 new file mode 100644 index 0000000000000000000000000000000000000000..3ada8dfe93a7d95925a9f52a1bf2cf385101bacd GIT binary patch literal 1301 zcmZWnQAk@?82)d1y_piamh`f#L!@1A(Y5IsX0;I_gJ9ar3bKc*%*)hU?J_db zHpya)flW574=cK`vDvNnWm{kNuoto79NUwy4is_bVa)mx!w{k+p1c1hX*=A&s%{wQRRi1nI9zSDv1 zJPLJiw$)+c()-6IejM1JczHl<1M;gJPYIVr@_U<${9*fTlx&tciEOvEkR3Vx2Doc) z3O)2`Rq?%YRUtWY*g(dLwdaA19X80Jse2cRyD{b%E?soEWt@3AL7PtV1uN2{^5bAUzCT&h3Dh;D&&*7BvD{v<+c;@^XuA) zH6HSE=u=q^X*C5})%ghW!|+LNgx~p!T>I8}=qU^;mivcc7~!vTqn!KhH+2OMYKU>} z7WaCs`!3{t3Co(DMbp%@ov?hq#Kw3RavLshi~)QI9XJ3ujyr|`=#Z-D5Jd}sK?w&y zqN{5F0f1Zu=vWYk&Uj5c4zRSe;x}5nN8?3TeX+>%05LyXLL80nN-d8cpE(0?F!?j$ z;AngSBt=?S04Va?lauMaqw#0;@3!nhP8<7Q{AvA*uxJCI#8**rxvYcnpQh&Kp1_lj z=jJ}2-T%9}d9S^_9bT+&KY#9(U$%OC-(FkWf~^-$lE#%uGJz_j>(EFpM&Xr;xN?2m}F*reTjZFfRof zTXCYrXT%-lj7$_oj4%ggWO!B(SbBMx@jOd1^z9a~JBLFMgmS+Om+1SMA3w7KqYs?a zRDua0R5#2%U2W1K5TL{qrcD9~g_vn27^Zq<`?MN015qPv5^98Xb=nNK{^xX9MFEQ0(9n^cvUT~Vjc{JvVlv!A|lx9~5`cIUbP literal 0 HcmV?d00001 diff --git a/res/pong2.c8 b/res/pong2.c8 new file mode 100644 index 0000000000000000000000000000000000000000..6af8d1e35400592ecbc0f2c816ff454fa0c06b96 GIT binary patch literal 294 zcmY%Tlg*Q3pUbo8)vaxJuH`W(T}flkU`j~%Ao_vbfI&#=xOh27=Kn<>t`$O5BrrZ$ zSp6@71xPX_$agc{+LplcU}5dQ1YRHs6zOHUa}A`rt)+cRf_)oPqI|oM8-q}Vo4rtz zyL{$v79}z@hyv+dVDbc*Jd~jDK|<+D zp9#=qcE*fA*ZnhQ%wQ4{tNiczFY~|9iAqLKrcA~JmJbqTjBXBP|AcZDefnqoDfOdf zibyKcmCzE=PnuUk8QwKO00RgdIB4#Gl5XNWCX+%VlyR+~?lv`40X#skLaSFO}dqV`E0DV;L4@g-?2y(W#Fx1@3Mc&ZNDkgLrFV^Cm-+M2rg zjM!iiTd~UQN-JPj=OW-q-SKIcNeUgIT_rCjxXUNY#8M`~7%h>@zU5Ei75S|TQ{~eY zGs<{VJTwsmk7WRuU;r5gjH4KbX3PZ3XD-eHy%{*pF6KkV))=4 z`JzkR?q2g_p!I^6O7DgGA{(S6IyO{AmyQH@i$ojd4RavFCM58G9nu!nCcxtj#eU@= zw4d4X3(SKF+M#^Vj^%BF6v*8n(9SpgEx(^=+f> 8; + int nn = (opcode & 0x00FF); + if (V[x] == nn) { + pc += 4; + System.out.println("VX = NN: Skipping 4"); + } else { + pc += 2; + } + break; + } + + case 0x6000: { + int index = (opcode & 0x0F00) >> 8; + V[index] = (char)(opcode & 0x00FF); + pc += 2; + break; + } + + case 0x7000: { + int x = (opcode & 0x0F00) >> 8; + int nn = (opcode & 0x00FF); + V[x] = (char)((V[x] + nn) & 0xFF); + pc += 2; + break; + } + + case 0x8000: //Contains more data in last nibble + + switch(opcode & 0x000F) { + + case 0x0000: //8XY0: Sets VX to the value of VY. + default: + System.err.println("Unsupported Opcode!"); + System.exit(0); + break; + + } + + break; + + case 0xA000: { + I = (char)(opcode & 0x0FFF); + pc += 2; + break; + } + + case 0xD000: { + int x = V[(opcode & 0x0F00) >> 8]; + int y = V[(opcode & 0x00F0) >> 4]; + int height = opcode & 0x000F; + + V[0xF] = 0; + + for (int _y=0;_y> _x); + if (pixel != 0) { + int totalX = _x + _x; + int totalY = y + _y; + int index = totalY * 64 + totalX; + + if (display[index] == 1) + V[0xF] = 1; + + display[index] ^= 1; + } + } + } + pc += 2; + needRedraw = true; + break; + } + + default: + System.err.println("Unsupported Opcode!"); + System.exit(0); + } + //execute opcode + } + + public byte[] getDisplay() { + return display; + } + + public boolean needsRedraw() { + return needRedraw; + } + + public void removeDrawFlag() { + needRedraw = false; + } + + public void loadProgram(String file) { + DataInputStream input = null; + try { + input = new DataInputStream(new FileInputStream(new File(file))); + + int offset = 0; + while(input.available() > 0) { + memory[0x200 + offset] = (char)(input.readByte() & 0xFF); + offset++; + } + + //for (int offset = 0; input.available() > 0; offset++) { + // + //} + } catch (IOException e) { + e.printStackTrace(); + System.exit(0); + } finally { + if(input != null) { + try { input.close(); } catch (IOException ex) {}; + } + } + } + + public void loadFontset() { + for (int i=0;i < ChipData.fontset.length;i++) { + memory[0x50 + i] = (char)(ChipData.fontset[i] & 0xFF); + } + } +} diff --git a/src/chip/ChipData.java b/src/chip/ChipData.java new file mode 100644 index 0000000..1e6122f --- /dev/null +++ b/src/chip/ChipData.java @@ -0,0 +1,29 @@ +package chip; + +public class ChipData { + + /** + * Fontset in bytes + * Memory position 0x50 + */ + + public static int[] fontset = + { + 0xF0, 0x90, 0x90, 0x90, 0xF0, // 0 + 0x20, 0x60, 0x20, 0x20, 0x70, // 1 + 0xF0, 0x10, 0xF0, 0x80, 0xF0, // 2 + 0xF0, 0x10, 0xF0, 0x10, 0xF0, // 3 + 0x90, 0x90, 0xF0, 0x10, 0x10, // 4 + 0xF0, 0x80, 0xF0, 0x10, 0xF0, // 5 + 0xF0, 0x80, 0xF0, 0x90, 0xF0, // 6 + 0xF0, 0x10, 0x20, 0x40, 0x40, // 7 + 0xF0, 0x90, 0xF0, 0x90, 0xF0, // 8 + 0xF0, 0x90, 0xF0, 0x10, 0xF0, // 9 + 0xF0, 0x90, 0xF0, 0x90, 0x90, // A + 0xE0, 0x90, 0xE0, 0x90, 0xE0, // B + 0xF0, 0x80, 0x80, 0x80, 0xF0, // C + 0xE0, 0x90, 0x90, 0x90, 0xE0, // D + 0xF0, 0x80, 0xF0, 0x80, 0xF0, // E + 0xF0, 0x80, 0xF0, 0x80, 0x80 // F + }; +} diff --git a/src/emu/ChipFrame.java b/src/emu/ChipFrame.java new file mode 100644 index 0000000..8d77bb1 --- /dev/null +++ b/src/emu/ChipFrame.java @@ -0,0 +1,27 @@ +package emu; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import javax.swing.JFrame; + +import chip.Chip; + +public class ChipFrame extends JFrame { + + private ChipPanel panel; + + public ChipFrame(Chip c) { + setPreferredSize(new Dimension(640, 320)); + pack(); + setPreferredSize(new Dimension(640 + getInsets().left + getInsets().right, 320 + getInsets().top + getInsets().bottom)); + panel = new ChipPanel(c); + setLayout(new BorderLayout()); + add(panel, BorderLayout.CENTER); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setTitle("Chip 8 Emulator"); + pack(); + setLocationRelativeTo(null); + setVisible(true); + } + +} diff --git a/src/emu/ChipPanel.java b/src/emu/ChipPanel.java new file mode 100644 index 0000000..16274e4 --- /dev/null +++ b/src/emu/ChipPanel.java @@ -0,0 +1,32 @@ +package emu; + +import java.awt.Color; +import java.awt.Graphics; + +import javax.swing.JPanel; + +import chip.Chip; + +public class ChipPanel extends JPanel { + + private Chip chip; + + public ChipPanel(Chip chip) { + this.chip = chip; + } + + public void paint(Graphics g) { + byte[] display = chip.getDisplay(); + for (int i=0;i