Bug fixes

main
Sixten Hugosson 2021-01-01 11:49:25 +01:00
parent 1734741725
commit 1302f6a59c
70 changed files with 8610 additions and 3174 deletions

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@ -6,3 +6,4 @@
*** SESSION Dec 29, 2020 20:45:41.12 ------------------------------------------- *** SESSION Dec 29, 2020 20:45:41.12 -------------------------------------------
*** SESSION Dec 30, 2020 07:33:14.96 ------------------------------------------- *** SESSION Dec 30, 2020 07:33:14.96 -------------------------------------------
*** SESSION Dec 31, 2020 06:46:47.09 ------------------------------------------- *** SESSION Dec 31, 2020 06:46:47.09 -------------------------------------------
*** SESSION Dec 31, 2020 19:47:23.71 -------------------------------------------

View File

@ -1,2 +1,2 @@
eclipse.preferences.version=1 eclipse.preferences.version=1
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\="&lt;?xml version\=&quot;1.0&quot; encoding\=&quot;UTF-8&quot; standalone\=&quot;no&quot;?&gt;&\#13;&\#10;&lt;project referencedProjects\=&quot;true&quot;/&gt;&\#13;&\#10;" typeId\="org.eclipse.cdt.debug.core.containerType.project"/>\r\n</sourceContainers>\r\n</sourceLookupDirector>\r\n 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\="&lt;?xml version\=&quot;1.0&quot; encoding\=&quot;UTF-8&quot; standalone\=&quot;no&quot;?&gt;&\#10;&lt;project referencedProjects\=&quot;true&quot;/&gt;&\#10;" typeId\="org.eclipse.cdt.debug.core.containerType.project"/>\n </sourceContainers>\n</sourceLookupDirector>\n

View File

@ -1,9 +1,9 @@
eclipse.preferences.version=1 eclipse.preferences.version=1
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.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"?>\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 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
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.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.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> 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>
pref_state_memento.org.eclipse.debug.ui.VariableView=<?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<COLUMN_SIZES IMemento.internal.id\="org.eclipse.debug.ui.VARIALBE_COLUMN_PRESENTATION.COL_VAR_VALUE" SIZE\="359"/>\r\n<COLUMN_SIZES IMemento.internal.id\="org.eclipse.debug.ui.VARIALBE_COLUMN_PRESENTATION.COL_VAR_NAME" SIZE\="316"/>\r\n<PRESENTATION_CONTEXT_PROPERTIES IMemento.internal.id\="org.eclipse.debug.ui.VariableView">\r\n<BOOLEAN BOOLEAN\="true" IMemento.internal.id\="PRESENTATION_SHOW_LOGICAL_STRUCTURES"/>\r\n</PRESENTATION_CONTEXT_PROPERTIES>\r\n</VariablesViewMemento> pref_state_memento.org.eclipse.debug.ui.VariableView=<?xml version\="1.0" encoding\="UTF-8"?>\n<VariablesViewMemento org.eclipse.debug.ui.SASH_DETAILS_PART\="315" org.eclipse.debug.ui.SASH_VIEW_PART\="684">\n<COLUMN_SIZES IMemento.internal.id\="org.eclipse.debug.ui.VARIALBE_COLUMN_PRESENTATION.COL_VAR_VALUE" SIZE\="359"/>\n<COLUMN_SIZES IMemento.internal.id\="org.eclipse.debug.ui.VARIALBE_COLUMN_PRESENTATION.COL_VAR_NAME" SIZE\="316"/>\n<PRESENTATION_CONTEXT_PROPERTIES IMemento.internal.id\="org.eclipse.debug.ui.VariableView">\n<BOOLEAN BOOLEAN\="true" IMemento.internal.id\="PRESENTATION_SHOW_LOGICAL_STRUCTURES"/>\n</PRESENTATION_CONTEXT_PROPERTIES>\n</VariablesViewMemento>
preferredDetailPanes=DefaultDetailPane,org.eclipse.jdt.debug.ui.JAVA_VARIABLE_DETAIL_PANE_VARIABLES\:org.eclipse.jdt.debug.ui.JAVA_VARIABLE_DETAIL_PANE_VARIABLES|org.eclipse.jdt.debug.ui.DETAIL_PANE_LINE_BREAKPOINT\:org.eclipse.jdt.debug.ui.DETAIL_PANE_LINE_BREAKPOINT|DefaultDetailPane\:DefaultDetailPane| preferredDetailPanes=DefaultDetailPane,org.eclipse.jdt.debug.ui.JAVA_VARIABLE_DETAIL_PANE_VARIABLES\:org.eclipse.jdt.debug.ui.JAVA_VARIABLE_DETAIL_PANE_VARIABLES|org.eclipse.jdt.debug.ui.DETAIL_PANE_LINE_BREAKPOINT\:org.eclipse.jdt.debug.ui.DETAIL_PANE_LINE_BREAKPOINT|DefaultDetailPane\:DefaultDetailPane|
preferredTargets=default\:default| preferredTargets=default\:default|org.eclipse.cdt.debug.ui.toggleCBreakpointTarget,org.eclipse.cdt.debug.ui.toggleCDynamicPrintfTarget\:org.eclipse.cdt.debug.ui.toggleCBreakpointTarget|

View File

@ -1,8 +1,20 @@
eclipse.preferences.version=1 eclipse.preferences.version=1
org.eclipse.jdt.core.codeComplete.argumentPrefixes=
org.eclipse.jdt.core.codeComplete.argumentSuffixes=
org.eclipse.jdt.core.codeComplete.fieldPrefixes=
org.eclipse.jdt.core.codeComplete.fieldSuffixes=
org.eclipse.jdt.core.codeComplete.localPrefixes=
org.eclipse.jdt.core.codeComplete.localSuffixes=
org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
org.eclipse.jdt.core.codeComplete.visibilityCheck=enabled org.eclipse.jdt.core.codeComplete.visibilityCheck=enabled
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.timeoutForParameterNameFromAttachedJavadoc=50

View File

@ -1,2 +1,2 @@
eclipse.preferences.version=1 eclipse.preferences.version=1
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,1608703468908" defaultVMConnector\="">\r\n<vmType id\="org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType">\r\n<vm id\="1608703468908" name\="jdk1.8.0_91" path\="C\:\\Program Files\\Java\\jdk1.8.0_91"/>\r\n</vmType>\r\n</vmSettings>\r\n 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

View File

@ -1,12 +1,20 @@
content_assist_disabled_computers=org.eclipse.jdt.ui.textProposalCategory\u0000org.eclipse.jdt.ui.javaAllProposalCategory\u0000org.eclipse.jdt.ui.javaTypeProposalCategory\u0000org.eclipse.jdt.ui.javaNoTypeProposalCategory\u0000org.eclipse.jdt.ui.javaChainProposalCategory\u0000 content_assist_disabled_computers=org.eclipse.jdt.ui.swtProposalCategory\u0000org.eclipse.jdt.ui.textProposalCategory\u0000org.eclipse.jdt.ui.javaPostfixProposalCategory\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_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=19 content_assist_number_of_computers=12
content_assist_proposals_background=255,255,255 content_assist_proposals_background=255,255,255
content_assist_proposals_foreground=0,0,0 content_assist_proposals_foreground=0,0,0
eclipse.preferences.version=1 eclipse.preferences.version=1
org.eclipse.jdt.internal.ui.navigator.layout=2 org.eclipse.jdt.internal.ui.navigator.layout=2
org.eclipse.jdt.internal.ui.navigator.librariesnode=true org.eclipse.jdt.internal.ui.navigator.librariesnode=true
org.eclipse.jdt.ui.formatterprofiles.version=17 org.eclipse.jdt.ui.exception.name=e
org.eclipse.jdt.ui.formatterprofiles.version=19
org.eclipse.jdt.ui.gettersetter.use.is=true
org.eclipse.jdt.ui.ignorelowercasenames=true
org.eclipse.jdt.ui.importorder=java;javax;org;com;
org.eclipse.jdt.ui.ondemandthreshold=99
org.eclipse.jdt.ui.overrideannotation=true
org.eclipse.jdt.ui.staticondemandthreshold=99
org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates/>
sourceHoverBackgroundColor=255,255,225 sourceHoverBackgroundColor=255,255,225
spelling_locale=en_GB spelling_locale=en_GB
spelling_locale_initialized=true spelling_locale_initialized=true

View File

@ -2,9 +2,9 @@
<launchHistory> <launchHistory>
<launchGroup id="org.eclipse.debug.ui.launchGroup.debug"> <launchGroup id="org.eclipse.debug.ui.launchGroup.debug">
<mruHistory> <mruHistory>
<launch memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;launchConfiguration local=&quot;true&quot; path=&quot;Application&quot;/&gt;&#13;&#10;"/> <launch memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;launchConfiguration local=&quot;true&quot; path=&quot;Application&quot;/&gt;&#10;"/>
<launch memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;launchConfiguration local=&quot;true&quot; path=&quot;GameBoyTest&quot;/&gt;&#13;&#10;"/> <launch memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;launchConfiguration local=&quot;true&quot; path=&quot;GameBoyTest&quot;/&gt;&#10;"/>
<launch memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;launchConfiguration local=&quot;true&quot; path=&quot;CPUDebugger&quot;/&gt;&#13;&#10;"/> <launch memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;launchConfiguration local=&quot;true&quot; path=&quot;CPUDebugger&quot;/&gt;&#10;"/>
</mruHistory> </mruHistory>
<favorites/> <favorites/>
</launchGroup> </launchGroup>
@ -14,9 +14,9 @@
</launchGroup> </launchGroup>
<launchGroup id="org.eclipse.eclemma.ui.launchGroup.coverage"> <launchGroup id="org.eclipse.eclemma.ui.launchGroup.coverage">
<mruHistory> <mruHistory>
<launch memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;launchConfiguration local=&quot;true&quot; path=&quot;Application&quot;/&gt;&#13;&#10;"/> <launch memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;launchConfiguration local=&quot;true&quot; path=&quot;Application&quot;/&gt;&#10;"/>
<launch memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;launchConfiguration local=&quot;true&quot; path=&quot;GameBoyTest&quot;/&gt;&#13;&#10;"/> <launch memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;launchConfiguration local=&quot;true&quot; path=&quot;GameBoyTest&quot;/&gt;&#10;"/>
<launch memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;launchConfiguration local=&quot;true&quot; path=&quot;CPUDebugger&quot;/&gt;&#13;&#10;"/> <launch memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;launchConfiguration local=&quot;true&quot; path=&quot;CPUDebugger&quot;/&gt;&#10;"/>
</mruHistory> </mruHistory>
<favorites/> <favorites/>
</launchGroup> </launchGroup>
@ -26,9 +26,9 @@
</launchGroup> </launchGroup>
<launchGroup id="org.eclipse.debug.ui.launchGroup.run"> <launchGroup id="org.eclipse.debug.ui.launchGroup.run">
<mruHistory> <mruHistory>
<launch memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;launchConfiguration local=&quot;true&quot; path=&quot;Application&quot;/&gt;&#13;&#10;"/> <launch memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;launchConfiguration local=&quot;true&quot; path=&quot;Application&quot;/&gt;&#10;"/>
<launch memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;launchConfiguration local=&quot;true&quot; path=&quot;GameBoyTest&quot;/&gt;&#13;&#10;"/> <launch memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;launchConfiguration local=&quot;true&quot; path=&quot;GameBoyTest&quot;/&gt;&#10;"/>
<launch memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;launchConfiguration local=&quot;true&quot; path=&quot;CPUDebugger&quot;/&gt;&#13;&#10;"/> <launch memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;launchConfiguration local=&quot;true&quot; path=&quot;CPUDebugger&quot;/&gt;&#10;"/>
</mruHistory> </mruHistory>
<favorites/> <favorites/>
</launchGroup> </launchGroup>

File diff suppressed because one or more lines are too long

View File

@ -1,22 +1,4 @@
INDEX VERSION 1.131+C:\dev\playing-coffee\.metadata\.plugins\org.eclipse.jdt.core INDEX VERSION 1.131+/home/sixten/Documents/playing-coffee/.metadata/.plugins/org.eclipse.jdt.core
3964923001.index 1558221869.index
3618832045.index 908895367.index
699245563.index 1819307639.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

View File

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<dirs> <dirs>
<entry loc="C:\Program Files\Java\jdk1.8.0_91" stamp="1466445490137"/> <entry loc="C:\Program Files\Java\jdk1.8.0_91" stamp="1466445490137"/>
<entry loc="/app/jdk" stamp="0"/>
</dirs> </dirs>

View File

@ -19,4 +19,5 @@
<entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\endorsed"/> <entry path="C:\Program Files\Java\jdk1.8.0_91\jre\lib\endorsed"/>
</endorsedDirs> </endorsedDirs>
</libraryInfo> </libraryInfo>
<libraryInfo home="/app/jdk" version="11.0.7"/>
</libraryInfos> </libraryInfos>

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,3 @@
#Thu Dec 31 06:46:38 CET 2020 #Thu Dec 31 19:48:20 CET 2020
org.eclipse.core.runtime=2 org.eclipse.core.runtime=2
org.eclipse.platform=4.13.0.v20190916-1045 org.eclipse.platform=4.16.0.v20200604-0540

View File

@ -6,11 +6,6 @@
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java"> <classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes> <attributes>
<attribute name="test" value="true"/> <attribute name="test" value="true"/>
@ -18,14 +13,9 @@
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="test" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes> <attributes>
<attribute name="module" value="true"/>
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
</attributes> </attributes>
</classpathentry> </classpathentry>

Binary file not shown.

View File

@ -40,7 +40,7 @@ public class Application extends Canvas implements Runnable {
int tileDataOffset = ((lcdControl & 0x10) != 0) ? 0x8000 : 0x8800; int tileDataOffset = ((lcdControl & 0x10) != 0) ? 0x8000 : 0x8800;
for (int tile = 0; tile < 512; tile++) { /*for (int tile = 0; tile < 512; tile++) {
int tileIndex = tile; int tileIndex = tile;
for (int y = 0; y < 8; y++) { for (int y = 0; y < 8; y++) {
for (int n = 0; n < 8; n++) { for (int n = 0; n < 8; n++) {
@ -48,11 +48,11 @@ public class Application extends Canvas implements Runnable {
(((gameBoy.getMMU().read(0x8000 + y * 2 + tileIndex * 16) >> (7 - n)) & 1)); (((gameBoy.getMMU().read(0x8000 + y * 2 + tileIndex * 16) >> (7 - n)) & 1));
g.setColor(new Color(value * 64, value * 64, value * 64)); g.setColor(new Color(value * 64, value * 64, value * 64));
if (value != 0x0) //if (value != 0x0)
g.fillRect((n + (tile % 16) * 8), (y + (tile / 16) * 8), 1, 1); //g.fillRect((n + (tile % 16) * 8), (y + (tile / 16) * 8), 1, 1);
}
} }
} }
}*/
if ((lcdControl & 0x80) != 0) { if ((lcdControl & 0x80) != 0) {
for (int tileY = 0; tileY < 32; tileY++) { for (int tileY = 0; tileY < 32; tileY++) {

View File

@ -23,9 +23,11 @@ public class GameBoy implements Runnable {
ppu = new PPU(mmu, interruptManager); ppu = new PPU(mmu, interruptManager);
cpu = new CPU(mmu, interruptManager); cpu = new CPU(mmu, interruptManager);
}
public void init() {
mmu.connectMemorySpace(interruptManager); mmu.connectMemorySpace(interruptManager);
mmu.connectMemorySpace(new Cartridge("roms/kwirk.gb")); mmu.connectMemorySpace(new Cartridge("roms/supermarioland.gb"));
} }
public void start() { public void start() {
@ -52,10 +54,12 @@ public class GameBoy implements Runnable {
public void run() { public void run() {
Log.init(); Log.init();
init();
while (running) { while (running) {
for (int i = 0; i < 8192; i++) { for (int i = 0; i < 8192; i++) {
ppu.clock();
cpu.clock(); cpu.clock();
ppu.clock();
interruptManager.clock(); interruptManager.clock();
} }

View File

@ -1,6 +1,7 @@
package playingcoffee.core; package playingcoffee.core;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
@ -10,6 +11,13 @@ public class Cartridge implements MemorySpace {
private int[] rom; private int[] rom;
private String title;
private boolean isGameBoyColor;
private int romSize;
private int ramSize;
private MBC mbc;
public Cartridge(String rom) { public Cartridge(String rom) {
byte[] bin = null; byte[] bin = null;
@ -24,16 +32,44 @@ public class Cartridge implements MemorySpace {
for (int i = 0; i < bin.length; i++) { for (int i = 0; i < bin.length; i++) {
this.rom[i] = Byte.toUnsignedInt(bin[i]); this.rom[i] = Byte.toUnsignedInt(bin[i]);
} }
byte[] binTitle = new byte[0x10];
for (int i = 0; i < 0x10; i++) {
binTitle[i] = bin[0x0134 + i];
}
this.title = new String(binTitle, StandardCharsets.US_ASCII);
this.isGameBoyColor = this.rom[0x0143] == 0xC0;
this.romSize = (32 * 1024) << this.rom[0x0148];
switch (this.rom[0x0149]) {
case 0: ramSize = 0; break;
case 1: ramSize = 2 * 1024; break;
case 2: ramSize = 8 * 1024; break;
case 4: ramSize = 32 * 1024; break;
case 5: ramSize = 128 * 1024; break;
case 6: ramSize = 64 * 1024; break;
}
this.mbc = MBC.create(this.rom[0x0147]);
Log.info("ROM Name: %s", title);
Log.info("Requires GBC: %s", isGameBoyColor);
Log.info("ROM Size: %s", romSize);
Log.info("RAM Size: %s", ramSize);
Log.info("Cartridge Type: 0x%2x", this.rom[0x0147]);
} }
@Override @Override
public int read(int address) { public int read(int address) {
return rom[address]; return mbc.read(rom, address);
} }
@Override @Override
public void write(int value, int address) { public void write(int value, int address) {
Log.warn("Attempting to write to ROM at address: 0x%4x.", address); //Log.warn("Attempting to write to ROM at address: 0x%4x.", address);
mbc.write(value, address);
} }
@Override @Override

View File

@ -0,0 +1,16 @@
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!");
}
}

View File

@ -0,0 +1,24 @@
package playingcoffee.core;
public class MBC1 implements MBC {
private int bank = 1;
@Override
public int read(int[] rom, int address) {
if (address >= 0x0000 && address <= 0x3FFF) {
return rom[address];
} else if (address >= 0x4000 && address <= 0x7FFF) {
return rom[(address % 0x4000) + bank * 0x4000];
}
return 0;
}
@Override
public void write(int value, int address) {
if (address >= 0x2000 && address <= 0x3FFF) {
bank = ((value & 0x1F) == 0) ? 1 : (value & 0x1F);
}
}
}

View File

@ -6,6 +6,8 @@ import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import playingcoffee.core.cpu.Registers;
public class MMU { public class MMU {
private int[] memory; private int[] memory;
@ -87,6 +89,23 @@ public class MMU {
memory[address] = value & 0xFF; memory[address] = value & 0xFF;
} }
public int popStack(Registers registers) {
int value = read(registers.getSP());
registers.incSP();
value |= read(registers.getSP()) << 8;
registers.incSP();
return value;
}
public void pushStack(int value, Registers registers) {
registers.decSP();
write(value >> 8, registers.getSP());
registers.decSP();
write(value, registers.getSP());
}
public int[] getMemory() { public int[] getMemory() {
return memory; return memory;
} }

View File

@ -0,0 +1,18 @@
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);
}
}

View File

@ -12,6 +12,7 @@ import playingcoffee.core.opcode.ALU16Opcode.ALU16Type;
import playingcoffee.core.opcode.ALUOpcode; import playingcoffee.core.opcode.ALUOpcode;
import playingcoffee.core.opcode.ALUOpcode.ALUType; import playingcoffee.core.opcode.ALUOpcode.ALUType;
import playingcoffee.core.opcode.Argument; import playingcoffee.core.opcode.Argument;
import playingcoffee.core.opcode.BCDOpcode;
import playingcoffee.core.opcode.CallOpcode; import playingcoffee.core.opcode.CallOpcode;
import playingcoffee.core.opcode.ComplementOpcode; import playingcoffee.core.opcode.ComplementOpcode;
import playingcoffee.core.opcode.FlipCarryOpcode; import playingcoffee.core.opcode.FlipCarryOpcode;
@ -26,6 +27,7 @@ import playingcoffee.core.opcode.RestartOpcode;
import playingcoffee.core.opcode.ReturnOpcode; import playingcoffee.core.opcode.ReturnOpcode;
import playingcoffee.core.opcode.RotateAOpcode; import playingcoffee.core.opcode.RotateAOpcode;
import playingcoffee.core.opcode.SetCarryOpcode; import playingcoffee.core.opcode.SetCarryOpcode;
import playingcoffee.core.opcode.StopOpcode;
import playingcoffee.core.opcode.prefixed.BitOpcode; import playingcoffee.core.opcode.prefixed.BitOpcode;
import playingcoffee.core.opcode.prefixed.ResetBitOpcode; import playingcoffee.core.opcode.prefixed.ResetBitOpcode;
import playingcoffee.core.opcode.prefixed.RotateOpcode; import playingcoffee.core.opcode.prefixed.RotateOpcode;
@ -44,6 +46,8 @@ public class CPU implements InterruptListener {
private int cycles; private int cycles;
private boolean lowPowerMode = false;
Opcode[] opcodes; Opcode[] opcodes;
Opcode[] prefixedOpcodes; Opcode[] prefixedOpcodes;
@ -127,6 +131,7 @@ public class CPU implements InterruptListener {
} }
// TODO: Override 0x76 with HALT // TODO: Override 0x76 with HALT
opcodes[0x76] = new StopOpcode(this);
// Jumps, Calls and Returns // Jumps, Calls and Returns
opcodes[0x20] = new JumpRelativeOpcode(Flags.ZERO, Argument.I8, true); opcodes[0x20] = new JumpRelativeOpcode(Flags.ZERO, Argument.I8, true);
@ -203,6 +208,9 @@ public class CPU implements InterruptListener {
opcodes[0xFB] = new InterruptOpcode(true, interruptManager); opcodes[0xFB] = new InterruptOpcode(true, interruptManager);
// Misc // Misc
opcodes[0x10] = new StopOpcode(this);
opcodes[0x27] = new BCDOpcode();
opcodes[0x2F] = new ComplementOpcode(); opcodes[0x2F] = new ComplementOpcode();
opcodes[0x37] = new SetCarryOpcode(); opcodes[0x37] = new SetCarryOpcode();
opcodes[0x3F] = new FlipCarryOpcode(); opcodes[0x3F] = new FlipCarryOpcode();
@ -263,10 +271,12 @@ public class CPU implements InterruptListener {
} }
public void clock() { public void clock() {
if (lowPowerMode) return;
if (cycles == 0) { if (cycles == 0) {
//Log.info("PC: 0x%4x", registers.getPC()); //Log.info("PC: 0x%4x", registers.getPC());
if (registers.getPC() == 0x2EFC) { if (registers.getPC() == 0x02cd) {
Log.info("Breakpoint."); Log.info("Breakpoint.");
} }
@ -296,8 +306,6 @@ public class CPU implements InterruptListener {
Log.close(); Log.close();
throw new IllegalStateException(); throw new IllegalStateException();
//System.exit(0);
} }
//Log.info("Executing opcode: 0x%2x (%s)", opcodeValue, opcode.toString()); //Log.info("Executing opcode: 0x%2x (%s)", opcodeValue, opcode.toString());
@ -313,30 +321,35 @@ public class CPU implements InterruptListener {
Log.close(); Log.close();
throw new IllegalStateException(); throw new IllegalStateException();
//System.exit(0);
} }
//Log.info("Executing prefixed opcode: 0x%2x (%s)", opcodeValue, opcode.toString()); //Log.info("Executing prefixed opcode: 0x%2x (%s)", opcodeValue, opcode.toString());
cycles += opcode.run(registers, mmu) + 8; // Adding 8 because we fetch the 0xCB prefix and the instruction. cycles += opcode.run(registers, mmu) + 8; // Adding 8 because we fetch the 0xCB prefix and the instruction.
} }
public void enterLowPowerMode() {
lowPowerMode = true;
}
public void exitLowPowerMode() {
lowPowerMode = false;
}
@Override @Override
public void interruptOccured(int types) { public void interruptOccured(int types) {
/*if ((types & InterruptManager.VBLANK) != 0) { if ((types & InterruptManager.VBLANK) != 0) {
interruptManager.disable(); interruptManager.disable();
lowPowerMode = false;
registers.decSP(); mmu.pushStack(registers.getPC(), registers);
mmu.write(registers.getPC() >> 8, registers.getSP());
registers.decSP();
mmu.write(registers.getPC(), registers.getSP());
Log.info("Pushing 0x%4x to the stack.", registers.getPC()); Log.info("Pushing 0x%4x to the stack.", registers.getPC());
Log.info("Firing V-Blank");
registers.setPC(0x40); registers.setPC(0x40);
cycles += 12; cycles += 12;
}*/ }
} }

View File

@ -31,10 +31,10 @@ public class ALU16Opcode implements Opcode {
result = registers.getHL() + value; result = registers.getHL() + value;
registers.getFlags().set(Flags.NEGATIVE, false); registers.getFlags().set(Flags.NEGATIVE, false);
registers.getFlags().set(Flags.HALF_CARRY, ((value & 0xF) + (registers.getHL() & 0xF) > 0xF)); registers.getFlags().set(Flags.HALF_CARRY, ((value & 0xF0) + (registers.getHL() & 0xF0) > 0xF0));
registers.getFlags().set(Flags.CARRY, (result & 0xFFFF0000) != 0); registers.getFlags().set(Flags.CARRY, (result & 0xFFFF0000) != 0);
register.write(result, registers, mmu); registers.setHL(result);
break; break;
default: default:
@ -42,7 +42,7 @@ public class ALU16Opcode implements Opcode {
break; break;
} }
return register.getCycles() + 4; return register.getCycles() * (type == ALU16Type.ADD ? 1 : 2);
} }
public enum ALU16Type { public enum ALU16Type {

View File

@ -30,7 +30,7 @@ public class ALUOpcode implements Opcode {
registers.getFlags().set(Flags.CARRY, (result & 0xFF00) > 0); registers.getFlags().set(Flags.CARRY, (result & 0xFF00) > 0);
break; break;
case ADC: case ADC: // NOTE: Tetris does not use this opcode.
int value = registerValue + (registers.getFlags().get(Flags.CARRY) ? 1 : 0); int value = registerValue + (registers.getFlags().get(Flags.CARRY) ? 1 : 0);
result = registers.getA() + value; result = registers.getA() + value;
@ -51,8 +51,6 @@ public class ALUOpcode implements Opcode {
break; break;
case CP: case CP:
result = registers.getA();
registers.getFlags().set(Flags.ZERO, registers.getA() == registerValue); registers.getFlags().set(Flags.ZERO, registers.getA() == registerValue);
registers.getFlags().set(Flags.NEGATIVE, true); registers.getFlags().set(Flags.NEGATIVE, true);
registers.getFlags().set(Flags.HALF_CARRY, (registerValue & 0xF) > (registers.getA() & 0xF)); registers.getFlags().set(Flags.HALF_CARRY, (registerValue & 0xF) > (registers.getA() & 0xF));
@ -66,7 +64,7 @@ public class ALUOpcode implements Opcode {
registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY | Flags.CARRY, false); registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY | Flags.CARRY, false);
break; break;
case SBC: case SBC: // NOTE: Tetris does not use this opcode.
value = registerValue + (registers.getFlags().get(Flags.CARRY) ? 1 : 0); value = registerValue + (registers.getFlags().get(Flags.CARRY) ? 1 : 0);
registers.getFlags().set(Flags.ZERO, value == registers.getA()); registers.getFlags().set(Flags.ZERO, value == registers.getA());
@ -80,7 +78,7 @@ public class ALUOpcode implements Opcode {
case SUB: case SUB:
registers.getFlags().set(Flags.ZERO, registerValue == registers.getA()); registers.getFlags().set(Flags.ZERO, registerValue == registers.getA());
registers.getFlags().set(Flags.NEGATIVE, true); registers.getFlags().set(Flags.NEGATIVE, true);
registers.getFlags().set(Flags.HALF_CARRY, registerValue > (registers.getA() & 0xF)); registers.getFlags().set(Flags.HALF_CARRY, (registerValue & 0xF) > (registers.getA() & 0xF));
registers.getFlags().set(Flags.CARRY, registerValue > registers.getA()); registers.getFlags().set(Flags.CARRY, registerValue > registers.getA());
result = registers.getA() - registerValue; result = registers.getA() - registerValue;
@ -116,7 +114,7 @@ public class ALUOpcode implements Opcode {
break; break;
} }
if (type != ALUType.INC && type != ALUType.DEC) if (type != ALUType.INC && type != ALUType.DEC && type != ALUType.CP)
registers.setA(result); registers.setA(result);
return 0; return 0;

View File

@ -0,0 +1,13 @@
package playingcoffee.core.opcode;
import playingcoffee.core.MMU;
import playingcoffee.core.cpu.Registers;
public class BCDOpcode implements Opcode {
@Override
public int run(Registers registers, MMU mmu) {
return 0;
}
}

View File

@ -26,10 +26,7 @@ public class CallOpcode implements Opcode {
int addressToJump = address.read(registers, mmu); int addressToJump = address.read(registers, mmu);
if (canExecute(registers)) { if (canExecute(registers)) {
registers.decSP(); mmu.pushStack(registers.getPC(), registers);
mmu.write(registers.getPC() >> 8, registers.getSP());
registers.decSP();
mmu.write(registers.getPC(), registers.getSP());
Log.info("Pushing 0x%4x to the stack.", registers.getPC()); Log.info("Pushing 0x%4x to the stack.", registers.getPC());

View File

@ -10,7 +10,7 @@ public class ComplementOpcode implements Opcode {
public int run(Registers registers, MMU mmu) { public int run(Registers registers, MMU mmu) {
registers.setA(~registers.getA()); registers.setA(~registers.getA());
registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY, false); registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY, true);
return 0; return 0;
} }

View File

@ -6,6 +6,8 @@ import playingcoffee.core.cpu.Registers;
public class FlipCarryOpcode implements Opcode { public class FlipCarryOpcode implements Opcode {
// NOTE: Tetris does not use this opcode.
@Override @Override
public int run(Registers registers, MMU mmu) { public int run(Registers registers, MMU mmu) {
registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY, false); registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY, false);

View File

@ -2,6 +2,7 @@ package playingcoffee.core.opcode;
import playingcoffee.core.MMU; import playingcoffee.core.MMU;
import playingcoffee.core.cpu.Registers; import playingcoffee.core.cpu.Registers;
import playingcoffee.log.Log;
public class PopOpcode implements Opcode { public class PopOpcode implements Opcode {
@ -13,14 +14,12 @@ public class PopOpcode implements Opcode {
@Override @Override
public int run(Registers registers, MMU mmu) { public int run(Registers registers, MMU mmu) {
int value = mmu.read(registers.getSP()); int value = mmu.popStack(registers);
registers.incSP();
value |= mmu.read(registers.getSP()) << 8;
registers.incSP();
register.write(value, registers, mmu); register.write(value, registers, mmu);
Log.info("Popping 0x%4x from the stack.", value);
return 8; return 8;
} }

View File

@ -16,11 +16,7 @@ public class PushOpcode implements Opcode {
public int run(Registers registers, MMU mmu) { public int run(Registers registers, MMU mmu) {
int value = register.read(registers, mmu); int value = register.read(registers, mmu);
registers.decSP(); mmu.pushStack(value, registers);
mmu.write(value >> 8, registers.getSP());
registers.decSP();
mmu.write(value, registers.getSP());
Log.info("Pushing 0x%4x to the stack.", value); Log.info("Pushing 0x%4x to the stack.", value);

View File

@ -13,11 +13,7 @@ public class RestartOpcode implements Opcode {
@Override @Override
public int run(Registers registers, MMU mmu) { public int run(Registers registers, MMU mmu) {
registers.decSP(); mmu.pushStack(registers.getPC(), registers);
mmu.write(registers.getPC() >> 8, registers.getSP());
registers.decSP();
mmu.write(registers.getPC(), registers.getSP());
registers.setPC(address); registers.setPC(address);
return 12; return 12;

View File

@ -27,13 +27,8 @@ public class ReturnOpcode implements Opcode {
@Override @Override
public int run(Registers registers, MMU mmu) { public int run(Registers registers, MMU mmu) {
int addressToJump = mmu.read(registers.getSP());
registers.incSP();
addressToJump |= mmu.read(registers.getSP()) << 8;
registers.incSP();
if (canExecute(registers)) { if (canExecute(registers)) {
int addressToJump = mmu.popStack(registers);
Log.info("Returning from 0x%4x to 0x%4x", registers.getPC(), addressToJump); Log.info("Returning from 0x%4x to 0x%4x", registers.getPC(), addressToJump);
registers.setPC(addressToJump); registers.setPC(addressToJump);

View File

@ -20,7 +20,7 @@ public class RotateAOpcode implements Opcode {
@Override @Override
public int run(Registers registers, MMU mmu) { public int run(Registers registers, MMU mmu) {
if (direction == LEFT) { if (direction == LEFT) {
if (withCarry) { if (withCarry) { // NOTE: Tetris does not use this opcode.
int value = registers.getA(); int value = registers.getA();
int result = (value << 1) | ((value >> 7) & 1); int result = (value << 1) | ((value >> 7) & 1);
@ -28,7 +28,7 @@ public class RotateAOpcode implements Opcode {
registers.getFlags().set(Flags.CARRY, (value & 0x80) != 0); registers.getFlags().set(Flags.CARRY, (value & 0x80) != 0);
registers.setA(result); registers.setA(result);
} else { } else { // NOTE: Tetris only uses this opcode.
int value = registers.getA(); int value = registers.getA();
int result = (value << 1) | (registers.getFlags().get(Flags.CARRY) ? 1 : 0); int result = (value << 1) | (registers.getFlags().get(Flags.CARRY) ? 1 : 0);
@ -37,7 +37,7 @@ public class RotateAOpcode implements Opcode {
registers.setA(result); registers.setA(result);
} }
} else { } else { // NOTE: Tetris does not use this opcode.
if (withCarry) { if (withCarry) {
int value = registers.getA(); int value = registers.getA();
int result = (value >> 1) | ((value & 1) << 7); int result = (value >> 1) | ((value & 1) << 7);
@ -46,7 +46,7 @@ public class RotateAOpcode implements Opcode {
registers.getFlags().set(Flags.CARRY, (value & 1) != 0); registers.getFlags().set(Flags.CARRY, (value & 1) != 0);
registers.setA(result); registers.setA(result);
} else { } else { // NOTE: Tetris does not use this opcode.
int value = registers.getA(); int value = registers.getA();
int result = (value >> 1) | ((registers.getFlags().get(Flags.CARRY) ? 1 : 0) << 7); int result = (value >> 1) | ((registers.getFlags().get(Flags.CARRY) ? 1 : 0) << 7);

View File

@ -6,6 +6,8 @@ import playingcoffee.core.cpu.Registers;
public class SetCarryOpcode implements Opcode { public class SetCarryOpcode implements Opcode {
// NOTE: Tetris does not use this opcode.
@Override @Override
public int run(Registers registers, MMU mmu) { public int run(Registers registers, MMU mmu) {
registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY, false); registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY, false);

View File

@ -0,0 +1,24 @@
package playingcoffee.core.opcode;
import playingcoffee.core.MMU;
import playingcoffee.core.cpu.CPU;
import playingcoffee.core.cpu.Registers;
public class StopOpcode implements Opcode {
private CPU cpu;
public StopOpcode(CPU cpu) {
this.cpu = cpu;
}
@Override
public int run(Registers registers, MMU mmu) {
cpu.enterLowPowerMode();
registers.incPC();
return 0;
}
}

View File

@ -24,16 +24,36 @@ public class RotateOpcode implements Opcode {
@Override @Override
public int run(Registers registers, MMU mmu) { public int run(Registers registers, MMU mmu) {
if (direction == LEFT) { if (direction == LEFT) {
int value = register.read(registers, mmu); /*int value = register.read(registers, mmu);
int result = (value << 1) | (!withCarry ? (registers.getFlags().get(Flags.CARRY) ? 1 : 0) : (value >> 7) & 1); int result = (value << 1) | (!withCarry ? (registers.getFlags().get(Flags.CARRY) ? 1 : 0) : (value >> 7) & 1);
registers.getFlags().set(Flags.ZERO, result == 0); registers.getFlags().set(Flags.ZERO, result == 0);
registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY, false); registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY, false);
registers.getFlags().set(Flags.CARRY, (value & 0x80) != 0); registers.getFlags().set(Flags.CARRY, (value & 0x80) != 0);
register.write(result, registers, mmu); register.write(result, registers, mmu);*/
if (withCarry) {
int value = register.read(registers, mmu);
int result = (value << 1) | ((value >> 7) & 1);
registers.getFlags().set(Flags.ZERO, result == 0);
registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY, false);
registers.getFlags().set(Flags.CARRY, (value & 0x80) != 0);
register.write(result, registers, mmu);
} else { } else {
int value = register.read(registers, mmu);
int result = (value << 1) | (registers.getFlags().get(Flags.CARRY) ? 1 : 0);
registers.getFlags().set(Flags.ZERO, result == 0);
registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY, false);
registers.getFlags().set(Flags.CARRY, (value & 0x80) != 0);
register.write(result, registers, mmu);
}
} else { // NOTE: Tetris does not use this opcode.
int value = register.read(registers, mmu); int value = register.read(registers, mmu);
int result = (value >> 1) | ((!withCarry ? (registers.getFlags().get(Flags.CARRY) ? 1 : 0) : (value & 0x1)) << 7); int result = (value >> 1) | ((!withCarry ? (registers.getFlags().get(Flags.CARRY) ? 1 : 0) : (value & 0x1)) << 7);

View File

@ -10,6 +10,8 @@ public class SetBitOpcode implements Opcode {
private int bit; private int bit;
private Argument argument; private Argument argument;
// NOTE: Tetris does not use this opcode.
public SetBitOpcode(int bit, Argument argument) { public SetBitOpcode(int bit, Argument argument) {
this.bit = bit; this.bit = bit;
this.argument = argument; this.argument = argument;

View File

@ -20,6 +20,8 @@ public class ShiftOpcode implements Opcode {
SLA, SRA, SRL SLA, SRA, SRL
} }
// NOTE: Tetris does not use these opcodes.
@Override @Override
public int run(Registers registers, MMU mmu) { public int run(Registers registers, MMU mmu) {
int value, result; int value, result;
@ -43,7 +45,7 @@ public class ShiftOpcode implements Opcode {
break; break;
case SRL: case SRL:
value = register.read(registers, mmu); value = register.read(registers, mmu);
result = (value >> 1); result = (value >> 1) | ((value << 7) & 0x80);
registers.getFlags().set(Flags.ZERO, result == 0); registers.getFlags().set(Flags.ZERO, result == 0);
registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY, false); registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY, false);

View File

@ -1,6 +1,7 @@
package playingcoffee.core.opcode.prefixed; package playingcoffee.core.opcode.prefixed;
import playingcoffee.core.MMU; import playingcoffee.core.MMU;
import playingcoffee.core.cpu.Flags;
import playingcoffee.core.cpu.Registers; import playingcoffee.core.cpu.Registers;
import playingcoffee.core.opcode.Argument; import playingcoffee.core.opcode.Argument;
import playingcoffee.core.opcode.Opcode; import playingcoffee.core.opcode.Opcode;
@ -16,8 +17,12 @@ public class SwapOpcode implements Opcode {
@Override @Override
public int run(Registers registers, MMU mmu) { public int run(Registers registers, MMU mmu) {
int value = register.read(registers, mmu); int value = register.read(registers, mmu);
int result = ((value & 0xF0) >> 4) | ((value & 0xF) << 4);
register.write(((value & 0xF0) >> 4) | ((value & 0xF) << 4), registers, mmu); register.write(result, registers, mmu);
registers.getFlags().set(Flags.ZERO, result == 0);
registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY | Flags.CARRY, false);
return register.getCycles() * 2; return register.getCycles() * 2;
} }

View File

@ -17,13 +17,17 @@ public class PPU {
this.mmu = mmu; this.mmu = mmu;
this.interruptManager = interruptManager; this.interruptManager = interruptManager;
registers = new PPURegisters(); registers = new PPURegisters(this);
vram = new VRAM(); vram = new VRAM();
this.mmu.connectMemorySpace(registers); this.mmu.connectMemorySpace(registers);
this.mmu.connectMemorySpace(vram); this.mmu.connectMemorySpace(vram);
} }
public void onLCDDisable() {
clockCount = 0;
}
public void OAMSeach() { public void OAMSeach() {
registers.setLCDCMode(2); registers.setLCDCMode(2);
} }

View File

@ -14,6 +14,13 @@ public class PPURegisters implements MemorySpace {
public int objPalette0, objPalette1; // 0xFF48 - 0xFF49 public int objPalette0, objPalette1; // 0xFF48 - 0xFF49
public int windowY, windowX; // 0xFF4A - 0xFF4B public int windowY, windowX; // 0xFF4A - 0xFF4B
@SuppressWarnings("unused")
private final PPU ppu;
public PPURegisters(PPU ppu) {
this.ppu = ppu;
}
public void setLCDCMode(int mode) { public void setLCDCMode(int mode) {
lcdcStatus = (lcdcStatus & 0xFC) | mode; lcdcStatus = (lcdcStatus & 0xFC) | mode;
} }
@ -43,6 +50,7 @@ public class PPURegisters implements MemorySpace {
case 0xFF41: lcdcStatus = value; return; case 0xFF41: lcdcStatus = value; return;
case 0xFF42: scrollY = value; return; case 0xFF42: scrollY = value; return;
case 0xFF43: scrollX = value; return; case 0xFF43: scrollX = value; return;
case 0xFF44: return;
case 0xFF45: lyCompare = value; return; case 0xFF45: lyCompare = value; return;
case 0xFF46: dmaTransferStart = value; return; // TODO: Do DMA (I have no idea how to do it though...) case 0xFF46: dmaTransferStart = value; return; // TODO: Do DMA (I have no idea how to do it though...)
case 0xFF47: bgPalette = value; return; case 0xFF47: bgPalette = value; return;

View File

@ -1,9 +1,13 @@
package playingcoffee.test; package playingcoffee.test;
import static org.junit.Assert.assertEquals;
import java.io.IOException; import java.io.IOException;
import org.junit.Test; import org.junit.Test;
import playingcoffee.core.cpu.Flags;
public class GameBoyTest { public class GameBoyTest {
@Test @Test
@ -23,4 +27,22 @@ public class GameBoyTest {
while (true) cpu.clock();*/ while (true) cpu.clock();*/
} }
@Test
public void testFlags() {
Flags flags = new Flags();
assertEquals(flags.get(), 0);
flags.set(Flags.ZERO | Flags.CARRY, true);
assertEquals(flags.get(), Flags.ZERO | Flags.CARRY);
flags.set(Flags.ZERO | Flags.HALF_CARRY, false);
assertEquals(flags.get(), Flags.CARRY);
flags.set(Flags.CARRY, true);
assertEquals(flags.get(), Flags.CARRY);
}
} }