Begining of PPU emulation.
parent
d546eaec1c
commit
71f1e0bf54
2917
.metadata/.log
2917
.metadata/.log
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -7,3 +7,4 @@
|
|||
*** SESSION Dec 30, 2020 07:33:14.96 -------------------------------------------
|
||||
*** SESSION Dec 31, 2020 06:46:47.09 -------------------------------------------
|
||||
*** SESSION Dec 31, 2020 19:47:23.71 -------------------------------------------
|
||||
*** SESSION Jan 01, 2021 12:04:55.25 -------------------------------------------
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1,2 +1,2 @@
|
|||
eclipse.preferences.version=1
|
||||
org.eclipse.cdt.debug.core.cDebug.default_source_containers=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?>\n<sourceLookupDirector>\n <sourceContainers duplicates\="false">\n <container memento\="AbsolutePath" typeId\="org.eclipse.cdt.debug.core.containerType.absolutePath"/>\n <container memento\="programRelativePath" typeId\="org.eclipse.cdt.debug.core.containerType.programRelativePath"/>\n <container memento\="<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?>&\#10;<project referencedProjects\="true"/>&\#10;" typeId\="org.eclipse.cdt.debug.core.containerType.project"/>\n </sourceContainers>\n</sourceLookupDirector>\n
|
||||
org.eclipse.cdt.debug.core.cDebug.default_source_containers=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?>\r\n<sourceLookupDirector>\r\n<sourceContainers duplicates\="false">\r\n<container memento\="AbsolutePath" typeId\="org.eclipse.cdt.debug.core.containerType.absolutePath"/>\r\n<container memento\="programRelativePath" typeId\="org.eclipse.cdt.debug.core.containerType.programRelativePath"/>\r\n<container memento\="<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?>&\#13;&\#10;<project referencedProjects\="true"/>&\#13;&\#10;" typeId\="org.eclipse.cdt.debug.core.containerType.project"/>\r\n</sourceContainers>\r\n</sourceLookupDirector>\r\n
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
eclipse.preferences.version=1
|
||||
org.eclipse.debug.ui.PREF_LAUNCH_PERSPECTIVES=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?>\n<launchPerspectives/>\n
|
||||
org.eclipse.debug.ui.user_view_bindings=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?>\n<viewBindings>\n <view id\="org.eclipse.jdt.debug.ui.DisplayView">\n <perspective id\="org.eclipse.debug.ui.DebugPerspective" userAction\="opened"/>\n </view>\n <view id\="org.eclipse.debug.ui.DebugView">\n <perspective id\="org.eclipse.debug.ui.DebugPerspective" userAction\="closed"/>\n </view>\n <view id\="org.eclipse.debug.ui.ExpressionView">\n <perspective id\="org.eclipse.debug.ui.DebugPerspective" userAction\="closed"/>\n </view>\n</viewBindings>\n
|
||||
org.eclipse.debug.ui.PREF_LAUNCH_PERSPECTIVES=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?>\r\n<launchPerspectives/>\r\n
|
||||
org.eclipse.debug.ui.user_view_bindings=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?>\r\n<viewBindings>\r\n<view id\="org.eclipse.jdt.debug.ui.DisplayView">\r\n<perspective id\="org.eclipse.debug.ui.DebugPerspective" userAction\="opened"/>\r\n</view>\r\n<view id\="org.eclipse.debug.ui.DebugView">\r\n<perspective id\="org.eclipse.debug.ui.DebugPerspective" userAction\="closed"/>\r\n</view>\r\n<view id\="org.eclipse.debug.ui.ExpressionView">\r\n<perspective id\="org.eclipse.debug.ui.DebugPerspective" userAction\="closed"/>\r\n</view>\r\n</viewBindings>\r\n
|
||||
pref_state_memento.org.eclipse.debug.ui.BreakpointView=<?xml version\="1.0" encoding\="UTF-8"?>\r\n<VariablesViewMemento org.eclipse.debug.ui.SASH_DETAILS_PART\="315" org.eclipse.debug.ui.SASH_VIEW_PART\="684">\r\n<PRESENTATION_CONTEXT_PROPERTIES IMemento.internal.id\="org.eclipse.debug.ui.BreakpointView">\r\n<BOOLEAN BOOLEAN\="true" IMemento.internal.id\="org.eclipse.debug.ui.check"/>\r\n</PRESENTATION_CONTEXT_PROPERTIES>\r\n</VariablesViewMemento>
|
||||
pref_state_memento.org.eclipse.debug.ui.DebugVieworg.eclipse.debug.ui.DebugView=<?xml version\="1.0" encoding\="UTF-8"?>\r\n<DebugViewMemento org.eclipse.debug.ui.BREADCRUMB_DROPDOWN_AUTO_EXPAND\="false"/>
|
||||
pref_state_memento.org.eclipse.debug.ui.ExpressionView=<?xml version\="1.0" encoding\="UTF-8"?>\r\n<VariablesViewMemento org.eclipse.debug.ui.SASH_DETAILS_PART\="315" org.eclipse.debug.ui.SASH_VIEW_PART\="684">\r\n<PRESENTATION_CONTEXT_PROPERTIES IMemento.internal.id\="org.eclipse.debug.ui.ExpressionView">\r\n<BOOLEAN BOOLEAN\="true" IMemento.internal.id\="PRESENTATION_SHOW_LOGICAL_STRUCTURES"/>\r\n</PRESENTATION_CONTEXT_PROPERTIES>\r\n</VariablesViewMemento>
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.launching.PREF_VM_XML=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?>\n<vmSettings defaultVM\="57,org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType13,1609440543502" defaultVMConnector\="">\n <vmType id\="org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType">\n <vm id\="1608703468908" name\="jdk1.8.0_91" path\="/home/sixten/C\:\\Program Files\\Java\\jdk1.8.0_91"/>\n <vm id\="1609440543502" javadocURL\="https\://docs.oracle.com/en/java/javase/11/docs/api/" name\="jdk" path\="/app/jdk"/>\n </vmType>\n</vmSettings>\n
|
||||
org.eclipse.jdt.launching.PREF_VM_XML=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?>\r\n<vmSettings defaultVM\="57,org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType13,1609499110415" defaultVMConnector\="">\r\n<vmType id\="org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType">\r\n<vm id\="1609499110415" name\="jdk1.8.0_91" path\="C\:\\Program Files\\Java\\jdk1.8.0_91"/>\r\n</vmType>\r\n</vmSettings>\r\n
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
content_assist_disabled_computers=org.eclipse.jdt.ui.swtProposalCategory\u0000org.eclipse.jdt.ui.textProposalCategory\u0000org.eclipse.jdt.ui.javaPostfixProposalCategory\u0000
|
||||
content_assist_disabled_computers=org.eclipse.jdt.ui.textProposalCategory\u0000org.eclipse.jdt.ui.swtProposalCategory\u0000org.eclipse.jdt.ui.javaPostfixProposalCategory\u0000org.eclipse.jdt.ui.javaNoTypeProposalCategory\u0000org.eclipse.jdt.ui.javaTypeProposalCategory\u0000
|
||||
content_assist_lru_history=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><history maxLHS\="100" maxRHS\="10"><lhs name\="java.util.Collection"><rhs name\="java.util.ArrayList"/></lhs><lhs name\="java.lang.Iterable"><rhs name\="java.util.ArrayList"/></lhs><lhs name\="java.util.List"><rhs name\="java.util.ArrayList"/></lhs><lhs name\="javax.swing.ListModel"><rhs name\="javax.swing.DefaultListModel"/></lhs><lhs name\="java.io.OutputStreamWriter"><rhs name\="java.io.FileWriter"/></lhs><lhs name\="java.io.Writer"><rhs name\="java.io.FileWriter"/></lhs><lhs name\="java.lang.Appendable"><rhs name\="java.io.FileWriter"/></lhs><lhs name\="java.io.Closeable"><rhs name\="java.io.FileWriter"/></lhs><lhs name\="java.lang.AutoCloseable"><rhs name\="java.io.FileWriter"/></lhs><lhs name\="java.io.Flushable"><rhs name\="java.io.FileWriter"/></lhs><lhs name\="java.io.FileWriter"><rhs name\="java.io.FileWriter"/></lhs><lhs name\="playingcoffee.core.cpu.Registers"><rhs name\="playingcoffee.core.cpu.Registers"/></lhs><lhs name\="playingcoffee.core.opcode.Opcode"><rhs name\="playingcoffee.core.opcode.RotateAOpcode"/><rhs name\="playingcoffee.core.opcode.ReturnOpcode"/><rhs name\="playingcoffee.core.opcode.InterruptOpcode"/><rhs name\="playingcoffee.core.opcode.ComplementOpcode"/><rhs name\="playingcoffee.core.opcode.RestartOpcode"/><rhs name\="playingcoffee.core.opcode.ALU16Opcode"/><rhs name\="playingcoffee.core.opcode.SetCarryOpcode"/><rhs name\="playingcoffee.core.opcode.prefixed.SwapOpcode"/><rhs name\="playingcoffee.core.opcode.prefixed.ResetBitOpcode"/><rhs name\="playingcoffee.core.opcode.prefixed.ShiftOpcode"/></lhs><lhs name\="java.lang.Enum"><rhs name\="playingcoffee.core.opcode.ALU16Opcode$ALU16Type"/></lhs><lhs name\="playingcoffee.core.opcode.ALU16Opcode$ALU16Type"><rhs name\="playingcoffee.core.opcode.ALU16Opcode$ALU16Type"/></lhs><lhs name\="java.awt.image.WritableRenderedImage"><rhs name\="java.awt.image.BufferedImage"/></lhs><lhs name\="java.awt.image.RenderedImage"><rhs name\="java.awt.image.BufferedImage"/></lhs><lhs name\="java.awt.Transparency"><rhs name\="java.awt.image.BufferedImage"/></lhs><lhs name\="java.awt.Image"><rhs name\="java.awt.image.BufferedImage"/></lhs><lhs name\="java.awt.image.BufferedImage"><rhs name\="java.awt.image.BufferedImage"/></lhs><lhs name\="java.lang.Runnable"><rhs name\="playingcoffee.application.GameBoyViewPanel"/><rhs name\="playingcoffee.application.Application"/><rhs name\="java.lang.Thread"/><rhs name\="playingcoffee.application.GameBoy"/></lhs><lhs name\="java.awt.Canvas"><rhs name\="playingcoffee.application.GameBoyViewPanel"/><rhs name\="playingcoffee.application.Application"/></lhs><lhs name\="javax.accessibility.Accessible"><rhs name\="playingcoffee.application.GameBoyViewPanel"/><rhs name\="playingcoffee.application.Application"/></lhs><lhs name\="java.awt.Component"><rhs name\="playingcoffee.application.GameBoyViewPanel"/><rhs name\="playingcoffee.application.Application"/></lhs><lhs name\="java.awt.image.ImageObserver"><rhs name\="playingcoffee.application.GameBoyViewPanel"/><rhs name\="playingcoffee.application.Application"/></lhs><lhs name\="java.awt.MenuContainer"><rhs name\="playingcoffee.application.GameBoyViewPanel"/><rhs name\="playingcoffee.application.Application"/></lhs><lhs name\="playingcoffee.application.GameBoyViewPanel"><rhs name\="playingcoffee.application.GameBoyViewPanel"/></lhs><lhs name\="playingcoffee.application.Application"><rhs name\="playingcoffee.application.Application"/></lhs><lhs name\="playingcoffee.core.MMU"><rhs name\="playingcoffee.core.MMU"/></lhs><lhs name\="playingcoffee.core.cpu.CPU"><rhs name\="playingcoffee.core.cpu.CPU"/></lhs><lhs name\="java.awt.geom.Dimension2D"><rhs name\="java.awt.Dimension"/></lhs><lhs name\="java.lang.Cloneable"><rhs name\="java.awt.Dimension"/></lhs><lhs name\="java.awt.Dimension"><rhs name\="java.awt.Dimension"/></lhs><lhs name\="playingcoffee.ppu.OAM"><rhs name\="playingcoffee.ppu.OAM"/></lhs><lhs name\="playingcoffee.core.MemorySpace"><rhs name\="playingcoffee.ppu.OAM"/><rhs name\="playingcoffee.ppu.PPURegisters"/><rhs name\="playingcoffee.ppu.VRAM"/><rhs name\="playingcoffee.core.InterruptManager"/><rhs name\="playingcoffee.core.Cartridge"/></lhs><lhs name\="playingcoffee.ppu.PPURegisters"><rhs name\="playingcoffee.ppu.PPURegisters"/></lhs><lhs name\="java.lang.Thread"><rhs name\="java.lang.Thread"/></lhs><lhs name\="playingcoffee.application.GameBoy"><rhs name\="playingcoffee.application.GameBoy"/></lhs><lhs name\="playingcoffee.ppu.VRAM"><rhs name\="playingcoffee.ppu.VRAM"/></lhs><lhs name\="playingcoffee.core.InterruptManager"><rhs name\="playingcoffee.core.InterruptManager"/></lhs></history>
|
||||
content_assist_number_of_computers=12
|
||||
content_assist_number_of_computers=19
|
||||
content_assist_proposals_background=255,255,255
|
||||
content_assist_proposals_foreground=0,0,0
|
||||
eclipse.preferences.version=1
|
||||
|
|
|
|||
|
|
@ -1,35 +1,35 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchHistory>
|
||||
<launchGroup id="org.eclipse.debug.ui.launchGroup.debug">
|
||||
<mruHistory>
|
||||
<launch memento="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <launchConfiguration local="true" path="Application"/> "/>
|
||||
<launch memento="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <launchConfiguration local="true" path="GameBoyTest"/> "/>
|
||||
<launch memento="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <launchConfiguration local="true" path="CPUDebugger"/> "/>
|
||||
</mruHistory>
|
||||
<favorites/>
|
||||
</launchGroup>
|
||||
<launchGroup id="org.eclipse.debug.ui.launchGroup.profile">
|
||||
<mruHistory/>
|
||||
<favorites/>
|
||||
</launchGroup>
|
||||
<launchGroup id="org.eclipse.eclemma.ui.launchGroup.coverage">
|
||||
<mruHistory>
|
||||
<launch memento="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <launchConfiguration local="true" path="Application"/> "/>
|
||||
<launch memento="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <launchConfiguration local="true" path="GameBoyTest"/> "/>
|
||||
<launch memento="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <launchConfiguration local="true" path="CPUDebugger"/> "/>
|
||||
</mruHistory>
|
||||
<favorites/>
|
||||
</launchGroup>
|
||||
<launchGroup id="org.eclipse.ui.externaltools.launchGroup">
|
||||
<mruHistory/>
|
||||
<favorites/>
|
||||
</launchGroup>
|
||||
<launchGroup id="org.eclipse.debug.ui.launchGroup.run">
|
||||
<mruHistory>
|
||||
<launch memento="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <launchConfiguration local="true" path="Application"/> "/>
|
||||
<launch memento="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <launchConfiguration local="true" path="GameBoyTest"/> "/>
|
||||
<launch memento="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <launchConfiguration local="true" path="CPUDebugger"/> "/>
|
||||
</mruHistory>
|
||||
<favorites/>
|
||||
</launchGroup>
|
||||
<launchGroup id="org.eclipse.debug.ui.launchGroup.debug">
|
||||
<mruHistory>
|
||||
<launch memento="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <launchConfiguration local="true" path="Application"/> "/>
|
||||
<launch memento="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <launchConfiguration local="true" path="GameBoyTest"/> "/>
|
||||
<launch memento="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <launchConfiguration local="true" path="CPUDebugger"/> "/>
|
||||
</mruHistory>
|
||||
<favorites/>
|
||||
</launchGroup>
|
||||
<launchGroup id="org.eclipse.debug.ui.launchGroup.profile">
|
||||
<mruHistory/>
|
||||
<favorites/>
|
||||
</launchGroup>
|
||||
<launchGroup id="org.eclipse.eclemma.ui.launchGroup.coverage">
|
||||
<mruHistory>
|
||||
<launch memento="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <launchConfiguration local="true" path="Application"/> "/>
|
||||
<launch memento="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <launchConfiguration local="true" path="GameBoyTest"/> "/>
|
||||
<launch memento="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <launchConfiguration local="true" path="CPUDebugger"/> "/>
|
||||
</mruHistory>
|
||||
<favorites/>
|
||||
</launchGroup>
|
||||
<launchGroup id="org.eclipse.ui.externaltools.launchGroup">
|
||||
<mruHistory/>
|
||||
<favorites/>
|
||||
</launchGroup>
|
||||
<launchGroup id="org.eclipse.debug.ui.launchGroup.run">
|
||||
<mruHistory>
|
||||
<launch memento="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <launchConfiguration local="true" path="Application"/> "/>
|
||||
<launch memento="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <launchConfiguration local="true" path="GameBoyTest"/> "/>
|
||||
<launch memento="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <launchConfiguration local="true" path="CPUDebugger"/> "/>
|
||||
</mruHistory>
|
||||
<favorites/>
|
||||
</launchGroup>
|
||||
</launchHistory>
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
|
@ -1,4 +1,22 @@
|
|||
INDEX VERSION 1.131+/home/sixten/Documents/playing-coffee/.metadata/.plugins/org.eclipse.jdt.core
|
||||
1558221869.index
|
||||
908895367.index
|
||||
1819307639.index
|
||||
INDEX VERSION 1.131+C:\dev\playing-coffee\.metadata\.plugins\org.eclipse.jdt.core
|
||||
3964923001.index
|
||||
3618832045.index
|
||||
699245563.index
|
||||
1583749204.index
|
||||
1593673412.index
|
||||
2562169395.index
|
||||
424447496.index
|
||||
2173726253.index
|
||||
854353447.index
|
||||
3608884278.index
|
||||
3992513546.index
|
||||
1630848587.index
|
||||
1851668056.index
|
||||
3550930481.index
|
||||
12417758.index
|
||||
21486501.index
|
||||
4163494320.index
|
||||
2709655776.index
|
||||
2068962978.index
|
||||
3179953034.index
|
||||
596698939.index
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<dirs>
|
||||
<entry loc="C:\Program Files\Java\jdk1.8.0_91" stamp="1466445490137"/>
|
||||
<entry loc="/app/jdk" stamp="0"/>
|
||||
<entry loc="C:\Program Files\Java\jdk1.8.0_91" stamp="1466445490137"/>
|
||||
<entry loc="/app/jdk" stamp="0"/>
|
||||
</dirs>
|
||||
|
|
|
|||
|
|
@ -1,23 +1,42 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<libraryInfos>
|
||||
<libraryInfo home="C:\Program Files\Java\jdk1.8.0_91" version="1.8.0_91">
|
||||
<bootpath>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\resources.jar"/>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\rt.jar"/>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\sunrsasign.jar"/>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\jsse.jar"/>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\jce.jar"/>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\charsets.jar"/>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\jfr.jar"/>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\classes"/>
|
||||
</bootpath>
|
||||
<extensionDirs>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\ext"/>
|
||||
<entry path="C:\WINDOWS\Sun\Java\lib\ext"/>
|
||||
</extensionDirs>
|
||||
<endorsedDirs>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\endorsed"/>
|
||||
</endorsedDirs>
|
||||
</libraryInfo>
|
||||
<libraryInfo home="/app/jdk" version="11.0.7"/>
|
||||
<libraryInfo home="C:\Program Files\Java\jdk1.8.0_91" version="1.8.0_91">
|
||||
<bootpath>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\resources.jar"/>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\rt.jar"/>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\sunrsasign.jar"/>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\jsse.jar"/>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\jce.jar"/>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\charsets.jar"/>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\jfr.jar"/>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\classes"/>
|
||||
</bootpath>
|
||||
<extensionDirs>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\ext"/>
|
||||
<entry path="C:\WINDOWS\Sun\Java\lib\ext"/>
|
||||
</extensionDirs>
|
||||
<endorsedDirs>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\endorsed"/>
|
||||
</endorsedDirs>
|
||||
</libraryInfo>
|
||||
<libraryInfo home="/app/jdk" version="11.0.7"/>
|
||||
<libraryInfo home="C:\Program Files\Java\jdk1.8.0_91\jre" version="1.8.0_91">
|
||||
<bootpath>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\resources.jar"/>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\rt.jar"/>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\sunrsasign.jar"/>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\jsse.jar"/>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\jce.jar"/>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\charsets.jar"/>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\jfr.jar"/>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\classes"/>
|
||||
</bootpath>
|
||||
<extensionDirs>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\ext"/>
|
||||
<entry path="C:\WINDOWS\Sun\Java\lib\ext"/>
|
||||
</extensionDirs>
|
||||
<endorsedDirs>
|
||||
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\endorsed"/>
|
||||
</endorsedDirs>
|
||||
</libraryInfo>
|
||||
</libraryInfos>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,3 +1,3 @@
|
|||
#Thu Dec 31 19:48:20 CET 2020
|
||||
#Sat Jan 02 08:08:01 CET 2021
|
||||
org.eclipse.core.runtime=2
|
||||
org.eclipse.platform=4.16.0.v20200604-0540
|
||||
org.eclipse.platform=4.13.0.v20190916-1045
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -18,7 +18,7 @@ public class Application extends Canvas implements Runnable {
|
|||
private GameBoy gameBoy;
|
||||
|
||||
public Application() {
|
||||
setPreferredSize(new Dimension(640, 288));
|
||||
setPreferredSize(new Dimension(320, 288));
|
||||
|
||||
gameBoy = new GameBoy();
|
||||
gameBoy.start();
|
||||
|
|
@ -33,60 +33,39 @@ public class Application extends Canvas implements Runnable {
|
|||
|
||||
Graphics g = bs.getDrawGraphics();
|
||||
|
||||
g.setColor(Color.WHITE);
|
||||
g.fillRect(0, 0, getWidth(), getHeight());
|
||||
int[] framebuffer = gameBoy.getPPU().getFrameBuffer();
|
||||
|
||||
int lcdControl = (gameBoy.getMMU().read(0xFF40));
|
||||
for (int x = 0; x < 160; x++) {
|
||||
for (int y = 0; y < 144; y++) {
|
||||
g.setColor(new Color(framebuffer[x + y * 160]));
|
||||
g.fillRect(x * 2, y * 2, 2, 2);
|
||||
}
|
||||
}
|
||||
|
||||
int tileDataOffset = ((lcdControl & 0x10) != 0) ? 0x8000 : 0x8800;
|
||||
int bgTileMap = ((lcdControl & 0x8) != 0) ? 0x9C00 : 0x9800;
|
||||
|
||||
/*for (int tile = 0; tile < 512; tile++) {
|
||||
int tileIndex = tile;
|
||||
for (int y = 0; y < 8; y++) {
|
||||
for (int n = 0; n < 8; n++) {
|
||||
int value = (((gameBoy.getMMU().read(0x8000 + y * 2 + tileIndex * 16 + 1) >> (7 - n)) & 1) << 1) |
|
||||
(((gameBoy.getMMU().read(0x8000 + y * 2 + tileIndex * 16) >> (7 - n)) & 1));
|
||||
|
||||
g.setColor(new Color(value * 64, value * 64, value * 64));
|
||||
//if (value != 0x0)
|
||||
//g.fillRect((n + (tile % 16) * 8), (y + (tile / 16) * 8), 1, 1);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
//if ((lcdControl & 0x80) != 0) {
|
||||
for (int tileY = 0; tileY < 32; tileY++) {
|
||||
for (int tileX = 0; tileX < 32; tileX++) {
|
||||
int tileIndex = gameBoy.getMMU().read(0x9800 + (tileX + tileY * 32));
|
||||
for (int y = 0; y < 8; y++) {
|
||||
for (int n = 0; n < 8; n++) {
|
||||
int value = (((gameBoy.getMMU().read(tileDataOffset + y * 2 + tileIndex * 16 + 1) >> (7 - n)) & 1) << 1) |
|
||||
(((gameBoy.getMMU().read(tileDataOffset + y * 2 + tileIndex * 16) >> (7 - n)) & 1));
|
||||
|
||||
g.setColor(new Color(value * 64, value * 64, value * 64));
|
||||
if (value != 0x0)
|
||||
g.fillRect((n + (tileX) * 8 - gameBoy.getPPU().getRegisters().scrollX) * 2, (y + (tileY) * 8 - gameBoy.getPPU().getRegisters().scrollY) * 2, 2, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int tileY = 0; tileY < 32; tileY++) {
|
||||
for (int tileX = 0; tileX < 32; tileX++) {
|
||||
int tileIndex = gameBoy.getMMU().read(0x9C00 + (tileX + tileY * 32));
|
||||
for (int y = 0; y < 8; y++) {
|
||||
for (int n = 0; n < 8; n++) {
|
||||
int value = (((gameBoy.getMMU().read(tileDataOffset + y * 2 + tileIndex * 16 + 1) >> (7 - n)) & 1) << 1) |
|
||||
(((gameBoy.getMMU().read(tileDataOffset + y * 2 + tileIndex * 16) >> (7 - n)) & 1));
|
||||
|
||||
g.setColor(new Color(value * 64, value * 64, value * 64));
|
||||
if (value != 0x0)
|
||||
g.fillRect((n + (tileX) * 8 - gameBoy.getPPU().getRegisters().scrollX + 160) * 2, (y + (tileY) * 8 - gameBoy.getPPU().getRegisters().scrollY) * 2, 2, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//}
|
||||
// g.setColor(Color.WHITE);
|
||||
// g.fillRect(0, 0, getWidth(), getHeight());
|
||||
//
|
||||
// int lcdControl = (gameBoy.getMMU().read(0xFF40));
|
||||
//
|
||||
// int tileDataOffset = ((lcdControl & 0x10) != 0) ? 0x8000 : 0x8800;
|
||||
// int bgTileMap = ((lcdControl & 0x8) != 0) ? 0x9C00 : 0x9800;
|
||||
//
|
||||
// for (int tileY = 0; tileY < 32; tileY++) {
|
||||
// for (int tileX = 0; tileX < 32; tileX++) {
|
||||
// int tileIndex = gameBoy.getPPU().getVRAM().background0[tileX + tileY * 32];
|
||||
//
|
||||
// for (int y = 0; y < 8; y++) {
|
||||
// for (int n = 0; n < 8; n++) {
|
||||
// int value = (((gameBoy.getMMU().read(0x9000 + y * 2 + (tileIndex > 127 ? tileIndex - 256 : tileIndex) * 16 + 1) >> (7 - n)) & 1) << 1) |
|
||||
// (((gameBoy.getMMU().read(0x9000 + y * 2 + (tileIndex > 127 ? tileIndex - 256 : tileIndex) * 16) >> (7 - n)) & 1));
|
||||
//
|
||||
// g.setColor(new Color(value * 64, value * 64, value * 64));
|
||||
// if (value != 0x0)
|
||||
// g.fillRect((n + (tileX) * 8 - gameBoy.getPPU().getRegisters().scrollX) * 2, (y + (tileY) * 8 - gameBoy.getPPU().getRegisters().scrollY) * 2, 2, 2);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
g.dispose();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package playingcoffee.application;
|
||||
|
||||
import playingcoffee.core.Cartridge;
|
||||
import playingcoffee.cartridge.Cartridge;
|
||||
import playingcoffee.core.InterruptManager;
|
||||
import playingcoffee.core.MMU;
|
||||
import playingcoffee.core.cpu.CPU;
|
||||
|
|
@ -27,7 +27,7 @@ public class GameBoy implements Runnable {
|
|||
|
||||
public void init() {
|
||||
mmu.connectMemorySpace(interruptManager);
|
||||
mmu.connectMemorySpace(new Cartridge("roms/cpu_instrs.gb"));
|
||||
mmu.connectMemorySpace(new Cartridge("roms/drmario.gb").getMBC());
|
||||
}
|
||||
|
||||
public void start() {
|
||||
|
|
@ -61,6 +61,11 @@ public class GameBoy implements Runnable {
|
|||
cpu.clock();
|
||||
ppu.clock();
|
||||
interruptManager.clock();
|
||||
|
||||
if (mmu.read(0xFF02) == 0x81) {
|
||||
System.out.print((char)mmu.read(0xFF01));
|
||||
mmu.write(0, 0xFF02);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package playingcoffee.core;
|
||||
package playingcoffee.cartridge;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
|
@ -7,7 +7,7 @@ import java.nio.file.Paths;
|
|||
|
||||
import playingcoffee.log.Log;
|
||||
|
||||
public class Cartridge implements MemorySpace {
|
||||
public class Cartridge {
|
||||
|
||||
private int[] rom;
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ public class Cartridge implements MemorySpace {
|
|||
case 6: ramSize = 64 * 1024; break;
|
||||
}
|
||||
|
||||
this.mbc = MBC.create(this.rom[0x0147]);
|
||||
this.mbc = MBC.create(this.rom[0x0147], this.rom);
|
||||
|
||||
Log.info("ROM Name: %s", title);
|
||||
Log.info("Requires GBC: %s", isGameBoyColor);
|
||||
|
|
@ -61,20 +61,8 @@ public class Cartridge implements MemorySpace {
|
|||
Log.info("Cartridge Type: 0x%2x", this.rom[0x0147]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(int address) {
|
||||
return mbc.read(rom, address);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int value, int address) {
|
||||
//Log.warn("Attempting to write to ROM at address: 0x%4x.", address);
|
||||
mbc.write(value, address);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inMemorySpace(int address) {
|
||||
return address >= 0x0000 && address <= 0x7FFF;
|
||||
public MBC getMBC() {
|
||||
return mbc;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package playingcoffee.cartridge;
|
||||
|
||||
import playingcoffee.core.MemorySpace;
|
||||
|
||||
public abstract class MBC implements MemorySpace {
|
||||
|
||||
protected int[] rom;
|
||||
|
||||
protected MBC(int[] rom) {
|
||||
this.rom = rom;
|
||||
}
|
||||
|
||||
public static MBC create(int type, int[] rom) {
|
||||
switch (type) {
|
||||
case 0: return new ROMOnlyMBC(rom);
|
||||
case 1: return new MBC1(false, false, rom);
|
||||
case 2: return new MBC1(true, false, rom);
|
||||
case 3: return new MBC1(true, true, rom);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unsupported Maapper!");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,21 @@
|
|||
package playingcoffee.core;
|
||||
package playingcoffee.cartridge;
|
||||
|
||||
public class MBC1 implements MBC {
|
||||
public class MBC1 extends MBC {
|
||||
|
||||
private boolean ram;
|
||||
private boolean battery;
|
||||
|
||||
private int bank = 1;
|
||||
|
||||
public MBC1(boolean hasRAM, boolean hasBattery, int[] rom) {
|
||||
super(rom);
|
||||
|
||||
this.ram = hasRAM;
|
||||
this.battery = hasBattery;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(int[] rom, int address) {
|
||||
public int read(int address) {
|
||||
if (address >= 0x0000 && address <= 0x3FFF) {
|
||||
return rom[address];
|
||||
} else if (address >= 0x4000 && address <= 0x7FFF) {
|
||||
|
|
@ -21,4 +31,10 @@ public class MBC1 implements MBC {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inMemorySpace(int address) {
|
||||
return address >= 0x0000 && address <= 0x7FFF;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package playingcoffee.cartridge;
|
||||
|
||||
import playingcoffee.log.Log;
|
||||
|
||||
public class ROMOnlyMBC extends MBC {
|
||||
|
||||
protected ROMOnlyMBC(int[] rom) {
|
||||
super(rom);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(int address) {
|
||||
return rom[address];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int value, int address) {
|
||||
// Don't do anything
|
||||
Log.warn("Attempting to write to rom at address: 0x%4x.", address);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inMemorySpace(int address) {
|
||||
return address >= 0x0000 && address <= 0x7FFF;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
package playingcoffee.core;
|
||||
|
||||
public interface MBC {
|
||||
|
||||
public int read(int[] rom, int address);
|
||||
public void write(int value, int address);
|
||||
|
||||
public static MBC create(int type) {
|
||||
switch (type) {
|
||||
case 0: return new ROMOnlyMBC();
|
||||
case 1: return new MBC1();
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unsupported Maapper!");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
package playingcoffee.core;
|
||||
|
||||
import playingcoffee.log.Log;
|
||||
|
||||
public class ROMOnlyMBC implements MBC {
|
||||
|
||||
@Override
|
||||
public int read(int[] rom, int address) {
|
||||
return rom[address];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int value, int address) {
|
||||
// Don't do anything
|
||||
Log.warn("Attempting to write to rom at address: 0x%4x.", address);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,12 +1,31 @@
|
|||
package playingcoffee.core.opcode;
|
||||
|
||||
import playingcoffee.core.MMU;
|
||||
import playingcoffee.core.cpu.Flags;
|
||||
import playingcoffee.core.cpu.Registers;
|
||||
|
||||
public class BCDOpcode implements Opcode {
|
||||
|
||||
@Override
|
||||
public int run(Registers registers, MMU mmu) {
|
||||
// TODO: Learn what this opcode actually does.
|
||||
|
||||
int s = registers.getA();
|
||||
|
||||
if (registers.getFlags().get(Flags.NEGATIVE)) {
|
||||
if (registers.getFlags().get(Flags.HALF_CARRY)) s = (s - 0x06) & 0xFF;
|
||||
if (registers.getFlags().get(Flags.CARRY)) s = (s - 0x60) & 0xFFFF;
|
||||
} else {
|
||||
if (registers.getFlags().get(Flags.HALF_CARRY) || (s & 0xF) > 9) s = (s + 0x06) & 0xFFFF;
|
||||
if (registers.getFlags().get(Flags.CARRY) || s > 0x9F) s = (s + 0x60) & 0xFFFF;
|
||||
}
|
||||
|
||||
registers.setA(s);
|
||||
|
||||
registers.getFlags().set(Flags.ZERO, registers.getA() == 0);
|
||||
registers.getFlags().set(Flags.HALF_CARRY, false);
|
||||
registers.getFlags().set(Flags.CARRY, s >= 0x100);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ public class Log {
|
|||
|
||||
ansiColor = useColors ? ansiColor : "";
|
||||
|
||||
System.out.println(ansiColor + finalMessage);
|
||||
//System.out.println(ansiColor + finalMessage);
|
||||
try {
|
||||
fileWriter.write(finalMessage + "\n");
|
||||
} catch (IOException e) {
|
||||
|
|
|
|||
|
|
@ -13,12 +13,21 @@ public class PPU {
|
|||
|
||||
private int clockCount = 0;
|
||||
|
||||
private int[] framebuffer;
|
||||
|
||||
public static final int HBLANK = 0;
|
||||
public static final int VBLANK = 1;
|
||||
public static final int OAM_SEARCH = 2;
|
||||
public static final int PIXEL_TRANSFER = 3;
|
||||
|
||||
public PPU(final MMU mmu, final InterruptManager interruptManager) {
|
||||
this.mmu = mmu;
|
||||
this.interruptManager = interruptManager;
|
||||
|
||||
registers = new PPURegisters(this);
|
||||
vram = new VRAM();
|
||||
vram = new VRAM(this);
|
||||
|
||||
framebuffer = new int[160 * 144];
|
||||
|
||||
this.mmu.connectMemorySpace(registers);
|
||||
this.mmu.connectMemorySpace(vram);
|
||||
|
|
@ -29,26 +38,29 @@ public class PPU {
|
|||
}
|
||||
|
||||
public void OAMSeach() {
|
||||
registers.setLCDCMode(2);
|
||||
registers.setLCDCMode(OAM_SEARCH);
|
||||
}
|
||||
|
||||
public void pixelTransfer() {
|
||||
registers.setLCDCMode(3);
|
||||
registers.setLCDCMode(PIXEL_TRANSFER);
|
||||
}
|
||||
|
||||
public void HBlank() {
|
||||
registers.setLCDCMode(0);
|
||||
registers.setLCDCMode(HBLANK);
|
||||
}
|
||||
|
||||
public void VBlank() {
|
||||
registers.setLCDCMode(1);
|
||||
registers.setLCDCMode(VBLANK);
|
||||
}
|
||||
|
||||
public void clock() {
|
||||
registers.lcdcYCoord = clockCount / 114;
|
||||
|
||||
if (clockCount == 114 * 144)
|
||||
if (clockCount == 144 * 114) renderToFramebuffer();
|
||||
if (clockCount == 114 * 144) {
|
||||
interruptManager.requestInterrupt(InterruptManager.VBLANK);
|
||||
}
|
||||
|
||||
|
||||
if (clockCount < 114 * 144) {
|
||||
if (clockCount % 114 < 20) OAMSeach();
|
||||
|
|
@ -66,12 +78,53 @@ public class PPU {
|
|||
}
|
||||
}
|
||||
|
||||
private void putPixel(int pixel, int x, int y) {
|
||||
if (x >= 0 && x < 160 && y >= 0 && y < 144) framebuffer[x + y * 160] = pixel;
|
||||
}
|
||||
|
||||
private void putTile(int address, int screenX, int screenY) {
|
||||
for (int y = 0; y < 8; y++) {
|
||||
for (int n = 0; n < 8; n++) {
|
||||
int value = ((vram.vram[address + y * 2] >> (7 - n)) & 1) |
|
||||
(((vram.vram[address + y * 2 + 1] >> (7 - n)) & 1) << 1);
|
||||
|
||||
int color = (value * 64) | ((value * 64) << 8) | ((value * 64) << 16);
|
||||
|
||||
putPixel(color, screenX + n, screenY + y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void renderToFramebuffer() {
|
||||
boolean backgroundTileDataSelect = (registers.lcdControl & 0x10) != 0;
|
||||
int[] backgroundMap = (registers.lcdControl & 0x8) != 0 ? vram.background1 : vram.background0;
|
||||
|
||||
for (int tileY = 0; tileY < 32; tileY++) {
|
||||
for (int tileX = 0; tileX < 32; tileX++) {
|
||||
int tileIndex = backgroundMap[tileX + tileY * 32];
|
||||
|
||||
int tileAddress = tileIndex * 16;
|
||||
|
||||
if (!backgroundTileDataSelect) {
|
||||
if (tileIndex >= 128) tileIndex -= 256;
|
||||
tileAddress = 0x1000 + tileIndex * 16;
|
||||
}
|
||||
|
||||
putTile(tileAddress, tileX * 8 - registers.scrollX, tileY * 8 - registers.scrollY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public PPURegisters getRegisters() {
|
||||
return registers;
|
||||
}
|
||||
|
||||
public VRAM getVram() {
|
||||
public VRAM getVRAM() {
|
||||
return vram;
|
||||
}
|
||||
|
||||
public int[] getFrameBuffer() {
|
||||
return framebuffer;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,10 @@ public class PPURegisters implements MemorySpace {
|
|||
lcdcStatus = (lcdcStatus & 0xFC) | mode;
|
||||
}
|
||||
|
||||
public int getLCDCMode() {
|
||||
return lcdcStatus & 0x3;
|
||||
}
|
||||
|
||||
public int read(int address) {
|
||||
switch (address) {
|
||||
case 0xFF40: return lcdControl;
|
||||
|
|
|
|||
|
|
@ -4,16 +4,27 @@ import playingcoffee.core.MemorySpace;
|
|||
|
||||
public class VRAM implements MemorySpace {
|
||||
|
||||
public int[] vram;
|
||||
|
||||
public int[] background0;
|
||||
public int[] background1;
|
||||
|
||||
public VRAM() {
|
||||
private final PPU ppu;
|
||||
|
||||
public VRAM(final PPU ppu) {
|
||||
vram = new int[0x1800];
|
||||
|
||||
background0 = new int[32 * 32];
|
||||
background1 = new int[32 * 32];
|
||||
|
||||
this.ppu = ppu;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(int address) {
|
||||
if (ppu.getRegisters().getLCDCMode() == PPU.PIXEL_TRANSFER) return 0xFF;
|
||||
|
||||
if (address >= 0x8000 && address <= 0x97FF) return vram[address - 0x8000];
|
||||
if (address >= 0x9800 && address <= 0x9BFF) return background0[address % (32 * 32)];
|
||||
if (address >= 0x9C00 && address <= 0x9FFF) return background1[address % (32 * 32)];
|
||||
|
||||
|
|
@ -22,14 +33,16 @@ public class VRAM implements MemorySpace {
|
|||
|
||||
@Override
|
||||
public void write(int value, int address) {
|
||||
if (ppu.getRegisters().getLCDCMode() == PPU.PIXEL_TRANSFER) return;
|
||||
|
||||
if (address >= 0x8000 && address <= 0x97FF) vram[address - 0x8000] = value;
|
||||
if (address >= 0x9800 && address <= 0x9BFF) background0[address % (32 * 32)] = value;
|
||||
if (address >= 0x9C00 && address <= 0x9FFF) background1[address % (32 * 32)] = value;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inMemorySpace(int address) {
|
||||
return address >= 0x9800 && address <= 0x9FFF;
|
||||
return address >= 0x8000 && address <= 0x9FFF;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue